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