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