diff options
author | Dirk Hohndel <dirk.hohndel@intel.com> | 1999-11-19 13:54:06 +0000 |
---|---|---|
committer | Dirk Hohndel <dirk.hohndel@intel.com> | 1999-11-19 13:54:06 +0000 |
commit | f13b792a3a8d307a18cd6a41aa5a06622009e42f (patch) | |
tree | 5d7e7eb1dd3d69a9a408d0082c031c6121d625ea /hw/kdrive/trident/tridentcurs.c |
3336. Fx up new MMIO macros (#3337, Matt Grossman).xf-3_9_16fxf-3_9_16exf-3_9_16dxf-3_9_16Z
3335. Clean up compiler warnings in lib/font/bitmap (#3411, Matt Grossman).
3334. TGA fixes, add sync on green (#3410, Matt Grossman).
3333. Fix NULL pointer dereference in libXaw (#3406, Christopher Sekiya).
3332. Add Rage128 support (#3405, Rik Faith, funded by ATI).
3331. Add MTRR support for NetBSD and OpenBSD. Add new NetBSD aperture
driver (#3404, Matthieu Herrb).
3330. Xterm patch #121 (#3402, Thomas Dickey).
3329. Rendition driver bugfixes and alpha related cleanups (#3400, Dejan
Ilic, Marc Langenbach, Egbert Eich).
3328. Add void input device (#3392, Frederic Lepied).
3327. Changed the Xon serial option to be able to select xon/xoff for
input, output or both. Add support for Graphire models. Change wacom
init phase to use new Xoff option (#3391, Frederic Lepied).
3326. Change the SwapAxes option to SwapXY in elographics/microtouch driver
to match an already existing option in the Dynapro driver. Add a Focus
class capability to the elographics driver (#3395, Patrick Lecoanet).
3325. Update mouse rate handling (#3388, Harald Koenig).
3324. Fix NULL pointer dereference in misprite.c (#3380, Edward Wang).
3323. Add FBDev and ShadowFB support to glint driver. Add new option
"NoWriteBitmap" (#3383, Michel Daenzer).
3322. Update SuperProbe to handle S3 Savage4, Savage200 and clean up
Trio3D/Savage3D detection (#3382,3384 Harald Koenig).
3321. Add new framebuffer code and tiny X DDX architecture (#3379, Keith
Packard).
3320. Add DGA2 documentation (#3378, Mark Vojkovich).
3319. Update XFree86 manpage wrt -bpp/-depth/-fbbpp (#3377, Andy Isaacson).
3318. Make SuperProbe check primary cards, only (#3374, Harald Koenig).
3317. Add SilkenMouse to *BSD (#3373, Matthieu Herrb).
3316. Allow SilkenMouse to work if not all drivers of an OS support SIGIO
(#3372, Keith Packard).
3315. Fix a few problems in TGA driver and add support for backing store
and SilkenMouse (#3371, Matt Grossman).
3314. Add smarter scheduler (#3370, Keith Packard).
3313. Xterm patch #120 (#3369, Thomas Dickey).
3312. Enable xf86SetKbdRate function on Solaris 8 (#3364, David Holland).
3311. Fix some bugs and add acceleration to Rendition server (#3360, Dejan
Ilic).
3310. Make raw DDC information available as properties in the root window
(#3357, Andrew Aitchison).
3309. Fix for xf86CreateRootWindow (#3355, Andrew Aitchison).
3308. Add manpage for the chips driver (#3353, David Bateman).
3307. Update contact info (#3352, Andrew van der Stock).
3306. Add kbd rate support for Linux (#3363, Harald Koenig).
3305. Update Portuguese XKB map (#3351, Joao Esteves, Francisco Colaco).
3304. Fix text clipping in 3dfx driver (#3349, Henrik Harmsen).
3303. Fix S3 ViRGE hw cursor (#3348, Harald Koenig).
3302. Fix clipping in 3dfx driver (#3342, Daryll Strauss).
3301. Enable SilkenMouse for 3dfx driver (#3341, Henrik Harmsen).
3300. Enable SIGIO support on LynxOS (#3339, Thomas Mueller).
3299. Get TRUE defined in sigio.c. Fix xterm compile problem on ISC (#3338,
Michael Rohleder).
3298. Correct DPMS suspend/standby modes for 3dfx driver (#3336, Henrik
Harmsen)
3297. Xterm patch #119 (#3335, Thomas Dickey).
Diffstat (limited to 'hw/kdrive/trident/tridentcurs.c')
-rw-r--r-- | hw/kdrive/trident/tridentcurs.c | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/hw/kdrive/trident/tridentcurs.c b/hw/kdrive/trident/tridentcurs.c new file mode 100644 index 000000000..9c4ebb5d0 --- /dev/null +++ b/hw/kdrive/trident/tridentcurs.c @@ -0,0 +1,414 @@ +/* + * $Id$ + * + * Copyright © 1999 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* $XFree86: $ */ + +#include "trident.h" +#include "cursorstr.h" + +#define SetupCursor(s) KdScreenPriv(s); \ + tridentCardInfo(pScreenPriv); \ + tridentScreenInfo(pScreenPriv); \ + TridentCursor *pCurPriv = &tridents->cursor + +static void +_tridentMoveCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor(pScreen); + CARD8 xlow, xhigh, ylow, yhigh; + CARD8 xoff, yoff; + + x -= pCurPriv->xhot; + xoff = 0; + if (x < 0) + { + xoff = -x; + x = 0; + } + y -= pCurPriv->yhot; + yoff = 0; + if (y < 0) + { + yoff = -y; + y = 0; + } + xlow = (CARD8) x; + xhigh = (CARD8) (x >> 8); + ylow = (CARD8) y; + yhigh = (CARD8) (y >> 8); + + + /* This is the recommended order to move the cursor */ + + tridentWriteIndex (tridentc, 0x3d4, 0x41, xhigh); + tridentWriteIndex (tridentc, 0x3d4, 0x40, xlow); + tridentWriteIndex (tridentc, 0x3d4, 0x42, ylow); + tridentWriteIndex (tridentc, 0x3d4, 0x46, xoff); + tridentWriteIndex (tridentc, 0x3d4, 0x47, yoff); + tridentWriteIndex (tridentc, 0x3d4, 0x43, yhigh); +} + +static void +tridentMoveCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor (pScreen); + + if (!pCurPriv->has_cursor) + return; + + if (!pScreenPriv->enabled) + return; + + _tridentMoveCursor (pScreen, x, y); +} + + +static void +tridentAllocCursorColors (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + xColorItem sourceColor, maskColor; + + /* + * Set these to an invalid pixel value so that + * when the store colors comes through, the cursor + * won't get recolored + */ + pCurPriv->source = ~0; + pCurPriv->mask = ~0; + /* + * XXX S3 bug workaround; s3 chip doesn't use RGB values from + * the cursor color registers as documented, rather it uses + * them to index the DAC. This is in the errata though. + */ + sourceColor.red = pCursor->foreRed; + sourceColor.green = pCursor->foreGreen; + sourceColor.blue = pCursor->foreBlue; + FakeAllocColor(pScreenPriv->pInstalledmap, &sourceColor); + maskColor.red = pCursor->backRed; + maskColor.green = pCursor->backGreen; + maskColor.blue = pCursor->backBlue; + FakeAllocColor(pScreenPriv->pInstalledmap, &maskColor); + FakeFreeColor(pScreenPriv->pInstalledmap, sourceColor.pixel); + FakeFreeColor(pScreenPriv->pInstalledmap, maskColor.pixel); + + pCurPriv->source = sourceColor.pixel; + pCurPriv->mask = maskColor.pixel; + switch (pScreenPriv->screen->bitsPerPixel) { + case 4: + pCurPriv->source |= pCurPriv->source << 4; + pCurPriv->mask |= pCurPriv->mask << 4; + case 8: + pCurPriv->source |= pCurPriv->source << 8; + pCurPriv->mask |= pCurPriv->mask << 8; + case 16: + pCurPriv->source |= pCurPriv->source << 16; + pCurPriv->mask |= pCurPriv->mask << 16; + } +} + +static void +tridentSetCursorColors (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + CARD32 fg, bg; + + fg = pCurPriv->source; + bg = pCurPriv->mask; + tridentWriteIndex (tridentc, 0x3d4, 0x48, fg); + tridentWriteIndex (tridentc, 0x3d4, 0x49, fg >> 8); + tridentWriteIndex (tridentc, 0x3d4, 0x4a, fg >> 16); + + tridentWriteIndex (tridentc, 0x3d4, 0x4c, bg); + tridentWriteIndex (tridentc, 0x3d4, 0x4d, bg >> 8); + tridentWriteIndex (tridentc, 0x3d4, 0x4e, bg >> 16); +} + +void +tridentRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + xColorItem sourceColor, maskColor; + + if (!pCurPriv->has_cursor || !pCursor) + return; + + if (!pScreenPriv->enabled) + return; + + if (pdef) + { + while (ndef) + { + if (pdef->pixel == pCurPriv->source || + pdef->pixel == pCurPriv->mask) + break; + ndef--; + } + if (!ndef) + return; + } + tridentAllocCursorColors (pScreen); + tridentSetCursorColors (pScreen); +} + +#define InvertBits32(v) { \ + v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \ + v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \ + v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \ +} + +static void +tridentLoadCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor(pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + CursorBitsPtr bits = pCursor->bits; + int w, h; + CARD32 *ram, *msk, *mskLine, *src, *srcLine; + int i, j; + int cursor_address; + int lwsrc; + unsigned char ramdac_control_; + CARD32 offset; + + /* + * Allocate new colors + */ + tridentAllocCursorColors (pScreen); + + pCurPriv->pCursor = pCursor; + pCurPriv->xhot = pCursor->bits->xhot; + pCurPriv->yhot = pCursor->bits->yhot; + + /* + * Stick new image into cursor memory + */ + ram = (CARD32 *) tridents->cursor_base; + mskLine = (CARD32 *) bits->mask; + srcLine = (CARD32 *) bits->source; + + h = bits->height; + if (h > TRIDENT_CURSOR_HEIGHT) + h = TRIDENT_CURSOR_HEIGHT; + + lwsrc = BitmapBytePad(bits->width) / 4; /* words per line */ + + for (i = 0; i < TRIDENT_CURSOR_HEIGHT; i++) { + msk = mskLine; + src = srcLine; + mskLine += lwsrc; + srcLine += lwsrc; + for (j = 0; j < TRIDENT_CURSOR_WIDTH / 32; j++) { + + CARD32 m, s; + +#if 1 + if (i < h && j < lwsrc) + { + m = *msk++; + s = *src++; + InvertBits32(m); + InvertBits32(s); + } + else + { + m = 0; + s = 0; + } +#endif + *ram++ = m; + *ram++ = s; + } + } + + /* Set address for cursor bits */ + offset = tridents->cursor_base - (CARD8 *) tridentc->fb.fb; + offset >>= 10; + tridentWriteIndex (tridentc, 0x3d4, 0x44, (CARD8) (offset & 0xff)); + tridentWriteIndex (tridentc, 0x3d4, 0x45, (CARD8) (offset >> 8)); + + /* Set new color */ + tridentSetCursorColors (pScreen); + + /* Enable the cursor */ + tridentWriteIndex (tridentc, 0x3d4, 0x50, 0xc1); + + /* Move to new position */ + tridentMoveCursor (pScreen, x, y); +} + +static void +tridentUnloadCursor (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + /* Disable cursor */ + tridentWriteIndex (tridentc, 0x3d4, 0x50, 0); +} + +static Bool +tridentRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + SetupCursor(pScreen); + + if (!pScreenPriv->enabled) + return TRUE; + + /* miRecolorCursor does this */ + if (pCurPriv->pCursor == pCursor) + { + if (pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + tridentLoadCursor (pScreen, x, y); + } + } + return TRUE; +} + +static Bool +tridentUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + +static void +tridentSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + SetupCursor(pScreen); + + pCurPriv->pCursor = pCursor; + + if (!pScreenPriv->enabled) + return; + + if (pCursor) + tridentLoadCursor (pScreen, x, y); + else + tridentUnloadCursor (pScreen); +} + +miPointerSpriteFuncRec tridentPointerSpriteFuncs = { + tridentRealizeCursor, + tridentUnrealizeCursor, + tridentSetCursor, + tridentMoveCursor, +}; + +static void +tridentQueryBestSize (int class, + unsigned short *pwidth, unsigned short *pheight, + ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + switch (class) + { + case CursorShape: + if (*pwidth > pCurPriv->width) + *pwidth = pCurPriv->width; + if (*pheight > pCurPriv->height) + *pheight = pCurPriv->height; + if (*pwidth > pScreen->width) + *pwidth = pScreen->width; + if (*pheight > pScreen->height) + *pheight = pScreen->height; + break; + default: + fbQueryBestSize (class, pwidth, pheight, pScreen); + break; + } +} + +Bool +tridentCursorInit (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (!tridents->cursor_base) + { + pCurPriv->has_cursor = FALSE; + return FALSE; + } + + pCurPriv->width = TRIDENT_CURSOR_WIDTH; + pCurPriv->height= TRIDENT_CURSOR_HEIGHT; + pScreen->QueryBestSize = tridentQueryBestSize; + miPointerInitialize (pScreen, + &tridentPointerSpriteFuncs, + &kdPointerScreenFuncs, + FALSE); + pCurPriv->has_cursor = TRUE; + pCurPriv->pCursor = NULL; + return TRUE; +} + +void +tridentCursorEnable (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + tridentLoadCursor (pScreen, x, y); + } + else + tridentUnloadCursor (pScreen); + } +} + +void +tridentCursorDisable (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (!pScreenPriv->enabled) + return; + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + tridentUnloadCursor (pScreen); + } + } +} + +void +tridentCursorFini (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + pCurPriv->pCursor = NULL; +} |