s3_cursor.c revision 340e3fbd
1/* 2 * Copyright 2001 Ani Joshi <ajoshi@unixbox.com> 3 * 4 * XFree86 4.x driver for S3 chipsets 5 * 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and its 8 * documentation for any purpose is hereby granted without fee, provided that 9 * the above copyright notice appear in all copies and that both that copyright 10 * notice and this permission notice appear in supporting documentation and 11 * that the name of Ani Joshi not be used in advertising or 12 * publicity pertaining to distribution of the software without specific, 13 * written prior permission. Ani Joshi makes no representations 14 * about the suitability of this software for any purpose. It is provided 15 * "as-is" without express or implied warranty. 16 * 17 * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19 * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23 * PERFORMANCE OF THIS SOFTWARE. 24 * 25 * 26 */ 27/* $XFree86: $ */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include "xf86.h" 34#include "xf86_OSproc.h" 35 36#include "compiler.h" 37 38#include "s3.h" 39#include "s3_reg.h" 40 41 42static void S3SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 43{ 44 S3Ptr pS3 = S3PTR(pScrn); 45 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 46 unsigned short packfg, packbg; 47 48 switch (pS3->s3Bpp) { 49 case 1: 50 /* XXX Trio series only */ 51 outb(vgaCRIndex, 0x45); 52 inb(vgaCRReg); 53 outb(vgaCRIndex, 0x4a); 54 outb(vgaCRReg, fg); 55 outb(vgaCRReg, fg); 56 57 outb(vgaCRIndex, 0x45); 58 inb(vgaCRReg); 59 outb(vgaCRIndex, 0x4b); 60 outb(vgaCRReg, bg); 61 outb(vgaCRReg, bg); 62 63 break; 64 case 2: 65 /* XXX depth 16 */ 66 packfg = ((fg & 0x00f80000) >> 19) | ((fg & 0x0000fc00) >> 5) | 67 ((fg & 0x000000f8) << 8); 68 packbg = ((bg & 0x00f80000) >> 19) | ((bg & 0x0000fc00) >> 5) | 69 ((bg & 0x000000f8) << 8); 70 71 outb(vgaCRIndex, 0x45); 72 inb(vgaCRReg); 73 outb(vgaCRIndex, 0x4a); 74 outb(vgaCRReg, packfg); 75 outb(vgaCRReg, packfg >> 8); 76 77 outb(vgaCRIndex, 0x45); 78 inb(vgaCRReg); 79 outb(vgaCRIndex, 0x4b); 80 outb(vgaCRReg, packbg); 81 outb(vgaCRReg, packbg >> 8); 82 83 break; 84 default: 85 outb(vgaCRIndex, 0x45); 86 inb(vgaCRReg); 87 outb(vgaCRIndex, 0x4a); 88 outb(vgaCRReg, (fg & 0x00ff0000) >> 16); 89 outb(vgaCRReg, (fg & 0x0000ff00) >> 8); 90 outb(vgaCRReg, (fg & 0x000000ff)); 91 92 outb(vgaCRIndex, 0x45); 93 inb(vgaCRReg); 94 outb(vgaCRIndex, 0x4b); 95 outb(vgaCRReg, (bg & 0x00ff0000) >> 16); 96 outb(vgaCRReg, (bg & 0x0000ff00) >> 8); 97 outb(vgaCRReg, (bg & 0x000000ff)); 98 99 break; 100 } 101} 102 103 104static void S3SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 105{ 106 S3Ptr pS3 = S3PTR(pScrn); 107 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 108 109 outb(vgaCRIndex, 0x39); 110 outb(vgaCRReg, 0xa5); 111 112 outb(vgaCRIndex, 0x46); 113 outb(vgaCRReg, x >> 8); 114 outb(vgaCRIndex, 0x47); 115 outb(vgaCRReg, x); 116 117 outb(vgaCRIndex, 0x49); 118 outb(vgaCRReg, y); 119 outb(vgaCRIndex, 0x48); 120 outb(vgaCRReg, y >> 8); 121} 122 123 124static void S3HideCursor(ScrnInfoPtr pScrn) 125{ 126 S3Ptr pS3 = S3PTR(pScrn); 127 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 128 unsigned char tmp; 129 130 outb(vgaCRIndex, 0x45); 131 tmp = inb(vgaCRReg); 132 outb(vgaCRReg, tmp & ~0x01); 133} 134 135 136static void S3ShowCursor(ScrnInfoPtr pScrn) 137{ 138 S3Ptr pS3 = S3PTR(pScrn); 139 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 140 unsigned char tmp; 141 142 outb(vgaCRIndex, 0x39); 143 outb(vgaCRReg, 0xa5); 144 145 outb(vgaCRIndex, 0x55); 146 tmp = inb(vgaCRReg); 147 outb(vgaCRReg, tmp | 0x10); 148 149 outb(vgaCRIndex, 0x4c); 150 outb(vgaCRReg, pS3->FBCursorOffset >> 8); 151 outb(vgaCRIndex, 0x4d); 152 outb(vgaCRReg, pS3->FBCursorOffset); 153 154 outb(vgaCRIndex, 0x45); 155 tmp = inb(vgaCRReg); 156 outb(vgaCRReg, tmp | 0x01); 157} 158 159 160static void S3LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) 161{ 162 S3Ptr pS3 = S3PTR(pScrn); 163 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 164 unsigned char cr45; 165 166 outb(vgaCRIndex, 0x39); 167 outb(vgaCRReg, 0xa5); 168 169 WaitIdle(); 170 171 VerticalRetraceWait(); 172 173 outb(vgaCRIndex, 0x45); 174 cr45 = inb(vgaCRReg); 175 outb(vgaCRReg, cr45 & 0xfe); 176 177 outb(vgaCRIndex, 0x46); 178 outb(vgaCRReg, 0xff); 179 outb(vgaCRIndex, 0x47); 180 outb(vgaCRReg, 0x7f); 181 outb(vgaCRIndex, 0x49); 182 outb(vgaCRReg, 0xff); 183 outb(vgaCRIndex, 0x4e); 184 outb(vgaCRReg, 0x3f); 185 outb(vgaCRIndex, 0x4f); 186 outb(vgaCRReg, 0x3f); 187 outb(vgaCRIndex, 0x48); 188 outb(vgaCRReg, 0x7f); 189 190 memcpy(pS3->FBBase + (pS3->FBCursorOffset * 1024), image, 1024); 191 192 VerticalRetraceWait(); 193 194 outb(vgaCRIndex, 0x45); 195 outb(vgaCRReg, cr45); 196} 197 198 199static Bool S3UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 200{ 201 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 202 S3Ptr pS3 = S3PTR(pScrn); 203 return (pS3->hwCursor); 204} 205 206 207Bool S3_CursorInit(ScreenPtr pScreen) 208{ 209 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 210 S3Ptr pS3 = S3PTR(pScrn); 211 xf86CursorInfoPtr pCurs; 212 213 if (!(pCurs = pS3->pCurs = xf86CreateCursorInfoRec())) 214 return FALSE; 215 216 pCurs->MaxWidth = 64; 217 pCurs->MaxHeight = 64; 218 pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 219 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 220 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST; 221 222 pCurs->SetCursorColors = S3SetCursorColors; 223 pCurs->SetCursorPosition = S3SetCursorPosition; 224 pCurs->LoadCursorImage = S3LoadCursorImage; 225 pCurs->HideCursor = S3HideCursor; 226 pCurs->ShowCursor = S3ShowCursor; 227 pCurs->UseHWCursor = S3UseHWCursor; 228 229 return xf86InitCursor(pScreen, pCurs); 230} 231 232