1a9060c92Schristos/* $NetBSD: wsfb_cursor.c,v 1.3 2011/05/15 23:44:47 christos Exp $ */ 25d492fd2Smacallan/* 35d492fd2Smacallan * Copyright (c) 2005 Michael Lorenz 45d492fd2Smacallan * All rights reserved. 55d492fd2Smacallan * 65d492fd2Smacallan * Redistribution and use in source and binary forms, with or without 75d492fd2Smacallan * modification, are permitted provided that the following conditions 85d492fd2Smacallan * are met: 95d492fd2Smacallan * 105d492fd2Smacallan * - Redistributions of source code must retain the above copyright 115d492fd2Smacallan * notice, this list of conditions and the following disclaimer. 125d492fd2Smacallan * - Redistributions in binary form must reproduce the above 135d492fd2Smacallan * copyright notice, this list of conditions and the following 145d492fd2Smacallan * disclaimer in the documentation and/or other materials provided 155d492fd2Smacallan * with the distribution. 165d492fd2Smacallan * 175d492fd2Smacallan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185d492fd2Smacallan * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195d492fd2Smacallan * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 205d492fd2Smacallan * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 215d492fd2Smacallan * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 225d492fd2Smacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 235d492fd2Smacallan * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 245d492fd2Smacallan * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 255d492fd2Smacallan * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 265d492fd2Smacallan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 275d492fd2Smacallan * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 285d492fd2Smacallan * POSSIBILITY OF SUCH DAMAGE. 295d492fd2Smacallan * 305d492fd2Smacallan */ 315d492fd2Smacallan 325d492fd2Smacallan/* 335d492fd2Smacallan * Based on fbdev.c written by: 345d492fd2Smacallan * 355d492fd2Smacallan * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> 365d492fd2Smacallan * Michel Dänzer, <michdaen@iiic.ethz.ch> 375d492fd2Smacallan */ 385d492fd2Smacallan 395d492fd2Smacallan#include <fcntl.h> 405d492fd2Smacallan#include <sys/types.h> 415d492fd2Smacallan#include <sys/time.h> 425d492fd2Smacallan#include <sys/endian.h> 435d492fd2Smacallan#include <dev/wscons/wsconsio.h> 445d492fd2Smacallan#include <errno.h> 455d492fd2Smacallan 465d492fd2Smacallan/* all driver need this */ 475d492fd2Smacallan#include "xf86.h" 485d492fd2Smacallan#include "xf86_OSproc.h" 49a9060c92Schristos#include "xf86_OSlib.h" 505d492fd2Smacallan 515d492fd2Smacallan#include "wsfb.h" 525d492fd2Smacallan 535d492fd2Smacallanstatic void WsfbLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); 545d492fd2Smacallanstatic void WsfbSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 555d492fd2Smacallanstatic void WsfbSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 565d492fd2Smacallan 575d492fd2Smacallanstatic void 585d492fd2SmacallanWsfbLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 595d492fd2Smacallan{ 605d492fd2Smacallan WsfbPtr pWsfb = WSFBPTR(pScrn); 615d492fd2Smacallan int err, i; 625d492fd2Smacallan 635d492fd2Smacallan pWsfb->cursor.which = WSDISPLAY_CURSOR_DOALL; 645d492fd2Smacallan pWsfb->cursor.image = src; 655d492fd2Smacallan pWsfb->cursor.mask = src + pWsfb->maskoffset; 665d492fd2Smacallan if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1) 675d492fd2Smacallan xf86Msg(X_ERROR, "WsfbLoadCursorImage: %d\n", errno); 685d492fd2Smacallan} 695d492fd2Smacallan 705d492fd2Smacallanvoid 715d492fd2SmacallanWsfbShowCursor(ScrnInfoPtr pScrn) 725d492fd2Smacallan{ 735d492fd2Smacallan WsfbPtr pWsfb = WSFBPTR(pScrn); 745d492fd2Smacallan 755d492fd2Smacallan pWsfb->cursor.which = WSDISPLAY_CURSOR_DOCUR; 765d492fd2Smacallan pWsfb->cursor.enable = 1; 775d492fd2Smacallan if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1) 785d492fd2Smacallan xf86Msg(X_ERROR, "WsfbShowCursor: %d\n", errno); 795d492fd2Smacallan} 805d492fd2Smacallan 815d492fd2Smacallanvoid 825d492fd2SmacallanWsfbHideCursor(ScrnInfoPtr pScrn) 835d492fd2Smacallan{ 845d492fd2Smacallan WsfbPtr pWsfb = WSFBPTR(pScrn); 855d492fd2Smacallan 865d492fd2Smacallan pWsfb->cursor.which = WSDISPLAY_CURSOR_DOCUR; 875d492fd2Smacallan pWsfb->cursor.enable = 0; 885d492fd2Smacallan if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1) 895d492fd2Smacallan xf86Msg(X_ERROR, "WsfbHideCursor: %d\n", errno); 905d492fd2Smacallan} 915d492fd2Smacallan 925d492fd2Smacallanstatic void 935d492fd2SmacallanWsfbSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 945d492fd2Smacallan{ 955d492fd2Smacallan WsfbPtr pWsfb = WSFBPTR(pScrn); 965d492fd2Smacallan int xoff = 0, yoff = 0; 975d492fd2Smacallan 985d492fd2Smacallan pWsfb->cursor.which = WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT; 995d492fd2Smacallan 1005d492fd2Smacallan if (x < 0) { 1015d492fd2Smacallan xoff = -x; 1025d492fd2Smacallan x = 0; 1035d492fd2Smacallan } 1045d492fd2Smacallan if (y < 0) { 1055d492fd2Smacallan yoff = -y; 1065d492fd2Smacallan y = 0; 1075d492fd2Smacallan } 1085d492fd2Smacallan 1095d492fd2Smacallan pWsfb->cursor.pos.x = x; 1105d492fd2Smacallan pWsfb->cursor.hot.x = xoff; 1115d492fd2Smacallan pWsfb->cursor.pos.y = y; 1125d492fd2Smacallan pWsfb->cursor.hot.y = yoff; 1135d492fd2Smacallan 1145d492fd2Smacallan if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1) 1155d492fd2Smacallan xf86Msg(X_ERROR, "WsfbSetCursorPosition: %d\n", errno); 1165d492fd2Smacallan} 1175d492fd2Smacallan 1185d492fd2Smacallanstatic void 1195d492fd2SmacallanWsfbSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 1205d492fd2Smacallan{ 1215d492fd2Smacallan WsfbPtr pWsfb = WSFBPTR(pScrn); 1225d492fd2Smacallan u_char r[4], g[4], b[4]; 1235d492fd2Smacallan 1245d492fd2Smacallan pWsfb->cursor.which = WSDISPLAY_CURSOR_DOCMAP; 1255d492fd2Smacallan pWsfb->cursor.cmap.red = r; 1265d492fd2Smacallan pWsfb->cursor.cmap.green = g; 1275d492fd2Smacallan pWsfb->cursor.cmap.blue = b; 1285d492fd2Smacallan r[1] = fg & 0xff; 1295d492fd2Smacallan g[1] = (fg & 0xff00) >> 8; 1305d492fd2Smacallan b[1] = (fg & 0xff0000) >> 16; 1315d492fd2Smacallan r[0] = bg & 0xff; 1325d492fd2Smacallan g[0] = (bg & 0xff00) >> 8; 1335d492fd2Smacallan b[0] = (bg & 0xff0000) >> 16; 1345d492fd2Smacallan pWsfb->cursor.cmap.index = 0; 1355d492fd2Smacallan pWsfb->cursor.cmap.count = 2; 1365d492fd2Smacallan if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1) 1375d492fd2Smacallan xf86Msg(X_ERROR, "WsfbSetCursorColors: %d\n", errno); 1385d492fd2Smacallan} 1395d492fd2Smacallan 1405d492fd2SmacallanBool 1415d492fd2SmacallanWsfbSetupCursor(ScreenPtr pScreen) 1425d492fd2Smacallan{ 1435d492fd2Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1445d492fd2Smacallan WsfbPtr pWsfb = WSFBPTR(pScrn); 1455d492fd2Smacallan xf86CursorInfoPtr infoPtr; 1465d492fd2Smacallan 1475d492fd2Smacallan pWsfb->cursor.pos.x = 0; 1485d492fd2Smacallan pWsfb->cursor.pos.y = 0; 1495d492fd2Smacallan pWsfb->cursor.enable = 0; 1505d492fd2Smacallan 1515d492fd2Smacallan infoPtr = xf86CreateCursorInfoRec(); 1525d492fd2Smacallan if(!infoPtr) return FALSE; 1535d492fd2Smacallan 1545d492fd2Smacallan pWsfb->CursorInfoRec = infoPtr; 1555d492fd2Smacallan if(ioctl(pWsfb->fd, WSDISPLAYIO_GCURMAX, &pWsfb->cursor.size) == -1) { 1565d492fd2Smacallan xf86Msg(X_WARNING, "No HW cursor support found\n"); 1575d492fd2Smacallan return FALSE; 1585d492fd2Smacallan } 1595d492fd2Smacallan 1605d492fd2Smacallan xf86Msg(X_INFO, "HW cursor enabled\n"); 1615d492fd2Smacallan 1625d492fd2Smacallan infoPtr->MaxWidth = pWsfb->cursor.size.x; 1635d492fd2Smacallan infoPtr->MaxHeight = pWsfb->cursor.size.y; 1645d492fd2Smacallan pWsfb->maskoffset = ( pWsfb->cursor.size.x >> 3) * pWsfb->cursor.size.y; 1655d492fd2Smacallan 1665d492fd2Smacallan pWsfb->cursor.hot.x = 0; 1675d492fd2Smacallan pWsfb->cursor.hot.y = 0; 1685d492fd2Smacallan pWsfb->cursor.which = WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOCUR | 1695d492fd2Smacallan WSDISPLAY_CURSOR_DOPOS; 1705d492fd2Smacallan if(ioctl(pWsfb->fd, WSDISPLAYIO_SCURSOR, &pWsfb->cursor) == -1) 1715d492fd2Smacallan xf86Msg(X_ERROR, "WSDISPLAYIO_SCURSOR: %d\n", errno); 1725d492fd2Smacallan 1735d492fd2Smacallan infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 1745d492fd2Smacallan HARDWARE_CURSOR_TRUECOLOR_AT_8BPP 1755d492fd2Smacallan/* XXX not sure why exactly we need this */ 1765d492fd2Smacallan#if BYTE_ORDER == BIG_ENDIAN 1775d492fd2Smacallan | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST 1785d492fd2Smacallan#endif 1795d492fd2Smacallan ; 1805d492fd2Smacallan infoPtr->SetCursorColors = WsfbSetCursorColors; 1815d492fd2Smacallan infoPtr->SetCursorPosition = WsfbSetCursorPosition; 1825d492fd2Smacallan infoPtr->LoadCursorImage = WsfbLoadCursorImage; 1835d492fd2Smacallan infoPtr->HideCursor = WsfbHideCursor; 1845d492fd2Smacallan infoPtr->ShowCursor = WsfbShowCursor; 1855d492fd2Smacallan infoPtr->UseHWCursor = NULL; 1865d492fd2Smacallan 1875d492fd2Smacallan return xf86InitCursor(pScreen, infoPtr); 1885d492fd2Smacallan} 189