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.
This commit is contained in:
parent
cbaf3cf74b
commit
f6500e94fe
|
|
@ -99,8 +99,6 @@ if test "x$GCC" = "xyes"; then
|
|||
-Wnested-externs -fno-strict-aliasing"
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS $WARN_CFLAGS"
|
||||
|
||||
AM_CONDITIONAL(DRI, test x$DRI = xyes)
|
||||
if test "$DRI" = yes; then
|
||||
PKG_CHECK_MODULES(DRI, [libdrm >= 2.0 xf86driproto])
|
||||
|
|
@ -110,6 +108,7 @@ fi
|
|||
|
||||
AC_SUBST([DRI_CFLAGS])
|
||||
AC_SUBST([XORG_CFLAGS])
|
||||
AC_SUBST([WARN_CFLAGS])
|
||||
AC_SUBST([moduledir])
|
||||
|
||||
DRIVER_NAME=i810
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ SUBDIRS = xvmc bios_reader ch7xxx sil164
|
|||
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
|
||||
# _ladir passes a dummy rpath to libtool so the thing will actually link
|
||||
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
|
||||
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV
|
||||
AM_CFLAGS = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ -DI830_XV
|
||||
|
||||
i810_drv_la_LTLIBRARIES = i810_drv.la
|
||||
i810_drv_la_LDFLAGS = -module -avoid-version
|
||||
|
|
|
|||
22
src/i830.h
22
src/i830.h
|
|
@ -79,6 +79,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
* Paulo César Pereira de Andrade <pcpa@conectiva.com.br>.
|
||||
*/
|
||||
|
||||
#define PIPE_CRT_ID 0
|
||||
#define PIPE_TV_ID 1
|
||||
#define PIPE_DFP_ID 2
|
||||
#define PIPE_LFP_ID 3
|
||||
#define PIPE_CRT2_ID 4
|
||||
#define PIPE_TV2_ID 5
|
||||
#define PIPE_DFP2_ID 6
|
||||
#define PIPE_LFP2_ID 7
|
||||
#define PIPE_NUM_ID 8
|
||||
|
||||
#define PIPE_NONE 0<<0
|
||||
#define PIPE_CRT 1<<0
|
||||
#define PIPE_TV 1<<1
|
||||
|
|
@ -201,10 +211,12 @@ typedef struct _I830SDVODriver {
|
|||
CARD32 save_SDVOX;
|
||||
} I830SDVORec, *I830SDVOPtr;
|
||||
|
||||
extern const char *i830_output_type_names[];
|
||||
|
||||
struct _I830OutputRec {
|
||||
int type;
|
||||
int pipe;
|
||||
int flags;
|
||||
/* int pipe;
|
||||
int flags;*/
|
||||
xf86MonPtr MonInfo;
|
||||
I2CBusPtr pI2CBus;
|
||||
I2CBusPtr pDDCBus;
|
||||
|
|
@ -233,6 +245,10 @@ typedef struct _I830Rec {
|
|||
|
||||
Bool gammaEnabled[MAX_DISPLAY_PIPES];
|
||||
|
||||
int pipeX[MAX_DISPLAY_PIPES];
|
||||
int pipeY[MAX_DISPLAY_PIPES];
|
||||
Bool cursorInRange[MAX_DISPLAY_PIPES];
|
||||
Bool cursorShown[MAX_DISPLAY_PIPES];
|
||||
Bool Clone;
|
||||
int CloneRefresh;
|
||||
int CloneHDisplay;
|
||||
|
|
@ -518,6 +534,7 @@ extern void I830SetMMIOAccess(I830Ptr pI830);
|
|||
extern void I830PrintErrorState(ScrnInfoPtr pScrn);
|
||||
extern void I830Sync(ScrnInfoPtr pScrn);
|
||||
extern void I830InitHWCursor(ScrnInfoPtr pScrn);
|
||||
extern void I830SetPipeCursor (ScrnInfoPtr pScrn, int pipe);
|
||||
extern Bool I830CursorInit(ScreenPtr pScreen);
|
||||
extern void I830EmitInvarientState(ScrnInfoPtr pScrn);
|
||||
extern void I830SelectBuffer(ScrnInfoPtr pScrn, int buffer);
|
||||
|
|
@ -610,6 +627,7 @@ DisplayModePtr i830GetGTF(int h_pixels, int v_lines, float freq,
|
|||
int I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time);
|
||||
|
||||
/* i830_randr.c */
|
||||
Bool I830RandRCreateScreenResources (ScreenPtr pScreen);
|
||||
Bool I830RandRInit(ScreenPtr pScreen, int rotation);
|
||||
Bool I830RandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate,
|
||||
RRScreenSizePtr pSize);
|
||||
|
|
|
|||
|
|
@ -79,13 +79,107 @@ static void I830LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
|
|||
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
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
x -= hotspotx;
|
||||
y -= hotspoty;
|
||||
|
||||
/* Now, readjust */
|
||||
x -= pScrn->frameX0;
|
||||
y -= pScrn->frameY0;
|
||||
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];
|
||||
|
||||
/* 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 (!pI830->planeEnabled[pipe])
|
||||
continue;
|
||||
|
||||
#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
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
OUTREG(CURSOR_A_POSITION, temp);
|
||||
if (pI830->Clone)
|
||||
OUTREG(CURSOR_B_POSITION, temp);
|
||||
if (pipe == 0)
|
||||
OUTREG(CURSOR_A_POSITION, temp);
|
||||
if (pipe == 1)
|
||||
OUTREG(CURSOR_B_POSITION, temp);
|
||||
|
||||
if (pI830->cursorOn) {
|
||||
if (hide)
|
||||
pI830->CursorInfoRec->HideCursor(pScrn);
|
||||
else if (show)
|
||||
pI830->CursorInfoRec->ShowCursor(pScrn);
|
||||
pI830->cursorOn = TRUE;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
/* 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
|
||||
|
|
|
|||
|
|
@ -245,13 +245,15 @@ i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y)
|
|||
OUTREG(DSPABASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
|
||||
else
|
||||
OUTREG(DSPBBASE, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
|
||||
pI830->pipeX[pipe] = x;
|
||||
pI830->pipeY[pipe] = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given video mode on the given pipe. Assumes that plane A feeds
|
||||
* pipe A, and plane B feeds pipe B. Should not affect the other planes/pipes.
|
||||
*/
|
||||
static Bool
|
||||
Bool
|
||||
i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
|
@ -608,7 +610,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
|
|||
OUTREG(DSPASTRIDE, pScrn->displayWidth * pI830->cpp);
|
||||
OUTREG(DSPASIZE, dspsize);
|
||||
OUTREG(DSPAPOS, 0);
|
||||
i830PipeSetBase(pScrn, pipe, pScrn->frameX0, pScrn->frameY0);
|
||||
i830PipeSetBase(pScrn, pipe, pI830->pipeX[pipe], pI830->pipeX[pipe]);
|
||||
OUTREG(PIPEASRC, pipesrc);
|
||||
|
||||
/* Then, turn the pipe on first */
|
||||
|
|
@ -656,7 +658,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
|
|||
OUTREG(DSPBSTRIDE, pScrn->displayWidth * pI830->cpp);
|
||||
OUTREG(DSPBSIZE, dspsize);
|
||||
OUTREG(DSPBPOS, 0);
|
||||
i830PipeSetBase(pScrn, pipe, pScrn->frameX0, pScrn->frameY0);
|
||||
i830PipeSetBase(pScrn, pipe, pI830->pipeX[pipe], pI830->pipeY[pipe]);
|
||||
OUTREG(PIPEBSRC, pipesrc);
|
||||
|
||||
if (outputs & PIPE_LCD_ACTIVE) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
|
||||
/* i830_display.c */
|
||||
Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe);
|
||||
Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
|
||||
Bool i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb);
|
||||
void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on);
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ static OptionInfoRec I830BIOSOptions[] = {
|
|||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static const char *output_type_names[] = {
|
||||
const char *i830_output_type_names[] = {
|
||||
"Unused",
|
||||
"Analog",
|
||||
"DVO",
|
||||
|
|
@ -1133,7 +1133,7 @@ I830DetectMonitors(ScrnInfoPtr pScrn)
|
|||
pI830->output[i].pDDCBus);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DDC %s %d, %08lX\n",
|
||||
output_type_names[pI830->output[i].type], i,
|
||||
i830_output_type_names[pI830->output[i].type], i,
|
||||
pI830->output[i].pDDCBus->DriverPrivate.uval);
|
||||
xf86PrintEDID(pI830->output[i].MonInfo);
|
||||
break;
|
||||
|
|
@ -3164,22 +3164,8 @@ I830CreateScreenResources (ScreenPtr pScreen)
|
|||
if (!(*pScreen->CreateScreenResources)(pScreen))
|
||||
return FALSE;
|
||||
|
||||
if (pI830->rotation != RR_Rotate_0) {
|
||||
RRScreenSize p;
|
||||
Rotation requestedRotation = pI830->rotation;
|
||||
|
||||
pI830->rotation = RR_Rotate_0;
|
||||
|
||||
/* Just setup enough for an initial rotate */
|
||||
p.width = pScreen->width;
|
||||
p.height = pScreen->height;
|
||||
p.mmWidth = pScreen->mmWidth;
|
||||
p.mmHeight = pScreen->mmHeight;
|
||||
|
||||
pI830->starting = TRUE; /* abuse this for dual head & rotation */
|
||||
I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
|
||||
pI830->starting = FALSE;
|
||||
}
|
||||
if (!I830RandRCreateScreenResources (pScreen))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -3507,6 +3493,9 @@ I830BIOSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
|||
if (!I830BIOSEnterVT(scrnIndex, 0))
|
||||
return FALSE;
|
||||
|
||||
if (pScrn->virtualX > pScrn->displayWidth)
|
||||
pScrn->displayWidth = pScrn->virtualX;
|
||||
|
||||
DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n");
|
||||
if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset,
|
||||
pScrn->virtualX, pScrn->virtualY,
|
||||
|
|
|
|||
|
|
@ -954,6 +954,11 @@ I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time)
|
|||
maxY = mode->VDisplay;
|
||||
}
|
||||
}
|
||||
/* let the user specify a bigger virtual size if they like */
|
||||
if (pScrn->display->virtualX > maxX)
|
||||
maxX = pScrn->display->virtualX;
|
||||
if (pScrn->display->virtualY > maxY)
|
||||
maxY = pScrn->display->virtualY;
|
||||
pScrn->virtualX = maxX;
|
||||
pScrn->virtualY = maxY;
|
||||
pScrn->displayWidth = (maxX + 63) & ~63;
|
||||
|
|
|
|||
450
src/i830_randr.c
450
src/i830_randr.c
|
|
@ -23,6 +23,10 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "xf86.h"
|
||||
#include "os.h"
|
||||
#include "mibank.h"
|
||||
|
|
@ -33,9 +37,11 @@
|
|||
#include "mipointer.h"
|
||||
#include "windowstr.h"
|
||||
#include <randrstr.h>
|
||||
#include <X11/extensions/render.h>
|
||||
|
||||
#include "i830.h"
|
||||
#include "i830_xf86Modes.h"
|
||||
#include "i830_display.h"
|
||||
|
||||
typedef struct _i830RandRInfo {
|
||||
int virtualX;
|
||||
|
|
@ -46,8 +52,18 @@ typedef struct _i830RandRInfo {
|
|||
int maxY;
|
||||
Rotation rotation; /* current mode */
|
||||
Rotation supported_rotations; /* driver supported */
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
RRCrtcPtr crtcs[MAX_DISPLAY_PIPES];
|
||||
RROutputPtr outputs[MAX_OUTPUTS];
|
||||
DisplayModePtr modes[MAX_DISPLAY_PIPES];
|
||||
#endif
|
||||
} XF86RandRInfoRec, *XF86RandRInfoPtr;
|
||||
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
static Bool I830RandRInit12 (ScreenPtr pScreen);
|
||||
static Bool I830RandRCreateScreenResources12 (ScreenPtr pScreen);
|
||||
#endif
|
||||
|
||||
static int i830RandRIndex;
|
||||
static int i830RandRGeneration;
|
||||
|
||||
|
|
@ -316,6 +332,40 @@ I830GetRotation(ScreenPtr pScreen)
|
|||
return randrp->rotation;
|
||||
}
|
||||
|
||||
Bool
|
||||
I830RandRCreateScreenResources (ScreenPtr pScreen)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
#ifdef PANORAMIX
|
||||
/* XXX disable RandR when using Xinerama */
|
||||
if (!noPanoramiXExtension)
|
||||
return TRUE;
|
||||
#endif
|
||||
#if RANDR_12_INTERFACE
|
||||
if (I830RandRCreateScreenResources12 (pScreen))
|
||||
return TRUE;
|
||||
#endif
|
||||
if (pI830->rotation != RR_Rotate_0) {
|
||||
RRScreenSize p;
|
||||
Rotation requestedRotation = pI830->rotation;
|
||||
|
||||
pI830->rotation = RR_Rotate_0;
|
||||
|
||||
/* Just setup enough for an initial rotate */
|
||||
p.width = pScreen->width;
|
||||
p.height = pScreen->height;
|
||||
p.mmWidth = pScreen->mmWidth;
|
||||
p.mmHeight = pScreen->mmHeight;
|
||||
|
||||
pI830->starting = TRUE; /* abuse this for dual head & rotation */
|
||||
I830RandRSetConfig (pScreen, requestedRotation, 0, &p);
|
||||
pI830->starting = FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
Bool
|
||||
I830RandRInit (ScreenPtr pScreen, int rotation)
|
||||
{
|
||||
|
|
@ -359,6 +409,10 @@ I830RandRInit (ScreenPtr pScreen, int rotation)
|
|||
|
||||
pScreen->devPrivates[i830RandRIndex].ptr = randrp;
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
if (!I830RandRInit12 (pScreen))
|
||||
return FALSE;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -379,3 +433,399 @@ I830GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
|
|||
*y = randrp->virtualY;
|
||||
}
|
||||
}
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
static Bool
|
||||
I830RandRScreenSetSize (ScreenPtr pScreen,
|
||||
CARD16 width,
|
||||
CARD16 height,
|
||||
CARD32 mmWidth,
|
||||
CARD32 mmHeight)
|
||||
{
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
|
||||
WindowPtr pRoot = WindowTable[pScreen->myNum];
|
||||
Bool ret = TRUE;
|
||||
|
||||
if (randrp->virtualX == -1 || randrp->virtualY == -1)
|
||||
{
|
||||
randrp->virtualX = pScrn->virtualX;
|
||||
randrp->virtualY = pScrn->virtualY;
|
||||
}
|
||||
if (pRoot)
|
||||
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
|
||||
pScrn->virtualX = width;
|
||||
pScrn->virtualY = height;
|
||||
|
||||
pScreen->width = pScrn->virtualX;
|
||||
pScreen->height = pScrn->virtualY;
|
||||
pScreen->mmWidth = mmWidth;
|
||||
pScreen->mmHeight = mmHeight;
|
||||
|
||||
xf86SetViewport (pScreen, pScreen->width, pScreen->height);
|
||||
xf86SetViewport (pScreen, 0, 0);
|
||||
if (pRoot)
|
||||
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
|
||||
if (WindowTable[pScreen->myNum])
|
||||
RRScreenSizeNotify (pScreen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830RandRCrtcNotify (RRCrtcPtr crtc)
|
||||
{
|
||||
ScreenPtr pScreen = crtc->pScreen;
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
RRModePtr mode = NULL;
|
||||
int x;
|
||||
int y;
|
||||
Rotation rotation;
|
||||
int numOutputs;
|
||||
RROutputPtr outputs[MAX_OUTPUTS];
|
||||
struct _I830OutputRec *output;
|
||||
RROutputPtr rrout;
|
||||
int pipe = (int) crtc->devPrivate;
|
||||
int i, j;
|
||||
DisplayModePtr pipeMode = &pI830->pipeCurMode[pipe];
|
||||
int pipe_type;
|
||||
|
||||
x = pI830->pipeX[pipe];
|
||||
y = pI830->pipeY[pipe];
|
||||
rotation = RR_Rotate_0;
|
||||
numOutputs = 0;
|
||||
for (i = 0; i < pI830->num_outputs; i++)
|
||||
{
|
||||
output = &pI830->output[i];
|
||||
/*
|
||||
* Valid crtcs
|
||||
*/
|
||||
switch (output->type) {
|
||||
case I830_OUTPUT_DVO:
|
||||
case I830_OUTPUT_SDVO:
|
||||
pipe_type = PIPE_DFP;
|
||||
break;
|
||||
case I830_OUTPUT_ANALOG:
|
||||
pipe_type = PIPE_CRT;
|
||||
break;
|
||||
case I830_OUTPUT_LVDS:
|
||||
pipe_type = PIPE_LFP;
|
||||
break;
|
||||
case I830_OUTPUT_TVOUT:
|
||||
pipe_type = PIPE_TV;
|
||||
break;
|
||||
default:
|
||||
pipe_type = PIPE_NONE;
|
||||
break;
|
||||
}
|
||||
if (pI830->operatingDevices & (pipe_type << (pipe << 3)))
|
||||
{
|
||||
rrout = randrp->outputs[i];
|
||||
outputs[numOutputs++] = rrout;
|
||||
for (j = 0; j < rrout->numModes; j++)
|
||||
{
|
||||
DisplayModePtr outMode = rrout->modes[j]->devPrivate;
|
||||
if (I830ModesEqual(pipeMode, outMode))
|
||||
mode = rrout->modes[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830RandRCrtcSet (ScreenPtr pScreen,
|
||||
RRCrtcPtr crtc,
|
||||
RRModePtr mode,
|
||||
int x,
|
||||
int y,
|
||||
Rotation rotation,
|
||||
int numOutputs,
|
||||
RROutputPtr *outputs)
|
||||
{
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int pipe = (int) (crtc->devPrivate);
|
||||
DisplayModePtr display_mode = mode->devPrivate;
|
||||
|
||||
/* Sync the engine before adjust mode */
|
||||
if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
|
||||
(*pI830->AccelInfoRec->Sync)(pScrn);
|
||||
pI830->AccelInfoRec->NeedToSync = FALSE;
|
||||
}
|
||||
|
||||
if (display_mode != randrp->modes[pipe])
|
||||
{
|
||||
if (!i830PipeSetMode (pScrn, display_mode, pipe))
|
||||
return FALSE;
|
||||
randrp->modes[pipe] = display_mode;
|
||||
}
|
||||
i830PipeSetBase(pScrn, pipe, x, y);
|
||||
return I830RandRCrtcNotify (crtc);
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830RandRCrtcSetGamma (ScreenPtr pScreen,
|
||||
RRCrtcPtr crtc)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mirror the current mode configuration to RandR
|
||||
*/
|
||||
static Bool
|
||||
I830RandRSetInfo12 (ScreenPtr pScreen)
|
||||
{
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
RROutputPtr clones[MAX_OUTPUTS];
|
||||
RRCrtcPtr crtc;
|
||||
int nclone;
|
||||
RRCrtcPtr crtcs[MAX_DISPLAY_PIPES];
|
||||
int ncrtc;
|
||||
RRModePtr *modes;
|
||||
int nmode;
|
||||
struct _I830OutputRec *output;
|
||||
int i;
|
||||
int j;
|
||||
int clone_types;
|
||||
int crtc_types;
|
||||
int connection;
|
||||
int pipe_type;
|
||||
int pipe;
|
||||
int subpixel;
|
||||
|
||||
if (randrp->virtualX == -1 || randrp->virtualY == -1)
|
||||
{
|
||||
randrp->virtualX = pScrn->virtualX;
|
||||
randrp->virtualY = pScrn->virtualY;
|
||||
}
|
||||
RRScreenSetSizeRange (pScreen, 320, 240,
|
||||
randrp->virtualX, randrp->virtualY);
|
||||
for (i = 0; i < pI830->num_outputs; i++)
|
||||
{
|
||||
output = &pI830->output[i];
|
||||
/*
|
||||
* Valid crtcs
|
||||
*/
|
||||
switch (output->type) {
|
||||
case I830_OUTPUT_DVO:
|
||||
case I830_OUTPUT_SDVO:
|
||||
crtc_types = ((1 << 0)|
|
||||
(1 << 1));
|
||||
clone_types = ((1 << I830_OUTPUT_ANALOG) |
|
||||
(1 << I830_OUTPUT_DVO) |
|
||||
(1 << I830_OUTPUT_SDVO));
|
||||
pipe_type = PIPE_DFP;
|
||||
subpixel = SubPixelHorizontalRGB;
|
||||
break;
|
||||
case I830_OUTPUT_ANALOG:
|
||||
crtc_types = (1 << 0);
|
||||
clone_types = ((1 << I830_OUTPUT_ANALOG) |
|
||||
(1 << I830_OUTPUT_DVO) |
|
||||
(1 << I830_OUTPUT_SDVO));
|
||||
pipe_type = PIPE_CRT;
|
||||
subpixel = SubPixelNone;
|
||||
break;
|
||||
case I830_OUTPUT_LVDS:
|
||||
crtc_types = (1 << 1);
|
||||
clone_types = (1 << I830_OUTPUT_LVDS);
|
||||
pipe_type = PIPE_LFP;
|
||||
subpixel = SubPixelHorizontalRGB;
|
||||
break;
|
||||
case I830_OUTPUT_TVOUT:
|
||||
crtc_types = ((1 << 0) |
|
||||
(1 << 1));
|
||||
clone_types = (1 << I830_OUTPUT_TVOUT);
|
||||
pipe_type = PIPE_TV;
|
||||
subpixel = SubPixelNone;
|
||||
break;
|
||||
default:
|
||||
crtc_types = 0;
|
||||
clone_types = 0;
|
||||
pipe_type = PIPE_NONE;
|
||||
subpixel = SubPixelUnknown;
|
||||
break;
|
||||
}
|
||||
ncrtc = 0;
|
||||
pipe = -1;
|
||||
crtc = NULL;
|
||||
for (j = 0; j < MAX_DISPLAY_PIPES; j++)
|
||||
{
|
||||
#if 0
|
||||
/* Can't flip outputs among crtcs yet */
|
||||
if (crtc_types & (1 << j))
|
||||
crtcs[ncrtc++] = randrp->crtcs[j];
|
||||
#endif
|
||||
if (pI830->operatingDevices & (pipe_type << (j << 3)))
|
||||
{
|
||||
pipe = j;
|
||||
crtc = randrp->crtcs[j];
|
||||
crtcs[ncrtc++] = crtc;
|
||||
}
|
||||
}
|
||||
if (!RROutputSetCrtcs (randrp->outputs[i], crtcs, ncrtc))
|
||||
return FALSE;
|
||||
|
||||
RROutputSetCrtc (randrp->outputs[i], crtc);
|
||||
|
||||
if (pipe >= 0)
|
||||
{
|
||||
MonPtr mon = pI830->pipeMon[pipe];
|
||||
DisplayModePtr mode;
|
||||
xRRModeInfo modeInfo;
|
||||
RRModePtr rrmode;
|
||||
|
||||
nmode = 0;
|
||||
for (mode = mon->Modes; mode; mode = mode->next)
|
||||
nmode++;
|
||||
|
||||
if (nmode)
|
||||
{
|
||||
modes = xalloc (nmode * sizeof (RRModePtr));
|
||||
if (!modes)
|
||||
return FALSE;
|
||||
nmode = 0;
|
||||
for (mode = mon->Modes; mode; mode = mode->next)
|
||||
{
|
||||
modeInfo.nameLength = strlen (mode->name);
|
||||
modeInfo.mmWidth = mon->widthmm;
|
||||
modeInfo.mmHeight = mon->heightmm;
|
||||
|
||||
modeInfo.width = mode->HDisplay;
|
||||
modeInfo.dotClock = mode->Clock * 1000;
|
||||
modeInfo.hSyncStart = mode->HSyncStart;
|
||||
modeInfo.hSyncEnd = mode->HSyncEnd;
|
||||
modeInfo.hTotal = mode->HTotal;
|
||||
modeInfo.hSkew = mode->HSkew;
|
||||
|
||||
modeInfo.height = mode->VDisplay;
|
||||
modeInfo.vSyncStart = mode->VSyncStart;
|
||||
modeInfo.vSyncEnd = mode->VSyncEnd;
|
||||
modeInfo.vTotal = mode->VTotal;
|
||||
modeInfo.modeFlags = mode->Flags;
|
||||
|
||||
rrmode = RRModeGet (pScreen, &modeInfo, mode->name);
|
||||
rrmode->devPrivate = mode;
|
||||
if (rrmode)
|
||||
modes[nmode++] = rrmode;
|
||||
}
|
||||
if (!RROutputSetModes (randrp->outputs[i], modes, nmode))
|
||||
{
|
||||
xfree (modes);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xfree (modes);
|
||||
}
|
||||
}
|
||||
connection = RR_Disconnected;
|
||||
if (pipe >= 0)
|
||||
connection = RR_Connected;
|
||||
|
||||
RROutputSetConnection (randrp->outputs[i], connection);
|
||||
|
||||
RROutputSetSubpixelOrder (randrp->outputs[i], subpixel);
|
||||
|
||||
/*
|
||||
* Valid clones
|
||||
*/
|
||||
nclone = 0;
|
||||
for (j = 0; j < pI830->num_outputs; j++)
|
||||
{
|
||||
if (i != j && ((1 << pI830->output[j].type) & clone_types))
|
||||
clones[nclone++] = randrp->outputs[j];
|
||||
}
|
||||
if (!RROutputSetClones (randrp->outputs[i], clones, nclone))
|
||||
return FALSE;
|
||||
}
|
||||
for (i = 0; i < MAX_DISPLAY_PIPES; i++)
|
||||
I830RandRCrtcNotify (randrp->crtcs[i]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Query the hardware for the current state, then mirror
|
||||
* that to RandR
|
||||
*/
|
||||
static Bool
|
||||
I830RandRGetInfo12 (ScreenPtr pScreen, Rotation *rotations)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
/* Re-probe the outputs for new monitors or modes */
|
||||
I830ValidateXF86ModeList(pScrn, FALSE);
|
||||
return I830RandRSetInfo12 (pScreen);
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830RandRCreateScreenResources12 (ScreenPtr pScreen)
|
||||
{
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
struct _I830OutputRec *output;
|
||||
const char *name;
|
||||
int i;
|
||||
DisplayModePtr mode;
|
||||
|
||||
/*
|
||||
* Create RandR resources, then probe them
|
||||
*/
|
||||
for (i = 0; i < MAX_DISPLAY_PIPES; i++)
|
||||
{
|
||||
randrp->crtcs[i] = RRCrtcCreate (pScreen, (void *) i);
|
||||
RRCrtcGammaSetSize (randrp->crtcs[i], 256);
|
||||
}
|
||||
|
||||
for (i = 0; i < pI830->num_outputs; i++)
|
||||
{
|
||||
output = &pI830->output[i];
|
||||
name = i830_output_type_names[output->type];
|
||||
randrp->outputs[i] = RROutputCreate (pScreen,
|
||||
name, strlen (name),
|
||||
(void *) i);
|
||||
}
|
||||
|
||||
mode = pScrn->currentMode;
|
||||
if (mode)
|
||||
{
|
||||
I830RandRScreenSetSize (pScreen,
|
||||
mode->HDisplay,
|
||||
mode->VDisplay,
|
||||
pScreen->mmWidth,
|
||||
pScreen->mmHeight);
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_DISPLAY_PIPES; i++)
|
||||
i830PipeSetBase(pScrn, i, 0, 0);
|
||||
|
||||
return I830RandRSetInfo12 (pScreen);
|
||||
}
|
||||
|
||||
static void
|
||||
I830RandRPointerMoved (int scrnIndex, int x, int y)
|
||||
{
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830RandRInit12 (ScreenPtr pScreen)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
rrScrPrivPtr rp = rrGetScrPriv(pScreen);
|
||||
|
||||
rp->rrGetInfo = I830RandRGetInfo12;
|
||||
rp->rrScreenSetSize = I830RandRScreenSetSize;
|
||||
rp->rrCrtcSet = I830RandRCrtcSet;
|
||||
rp->rrCrtcSetGamma = I830RandRCrtcSetGamma;
|
||||
rp->rrSetConfig = NULL;
|
||||
memset (rp->modes, '\0', sizeof (rp->modes));
|
||||
pScrn->PointerMoved = I830RandRPointerMoved;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue