diff options
Diffstat (limited to 'src/i830_cursor.c')
-rw-r--r-- | src/i830_cursor.c | 202 |
1 files changed, 177 insertions, 25 deletions
diff --git a/src/i830_cursor.c b/src/i830_cursor.c index ef9a81ee..d59c19dd 100644 --- a/src/i830_cursor.c +++ b/src/i830_cursor.c @@ -26,7 +26,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c,v 1.7 2003/06/18 13:14:17 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_cursor.c,v 1.6 2002/12/18 15:49:01 dawes Exp $ */ /* * Reformatted with GNU indent (2.2.8), using the following options: @@ -46,6 +46,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Keith Whitwell <keith@tungstengraphics.com> * David Dawes <dawes@xfree86.org> * + * Updated for Dual Head capabilities: + * Alan Hourihane <alanh@tungstengraphics.com> + * + * Add ARGB HW cursor support: + * Alan Hourihane <alanh@tungstengraphics.com> + * */ #include "xf86.h" @@ -63,6 +69,10 @@ static void I830HideCursor(ScrnInfoPtr pScrn); static void I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); static void I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); static Bool I830UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); +#ifdef ARGB_CURSOR +static void I830LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs); +static Bool I830UseHWCursorARGB(ScreenPtr pScrn, CursorPtr pCurs); +#endif void I830InitHWCursor(ScrnInfoPtr pScrn) @@ -71,24 +81,28 @@ I830InitHWCursor(ScrnInfoPtr pScrn) CARD32 temp; DPRINTF(PFX, "I830InitHWCursor\n"); - /* Initialise the HW cursor registers, leaving the cursor hidden. */ - if (IS_MOBILE(pI830)) { + if (IS_MOBILE(pI830) || IS_I915G(pI830)) { temp = INREG(CURSOR_A_CONTROL); temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL | MCURSOR_PIPE_SELECT); temp |= CURSOR_MODE_DISABLE; - /* - * XXX Should enable cursor B when both pipes are enabled. - * For now, give pipe A preference. - */ - if (pI830->pipeEnabled[0]) - temp |= MCURSOR_PIPE_A; - else if (pI830->pipeEnabled[1]) - temp |= MCURSOR_PIPE_B; + temp |= (pI830->pipe << 28); /* Need to set control, then address. */ OUTREG(CURSOR_A_CONTROL, temp); - OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical); + if (pI830->Clone) { + temp &= ~MCURSOR_PIPE_SELECT; + temp |= (!pI830->pipe << 28); + OUTREG(CURSOR_B_CONTROL, temp); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical); + } } else { temp = INREG(CURSOR_CONTROL); temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE | @@ -97,7 +111,10 @@ I830InitHWCursor(ScrnInfoPtr pScrn) /* This initialises the format and leave the cursor disabled. */ OUTREG(CURSOR_CONTROL, temp); /* Need to set address and size after disabling. */ - OUTREG(CURSOR_BASEADDR, pI830->CursorMem.Start); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_BASEADDR, pI830->CursorMemARGB->Start); + else + OUTREG(CURSOR_BASEADDR, pI830->CursorMem->Start); temp = ((I810_CURSOR_X & CURSOR_SIZE_MASK) << CURSOR_SIZE_HSHIFT) | ((I810_CURSOR_Y & CURSOR_SIZE_MASK) << CURSOR_SIZE_VSHIFT); OUTREG(CURSOR_SIZE, temp); @@ -134,7 +151,17 @@ I830CursorInit(ScreenPtr pScreen) infoPtr->ShowCursor = I830ShowCursor; infoPtr->UseHWCursor = I830UseHWCursor; - if (pI830->CursorNeedsPhysical && !pI830->CursorMem.Physical) +#ifdef ARGB_CURSOR + pI830->CursorIsARGB = FALSE; + + if (pI830->CursorMemARGB->Start) { + /* Use ARGB if we were able to allocate the 16kb needed */ + infoPtr->UseHWCursorARGB = I830UseHWCursorARGB; + infoPtr->LoadCursorARGB = I830LoadCursorARGB; + } +#endif + + if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical) return FALSE; I830HideCursor(pScrn); @@ -149,7 +176,7 @@ I830UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) I830Ptr pI830 = I830PTR(pScrn); DPRINTF(PFX, "I830UseHWCursor\n"); - if (pI830->CursorNeedsPhysical && !pI830->CursorMem.Physical) + if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical) return FALSE; return TRUE; @@ -159,10 +186,15 @@ static void I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { I830Ptr pI830 = I830PTR(pScrn); - CARD8 *pcurs = (CARD8 *) (pI830->FbBase + pI830->CursorMem.Start); + CARD8 *pcurs = (CARD8 *) (pI830->FbBase + pI830->CursorMem->Start); int x, y; DPRINTF(PFX, "I830LoadCursorImage\n"); + +#ifdef ARGB_CURSOR + pI830->CursorIsARGB = FALSE; +#endif + for (y = 0; y < 64; y++) { for (x = 0; x < 64 / 4; x++) { *pcurs++ = *src++; @@ -170,6 +202,59 @@ I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) } } +#ifdef ARGB_CURSOR +#include "cursorstr.h" + +static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + + DPRINTF(PFX, "I830UseHWCursorARGB\n"); + if (pScrn->bitsPerPixel == 8) + return FALSE; + + if (pI830->CursorNeedsPhysical && !pI830->CursorMemARGB->Physical) + return FALSE; + + if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64) + return TRUE; + + return FALSE; +} + +static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) +{ + I830Ptr pI830 = I830PTR(pScrn); + CARD32 *dst = (CARD32 *) (pI830->FbBase + pI830->CursorMemARGB->Start); + CARD32 *image = (CARD32 *)pCurs->bits->argb; + int x, y, w, h; + + DPRINTF(PFX, "I830LoadCursorARGB\n"); + + if (!image) + return; /* XXX can't happen */ + +#ifdef ARGB_CURSOR + pI830->CursorIsARGB = TRUE; +#endif + + w = pCurs->bits->width; + h = pCurs->bits->height; + + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) + *dst++ = *image++; + for(; x < 64; x++) + *dst++ = 0; + } + + for(; y < 64; y++) { + for(x = 0; x < 64; x++) + *dst++ = 0; + } +} +#endif static void I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) @@ -207,6 +292,8 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); OUTREG(CURSOR_A_POSITION, temp); + if (pI830->Clone) + OUTREG(CURSOR_B_POSITION, temp); if (pI830->cursorOn) { if (hide) @@ -215,6 +302,20 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) pI830->CursorInfoRec->ShowCursor(pScrn); pI830->cursorOn = TRUE; } + + /* have to upload the base for the new position */ + if (IS_I915G(pI830)) { + if (pI830->CursorIsARGB) + OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical); + if (pI830->Clone) { + if (pI830->CursorIsARGB) + OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical); + } + } } static void @@ -225,22 +326,51 @@ I830ShowCursor(ScrnInfoPtr pScrn) DPRINTF(PFX, "I830ShowCursor\n"); DPRINTF(PFX, - "Value of CursorMem.Physical is %x, " - " Value of CursorMem.Start is %x ", - pI830->CursorMem.Physical, pI830->CursorMem.Start); + "Value of CursorMem->Physical is %x, " + " Value of CursorMem->Start is %x ", + pI830->CursorMem->Physical, pI830->CursorMem->Start); + DPRINTF(PFX, + "Value of CursorMemARGB->Physical is %x, " + " Value of CursorMemARGB->Start is %x ", + pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start); pI830->cursorOn = TRUE; - if (IS_MOBILE(pI830)) { + if (IS_MOBILE(pI830) || IS_I915G(pI830)) { temp = INREG(CURSOR_A_CONTROL); - temp &= ~CURSOR_MODE; - temp |= CURSOR_MODE_64_4C_AX; + temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); + if (pI830->CursorIsARGB) + temp |= CURSOR_MODE_64_ARGB_AX; + else + temp |= CURSOR_MODE_64_4C_AX; + temp |= (pI830->pipe << 28); /* Connect to correct pipe */ /* Need to set mode, then address. */ OUTREG(CURSOR_A_CONTROL, temp); - OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical); + if (pI830->Clone) { + temp &= ~MCURSOR_PIPE_SELECT; + temp |= (!pI830->pipe << 28); + OUTREG(CURSOR_B_CONTROL, temp); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical); + } } else { temp = INREG(CURSOR_CONTROL); + temp &= ~(CURSOR_FORMAT_MASK); temp |= CURSOR_ENABLE; + if (pI830->CursorIsARGB) + temp |= CURSOR_FORMAT_ARGB; + else + temp |= CURSOR_FORMAT_3C; OUTREG(CURSOR_CONTROL, temp); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_BASEADDR, pI830->CursorMemARGB->Start); + else + OUTREG(CURSOR_BASEADDR, pI830->CursorMem->Start); } } @@ -253,13 +383,23 @@ I830HideCursor(ScrnInfoPtr pScrn) DPRINTF(PFX, "I830HideCursor\n"); pI830->cursorOn = FALSE; - if (IS_MOBILE(pI830)) { + if (IS_MOBILE(pI830) || IS_I915G(pI830)) { temp = INREG(CURSOR_A_CONTROL); temp &= ~CURSOR_MODE; temp |= CURSOR_MODE_DISABLE; OUTREG(CURSOR_A_CONTROL, temp); /* This is needed to flush the above change. */ - OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_A_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_A_BASE, pI830->CursorMem->Physical); + if (pI830->Clone) { + OUTREG(CURSOR_B_CONTROL, temp); + if (pI830->CursorIsARGB) + OUTREG(CURSOR_B_BASE, pI830->CursorMemARGB->Physical); + else + OUTREG(CURSOR_B_BASE, pI830->CursorMem->Physical); + } } else { temp = INREG(CURSOR_CONTROL); temp &= ~CURSOR_ENABLE; @@ -272,10 +412,22 @@ I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { I830Ptr pI830 = I830PTR(pScrn); +#ifdef ARGB_CURSOR + /* Don't recolour cursors set with SetCursorARGB. */ + if (pI830->CursorIsARGB) + return; +#endif + DPRINTF(PFX, "I830SetCursorColors\n"); OUTREG(CURSOR_A_PALETTE0, bg & 0x00ffffff); OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff); OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff); OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff); + if (pI830->Clone) { + OUTREG(CURSOR_B_PALETTE0, bg & 0x00ffffff); + OUTREG(CURSOR_B_PALETTE1, fg & 0x00ffffff); + OUTREG(CURSOR_B_PALETTE2, fg & 0x00ffffff); + OUTREG(CURSOR_B_PALETTE3, bg & 0x00ffffff); + } } |