1 2/************************************************************************** 3 4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 5All Rights Reserved. 6 7Permission is hereby granted, free of charge, to any person obtaining a 8copy of this software and associated documentation files (the 9"Software"), to deal in the Software without restriction, including 10without limitation the rights to use, copy, modify, merge, publish, 11distribute, sub license, and/or sell copies of the Software, and to 12permit persons to whom the Software is furnished to do so, subject to 13the following conditions: 14 15The above copyright notice and this permission notice (including the 16next paragraph) shall be included in all copies or substantial portions 17of the Software. 18 19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 23ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 27**************************************************************************/ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33/* 34 * Authors: 35 * Keith Whitwell <keith@tungstengraphics.com> 36 * 37 * Add ARGB HW cursor support: 38 * Alan Hourihane <alanh@tungstengraphics.com> 39 * 40 */ 41 42#include "xorg-server.h" 43#include "xf86.h" 44#include "xf86_OSproc.h" 45#include "compiler.h" 46 47#include "xf86fbman.h" 48 49#include "i810.h" 50 51static Bool I810UseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs); 52static void I810LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); 53static void I810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); 54static void I810ShowCursor(ScrnInfoPtr pScrn); 55static void I810HideCursor(ScrnInfoPtr pScrn); 56static void I810SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); 57static void I810SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 58static Bool I810UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); 59 60Bool 61I810CursorInit(ScreenPtr pScreen) 62{ 63 ScrnInfoPtr pScrn; 64 I810Ptr pI810; 65 xf86CursorInfoPtr infoPtr; 66 67 pScrn = xf86ScreenToScrn(pScreen); 68 pI810 = I810PTR(pScrn); 69 pI810->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec(); 70 if (!infoPtr) 71 return FALSE; 72 73 infoPtr->MaxWidth = 64; 74 infoPtr->MaxHeight = 64; 75 infoPtr->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 76 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 77 HARDWARE_CURSOR_INVERT_MASK | 78 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 79 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 80 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 0); 81 82 infoPtr->SetCursorColors = I810SetCursorColors; 83 infoPtr->SetCursorPosition = I810SetCursorPosition; 84 infoPtr->LoadCursorImage = I810LoadCursorImage; 85 infoPtr->HideCursor = I810HideCursor; 86 infoPtr->ShowCursor = I810ShowCursor; 87 infoPtr->UseHWCursor = I810UseHWCursor; 88#ifdef ARGB_CURSOR 89 pI810->CursorIsARGB = FALSE; 90 91 if (!pI810->CursorARGBPhysical) { 92 infoPtr->UseHWCursorARGB = I810UseHWCursorARGB; 93 infoPtr->LoadCursorARGB = I810LoadCursorARGB; 94 } 95#endif 96 97 return xf86InitCursor(pScreen, infoPtr); 98} 99 100#ifdef ARGB_CURSOR 101#include "cursorstr.h" 102 103static Bool I810UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) 104{ 105 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 106 I810Ptr pI810 = I810PTR(pScrn); 107 108 if (!pI810->CursorARGBPhysical) 109 return FALSE; 110 111 if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64) 112 return TRUE; 113 114 return FALSE; 115} 116 117static void I810LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) 118{ 119 I810Ptr pI810 = I810PTR(pScrn); 120 uint32_t *pcurs = (uint32_t *) (pI810->FbBase + pI810->CursorStart); 121 uint32_t *image = (uint32_t *) pCurs->bits->argb; 122 int x, y, w, h; 123 124#ifdef ARGB_CURSOR 125 pI810->CursorIsARGB = TRUE; 126#endif 127 128 w = pCurs->bits->width; 129 h = pCurs->bits->height; 130 131 for (y = 0; y < h; y++) 132 { 133 for (x = 0; x < w; x++) 134 *pcurs++ = *image++; 135 for (; x < 64; x++) 136 *pcurs++ = 0; 137 } 138 139 for (; y < 64; y++) 140 for (x = 0; x < 64; x++) 141 *pcurs++ = 0; 142} 143#endif 144 145static Bool 146I810UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 147{ 148 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 149 I810Ptr pI810 = I810PTR(pScrn); 150 151 if (!pI810->CursorPhysical) 152 return FALSE; 153 else 154 return TRUE; 155} 156 157static void 158I810LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 159{ 160 I810Ptr pI810 = I810PTR(pScrn); 161 uint8_t *pcurs = (uint8_t *) (pI810->FbBase + pI810->CursorStart); 162 int x, y; 163 164#ifdef ARGB_CURSOR 165 pI810->CursorIsARGB = FALSE; 166#endif 167 168 for (y = 0; y < 64; y++) { 169 for (x = 0; x < 64 / 4; x++) { 170 *pcurs++ = *src++; 171 } 172 } 173} 174 175static void 176I810SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 177{ 178 I810Ptr pI810 = I810PTR(pScrn); 179 int flag; 180 181 x += pI810->CursorOffset; 182 183 if (x >= 0) 184 flag = CURSOR_X_POS; 185 else { 186 flag = CURSOR_X_NEG; 187 x = -x; 188 } 189 190 OUTREG8(CURSOR_X_LO, x & 0xFF); 191 OUTREG8(CURSOR_X_HI, (((x >> 8) & 0x07) | flag)); 192 193 if (y >= 0) 194 flag = CURSOR_Y_POS; 195 else { 196 flag = CURSOR_Y_NEG; 197 y = -y; 198 } 199 OUTREG8(CURSOR_Y_LO, y & 0xFF); 200 OUTREG8(CURSOR_Y_HI, (((y >> 8) & 0x07) | flag)); 201 202 if (pI810->CursorIsARGB) 203 OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical); 204 else 205 OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical); 206} 207 208static void 209I810ShowCursor(ScrnInfoPtr pScrn) 210{ 211 I810Ptr pI810 = I810PTR(pScrn); 212 unsigned char tmp; 213 214 if (pI810->CursorIsARGB) { 215 OUTREG(CURSOR_BASEADDR, pI810->CursorARGBPhysical); 216 OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_ARGB_AX); 217 } else { 218 OUTREG(CURSOR_BASEADDR, pI810->CursorPhysical); 219 OUTREG8(CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); 220 } 221 222 tmp = INREG8(PIXPIPE_CONFIG_0); 223 tmp |= HW_CURSOR_ENABLE; 224 OUTREG8(PIXPIPE_CONFIG_0, tmp); 225} 226 227static void 228I810HideCursor(ScrnInfoPtr pScrn) 229{ 230 unsigned char tmp; 231 I810Ptr pI810 = I810PTR(pScrn); 232 233 tmp = INREG8(PIXPIPE_CONFIG_0); 234 tmp &= ~HW_CURSOR_ENABLE; 235 OUTREG8(PIXPIPE_CONFIG_0, tmp); 236} 237 238static void 239I810SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 240{ 241 int tmp; 242 I810Ptr pI810 = I810PTR(pScrn); 243 vgaHWPtr hwp; 244 245#ifdef ARGB_CURSOR 246 if (pI810->CursorIsARGB) 247 return; 248#endif 249 250 hwp = VGAHWPTR(pScrn); 251 252 tmp = INREG8(PIXPIPE_CONFIG_0); 253 tmp |= EXTENDED_PALETTE; 254 OUTREG8(PIXPIPE_CONFIG_0, tmp); 255 256 hwp->writeDacMask(hwp, 0xFF); 257 hwp->writeDacWriteAddr(hwp, 0x04); 258 259 hwp->writeDacData(hwp, (bg & 0x00FF0000) >> 16); 260 hwp->writeDacData(hwp, (bg & 0x0000FF00) >> 8); 261 hwp->writeDacData(hwp, (bg & 0x000000FF)); 262 263 hwp->writeDacData(hwp, (fg & 0x00FF0000) >> 16); 264 hwp->writeDacData(hwp, (fg & 0x0000FF00) >> 8); 265 hwp->writeDacData(hwp, (fg & 0x000000FF)); 266 267 tmp = INREG8(PIXPIPE_CONFIG_0); 268 tmp &= ~EXTENDED_PALETTE; 269 OUTREG8(PIXPIPE_CONFIG_0, tmp); 270} 271