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