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