summaryrefslogtreecommitdiff
path: root/src/i830_cursor.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@guitar.keithp.com>2006-09-20 22:38:55 -0700
committerKeith Packard <keithp@guitar.keithp.com>2006-09-20 22:38:55 -0700
commitf6500e94fec0d6db8c1f1350bee1d137bf06a09e (patch)
treea26330810dec0fe897bf09dd28ed0b1f8fa2e291 /src/i830_cursor.c
parentcbaf3cf74bd420533d299c4113761ec536097e33 (diff)
Update driver for RandR 1.2 X server API.
This is not entirely what I'd like to see, but it's at least functional. Limitations: Can't disable/enable crtcs Can't move outputs on/off crtcs But, it does handle monitor hot-plug, detecting changes in VGA and SDVO status on-the fly. Which makes for good demo material.
Diffstat (limited to 'src/i830_cursor.c')
-rw-r--r--src/i830_cursor.c371
1 files changed, 197 insertions, 174 deletions
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 2cb069cc..1e7beef2 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -80,12 +80,106 @@ static Bool I830UseHWCursorARGB(ScreenPtr pScrn, CursorPtr pCurs);
#endif
void
+I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
+ Bool show;
+
+ if (!pI830->planeEnabled[pipe])
+ return;
+
+ show = pI830->cursorOn && pI830->cursorInRange[pipe];
+ if (show && !pI830->cursorShown[pipe])
+ {
+ if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
+ int cursor_control, cursor_base;
+ if (pipe == 0)
+ {
+ cursor_control = CURSOR_A_CONTROL;
+ cursor_base = CURSOR_A_BASE;
+ }
+ else
+ {
+ cursor_control = CURSOR_B_CONTROL;
+ cursor_base = CURSOR_B_BASE;
+ }
+ temp = INREG(cursor_control);
+ temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
+ if (pI830->CursorIsARGB) {
+ temp |= CURSOR_MODE_64_ARGB_AX;
+ if (pI830->gammaEnabled[pipe])
+ temp |= MCURSOR_GAMMA_ENABLE;
+ } else
+ temp |= CURSOR_MODE_64_4C_AX;
+
+ temp |= (pipe << 28); /* Connect to correct pipe */
+ /* Need to set mode, then address. */
+ OUTREG(cursor_control, temp);
+ if (pI830->CursorIsARGB)
+ OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(cursor_base, pI830->CursorMem->Physical);
+ } else {
+ temp = INREG(CURSOR_CONTROL);
+ temp &= ~(CURSOR_FORMAT_MASK);
+ temp |= CURSOR_ENABLE;
+ if (pI830->CursorIsARGB) {
+ temp |= CURSOR_FORMAT_ARGB;
+ if (pI830->gammaEnabled[pipe])
+ temp |= CURSOR_GAMMA_ENABLE;
+ } 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);
+ }
+ pI830->cursorShown[pipe] = TRUE;
+ }
+ else if (!show && pI830->cursorShown[pipe])
+ {
+ if (IS_MOBILE(pI830) || IS_I9XX(pI830))
+ {
+ int cursor_control, cursor_base;
+ if (pipe == 0)
+ {
+ cursor_control = CURSOR_A_CONTROL;
+ cursor_base = CURSOR_A_BASE;
+ }
+ else
+ {
+ cursor_control = CURSOR_B_CONTROL;
+ cursor_base = CURSOR_B_BASE;
+ }
+ temp = INREG(cursor_control);
+ temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
+ temp |= CURSOR_MODE_DISABLE;
+ OUTREG(cursor_control, temp);
+ /* This is needed to flush the above change. */
+ if (pI830->CursorIsARGB)
+ OUTREG(cursor_base, pI830->CursorMemARGB->Physical);
+ else
+ OUTREG(cursor_base, pI830->CursorMem->Physical);
+ } else {
+ temp = INREG(CURSOR_CONTROL);
+ temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE);
+ OUTREG(CURSOR_CONTROL, temp);
+ }
+ pI830->cursorShown[pipe] = FALSE;
+ }
+}
+
+void
I830InitHWCursor(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp;
+ int i;
DPRINTF(PFX, "I830InitHWCursor\n");
+ for (i = 0; i < MAX_DISPLAY_PIPES; i++) pI830->cursorShown[i] = FALSE;
/* Initialise the HW cursor registers, leaving the cursor hidden. */
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
@@ -356,121 +450,109 @@ static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
static void
I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 temp = 0;
- Bool hide = FALSE, show = FALSE;
- int oldx = x, oldy = y;
- int hotspotx = 0, hotspoty = 0;
-#if 0
- static Bool outsideViewport = FALSE;
-#endif
-
- oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
- oldy += pScrn->frameY0;
-
- switch (pI830->rotation) {
- case RR_Rotate_0:
- x = oldx;
- y = oldy;
- break;
- case RR_Rotate_90:
- x = oldy;
- y = pScrn->pScreen->width - oldx;
- hotspoty = I810_CURSOR_X;
- break;
- case RR_Rotate_180:
- x = pScrn->pScreen->width - oldx;
- y = pScrn->pScreen->height - oldy;
- hotspotx = I810_CURSOR_X;
- hotspoty = I810_CURSOR_Y;
- break;
- case RR_Rotate_270:
- x = pScrn->pScreen->height - oldy;
- y = oldx;
- hotspotx = I810_CURSOR_Y;
- break;
- }
-
- x -= hotspotx;
- y -= hotspoty;
-
- /* Now, readjust */
- x -= pScrn->frameX0;
- y -= pScrn->frameY0;
-
- /* Clamp the cursor position to the visible screen area. Ignore this if we
- * are doing motion (with SilkenMouse) while the currentMode being changed.
- */
- if (pScrn->currentMode != NULL) {
- if (x >= pScrn->currentMode->HDisplay)
- x = pScrn->currentMode->HDisplay - 1;
- if (y >= pScrn->currentMode->VDisplay)
- y = pScrn->currentMode->VDisplay - 1;
- }
- if (x <= -I810_CURSOR_X) x = -I810_CURSOR_X + 1;
- if (y <= -I810_CURSOR_Y) y = -I810_CURSOR_Y + 1;
-
-#if 0
- /*
- * 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.
- */
- if (x >= pScrn->currentMode->HDisplay ||
- y >= pScrn->currentMode->VDisplay ||
- x <= -I810_CURSOR_X || y <= -I810_CURSOR_Y) {
- hide = TRUE;
- outsideViewport = TRUE;
- } else if (outsideViewport) {
- show = TRUE;
- outsideViewport = FALSE;
- }
-#endif
-
- if (x < 0) {
- temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
- x = -x;
- }
- if (y < 0) {
- temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
- y = -y;
- }
- temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
- 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)
- pI830->CursorInfoRec->HideCursor(pScrn);
- else if (show)
- pI830->CursorInfoRec->ShowCursor(pScrn);
- pI830->cursorOn = TRUE;
- }
-
- /* have to upload the base for the new position */
- if (IS_I9XX(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);
- }
- }
+ I830Ptr pI830 = I830PTR(pScrn);
+ CARD32 temp;
+ Bool inrange;
+ int oldx = x, oldy = y;
+ int hotspotx = 0, hotspoty = 0;
+ int pipe;
+
+ oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
+ oldy += pScrn->frameY0;
+
+ switch (pI830->rotation) {
+ case RR_Rotate_0:
+ x = oldx;
+ y = oldy;
+ break;
+ case RR_Rotate_90:
+ x = oldy;
+ y = pScrn->pScreen->width - oldx;
+ hotspoty = I810_CURSOR_X;
+ break;
+ case RR_Rotate_180:
+ x = pScrn->pScreen->width - oldx;
+ y = pScrn->pScreen->height - oldy;
+ hotspotx = I810_CURSOR_X;
+ hotspoty = I810_CURSOR_Y;
+ break;
+ case RR_Rotate_270:
+ x = pScrn->pScreen->height - oldy;
+ y = oldx;
+ hotspotx = I810_CURSOR_Y;
+ break;
+ }
+
+ x -= hotspotx;
+ y -= hotspoty;
+
+ for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+ {
+ DisplayModePtr mode = &pI830->pipeCurMode[pipe];
+ int thisx = x - pI830->pipeX[pipe];
+ int thisy = y - pI830->pipeY[pipe];
+
+ if (!pI830->planeEnabled[pipe])
+ 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 <= -I810_CURSOR_X || thisy <= -I810_CURSOR_Y)
+ {
+ inrange = FALSE;
+ thisx = 0;
+ thisy = 0;
+ }
+
+ temp = 0;
+ if (thisx < 0) {
+ temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+ thisx = -thisx;
+ }
+ if (thisy < 0) {
+ temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+ thisy = -thisy;
+ }
+ temp |= ((thisx & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+ temp |= ((thisy & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+
+ if (pipe == 0)
+ OUTREG(CURSOR_A_POSITION, temp);
+ if (pipe == 1)
+ OUTREG(CURSOR_B_POSITION, temp);
+
+ pI830->cursorInRange[pipe] = inrange;
+
+ I830SetPipeCursor (pScrn, pipe);
+ }
+
+ /* have to upload the base for the new position */
+ if (IS_I9XX(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
I830ShowCursor(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
- CARD32 temp;
+ int pipe;
DPRINTF(PFX, "I830ShowCursor\n");
DPRINTF(PFX,
@@ -482,81 +564,22 @@ I830ShowCursor(ScrnInfoPtr pScrn)
" Value of CursorMemARGB->Start is %x ",
pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
- pI830->cursorOn = TRUE;
- if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
- temp = INREG(CURSOR_A_CONTROL);
- temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
- if (pI830->CursorIsARGB) {
- temp |= CURSOR_MODE_64_ARGB_AX;
- if (pI830->gammaEnabled[pI830->pipe])
- temp |= MCURSOR_GAMMA_ENABLE;
- } 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);
- 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;
- if (pI830->gammaEnabled[pI830->pipe])
- temp |= CURSOR_GAMMA_ENABLE;
- } 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);
- }
+ pI830->cursorOn = TRUE;
+ for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+ I830SetPipeCursor (pScrn, pipe);
}
static void
I830HideCursor(ScrnInfoPtr pScrn)
{
- CARD32 temp;
I830Ptr pI830 = I830PTR(pScrn);
+ int pipe;
DPRINTF(PFX, "I830HideCursor\n");
pI830->cursorOn = FALSE;
- if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
- temp = INREG(CURSOR_A_CONTROL);
- temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE);
- temp |= CURSOR_MODE_DISABLE;
- OUTREG(CURSOR_A_CONTROL, temp);
- /* This is needed to flush the above change. */
- 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|CURSOR_GAMMA_ENABLE);
- OUTREG(CURSOR_CONTROL, temp);
- }
+ for (pipe = 0; pipe < MAX_DISPLAY_PIPES; pipe++)
+ I830SetPipeCursor (pScrn, pipe);
}
static void