tcx_cursor.c revision e4da13ee
1/*
2 * Hardware cursor support for TCX
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/* $XFree86:$ */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "tcx.h"
33
34static void TCXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
35static void TCXShowCursor(ScrnInfoPtr pScrn);
36static void TCXHideCursor(ScrnInfoPtr pScrn);
37static void TCXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
38static void TCXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
39
40static void
41TCXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
42{
43    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
44    int i, x, y;
45    unsigned int *data = (unsigned int *)src;
46
47    pTcx->CursorData = src;
48    x = pTcx->CursorShiftX;
49    y = pTcx->CursorShiftY;
50    if (x >= 32 || y >= 32)
51	y = 32;
52    data += y;
53    for (i = 0; i < 32 - y; i++)
54	pTcx->thc->thc_cursmask[i] = *data++ << x;
55    for (; i < 32; i++)
56	pTcx->thc->thc_cursmask[i] = 0;
57    data += y;
58    for (i = 0; i < 32 - y; i++)
59	pTcx->thc->thc_cursbits[i] = *data++ << x;
60    for (; i < 32; i++)
61	pTcx->thc->thc_cursbits[i] = 0;
62}
63
64static void
65TCXShowCursor(ScrnInfoPtr pScrn)
66{
67    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
68
69    pTcx->thc->thc_cursxy = pTcx->CursorXY;
70    pTcx->CursorEnabled = TRUE;
71}
72
73static void
74TCXHideCursor(ScrnInfoPtr pScrn)
75{
76    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
77
78    pTcx->thc->thc_cursxy = ((65536 - 32) << 16) | (65536 - 32);
79    pTcx->CursorEnabled = FALSE;
80}
81
82static void
83TCXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
84{
85    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
86    int CursorShiftX = 0, CursorShiftY = 0;
87
88    if (x < 0) {
89	CursorShiftX = -x;
90	x = 0;
91	if (CursorShiftX > 32)
92	    CursorShiftX = 32;
93    }
94    if (y < 0) {
95	CursorShiftY = -y;
96	y = 0;
97	if (CursorShiftY > 32)
98	    CursorShiftY = 32;
99    }
100    if ((CursorShiftX != pTcx->CursorShiftX ||
101	 CursorShiftY != pTcx->CursorShiftY) &&
102	 pTcx->CursorData != NULL) {
103	pTcx->CursorShiftX = CursorShiftX;
104	pTcx->CursorShiftY = CursorShiftY;
105	TCXLoadCursorImage(pScrn, pTcx->CursorData);
106    }
107
108    pTcx->CursorXY = ((x & 0xffff) << 16) | (y & 0xffff);
109    if (pTcx->CursorEnabled)
110	pTcx->thc->thc_cursxy = pTcx->CursorXY;
111}
112
113static void
114TCXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
115{
116    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
117
118    if (bg != pTcx->CursorBg || fg != pTcx->CursorFg) {
119	xf86SbusSetOsHwCursorCmap(pTcx->psdp, bg, fg);
120	pTcx->CursorBg = bg;
121	pTcx->CursorFg = fg;
122    }
123}
124
125Bool
126TCXHWCursorInit(ScreenPtr pScreen)
127{
128    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
129    TcxPtr pTcx;
130    xf86CursorInfoPtr infoPtr;
131
132    pTcx = GET_TCX_FROM_SCRN(pScrn);
133    pTcx->CursorXY = 0;
134    pTcx->CursorBg = pTcx->CursorFg = 0;
135    pTcx->CursorEnabled = FALSE;
136    pTcx->CursorShiftX = 0;
137    pTcx->CursorShiftY = 0;
138    pTcx->CursorData = NULL;
139
140    infoPtr = xf86CreateCursorInfoRec();
141    if(!infoPtr) return FALSE;
142
143    pTcx->CursorInfoRec = infoPtr;
144
145    infoPtr->MaxWidth = 32;
146    infoPtr->MaxHeight = 32;
147    infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
148	HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
149	HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED |
150	HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
151
152    infoPtr->SetCursorColors = TCXSetCursorColors;
153    infoPtr->SetCursorPosition = TCXSetCursorPosition;
154    infoPtr->LoadCursorImage = TCXLoadCursorImage;
155    infoPtr->HideCursor = TCXHideCursor;
156    infoPtr->ShowCursor = TCXShowCursor;
157    infoPtr->UseHWCursor = NULL;
158
159    return xf86InitCursor(pScreen, infoPtr);
160}
161