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