1/* $NetBSD: igs_cursor.c,v 1.4 2016/08/18 09:32:26 mrg Exp $ */
2/*
3 * Copyright (c) 2005 Michael Lorenz
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 *    - Redistributions of source code must retain the above copyright
11 *      notice, this list of conditions and the following disclaimer.
12 *    - Redistributions in binary form must reproduce the above
13 *      copyright notice, this list of conditions and the following
14 *      disclaimer in the documentation and/or other materials provided
15 *      with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 */
31
32#include <fcntl.h>
33#include <sys/types.h>
34#include <sys/time.h>
35#include <sys/endian.h>
36#include <dev/wscons/wsconsio.h>
37#include <sys/ioctl.h>
38#include <errno.h>
39
40#include "igs.h"
41
42static void IgsLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
43static void IgsSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
44static void IgsSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
45
46static void
47IgsLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
48{
49	IgsPtr pIgs = IGSPTR(pScrn);
50	int err, i;
51
52	pIgs->cursor.which = WSDISPLAY_CURSOR_DOALL;
53	pIgs->cursor.image = src;
54	pIgs->cursor.mask = src + pIgs->maskoffset;
55	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
56		xf86Msg(X_ERROR, "IgsLoadCursorImage: %d\n", errno);
57}
58
59void
60IgsShowCursor(ScrnInfoPtr pScrn)
61{
62	IgsPtr pIgs = IGSPTR(pScrn);
63
64	pIgs->cursor.which = WSDISPLAY_CURSOR_DOCUR;
65	pIgs->cursor.enable = 1;
66	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
67		xf86Msg(X_ERROR, "IgsShowCursor: %d\n", errno);
68}
69
70void
71IgsHideCursor(ScrnInfoPtr pScrn)
72{
73	IgsPtr pIgs = IGSPTR(pScrn);
74
75	pIgs->cursor.which = WSDISPLAY_CURSOR_DOCUR;
76	pIgs->cursor.enable = 0;
77	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
78		xf86Msg(X_ERROR, "IgsHideCursor: %d\n", errno);
79}
80
81static void
82IgsSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
83{
84	IgsPtr pIgs = IGSPTR(pScrn);
85	int xoff = 0, yoff = 0;
86
87	pIgs->cursor.which = WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT;
88
89	if (x < 0) {
90		xoff = -x;
91		x = 0;
92	}
93	if (y < 0) {
94		yoff = -y;
95		y = 0;
96	}
97
98	pIgs->cursor.pos.x = x;
99	pIgs->cursor.hot.x = xoff;
100	pIgs->cursor.pos.y = y;
101	pIgs->cursor.hot.y = yoff;
102
103	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
104		xf86Msg(X_ERROR, "IgsSetCursorPosition: %d\n", errno);
105}
106
107static void
108IgsSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
109{
110	IgsPtr pIgs = IGSPTR(pScrn);
111	u_char r[4], g[4], b[4];
112
113	pIgs->cursor.which = WSDISPLAY_CURSOR_DOCMAP;
114	pIgs->cursor.cmap.red = r;
115	pIgs->cursor.cmap.green = g;
116	pIgs->cursor.cmap.blue = b;
117	r[1] = fg & 0xff;
118	g[1] = (fg & 0xff00) >> 8;
119	b[1] = (fg & 0xff0000) >> 16;
120	r[0] = bg & 0xff;
121	g[0] = (bg & 0xff00) >> 8;
122	b[0] = (bg & 0xff0000) >> 16;
123	pIgs->cursor.cmap.index = 0;
124	pIgs->cursor.cmap.count = 2;
125	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
126		xf86Msg(X_ERROR, "IgsSetCursorColors: %d\n", errno);
127}
128
129Bool
130IgsSetupCursor(ScreenPtr pScreen)
131{
132	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
133	IgsPtr pIgs = IGSPTR(pScrn);
134	xf86CursorInfoPtr infoPtr;
135
136	pIgs->cursor.pos.x = 0;
137	pIgs->cursor.pos.y = 0;
138	pIgs->cursor.enable = 0;
139
140	infoPtr = xf86CreateCursorInfoRec();
141	if(!infoPtr) return FALSE;
142
143	pIgs->CursorInfoRec = infoPtr;
144	if(ioctl(pIgs->fd, WSDISPLAYIO_GCURMAX, &pIgs->cursor.size) == -1) {
145		xf86Msg(X_WARNING, "No HW cursor support found\n");
146		return FALSE;
147	}
148
149	xf86Msg(X_INFO, "HW cursor enabled\n");
150
151	infoPtr->MaxWidth = pIgs->cursor.size.x;
152	infoPtr->MaxHeight = pIgs->cursor.size.y;
153	pIgs->maskoffset = ( pIgs->cursor.size.x >> 3) * pIgs->cursor.size.y;
154
155	pIgs->cursor.hot.x = 0;
156	pIgs->cursor.hot.y = 0;
157	pIgs->cursor.which = WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCUR |
158	    WSDISPLAY_CURSOR_DOPOS;
159	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
160		xf86Msg(X_ERROR, "WSDISPLAYIO_SCURSOR: %d\n", errno);
161
162	infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
163	    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
164/* XXX not sure why exactly we need this */
165#if BYTE_ORDER == BIG_ENDIAN
166	    | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
167#endif
168	;
169	infoPtr->SetCursorColors = IgsSetCursorColors;
170	infoPtr->SetCursorPosition = IgsSetCursorPosition;
171	infoPtr->LoadCursorImage = IgsLoadCursorImage;
172	infoPtr->HideCursor = IgsHideCursor;
173	infoPtr->ShowCursor = IgsShowCursor;
174	infoPtr->UseHWCursor = NULL;
175
176	return xf86InitCursor(pScreen, infoPtr);
177}
178