igs_cursor.c revision be1ef3d3
1be1ef3d3Smacallan/* $NetBSD: igs_cursor.c,v 1.1 2009/11/10 21:39:45 macallan 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>
37be1ef3d3Smacallan#include <errno.h>
38be1ef3d3Smacallan
39be1ef3d3Smacallan/* all driver need this */
40be1ef3d3Smacallan#include "xf86.h"
41be1ef3d3Smacallan#include "xf86_OSproc.h"
42be1ef3d3Smacallan
43be1ef3d3Smacallan#include "igs.h"
44be1ef3d3Smacallan
45be1ef3d3Smacallanstatic void IgsLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
46be1ef3d3Smacallanstatic void IgsSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
47be1ef3d3Smacallanstatic void IgsSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
48be1ef3d3Smacallan
49be1ef3d3Smacallanstatic void
50be1ef3d3SmacallanIgsLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
51be1ef3d3Smacallan{
52be1ef3d3Smacallan	IgsPtr pIgs = IGSPTR(pScrn);
53be1ef3d3Smacallan	int err, i;
54be1ef3d3Smacallan
55be1ef3d3Smacallan	pIgs->cursor.which = WSDISPLAY_CURSOR_DOALL;
56be1ef3d3Smacallan	pIgs->cursor.image = src;
57be1ef3d3Smacallan	pIgs->cursor.mask = src + pIgs->maskoffset;
58be1ef3d3Smacallan	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
59be1ef3d3Smacallan		xf86Msg(X_ERROR, "IgsLoadCursorImage: %d\n", errno);
60be1ef3d3Smacallan}
61be1ef3d3Smacallan
62be1ef3d3Smacallanvoid
63be1ef3d3SmacallanIgsShowCursor(ScrnInfoPtr pScrn)
64be1ef3d3Smacallan{
65be1ef3d3Smacallan	IgsPtr pIgs = IGSPTR(pScrn);
66be1ef3d3Smacallan
67be1ef3d3Smacallan	pIgs->cursor.which = WSDISPLAY_CURSOR_DOCUR;
68be1ef3d3Smacallan	pIgs->cursor.enable = 1;
69be1ef3d3Smacallan	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
70be1ef3d3Smacallan		xf86Msg(X_ERROR, "IgsShowCursor: %d\n", errno);
71be1ef3d3Smacallan}
72be1ef3d3Smacallan
73be1ef3d3Smacallanvoid
74be1ef3d3SmacallanIgsHideCursor(ScrnInfoPtr pScrn)
75be1ef3d3Smacallan{
76be1ef3d3Smacallan	IgsPtr pIgs = IGSPTR(pScrn);
77be1ef3d3Smacallan
78be1ef3d3Smacallan	pIgs->cursor.which = WSDISPLAY_CURSOR_DOCUR;
79be1ef3d3Smacallan	pIgs->cursor.enable = 0;
80be1ef3d3Smacallan	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
81be1ef3d3Smacallan		xf86Msg(X_ERROR, "IgsHideCursor: %d\n", errno);
82be1ef3d3Smacallan}
83be1ef3d3Smacallan
84be1ef3d3Smacallanstatic void
85be1ef3d3SmacallanIgsSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
86be1ef3d3Smacallan{
87be1ef3d3Smacallan	IgsPtr pIgs = IGSPTR(pScrn);
88be1ef3d3Smacallan	int xoff = 0, yoff = 0;
89be1ef3d3Smacallan
90be1ef3d3Smacallan	pIgs->cursor.which = WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT;
91be1ef3d3Smacallan
92be1ef3d3Smacallan	if (x < 0) {
93be1ef3d3Smacallan		xoff = -x;
94be1ef3d3Smacallan		x = 0;
95be1ef3d3Smacallan	}
96be1ef3d3Smacallan	if (y < 0) {
97be1ef3d3Smacallan		yoff = -y;
98be1ef3d3Smacallan		y = 0;
99be1ef3d3Smacallan	}
100be1ef3d3Smacallan
101be1ef3d3Smacallan	pIgs->cursor.pos.x = x;
102be1ef3d3Smacallan	pIgs->cursor.hot.x = xoff;
103be1ef3d3Smacallan	pIgs->cursor.pos.y = y;
104be1ef3d3Smacallan	pIgs->cursor.hot.y = yoff;
105be1ef3d3Smacallan
106be1ef3d3Smacallan	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
107be1ef3d3Smacallan		xf86Msg(X_ERROR, "IgsSetCursorPosition: %d\n", errno);
108be1ef3d3Smacallan}
109be1ef3d3Smacallan
110be1ef3d3Smacallanstatic void
111be1ef3d3SmacallanIgsSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
112be1ef3d3Smacallan{
113be1ef3d3Smacallan	IgsPtr pIgs = IGSPTR(pScrn);
114be1ef3d3Smacallan	u_char r[4], g[4], b[4];
115be1ef3d3Smacallan
116be1ef3d3Smacallan	pIgs->cursor.which = WSDISPLAY_CURSOR_DOCMAP;
117be1ef3d3Smacallan	pIgs->cursor.cmap.red = r;
118be1ef3d3Smacallan	pIgs->cursor.cmap.green = g;
119be1ef3d3Smacallan	pIgs->cursor.cmap.blue = b;
120be1ef3d3Smacallan	r[1] = fg & 0xff;
121be1ef3d3Smacallan	g[1] = (fg & 0xff00) >> 8;
122be1ef3d3Smacallan	b[1] = (fg & 0xff0000) >> 16;
123be1ef3d3Smacallan	r[0] = bg & 0xff;
124be1ef3d3Smacallan	g[0] = (bg & 0xff00) >> 8;
125be1ef3d3Smacallan	b[0] = (bg & 0xff0000) >> 16;
126be1ef3d3Smacallan	pIgs->cursor.cmap.index = 0;
127be1ef3d3Smacallan	pIgs->cursor.cmap.count = 2;
128be1ef3d3Smacallan	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
129be1ef3d3Smacallan		xf86Msg(X_ERROR, "IgsSetCursorColors: %d\n", errno);
130be1ef3d3Smacallan}
131be1ef3d3Smacallan
132be1ef3d3SmacallanBool
133be1ef3d3SmacallanIgsSetupCursor(ScreenPtr pScreen)
134be1ef3d3Smacallan{
135be1ef3d3Smacallan	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
136be1ef3d3Smacallan	IgsPtr pIgs = IGSPTR(pScrn);
137be1ef3d3Smacallan	xf86CursorInfoPtr infoPtr;
138be1ef3d3Smacallan
139be1ef3d3Smacallan	pIgs->cursor.pos.x = 0;
140be1ef3d3Smacallan	pIgs->cursor.pos.y = 0;
141be1ef3d3Smacallan	pIgs->cursor.enable = 0;
142be1ef3d3Smacallan
143be1ef3d3Smacallan	infoPtr = xf86CreateCursorInfoRec();
144be1ef3d3Smacallan	if(!infoPtr) return FALSE;
145be1ef3d3Smacallan
146be1ef3d3Smacallan	pIgs->CursorInfoRec = infoPtr;
147be1ef3d3Smacallan	if(ioctl(pIgs->fd, WSDISPLAYIO_GCURMAX, &pIgs->cursor.size) == -1) {
148be1ef3d3Smacallan		xf86Msg(X_WARNING, "No HW cursor support found\n");
149be1ef3d3Smacallan		return FALSE;
150be1ef3d3Smacallan	}
151be1ef3d3Smacallan
152be1ef3d3Smacallan	xf86Msg(X_INFO, "HW cursor enabled\n");
153be1ef3d3Smacallan
154be1ef3d3Smacallan	infoPtr->MaxWidth = pIgs->cursor.size.x;
155be1ef3d3Smacallan	infoPtr->MaxHeight = pIgs->cursor.size.y;
156be1ef3d3Smacallan	pIgs->maskoffset = ( pIgs->cursor.size.x >> 3) * pIgs->cursor.size.y;
157be1ef3d3Smacallan
158be1ef3d3Smacallan	pIgs->cursor.hot.x = 0;
159be1ef3d3Smacallan	pIgs->cursor.hot.y = 0;
160be1ef3d3Smacallan	pIgs->cursor.which = WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCUR |
161be1ef3d3Smacallan	    WSDISPLAY_CURSOR_DOPOS;
162be1ef3d3Smacallan	if(ioctl(pIgs->fd, WSDISPLAYIO_SCURSOR, &pIgs->cursor) == -1)
163be1ef3d3Smacallan		xf86Msg(X_ERROR, "WSDISPLAYIO_SCURSOR: %d\n", errno);
164be1ef3d3Smacallan
165be1ef3d3Smacallan	infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
166be1ef3d3Smacallan	    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
167be1ef3d3Smacallan/* XXX not sure why exactly we need this */
168be1ef3d3Smacallan#if BYTE_ORDER == BIG_ENDIAN
169be1ef3d3Smacallan	    | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
170be1ef3d3Smacallan#endif
171be1ef3d3Smacallan	;
172be1ef3d3Smacallan	infoPtr->SetCursorColors = IgsSetCursorColors;
173be1ef3d3Smacallan	infoPtr->SetCursorPosition = IgsSetCursorPosition;
174be1ef3d3Smacallan	infoPtr->LoadCursorImage = IgsLoadCursorImage;
175be1ef3d3Smacallan	infoPtr->HideCursor = IgsHideCursor;
176be1ef3d3Smacallan	infoPtr->ShowCursor = IgsShowCursor;
177be1ef3d3Smacallan	infoPtr->UseHWCursor = NULL;
178be1ef3d3Smacallan
179be1ef3d3Smacallan	return xf86InitCursor(pScreen, infoPtr);
180be1ef3d3Smacallan}
181