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