1/* $NetBSD: ngle_cursor.c,v 1.2 2024/10/27 11:09:37 macallan 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#include "xf86_OSlib.h"
50
51#include "ngle.h"
52
53static void NGLELoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
54static void NGLESetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
55static void NGLESetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
56
57static void
58NGLELoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
59{
60	NGLEPtr pNGLE = NGLEPTR(pScrn);
61	int err, i;
62
63	pNGLE->cursor.which = WSDISPLAY_CURSOR_DOALL;
64	pNGLE->cursor.image = src;
65	pNGLE->cursor.mask = src + pNGLE->maskoffset;
66	if(ioctl(pNGLE->fd, WSDISPLAYIO_SCURSOR, &pNGLE->cursor) == -1)
67		xf86Msg(X_ERROR, "NGLELoadCursorImage: %d\n", errno);
68	pNGLE->hwmode = -1;
69}
70
71void
72NGLEShowCursor(ScrnInfoPtr pScrn)
73{
74	NGLEPtr pNGLE = NGLEPTR(pScrn);
75
76	pNGLE->cursor.which = WSDISPLAY_CURSOR_DOCUR;
77	pNGLE->cursor.enable = 1;
78	if(ioctl(pNGLE->fd, WSDISPLAYIO_SCURSOR, &pNGLE->cursor) == -1)
79		xf86Msg(X_ERROR, "NGLEShowCursor: %d\n", errno);
80}
81
82void
83NGLEHideCursor(ScrnInfoPtr pScrn)
84{
85	NGLEPtr pNGLE = NGLEPTR(pScrn);
86
87	pNGLE->cursor.which = WSDISPLAY_CURSOR_DOCUR;
88	pNGLE->cursor.enable = 0;
89	if(ioctl(pNGLE->fd, WSDISPLAYIO_SCURSOR, &pNGLE->cursor) == -1)
90		xf86Msg(X_ERROR, "NGLEHideCursor: %d\n", errno);
91}
92
93static void
94NGLESetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
95{
96	NGLEPtr pNGLE = NGLEPTR(pScrn);
97	int xoff = 0, yoff = 0;
98
99	pNGLE->cursor.which = WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT;
100
101	if (x < 0) {
102		xoff = -x;
103		x = 0;
104	}
105	if (y < 0) {
106		yoff = -y;
107		y = 0;
108	}
109
110	pNGLE->cursor.pos.x = x;
111	pNGLE->cursor.hot.x = xoff;
112	pNGLE->cursor.pos.y = y;
113	pNGLE->cursor.hot.y = yoff;
114
115	if(ioctl(pNGLE->fd, WSDISPLAYIO_SCURSOR, &pNGLE->cursor) == -1)
116		xf86Msg(X_ERROR, "NGLESetCursorPosition: %d\n", errno);
117}
118
119static void
120NGLESetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
121{
122	NGLEPtr pNGLE = NGLEPTR(pScrn);
123	u_char r[4], g[4], b[4];
124
125	pNGLE->cursor.which = WSDISPLAY_CURSOR_DOCMAP;
126	pNGLE->cursor.cmap.red = r;
127	pNGLE->cursor.cmap.green = g;
128	pNGLE->cursor.cmap.blue = b;
129	r[1] = fg & 0xff;
130	g[1] = (fg & 0xff00) >> 8;
131	b[1] = (fg & 0xff0000) >> 16;
132	r[0] = bg & 0xff;
133	g[0] = (bg & 0xff00) >> 8;
134	b[0] = (bg & 0xff0000) >> 16;
135	pNGLE->cursor.cmap.index = 0;
136	pNGLE->cursor.cmap.count = 2;
137	if(ioctl(pNGLE->fd, WSDISPLAYIO_SCURSOR, &pNGLE->cursor) == -1)
138		xf86Msg(X_ERROR, "NGLESetCursorColors: %d\n", errno);
139	pNGLE->hwmode = -1;
140}
141
142Bool
143NGLESetupCursor(ScreenPtr pScreen)
144{
145	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
146	NGLEPtr pNGLE = NGLEPTR(pScrn);
147	xf86CursorInfoPtr infoPtr;
148
149	pNGLE->cursor.pos.x = 0;
150	pNGLE->cursor.pos.y = 0;
151	pNGLE->cursor.enable = 0;
152
153	infoPtr = xf86CreateCursorInfoRec();
154	if(!infoPtr) return FALSE;
155
156	pNGLE->CursorInfoRec = infoPtr;
157	if(ioctl(pNGLE->fd, WSDISPLAYIO_GCURMAX, &pNGLE->cursor.size) == -1) {
158		xf86Msg(X_WARNING, "No HW cursor support found\n");
159		return FALSE;
160	}
161
162	xf86Msg(X_INFO, "HW cursor enabled\n");
163
164	infoPtr->MaxWidth = pNGLE->cursor.size.x;
165	infoPtr->MaxHeight = pNGLE->cursor.size.y;
166	pNGLE->maskoffset = ( pNGLE->cursor.size.x >> 3) * pNGLE->cursor.size.y;
167
168	pNGLE->cursor.hot.x = 0;
169	pNGLE->cursor.hot.y = 0;
170	pNGLE->cursor.which = WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCUR |
171	    WSDISPLAY_CURSOR_DOPOS;
172	if(ioctl(pNGLE->fd, WSDISPLAYIO_SCURSOR, &pNGLE->cursor) == -1)
173		xf86Msg(X_ERROR, "WSDISPLAYIO_SCURSOR: %d\n", errno);
174
175	infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
176	    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
177/* XXX not sure why exactly we need this */
178#if BYTE_ORDER == BIG_ENDIAN
179	    | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
180#endif
181	;
182	infoPtr->SetCursorColors = NGLESetCursorColors;
183	infoPtr->SetCursorPosition = NGLESetCursorPosition;
184	infoPtr->LoadCursorImage = NGLELoadCursorImage;
185	infoPtr->HideCursor = NGLEHideCursor;
186	infoPtr->ShowCursor = NGLEShowCursor;
187	infoPtr->UseHWCursor = NULL;
188
189	return xf86InitCursor(pScreen, infoPtr);
190}
191