wsfb_cursor.c revision 2b2b17b3
1/* $NetBSD: wsfb_cursor.c,v 1.2 2009/06/12 01:53:00 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/*
33 * Based on fbdev.c written by:
34 *
35 * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
36 *	     Michel Dänzer, <michdaen@iiic.ethz.ch>
37 */
38
39#include <fcntl.h>
40#include <sys/types.h>
41#include <sys/time.h>
42#include <sys/endian.h>
43#include <dev/wscons/wsconsio.h>
44#include <errno.h>
45
46/* all driver need this */
47#include "xf86.h"
48#include "xf86_OSproc.h"
49
50#include "wsfb.h"
51
52static void WsfbLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
53static void WsfbSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
54static void WsfbSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
55
56static void
57WsfbLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
58{
59	WsfbPtr pWsfb = WSFBPTR(pScrn);
60	int err, i;
61
62	pWsfb->cursor.which = WSDISPLAY_CURSOR_DOALL;
63	pWsfb->cursor.image = src;
64	pWsfb->cursor.mask = src + pWsfb->maskoffset;
65	if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1)
66		xf86Msg(X_ERROR, "WsfbLoadCursorImage: %d\n", errno);
67}
68
69void
70WsfbShowCursor(ScrnInfoPtr pScrn)
71{
72	WsfbPtr pWsfb = WSFBPTR(pScrn);
73
74	pWsfb->cursor.which = WSDISPLAY_CURSOR_DOCUR;
75	pWsfb->cursor.enable = 1;
76	if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1)
77		xf86Msg(X_ERROR, "WsfbShowCursor: %d\n", errno);
78}
79
80void
81WsfbHideCursor(ScrnInfoPtr pScrn)
82{
83	WsfbPtr pWsfb = WSFBPTR(pScrn);
84
85	pWsfb->cursor.which = WSDISPLAY_CURSOR_DOCUR;
86	pWsfb->cursor.enable = 0;
87	if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1)
88		xf86Msg(X_ERROR, "WsfbHideCursor: %d\n", errno);
89}
90
91static void
92WsfbSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
93{
94	WsfbPtr pWsfb = WSFBPTR(pScrn);
95	int xoff = 0, yoff = 0;
96
97	pWsfb->cursor.which = WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT;
98
99	if (x < 0) {
100		xoff = -x;
101		x = 0;
102	}
103	if (y < 0) {
104		yoff = -y;
105		y = 0;
106	}
107
108	pWsfb->cursor.pos.x = x;
109	pWsfb->cursor.hot.x = xoff;
110	pWsfb->cursor.pos.y = y;
111	pWsfb->cursor.hot.y = yoff;
112
113	if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1)
114		xf86Msg(X_ERROR, "WsfbSetCursorPosition: %d\n", errno);
115}
116
117static void
118WsfbSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
119{
120	WsfbPtr pWsfb = WSFBPTR(pScrn);
121	u_char r[4], g[4], b[4];
122
123	pWsfb->cursor.which = WSDISPLAY_CURSOR_DOCMAP;
124	pWsfb->cursor.cmap.red = r;
125	pWsfb->cursor.cmap.green = g;
126	pWsfb->cursor.cmap.blue = b;
127	r[1] = fg & 0xff;
128	g[1] = (fg & 0xff00) >> 8;
129	b[1] = (fg & 0xff0000) >> 16;
130	r[0] = bg & 0xff;
131	g[0] = (bg & 0xff00) >> 8;
132	b[0] = (bg & 0xff0000) >> 16;
133	pWsfb->cursor.cmap.index = 0;
134	pWsfb->cursor.cmap.count = 2;
135	if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1)
136		xf86Msg(X_ERROR, "WsfbSetCursorColors: %d\n", errno);
137}
138
139Bool
140WsfbSetupCursor(ScreenPtr pScreen)
141{
142	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
143	WsfbPtr pWsfb = WSFBPTR(pScrn);
144	xf86CursorInfoPtr infoPtr;
145
146	pWsfb->cursor.pos.x = 0;
147	pWsfb->cursor.pos.y = 0;
148	pWsfb->cursor.enable = 0;
149
150	infoPtr = xf86CreateCursorInfoRec();
151	if(!infoPtr) return FALSE;
152
153	pWsfb->CursorInfoRec = infoPtr;
154	if(ioctl(pWsfb->fd, WSDISPLAYIO_GCURMAX, &pWsfb->cursor.size) == -1) {
155		xf86Msg(X_WARNING, "No HW cursor support found\n");
156		return FALSE;
157	}
158
159	xf86Msg(X_INFO, "HW cursor enabled\n");
160
161	infoPtr->MaxWidth = pWsfb->cursor.size.x;
162	infoPtr->MaxHeight = pWsfb->cursor.size.y;
163	pWsfb->maskoffset = ( pWsfb->cursor.size.x >> 3) * pWsfb->cursor.size.y;
164
165	pWsfb->cursor.hot.x = 0;
166	pWsfb->cursor.hot.y = 0;
167	pWsfb->cursor.which = WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCUR |
168	    WSDISPLAY_CURSOR_DOPOS;
169	if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1)
170		xf86Msg(X_ERROR, "WSDISPLAYIO_SCURSOR: %d\n", errno);
171
172	infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
173	    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
174/* XXX not sure why exactly we need this */
175#if BYTE_ORDER == BIG_ENDIAN
176	    | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
177#endif
178	;
179	infoPtr->SetCursorColors = WsfbSetCursorColors;
180	infoPtr->SetCursorPosition = WsfbSetCursorPosition;
181	infoPtr->LoadCursorImage = WsfbLoadCursorImage;
182	infoPtr->HideCursor = WsfbHideCursor;
183	infoPtr->ShowCursor = WsfbShowCursor;
184	infoPtr->UseHWCursor = NULL;
185
186	return xf86InitCursor(pScreen, infoPtr);
187}
188