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