1e4da13eeSmacallan/*
2e4da13eeSmacallan * Hardware cursor support for TCX
3e4da13eeSmacallan *
4e4da13eeSmacallan * Copyright 2000 by Jakub Jelinek <jakub@redhat.com>.
5e4da13eeSmacallan *
6e4da13eeSmacallan * Permission to use, copy, modify, distribute, and sell this software
7e4da13eeSmacallan * and its documentation for any purpose is hereby granted without
8e4da13eeSmacallan * fee, provided that the above copyright notice appear in all copies
9e4da13eeSmacallan * and that both that copyright notice and this permission notice
10e4da13eeSmacallan * appear in supporting documentation, and that the name of Jakub
11e4da13eeSmacallan * Jelinek not be used in advertising or publicity pertaining to
12e4da13eeSmacallan * distribution of the software without specific, written prior
13e4da13eeSmacallan * permission.  Jakub Jelinek makes no representations about the
14e4da13eeSmacallan * suitability of this software for any purpose.  It is provided "as
15e4da13eeSmacallan * is" without express or implied warranty.
16e4da13eeSmacallan *
17e4da13eeSmacallan * JAKUB JELINEK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
18e4da13eeSmacallan * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19e4da13eeSmacallan * FITNESS, IN NO EVENT SHALL JAKUB JELINEK BE LIABLE FOR ANY
20e4da13eeSmacallan * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21e4da13eeSmacallan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
22e4da13eeSmacallan * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23e4da13eeSmacallan * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24e4da13eeSmacallan * SOFTWARE.
25e4da13eeSmacallan */
26e4da13eeSmacallan
27e4da13eeSmacallan#ifdef HAVE_CONFIG_H
28e4da13eeSmacallan#include "config.h"
29e4da13eeSmacallan#endif
30e4da13eeSmacallan
31e4da13eeSmacallan#include "tcx.h"
32e4da13eeSmacallan
33e4da13eeSmacallanstatic void TCXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
34e4da13eeSmacallanstatic void TCXShowCursor(ScrnInfoPtr pScrn);
35e4da13eeSmacallanstatic void TCXHideCursor(ScrnInfoPtr pScrn);
36e4da13eeSmacallanstatic void TCXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
37e4da13eeSmacallanstatic void TCXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
38e4da13eeSmacallan
39e4da13eeSmacallanstatic void
40e4da13eeSmacallanTCXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
41e4da13eeSmacallan{
42e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
43e4da13eeSmacallan    int i, x, y;
44e4da13eeSmacallan    unsigned int *data = (unsigned int *)src;
45e4da13eeSmacallan
46e4da13eeSmacallan    pTcx->CursorData = src;
47e4da13eeSmacallan    x = pTcx->CursorShiftX;
48e4da13eeSmacallan    y = pTcx->CursorShiftY;
49e4da13eeSmacallan    if (x >= 32 || y >= 32)
50e4da13eeSmacallan	y = 32;
51e4da13eeSmacallan    data += y;
52e4da13eeSmacallan    for (i = 0; i < 32 - y; i++)
53e4da13eeSmacallan	pTcx->thc->thc_cursmask[i] = *data++ << x;
54e4da13eeSmacallan    for (; i < 32; i++)
55e4da13eeSmacallan	pTcx->thc->thc_cursmask[i] = 0;
56e4da13eeSmacallan    data += y;
57e4da13eeSmacallan    for (i = 0; i < 32 - y; i++)
58e4da13eeSmacallan	pTcx->thc->thc_cursbits[i] = *data++ << x;
59e4da13eeSmacallan    for (; i < 32; i++)
60e4da13eeSmacallan	pTcx->thc->thc_cursbits[i] = 0;
61e4da13eeSmacallan}
62e4da13eeSmacallan
63e4da13eeSmacallanstatic void
64e4da13eeSmacallanTCXShowCursor(ScrnInfoPtr pScrn)
65e4da13eeSmacallan{
66e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
67e4da13eeSmacallan
68e4da13eeSmacallan    pTcx->thc->thc_cursxy = pTcx->CursorXY;
69e4da13eeSmacallan    pTcx->CursorEnabled = TRUE;
70e4da13eeSmacallan}
71e4da13eeSmacallan
72e4da13eeSmacallanstatic void
73e4da13eeSmacallanTCXHideCursor(ScrnInfoPtr pScrn)
74e4da13eeSmacallan{
75e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
76e4da13eeSmacallan
77e4da13eeSmacallan    pTcx->thc->thc_cursxy = ((65536 - 32) << 16) | (65536 - 32);
78e4da13eeSmacallan    pTcx->CursorEnabled = FALSE;
79e4da13eeSmacallan}
80e4da13eeSmacallan
81e4da13eeSmacallanstatic void
82e4da13eeSmacallanTCXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
83e4da13eeSmacallan{
84e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
85e4da13eeSmacallan    int CursorShiftX = 0, CursorShiftY = 0;
86e4da13eeSmacallan
87e4da13eeSmacallan    if (x < 0) {
88e4da13eeSmacallan	CursorShiftX = -x;
89e4da13eeSmacallan	x = 0;
90e4da13eeSmacallan	if (CursorShiftX > 32)
91e4da13eeSmacallan	    CursorShiftX = 32;
92e4da13eeSmacallan    }
93e4da13eeSmacallan    if (y < 0) {
94e4da13eeSmacallan	CursorShiftY = -y;
95e4da13eeSmacallan	y = 0;
96e4da13eeSmacallan	if (CursorShiftY > 32)
97e4da13eeSmacallan	    CursorShiftY = 32;
98e4da13eeSmacallan    }
99e4da13eeSmacallan    if ((CursorShiftX != pTcx->CursorShiftX ||
100e4da13eeSmacallan	 CursorShiftY != pTcx->CursorShiftY) &&
101e4da13eeSmacallan	 pTcx->CursorData != NULL) {
102e4da13eeSmacallan	pTcx->CursorShiftX = CursorShiftX;
103e4da13eeSmacallan	pTcx->CursorShiftY = CursorShiftY;
104e4da13eeSmacallan	TCXLoadCursorImage(pScrn, pTcx->CursorData);
105e4da13eeSmacallan    }
106e4da13eeSmacallan
107e4da13eeSmacallan    pTcx->CursorXY = ((x & 0xffff) << 16) | (y & 0xffff);
108e4da13eeSmacallan    if (pTcx->CursorEnabled)
109e4da13eeSmacallan	pTcx->thc->thc_cursxy = pTcx->CursorXY;
110e4da13eeSmacallan}
111e4da13eeSmacallan
112e4da13eeSmacallanstatic void
113e4da13eeSmacallanTCXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
114e4da13eeSmacallan{
115e4da13eeSmacallan    TcxPtr pTcx = GET_TCX_FROM_SCRN(pScrn);
116e4da13eeSmacallan
117e4da13eeSmacallan    if (bg != pTcx->CursorBg || fg != pTcx->CursorFg) {
118e4da13eeSmacallan	xf86SbusSetOsHwCursorCmap(pTcx->psdp, bg, fg);
119e4da13eeSmacallan	pTcx->CursorBg = bg;
120e4da13eeSmacallan	pTcx->CursorFg = fg;
121e4da13eeSmacallan    }
122e4da13eeSmacallan}
123e4da13eeSmacallan
124e4da13eeSmacallanBool
125e4da13eeSmacallanTCXHWCursorInit(ScreenPtr pScreen)
126e4da13eeSmacallan{
12765d490d0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
128e4da13eeSmacallan    TcxPtr pTcx;
129e4da13eeSmacallan    xf86CursorInfoPtr infoPtr;
130e4da13eeSmacallan
131e4da13eeSmacallan    pTcx = GET_TCX_FROM_SCRN(pScrn);
132e4da13eeSmacallan    pTcx->CursorXY = 0;
133e4da13eeSmacallan    pTcx->CursorBg = pTcx->CursorFg = 0;
134e4da13eeSmacallan    pTcx->CursorEnabled = FALSE;
135e4da13eeSmacallan    pTcx->CursorShiftX = 0;
136e4da13eeSmacallan    pTcx->CursorShiftY = 0;
137e4da13eeSmacallan    pTcx->CursorData = NULL;
138e4da13eeSmacallan
139e4da13eeSmacallan    infoPtr = xf86CreateCursorInfoRec();
140e4da13eeSmacallan    if(!infoPtr) return FALSE;
141e4da13eeSmacallan
142e4da13eeSmacallan    pTcx->CursorInfoRec = infoPtr;
143e4da13eeSmacallan
144e4da13eeSmacallan    infoPtr->MaxWidth = 32;
145e4da13eeSmacallan    infoPtr->MaxHeight = 32;
146e4da13eeSmacallan    infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
147e4da13eeSmacallan	HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
148e4da13eeSmacallan	HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED |
149e4da13eeSmacallan	HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
150e4da13eeSmacallan
151e4da13eeSmacallan    infoPtr->SetCursorColors = TCXSetCursorColors;
152e4da13eeSmacallan    infoPtr->SetCursorPosition = TCXSetCursorPosition;
153e4da13eeSmacallan    infoPtr->LoadCursorImage = TCXLoadCursorImage;
154e4da13eeSmacallan    infoPtr->HideCursor = TCXHideCursor;
155e4da13eeSmacallan    infoPtr->ShowCursor = TCXShowCursor;
156e4da13eeSmacallan    infoPtr->UseHWCursor = NULL;
157e4da13eeSmacallan
158e4da13eeSmacallan    return xf86InitCursor(pScreen, infoPtr);
159e4da13eeSmacallan}
160