diff options
Diffstat (limited to 'src/radeon_cursor.c')
-rw-r--r-- | src/radeon_cursor.c | 312 |
1 files changed, 192 insertions, 120 deletions
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c index 6d61b079..f6c116cc 100644 --- a/src/radeon_cursor.c +++ b/src/radeon_cursor.c @@ -103,43 +103,41 @@ static CARD32 mono_cursor_color[] = { #endif -static void -RADEONCrtcCursor(xf86CrtcPtr crtc, Bool force) +void +radeon_crtc_show_cursor (xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; int crtc_id = radeon_crtc->crtc_id; RADEONInfoPtr info = RADEONPTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - Bool show; unsigned char *RADEONMMIO = info->MMIO; - CARD32 save1 = 0, save2 = 0; - if (!crtc->enabled && !crtc->cursorShown) - return; + if (crtc_id == 0) + OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, + ~RADEON_CRTC_CUR_EN); + else if (crtc_id == 1) + OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, + ~RADEON_CRTC2_CUR_EN); + + +} + +void +radeon_crtc_hide_cursor (xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + int crtc_id = radeon_crtc->crtc_id; + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + if (crtc_id == 0) + OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); + else if (crtc_id == 1) + OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); - - show = crtc->cursorInRange && crtc->enabled; - if (show && (force || !crtc->cursorShown)) - { - if (crtc_id == 0) - OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN, - ~RADEON_CRTC_CUR_EN); - else if (crtc_id == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN, - ~RADEON_CRTC2_CUR_EN); - crtc->cursorShown = TRUE; - } else if (!show && (force || crtc->cursorShown)) { - - if (crtc_id == 0) - OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN); - else if (crtc_id == 1) - OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN); - - crtc->cursorShown = FALSE; - } - -} + +} /* Set cursor foreground and background colors */ static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) @@ -179,20 +177,21 @@ static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) info->cursor_bg = bg; } -static void -RADEONRandrSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) +void +radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + ScrnInfoPtr pScrn = crtc->scrn; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + int crtc_id = radeon_crtc->crtc_id; RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - xf86CursorInfoPtr cursor = info->cursor; - Bool inrange; int temp; int oldx = x, oldy = y; int hotspotx = 0, hotspoty = 0; int c; int xorigin, yorigin; int stride = 256; + int thisx, thisy; oldx += pScrn->frameX0; /* undo what xf86HWCurs did */ oldy += pScrn->frameY0; @@ -200,70 +199,90 @@ RADEONRandrSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) x = oldx; y = oldy; - for (c = 0 ; c < xf86_config->num_crtc; c++) { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - DisplayModePtr mode = &crtc->mode; - int thisx = x - crtc->x; - int thisy = y - crtc->y; - - if (!crtc->enabled && !crtc->cursorShown) - continue; - - /* - * There is a screen display problem when the cursor position is set - * wholely outside of the viewport. We trap that here, turning the - * cursor off when that happens, and back on when it comes back into - * the viewport. - */ - inrange = TRUE; - if (thisx >= mode->HDisplay || - thisy >= mode->VDisplay || - thisx <= -cursor->MaxWidth || thisy <= -cursor->MaxHeight) - { - inrange = FALSE; - thisx = 0; - thisy = 0; - } + DisplayModePtr mode = &crtc->mode; + thisx = x - crtc->x; + thisy = y - crtc->y; - temp = 0; - xorigin = 0; - yorigin = 0; - if (thisx < 0) xorigin = -thisx+1; - if (thisy < 0) yorigin = -thisy+1; - if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; - if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; - - temp |= (xorigin ? 0 : thisx) << 16; - temp |= (yorigin ? 0 : thisy); - - if (c == 0) { - OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK - | (xorigin << 16) - | yorigin)); - OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | - temp)); - RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n", - info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); - OUTREG(RADEON_CUR_OFFSET, - info->cursor_offset + pScrn->fbOffset + yorigin * stride); - } - if (c == 1) { - OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK - | (xorigin << 16) - | yorigin)); - OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK | - temp)); - RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n", - info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); - OUTREG(RADEON_CUR2_OFFSET, - info->cursor_offset + pScrn->fbOffset + yorigin * stride); - } - crtc->cursorInRange = inrange; + if (thisx >= mode->HDisplay || + thisy >= mode->VDisplay) + { + thisx = 0; + thisy = 0; + } - RADEONCrtcCursor(crtc, FALSE); + temp = 0; + xorigin = 0; + yorigin = 0; + if (thisx < 0) xorigin = -thisx+1; + if (thisy < 0) yorigin = -thisy+1; +#if 0 + if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1; + if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1; +#endif + temp |= (xorigin ? 0 : thisx) << 16; + temp |= (yorigin ? 0 : thisy); + + if (crtc_id == 0) { + OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK + | (xorigin << 16) + | yorigin)); + OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK | + temp)); + RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n", + info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); + OUTREG(RADEON_CUR_OFFSET, + info->cursor_offset + pScrn->fbOffset + yorigin * stride); + } else if (crtc_id == 1) { + OUTREG(RADEON_CUR2_HORZ_VERT_OFF, (RADEON_CUR2_LOCK + | (xorigin << 16) + | yorigin)); + OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK | + temp)); + RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n", + info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp)); + OUTREG(RADEON_CUR2_OFFSET, + info->cursor_offset + pScrn->fbOffset + yorigin * stride); } +} +void +radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) +{ + ScrnInfoPtr pScrn = crtc->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); + CARD32 *pixels = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset); + int pixel, i; + CURSOR_SWAPPING_DECL_MMIO + + RADEONCTRACE(("RADEONSetCursorColors\n")); + +#ifdef ARGB_CURSOR + /* Don't recolour cursors set with SetCursorARGB. */ + if (info->cursor_argb) + return; +#endif + + fg |= 0xff000000; + bg |= 0xff000000; + + /* Don't recolour the image if we don't have to. */ + if (fg == info->cursor_fg && bg == info->cursor_bg) + return; + + CURSOR_SWAPPING_START(); + + /* Note: We assume that the pixels are either fully opaque or fully + * transparent, so we won't premultiply them, and we can just + * check for non-zero pixel values; those are either fg or bg + */ + for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++) + if ((pixel = *pixels)) + *pixels = (pixel == info->cursor_fg) ? fg : bg; + + CURSOR_SWAPPING_END(); + info->cursor_fg = fg; + info->cursor_bg = bg; } /* Copy cursor image from `image' to video memory. RADEONSetCursorPosition @@ -380,6 +399,73 @@ static Bool RADEONUseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs) return FALSE; } +void +radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) +{ + ScrnInfoPtr pScrn = crtc->scrn; + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + int crtc_id = radeon_crtc->crtc_id; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset); + int x, y, w, h; + CARD32 save1 = 0; + CARD32 save2 = 0; + CARD32 *i; + + RADEONCTRACE(("RADEONLoadCursorARGB\n")); + + if (crtc_id == 0) { + save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20); + save1 |= (CARD32) (2 << 20); + OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN); + } else if (crtc_id == 1) { + save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20); + save2 |= (CARD32) (2 << 20); + OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN); + } + +#ifdef ARGB_CURSOR + info->cursor_argb = TRUE; +#endif + + CURSOR_SWAPPING_START(); + + + memcpy (d, image, CURSOR_HEIGHT * CURSOR_WIDTH * 4); +#if 0 + w = pCurs->bits->width; + if (w > CURSOR_WIDTH) + w = CURSOR_WIDTH; + h = pCurs->bits->height; + if (h > CURSOR_HEIGHT) + h = CURSOR_HEIGHT; + for (y = 0; y < h; y++) + { + i = image; + image += pCurs->bits->width; + for (x = 0; x < w; x++) + *d++ = *i++; + /* pad to the right with transparent */ + for (; x < CURSOR_WIDTH; x++) + *d++ = 0; + } + /* pad below with transparent */ + for (; y < CURSOR_HEIGHT; y++) + for (x = 0; x < CURSOR_WIDTH; x++) + *d++ = 0; +#endif + + CURSOR_SWAPPING_END (); + + if (crtc_id == 0) { + OUTREG(RADEON_CRTC_GEN_CNTL, save1); + } else if (crtc_id == 1) { + OUTREG(RADEON_CRTC2_GEN_CNTL, save2); + } +} + static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs) { RADEONInfoPtr info = RADEONPTR(pScrn); @@ -462,33 +548,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen) int height; int size_bytes; - if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE; - - cursor->MaxWidth = CURSOR_WIDTH; - cursor->MaxHeight = CURSOR_HEIGHT; - cursor->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP - | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* this is a lie -- - * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST - * actually inverts the bit order, so - * this switches to LSBFIRST - */ - | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST -#endif - | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1); - cursor->SetCursorColors = RADEONSetCursorColors; - cursor->SetCursorPosition = RADEONRandrSetCursorPosition; - cursor->LoadCursorImage = RADEONLoadCursorImage; - cursor->HideCursor = RADEONHideCursor; - cursor->ShowCursor = RADEONShowCursor; - cursor->UseHWCursor = RADEONUseHWCursor; - -#ifdef ARGB_CURSOR - cursor->UseHWCursorARGB = RADEONUseHWCursorARGB; - cursor->LoadCursorARGB = RADEONLoadCursorARGB; -#endif size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT; width = pScrn->displayWidth; width_bytes = width * (pScrn->bitsPerPixel / 8); @@ -518,5 +578,17 @@ Bool RADEONCursorInit(ScreenPtr pScreen) } #endif - return xf86InitCursor(pScreen, cursor); + return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT, + (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* this is a lie -- + * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST + * actually inverts the bit order, so + * this switches to LSBFIRST + */ + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | +#endif + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 | + HARDWARE_CURSOR_ARGB)); } |