leo_cursor.c revision 4a041c5b
1/*
2 * Hardware cursor support for Leo (ZX)
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 "leo.h"
33
34static void LeoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
35static void LeoShowCursor(ScrnInfoPtr pScrn);
36static void LeoHideCursor(ScrnInfoPtr pScrn);
37static void LeoSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
38static void LeoSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
39
40static void
41LeoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
42{
43    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
44    int i, j, x, y;
45    unsigned int *data = (unsigned int *)src, value;
46
47    pLeo->CursorData = src;
48    x = pLeo->CursorShiftX;
49    y = pLeo->CursorShiftY;
50    if (x >= 32 || y >= 32)
51	y = 32;
52    pLeo->dac->cur_type = 0;
53    for (j = 0; j < 2; j++) {
54	data += y;
55	for (i = y; i < 32; i++, data++) {
56	    value = (*data >> 16) | (*data << 16);
57	    value = ((value & 0xff00ff00) >> 8) |
58		    ((value & 0x00ff00ff) << 8);
59	    pLeo->dac->cur_data = value >> x;
60	}
61	for (i = 0; i < y; i++)
62	    pLeo->dac->cur_data = 0;
63    }
64}
65
66static void
67LeoShowCursor(ScrnInfoPtr pScrn)
68{
69    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
70
71    pLeo->dac->cur_misc |= 0x80;
72}
73
74static void
75LeoHideCursor(ScrnInfoPtr pScrn)
76{
77    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
78
79    pLeo->dac->cur_misc &= ~0x80;
80    pLeo->CursorData = NULL;
81}
82
83static void
84LeoSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
85{
86    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
87    int CursorShiftX = 0, CursorShiftY = 0;
88
89    if (x < 0) {
90	CursorShiftX = -x;
91	x = 0;
92	if (CursorShiftX > 32)
93	    CursorShiftX = 32;
94    }
95    if (y < 0) {
96	CursorShiftY = -y;
97	y = 0;
98	if (CursorShiftY > 32)
99	    CursorShiftY = 32;
100    }
101    pLeo->dac->cur_misc &= ~0x80;
102    if ((CursorShiftX != pLeo->CursorShiftX ||
103	 CursorShiftY != pLeo->CursorShiftY) &&
104	pLeo->CursorData != NULL) {
105	pLeo->CursorShiftX = CursorShiftX;
106	pLeo->CursorShiftY = CursorShiftY;
107	LeoLoadCursorImage(pScrn, pLeo->CursorData);
108    }
109
110    pLeo->dac->cur_cursxy = ((y & 0x7ff) << 11) | (x & 0x7ff);
111    pLeo->dac->cur_misc |= 0x30;
112    pLeo->dac->cur_misc |= 0x80;
113}
114
115static void
116LeoSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
117{
118    LeoPtr pLeo = GET_LEO_FROM_SCRN(pScrn);
119
120    pLeo->dac->cur_type = 0x50;
121    pLeo->dac->cur_data = bg;
122    pLeo->dac->cur_data = fg;
123    pLeo->dac->cur_misc |= 0x03;
124}
125
126Bool
127LeoHWCursorInit(ScreenPtr pScreen)
128{
129    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
130    LeoPtr pLeo;
131    xf86CursorInfoPtr infoPtr;
132
133    pLeo = GET_LEO_FROM_SCRN(pScrn);
134    pLeo->CursorShiftX = 0;
135    pLeo->CursorShiftY = 0;
136    pLeo->CursorData = NULL;
137
138    infoPtr = xf86CreateCursorInfoRec();
139    if(!infoPtr) return FALSE;
140
141    pLeo->CursorInfoRec = infoPtr;
142    pLeo->dac = (LeoCursor *)((char *)pLeo->fb + LEO_LX0_CURSOR_VOFF);
143
144    infoPtr->MaxWidth = 32;
145    infoPtr->MaxHeight = 32;
146    infoPtr->Flags =  HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
147	HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
148	HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
149	HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
150
151    infoPtr->SetCursorColors = LeoSetCursorColors;
152    infoPtr->SetCursorPosition = LeoSetCursorPosition;
153    infoPtr->LoadCursorImage = LeoLoadCursorImage;
154    infoPtr->HideCursor = LeoHideCursor;
155    infoPtr->ShowCursor = LeoShowCursor;
156    infoPtr->UseHWCursor = NULL;
157
158    return xf86InitCursor(pScreen, infoPtr);
159}
160