s3_cursor.c revision 340e3fbd
1340e3fbdSmrg/* 2340e3fbdSmrg * Copyright 2001 Ani Joshi <ajoshi@unixbox.com> 3340e3fbdSmrg * 4340e3fbdSmrg * XFree86 4.x driver for S3 chipsets 5340e3fbdSmrg * 6340e3fbdSmrg * 7340e3fbdSmrg * Permission to use, copy, modify, distribute, and sell this software and its 8340e3fbdSmrg * documentation for any purpose is hereby granted without fee, provided that 9340e3fbdSmrg * the above copyright notice appear in all copies and that both that copyright 10340e3fbdSmrg * notice and this permission notice appear in supporting documentation and 11340e3fbdSmrg * that the name of Ani Joshi not be used in advertising or 12340e3fbdSmrg * publicity pertaining to distribution of the software without specific, 13340e3fbdSmrg * written prior permission. Ani Joshi makes no representations 14340e3fbdSmrg * about the suitability of this software for any purpose. It is provided 15340e3fbdSmrg * "as-is" without express or implied warranty. 16340e3fbdSmrg * 17340e3fbdSmrg * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18340e3fbdSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19340e3fbdSmrg * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20340e3fbdSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21340e3fbdSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22340e3fbdSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23340e3fbdSmrg * PERFORMANCE OF THIS SOFTWARE. 24340e3fbdSmrg * 25340e3fbdSmrg * 26340e3fbdSmrg */ 27340e3fbdSmrg/* $XFree86: $ */ 28340e3fbdSmrg 29340e3fbdSmrg#ifdef HAVE_CONFIG_H 30340e3fbdSmrg#include "config.h" 31340e3fbdSmrg#endif 32340e3fbdSmrg 33340e3fbdSmrg#include "xf86.h" 34340e3fbdSmrg#include "xf86_OSproc.h" 35340e3fbdSmrg 36340e3fbdSmrg#include "compiler.h" 37340e3fbdSmrg 38340e3fbdSmrg#include "s3.h" 39340e3fbdSmrg#include "s3_reg.h" 40340e3fbdSmrg 41340e3fbdSmrg 42340e3fbdSmrgstatic void S3SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 43340e3fbdSmrg{ 44340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 45340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 46340e3fbdSmrg unsigned short packfg, packbg; 47340e3fbdSmrg 48340e3fbdSmrg switch (pS3->s3Bpp) { 49340e3fbdSmrg case 1: 50340e3fbdSmrg /* XXX Trio series only */ 51340e3fbdSmrg outb(vgaCRIndex, 0x45); 52340e3fbdSmrg inb(vgaCRReg); 53340e3fbdSmrg outb(vgaCRIndex, 0x4a); 54340e3fbdSmrg outb(vgaCRReg, fg); 55340e3fbdSmrg outb(vgaCRReg, fg); 56340e3fbdSmrg 57340e3fbdSmrg outb(vgaCRIndex, 0x45); 58340e3fbdSmrg inb(vgaCRReg); 59340e3fbdSmrg outb(vgaCRIndex, 0x4b); 60340e3fbdSmrg outb(vgaCRReg, bg); 61340e3fbdSmrg outb(vgaCRReg, bg); 62340e3fbdSmrg 63340e3fbdSmrg break; 64340e3fbdSmrg case 2: 65340e3fbdSmrg /* XXX depth 16 */ 66340e3fbdSmrg packfg = ((fg & 0x00f80000) >> 19) | ((fg & 0x0000fc00) >> 5) | 67340e3fbdSmrg ((fg & 0x000000f8) << 8); 68340e3fbdSmrg packbg = ((bg & 0x00f80000) >> 19) | ((bg & 0x0000fc00) >> 5) | 69340e3fbdSmrg ((bg & 0x000000f8) << 8); 70340e3fbdSmrg 71340e3fbdSmrg outb(vgaCRIndex, 0x45); 72340e3fbdSmrg inb(vgaCRReg); 73340e3fbdSmrg outb(vgaCRIndex, 0x4a); 74340e3fbdSmrg outb(vgaCRReg, packfg); 75340e3fbdSmrg outb(vgaCRReg, packfg >> 8); 76340e3fbdSmrg 77340e3fbdSmrg outb(vgaCRIndex, 0x45); 78340e3fbdSmrg inb(vgaCRReg); 79340e3fbdSmrg outb(vgaCRIndex, 0x4b); 80340e3fbdSmrg outb(vgaCRReg, packbg); 81340e3fbdSmrg outb(vgaCRReg, packbg >> 8); 82340e3fbdSmrg 83340e3fbdSmrg break; 84340e3fbdSmrg default: 85340e3fbdSmrg outb(vgaCRIndex, 0x45); 86340e3fbdSmrg inb(vgaCRReg); 87340e3fbdSmrg outb(vgaCRIndex, 0x4a); 88340e3fbdSmrg outb(vgaCRReg, (fg & 0x00ff0000) >> 16); 89340e3fbdSmrg outb(vgaCRReg, (fg & 0x0000ff00) >> 8); 90340e3fbdSmrg outb(vgaCRReg, (fg & 0x000000ff)); 91340e3fbdSmrg 92340e3fbdSmrg outb(vgaCRIndex, 0x45); 93340e3fbdSmrg inb(vgaCRReg); 94340e3fbdSmrg outb(vgaCRIndex, 0x4b); 95340e3fbdSmrg outb(vgaCRReg, (bg & 0x00ff0000) >> 16); 96340e3fbdSmrg outb(vgaCRReg, (bg & 0x0000ff00) >> 8); 97340e3fbdSmrg outb(vgaCRReg, (bg & 0x000000ff)); 98340e3fbdSmrg 99340e3fbdSmrg break; 100340e3fbdSmrg } 101340e3fbdSmrg} 102340e3fbdSmrg 103340e3fbdSmrg 104340e3fbdSmrgstatic void S3SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 105340e3fbdSmrg{ 106340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 107340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 108340e3fbdSmrg 109340e3fbdSmrg outb(vgaCRIndex, 0x39); 110340e3fbdSmrg outb(vgaCRReg, 0xa5); 111340e3fbdSmrg 112340e3fbdSmrg outb(vgaCRIndex, 0x46); 113340e3fbdSmrg outb(vgaCRReg, x >> 8); 114340e3fbdSmrg outb(vgaCRIndex, 0x47); 115340e3fbdSmrg outb(vgaCRReg, x); 116340e3fbdSmrg 117340e3fbdSmrg outb(vgaCRIndex, 0x49); 118340e3fbdSmrg outb(vgaCRReg, y); 119340e3fbdSmrg outb(vgaCRIndex, 0x48); 120340e3fbdSmrg outb(vgaCRReg, y >> 8); 121340e3fbdSmrg} 122340e3fbdSmrg 123340e3fbdSmrg 124340e3fbdSmrgstatic void S3HideCursor(ScrnInfoPtr pScrn) 125340e3fbdSmrg{ 126340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 127340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 128340e3fbdSmrg unsigned char tmp; 129340e3fbdSmrg 130340e3fbdSmrg outb(vgaCRIndex, 0x45); 131340e3fbdSmrg tmp = inb(vgaCRReg); 132340e3fbdSmrg outb(vgaCRReg, tmp & ~0x01); 133340e3fbdSmrg} 134340e3fbdSmrg 135340e3fbdSmrg 136340e3fbdSmrgstatic void S3ShowCursor(ScrnInfoPtr pScrn) 137340e3fbdSmrg{ 138340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 139340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 140340e3fbdSmrg unsigned char tmp; 141340e3fbdSmrg 142340e3fbdSmrg outb(vgaCRIndex, 0x39); 143340e3fbdSmrg outb(vgaCRReg, 0xa5); 144340e3fbdSmrg 145340e3fbdSmrg outb(vgaCRIndex, 0x55); 146340e3fbdSmrg tmp = inb(vgaCRReg); 147340e3fbdSmrg outb(vgaCRReg, tmp | 0x10); 148340e3fbdSmrg 149340e3fbdSmrg outb(vgaCRIndex, 0x4c); 150340e3fbdSmrg outb(vgaCRReg, pS3->FBCursorOffset >> 8); 151340e3fbdSmrg outb(vgaCRIndex, 0x4d); 152340e3fbdSmrg outb(vgaCRReg, pS3->FBCursorOffset); 153340e3fbdSmrg 154340e3fbdSmrg outb(vgaCRIndex, 0x45); 155340e3fbdSmrg tmp = inb(vgaCRReg); 156340e3fbdSmrg outb(vgaCRReg, tmp | 0x01); 157340e3fbdSmrg} 158340e3fbdSmrg 159340e3fbdSmrg 160340e3fbdSmrgstatic void S3LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image) 161340e3fbdSmrg{ 162340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 163340e3fbdSmrg int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 164340e3fbdSmrg unsigned char cr45; 165340e3fbdSmrg 166340e3fbdSmrg outb(vgaCRIndex, 0x39); 167340e3fbdSmrg outb(vgaCRReg, 0xa5); 168340e3fbdSmrg 169340e3fbdSmrg WaitIdle(); 170340e3fbdSmrg 171340e3fbdSmrg VerticalRetraceWait(); 172340e3fbdSmrg 173340e3fbdSmrg outb(vgaCRIndex, 0x45); 174340e3fbdSmrg cr45 = inb(vgaCRReg); 175340e3fbdSmrg outb(vgaCRReg, cr45 & 0xfe); 176340e3fbdSmrg 177340e3fbdSmrg outb(vgaCRIndex, 0x46); 178340e3fbdSmrg outb(vgaCRReg, 0xff); 179340e3fbdSmrg outb(vgaCRIndex, 0x47); 180340e3fbdSmrg outb(vgaCRReg, 0x7f); 181340e3fbdSmrg outb(vgaCRIndex, 0x49); 182340e3fbdSmrg outb(vgaCRReg, 0xff); 183340e3fbdSmrg outb(vgaCRIndex, 0x4e); 184340e3fbdSmrg outb(vgaCRReg, 0x3f); 185340e3fbdSmrg outb(vgaCRIndex, 0x4f); 186340e3fbdSmrg outb(vgaCRReg, 0x3f); 187340e3fbdSmrg outb(vgaCRIndex, 0x48); 188340e3fbdSmrg outb(vgaCRReg, 0x7f); 189340e3fbdSmrg 190340e3fbdSmrg memcpy(pS3->FBBase + (pS3->FBCursorOffset * 1024), image, 1024); 191340e3fbdSmrg 192340e3fbdSmrg VerticalRetraceWait(); 193340e3fbdSmrg 194340e3fbdSmrg outb(vgaCRIndex, 0x45); 195340e3fbdSmrg outb(vgaCRReg, cr45); 196340e3fbdSmrg} 197340e3fbdSmrg 198340e3fbdSmrg 199340e3fbdSmrgstatic Bool S3UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 200340e3fbdSmrg{ 201340e3fbdSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 202340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 203340e3fbdSmrg return (pS3->hwCursor); 204340e3fbdSmrg} 205340e3fbdSmrg 206340e3fbdSmrg 207340e3fbdSmrgBool S3_CursorInit(ScreenPtr pScreen) 208340e3fbdSmrg{ 209340e3fbdSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 210340e3fbdSmrg S3Ptr pS3 = S3PTR(pScrn); 211340e3fbdSmrg xf86CursorInfoPtr pCurs; 212340e3fbdSmrg 213340e3fbdSmrg if (!(pCurs = pS3->pCurs = xf86CreateCursorInfoRec())) 214340e3fbdSmrg return FALSE; 215340e3fbdSmrg 216340e3fbdSmrg pCurs->MaxWidth = 64; 217340e3fbdSmrg pCurs->MaxHeight = 64; 218340e3fbdSmrg pCurs->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 219340e3fbdSmrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | 220340e3fbdSmrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST; 221340e3fbdSmrg 222340e3fbdSmrg pCurs->SetCursorColors = S3SetCursorColors; 223340e3fbdSmrg pCurs->SetCursorPosition = S3SetCursorPosition; 224340e3fbdSmrg pCurs->LoadCursorImage = S3LoadCursorImage; 225340e3fbdSmrg pCurs->HideCursor = S3HideCursor; 226340e3fbdSmrg pCurs->ShowCursor = S3ShowCursor; 227340e3fbdSmrg pCurs->UseHWCursor = S3UseHWCursor; 228340e3fbdSmrg 229340e3fbdSmrg return xf86InitCursor(pScreen, pCurs); 230340e3fbdSmrg} 231340e3fbdSmrg 232