diff options
author | Keith Packard <keithp@mandolin.keithp.com> | 2006-11-08 23:19:59 -0800 |
---|---|---|
committer | Keith Packard <keithp@mandolin.keithp.com> | 2006-11-08 23:19:59 -0800 |
commit | 0f5886689d7ef7dbbef6425d5c855ac6b67d3350 (patch) | |
tree | 2176065e003195d09a466950183b2b7866738500 | |
parent | 679c7bd82639a09cdce133becb8a08629ce3a4e9 (diff) |
Create RandR 1.2 objects in I830PreInit.
Creating the objects early will allow the driver to use
randr structures to select a reasonable configuration.
That part has not been done yet.
-rw-r--r-- | src/i830.h | 7 | ||||
-rw-r--r-- | src/i830_driver.c | 6 | ||||
-rw-r--r-- | src/i830_randr.c | 319 |
3 files changed, 192 insertions, 140 deletions
@@ -270,6 +270,9 @@ struct _I830OutputRec { struct _I830DVODriver *i2c_drv; /** Output-private structure. Should replace i2c_drv */ void *dev_priv; +#ifdef RANDR_12_INTERFACE + RROutputPtr randr_output; +#endif }; typedef struct _I830PipeRec { @@ -280,6 +283,9 @@ typedef struct _I830PipeRec { Bool cursorInRange; Bool cursorShown; DisplayModeRec curMode; +#ifdef RANDR_12_INTERFACE + RRCrtcPtr randr_crtc; +#endif } I830PipeRec, *I830PipePtr; typedef struct _I830Rec { @@ -676,6 +682,7 @@ Bool I830RandRSetConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); Rotation I830GetRotation(ScreenPtr pScreen); void I830GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y); +Bool I830RandRPreInit (ScrnInfoPtr pScrn); /* i830_tv.c */ void i830_tv_init(ScrnInfoPtr pScrn); diff --git a/src/i830_driver.c b/src/i830_driver.c index 63c1fd2e..1f3ff0a7 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -771,7 +771,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) I830EntPtr pI830Ent = NULL; int mem; int flags24; - int i, n; + int i; char *s; pointer pVBEModule = NULL; Bool enable; @@ -1653,8 +1653,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Maximum frambuffer space: %d kByte\n", pScrn->videoRam); - n = I830ValidateXF86ModeList(pScrn, TRUE); - if (n <= 0) { + if (!I830RandRPreInit (pScrn)) + { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); PreInitCleanup(pScrn); return FALSE; diff --git a/src/i830_randr.c b/src/i830_randr.c index d6e5f0b8..87864f29 100644 --- a/src/i830_randr.c +++ b/src/i830_randr.c @@ -53,8 +53,6 @@ typedef struct _i830RandRInfo { 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; @@ -477,7 +475,6 @@ 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; @@ -503,7 +500,7 @@ I830RandRCrtcNotify (RRCrtcPtr crtc) output = &pI830->output[i]; if (output->enabled && output->pipe == pipe) { - rrout = randrp->outputs[i]; + rrout = output->randr_output; outputs[numOutputs++] = rrout; /* * We make copies of modes, so pointer equality @@ -572,45 +569,91 @@ I830RandRCrtcSetGamma (ScreenPtr pScreen, return FALSE; } +/** + * Given a list of xf86 modes and a RandR Output object, construct + * RandR modes and assign them to the output + */ +static Bool +I830xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes) +{ + DisplayModePtr mode; + RRModePtr *rrmodes = NULL; + int nmode = 0; + int npreferred = 0; + Bool ret = TRUE; + int pref; + + for (mode = modes; mode; mode = mode->next) + nmode++; + + if (nmode) { + rrmodes = xalloc (nmode * sizeof (RRModePtr)); + + if (!rrmodes) + return FALSE; + nmode = 0; + + for (pref = 1; pref >= 0; pref--) { + for (mode = modes; mode; mode = mode->next) { + if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) { + xRRModeInfo modeInfo; + RRModePtr rrmode; + + modeInfo.nameLength = strlen (mode->name); + 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 (&modeInfo, mode->name); + rrmode->devPrivate = mode; + if (rrmode) { + rrmodes[nmode++] = rrmode; + npreferred += pref; + } + } + } + } + } + + ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred); + xfree (rrmodes); + return ret; +} + /* * Mirror the current mode configuration to RandR */ static Bool -I830RandRSetInfo12 (ScreenPtr pScreen) +I830RandRSetInfo12 (ScrnInfoPtr pScrn) { - 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; - int nmode, npreferred; - struct _I830OutputRec *output; - int i; - int j; - int p; - int clone_types; - int crtc_types; - int pipe; - int subpixel; - DisplayModePtr modes, mode; - xRRModeInfo modeInfo; - RRModePtr rrmode, *rrmodes; - CARD32 possibleOptions = 0; - CARD32 currentOptions = 0; - - 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++) + I830Ptr pI830 = I830PTR(pScrn); + RROutputPtr clones[MAX_OUTPUTS]; + RRCrtcPtr crtcs[MAX_DISPLAY_PIPES]; + int ncrtc; + I830OutputPtr output; + int o, c, p; + int clone_types; + int crtc_types; + int subpixel; + CARD32 possibleOptions = 0; + CARD32 currentOptions = 0; + RRCrtcPtr randr_crtc; + RROutputPtr randr_output; + int nclone; + + for (o = 0; o < pI830->num_outputs; o++) { - output = &pI830->output[i]; + output = &pI830->output[o]; + randr_output = output->randr_output; /* * Valid crtcs */ @@ -625,7 +668,7 @@ I830RandRSetInfo12 (ScreenPtr pScreen) subpixel = SubPixelHorizontalRGB; break; case I830_OUTPUT_ANALOG: - crtc_types = (1 << 0); + crtc_types = ((1 << 0) | (1 << 1)); clone_types = ((1 << I830_OUTPUT_ANALOG) | (1 << I830_OUTPUT_DVO) | (1 << I830_OUTPUT_SDVO)); @@ -654,110 +697,58 @@ I830RandRSetInfo12 (ScreenPtr pScreen) } if (output->enabled) { - /* Can't flip outputs among crtcs yet */ - ncrtc = 1; - pipe = output->pipe; - crtc = randrp->crtcs[pipe]; - crtcs[0] = randrp->crtcs[pipe]; + ncrtc = 0; + for (p = 0; p < pI830->num_pipes; p++) + if (crtc_types & (1 << p)) + crtcs[ncrtc++] = pI830->pipes[p].randr_crtc; + randr_crtc = pI830->pipes[output->pipe].randr_crtc; } else { ncrtc = 0; - pipe = -1; - crtc = NULL; + randr_crtc = NULL; } - if (!RROutputSetCrtcs (randrp->outputs[i], crtcs, ncrtc)) + if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc)) return FALSE; - RROutputSetCrtc (randrp->outputs[i], crtc); - RROutputSetPhysicalSize(randrp->outputs[i], pI830->output[i].mm_width, - pI830->output[i].mm_height); - RROutputSetPossibleOptions (randrp->outputs[i], possibleOptions); - RROutputSetCurrentOptions (randrp->outputs[i], currentOptions); - nmode = 0; - npreferred = 0; - rrmodes = NULL; + RROutputSetCrtc (output->randr_output, randr_crtc); + RROutputSetPhysicalSize(output->randr_output, + output->mm_width, + output->mm_height); + RROutputSetPossibleOptions (output->randr_output, possibleOptions); + RROutputSetCurrentOptions (output->randr_output, currentOptions); - modes = pI830->output[i].probed_modes; + I830xf86RROutputSetModes (output->randr_output, output->probed_modes); - for (mode = modes; mode; mode = mode->next) - nmode++; - - if (nmode) { - rrmodes = xalloc (nmode * sizeof (RRModePtr)); - if (!rrmodes) - return FALSE; - nmode = 0; - - for (p = 1; p >= 0; p--) { - for (mode = modes; mode; mode = mode->next) { - if ((p != 0) == ((mode->type & M_T_PREFERRED) != 0)) { - modeInfo.nameLength = strlen (mode->name); - - 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 (&modeInfo, mode->name); - rrmode->devPrivate = mode; - if (rrmode) { - rrmodes[nmode++] = rrmode; - npreferred += p; - } - } - } - } - } - - if (!RROutputSetModes (randrp->outputs[i], rrmodes, nmode, npreferred)) - { - xfree (rrmodes); - return FALSE; - } - - xfree (rrmodes); - - switch (pI830->output[i].detect(pScrn, &pI830->output[i])) { + switch (output->detect(pScrn, output)) { case OUTPUT_STATUS_CONNECTED: - RROutputSetConnection (randrp->outputs[i], RR_Connected); + RROutputSetConnection (output->randr_output, RR_Connected); break; case OUTPUT_STATUS_DISCONNECTED: - RROutputSetConnection (randrp->outputs[i], RR_Disconnected); + RROutputSetConnection (output->randr_output, RR_Disconnected); break; case OUTPUT_STATUS_UNKNOWN: - RROutputSetConnection (randrp->outputs[i], RR_UnknownConnection); + RROutputSetConnection (output->randr_output, RR_UnknownConnection); break; } - RROutputSetSubpixelOrder (randrp->outputs[i], subpixel); + RROutputSetSubpixelOrder (output->randr_output, subpixel); /* * Valid clones */ nclone = 0; - for (j = 0; j < pI830->num_outputs; j++) + for (c = 0; c < pI830->num_outputs; c++) { - if (i != j && ((1 << pI830->output[j].type) & clone_types)) - clones[nclone++] = randrp->outputs[j]; + if (o != c && ((1 << pI830->output[c].type) & clone_types)) + clones[nclone++] = pI830->output[c].randr_output; } - if (!RROutputSetClones (randrp->outputs[i], clones, nclone)) + if (!RROutputSetClones (output->randr_output, clones, nclone)) return FALSE; } - for (i = 0; i < pI830->num_pipes; i++) - I830RandRCrtcNotify (randrp->crtcs[i]); return TRUE; } - /* * Query the hardware for the current state, then mirror * that to RandR @@ -768,43 +759,70 @@ I830RandRGetInfo12 (ScreenPtr pScreen, Rotation *rotations) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; i830_reprobe_output_modes(pScrn); - return I830RandRSetInfo12 (pScreen); + return I830RandRSetInfo12 (pScrn); } static Bool -I830RandRCreateScreenResources12 (ScreenPtr pScreen) +I830RandRCreateObjects12 (ScrnInfoPtr pScrn) { - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); - struct _I830OutputRec *output; - const char *name; - int i; - DisplayModePtr mode; + int p; + int o; + + if (!RRInit ()) + return FALSE; /* * Create RandR resources, then probe them */ - for (i = 0; i < pI830->num_pipes; i++) + for (p = 0; p < pI830->num_pipes; p++) { - randrp->crtcs[i] = RRCrtcCreate ((void *) i); - if (!randrp->crtcs[i]) + I830PipePtr pipe = &pI830->pipes[p]; + RRCrtcPtr randr_crtc = RRCrtcCreate ((void *) p); + + if (!randr_crtc) return FALSE; - if (!RRCrtcAttachScreen (randrp->crtcs[i], pScreen)) - return FALSE; - RRCrtcGammaSetSize (randrp->crtcs[i], 256); + RRCrtcGammaSetSize (randr_crtc, 256); + pipe->randr_crtc = randr_crtc; } - for (i = 0; i < pI830->num_outputs; i++) + for (o = 0; o < pI830->num_outputs; o++) { - output = &pI830->output[i]; - name = i830_output_type_names[output->type]; - randrp->outputs[i] = RROutputCreate (name, strlen (name), (void *) i); - if (!randrp->outputs[i]) - return FALSE; - if (!RROutputAttachScreen (randrp->outputs[i], pScreen)) + I830OutputPtr output = &pI830->output[o]; + const char *name = i830_output_type_names[output->type]; + RROutputPtr randr_output = RROutputCreate (name, strlen (name), + (void *) o); + if (!randr_output) return FALSE; + output->randr_output = randr_output; } + /* + * Configure output modes + */ + if (!I830RandRSetInfo12 (pScrn)) + return FALSE; + return TRUE; +} + +static Bool +I830RandRCreateScreenResources12 (ScreenPtr pScreen) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + I830Ptr pI830 = I830PTR(pScrn); + int p, o; + DisplayModePtr mode; + + /* + * Attach RandR objects to screen + */ + for (p = 0; p < pI830->num_pipes; p++) + if (!RRCrtcAttachScreen (pI830->pipes[p].randr_crtc, pScreen)) + return FALSE; + + for (o = 0; o < pI830->num_outputs; o++) + if (!RROutputAttachScreen (pI830->output[o].randr_output, pScreen)) + return FALSE; mode = pScrn->currentMode; if (mode) @@ -827,10 +845,22 @@ I830RandRCreateScreenResources12 (ScreenPtr pScreen) mmHeight); } - for (i = 0; i < pI830->num_pipes; i++) - i830PipeSetBase(pScrn, i, 0, 0); + for (p = 0; p < pI830->num_pipes; p++) + { + i830PipeSetBase(pScrn, p, 0, 0); + I830RandRCrtcNotify (pI830->pipes[p].randr_crtc); + } - return I830RandRSetInfo12 (pScreen); + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = pScrn->virtualX; + randrp->virtualY = pScrn->virtualY; + } + + RRScreenSetSizeRange (pScreen, 320, 240, + randrp->virtualX, randrp->virtualY); + return TRUE; } static void @@ -853,3 +883,18 @@ I830RandRInit12 (ScreenPtr pScreen) return TRUE; } #endif + +Bool +I830RandRPreInit (ScrnInfoPtr pScrn) +{ + int n; + + n = I830ValidateXF86ModeList(pScrn, TRUE); + if (n <= 0) + return FALSE; +#if RANDR_12_INTERFACE + if (!I830RandRCreateObjects12 (pScrn)) + return FALSE; +#endif + return TRUE; +} |