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