1/*
2 * Hardware cursor support for Creator, Creator 3D and Elite 3D
3 *
4 * Copyright 2000 by Jakub Jelinek <jakub@redhat.com>.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software
7 * and its documentation for any purpose is hereby granted without
8 * fee, provided that the above copyright notice appear in all copies
9 * and that both that copyright notice and this permission notice
10 * appear in supporting documentation, and that the name of Jakub
11 * Jelinek not be used in advertising or publicity pertaining to
12 * distribution of the software without specific, written prior
13 * permission.  Jakub Jelinek makes no representations about the
14 * suitability of this software for any purpose.  It is provided "as
15 * is" without express or implied warranty.
16 *
17 * JAKUB JELINEK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 * FITNESS, IN NO EVENT SHALL JAKUB JELINEK BE LIABLE FOR ANY
20 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
22 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24 * SOFTWARE.
25 */
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include "ffb.h"
32
33/* This file just performs cursor software state management.  The
34 * actual programming is done by calls into the DAC layer.
35 */
36
37static void FFBLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
38static void FFBShowCursor(ScrnInfoPtr pScrn);
39static void FFBHideCursor(ScrnInfoPtr pScrn);
40static void FFBSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
41static void FFBSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
42
43static void
44FFBLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
45{
46    FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
47    unsigned int *data = (unsigned int *)src;
48    int x, y;
49
50    pFfb->CursorData = src;
51    x = pFfb->CursorShiftX;
52    y = pFfb->CursorShiftY;
53    if (x >= 64 || y >= 64)
54	y = 64;
55    FFBDacCursorLoadBitmap(pFfb, x, y, data);
56}
57
58static void
59FFBShowCursor(ScrnInfoPtr pScrn)
60{
61    FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
62
63    FFBDacCursorEnableDisable(pFfb, 1);
64}
65
66static void
67FFBHideCursor(ScrnInfoPtr pScrn)
68{
69    FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
70
71    FFBDacCursorEnableDisable(pFfb, 0);
72    pFfb->CursorData = NULL;
73}
74
75static void
76FFBSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
77{
78    FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
79    int CursorShiftX = 0, CursorShiftY = 0;
80
81    if (x < 0) {
82	CursorShiftX = -x;
83	x = 0;
84	if (CursorShiftX > 64)
85	    CursorShiftX = 64;
86    }
87    if (y < 0) {
88	CursorShiftY = -y;
89	y = 0;
90	if (CursorShiftY > 64)
91	    CursorShiftY = 64;
92    }
93    if ((CursorShiftX != pFfb->CursorShiftX ||
94	 CursorShiftY != pFfb->CursorShiftY) &&
95	pFfb->CursorData != NULL) {
96	pFfb->CursorShiftX = CursorShiftX;
97	pFfb->CursorShiftY = CursorShiftY;
98	FFBLoadCursorImage(pScrn, pFfb->CursorData);
99    }
100
101    FFBDacLoadCursorPos(pFfb, x, y);
102}
103
104static void
105FFBSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
106{
107    FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
108
109    FFBDacLoadCursorColor(pFfb, fg, bg);
110}
111
112Bool
113FFBHWCursorInit(ScreenPtr pScreen)
114{
115    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
116    FFBPtr pFfb;
117    xf86CursorInfoPtr infoPtr;
118
119    pFfb = GET_FFB_FROM_SCRN(pScrn);
120    pFfb->CursorShiftX = 0;
121    pFfb->CursorShiftY = 0;
122    pFfb->CursorData = NULL;
123
124    infoPtr = xf86CreateCursorInfoRec();
125    if(!infoPtr) return FALSE;
126
127    pFfb->CursorInfoRec = infoPtr;
128
129    infoPtr->MaxWidth = 64;
130    infoPtr->MaxHeight = 64;
131    infoPtr->Flags =  HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
132	HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
133
134    infoPtr->SetCursorColors = FFBSetCursorColors;
135    infoPtr->SetCursorPosition = FFBSetCursorPosition;
136    infoPtr->LoadCursorImage = FFBLoadCursorImage;
137    infoPtr->HideCursor = FFBHideCursor;
138    infoPtr->ShowCursor = FFBShowCursor;
139    infoPtr->UseHWCursor = NULL;
140
141    return xf86InitCursor(pScreen, infoPtr);
142}
143