diff options
author | Dave Airlie <airlied@linux.ie> | 2007-01-04 12:29:51 +1100 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-01-04 12:29:51 +1100 |
commit | a43c1d55f5f855d9e6ae939dd4eec1c607b6d514 (patch) | |
tree | 3eb7861c6a9d2a1297d780bdceeaa46c6690e9cd | |
parent | 87592ffb717da1f0a1767a38918d16d60953599c (diff) |
bring radeon randr code inline with intel randr code
-rw-r--r-- | src/radeon_driver.c | 10 | ||||
-rw-r--r-- | src/radeon_randr.c | 959 | ||||
-rw-r--r-- | src/radeon_xf86Crtc.c | 787 | ||||
-rw-r--r-- | src/radeon_xf86Crtc.h | 60 | ||||
-rw-r--r-- | src/radeon_xf86Modes.c | 612 | ||||
-rw-r--r-- | src/radeon_xf86Modes.h | 75 | ||||
-rw-r--r-- | src/xf86Optrec.h | 112 | ||||
-rw-r--r-- | src/xf86Parser.h | 483 |
8 files changed, 1886 insertions, 1212 deletions
diff --git a/src/radeon_driver.c b/src/radeon_driver.c index 615525c4..fb0fa80c 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -3267,14 +3267,12 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags) if (!xf86RandR12PreInit (pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n"); - PreInitCleanup(pScrn); - return FALSE; + goto fail; } if (pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); - PreInitCleanup(pScrn); - return FALSE; + goto fail; } /* Free the video bios (if applicable) */ @@ -4303,9 +4301,9 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, /* Rotation */ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n"); xf86DisableRandR(); /* Disable built-in RandR extension */ - /* support all rotations */ + xf86RandR12Init (pScreen); - xf86RandR12SetRotations (pScreen, RR_Rotate_0); /* only 0 degrees for I965G */ + xf86RandR12SetRotations (pScreen, RR_Rotate_0); info->CreateScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = RADEONCreateScreenResources; diff --git a/src/radeon_randr.c b/src/radeon_randr.c index ce28e7b7..fef36672 100644 --- a/src/radeon_randr.c +++ b/src/radeon_randr.c @@ -1,28 +1,24 @@ /* * Copyright 2006 Dave Airlie + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. * - * All Rights Reserved. + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS AND/OR - * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. */ @@ -49,7 +45,7 @@ #include "radeon_version.h" #include "radeon_mergedfb.h" -typedef struct _radeonRandRInfo { +typedef struct _xf86RandR12Info { int virtualX; int virtualY; int mmWidth; @@ -69,27 +65,8 @@ static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen); static int xf86RandR12Index; static int xf86RandR12Generation; -#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) (p)->devPrivates[xf86RandR12Index].ptr) - -#if RANDR_12_INTERFACE - -void -xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y) -{ - ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; - - if (xf86RandR12Generation != serverGeneration || - XF86RANDRINFO(pScreen)->virtualX == -1) - { - *x = pScrn->virtualX; - *y = pScrn->virtualY; - } else { - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - - *x = randrp->virtualX; - *y = randrp->virtualY; - } -} +#define XF86RANDRINFO(p) \ + ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr) static int xf86RandR12ModeRefresh (DisplayModePtr mode) @@ -119,7 +96,7 @@ xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations) } /* Re-probe the outputs for new monitors or modes */ - xf86ProbeOutputModes (scrp); + xf86ProbeOutputModes (scrp, 0, 0); xf86SetScrnInfoModes (scrp); for (mode = scrp->modes; ; mode = mode->next) @@ -348,20 +325,6 @@ xf86RandR12SetConfig (ScreenPtr pScreen, return TRUE; } -Rotation -xf86RandR12GetRotation(ScreenPtr pScreen) -{ - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); - - return randrp->rotation; -} - - -static void -RADEONRandRPointerMoved (int scrnIndex, int x, int y) -{ -} - static Bool xf86RandR12ScreenSetSize (ScreenPtr pScreen, CARD16 width, @@ -389,15 +352,171 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, pScreen->mmWidth = mmWidth; pScreen->mmHeight = mmHeight; - xf86SetViewport (pScreen, pScreen->width, pScreen->height); + xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1); xf86SetViewport (pScreen, 0, 0); if (pRoot) (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); +#if RANDR_12_INTERFACE if (WindowTable[pScreen->myNum]) RRScreenSizeNotify (pScreen); +#endif return ret; } +Rotation +xf86RandR12GetRotation(ScreenPtr pScreen) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + return randrp->rotation; +} + +Bool +xf86RandR12CreateScreenResources (ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + int c; + int width, height; + int mmWidth, mmHeight; +#ifdef PANORAMIX + /* XXX disable RandR when using Xinerama */ + if (!noPanoramiXExtension) + return TRUE; +#endif + + /* + * Compute size of screen + */ + width = 0; height = 0; + for (c = 0; c < config->num_crtc; c++) + { + xf86CrtcPtr crtc = config->crtc[c]; + int crtc_width = crtc->x + crtc->curMode.HDisplay; + int crtc_height = crtc->y + crtc->curMode.VDisplay; + + if (crtc->enabled && crtc_width > width) + width = crtc_width; + if (crtc->enabled && crtc_height > height) + height = crtc_height; + } + + if (width && height) + { + /* + * Compute physical size of screen + */ + if (monitorResolution) + { + mmWidth = width * 25.4 / monitorResolution; + mmHeight = height * 25.4 / monitorResolution; + } + else + { + mmWidth = pScreen->mmWidth; + mmHeight = pScreen->mmHeight; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Setting screen physical size to %d x %d\n", + mmWidth, mmHeight); + xf86RandR12ScreenSetSize (pScreen, + width, + height, + mmWidth, + mmHeight); + } + + if (randrp->virtualX == -1 || randrp->virtualY == -1) + { + randrp->virtualX = pScrn->virtualX; + randrp->virtualY = pScrn->virtualY; + } +#if RANDR_12_INTERFACE + if (xf86RandR12CreateScreenResources12 (pScreen)) + return TRUE; +#endif + return TRUE; +} + + +Bool +xf86RandR12Init (ScreenPtr pScreen) +{ + rrScrPrivPtr rp; + XF86RandRInfoPtr randrp; + +#ifdef PANORAMIX + /* XXX disable RandR when using Xinerama */ + if (!noPanoramiXExtension) + return TRUE; +#endif + if (xf86RandR12Generation != serverGeneration) + { + xf86RandR12Index = AllocateScreenPrivateIndex(); + xf86RandR12Generation = serverGeneration; + } + + randrp = xalloc (sizeof (XF86RandRInfoRec)); + if (!randrp) + return FALSE; + + if (!RRScreenInit(pScreen)) + { + xfree (randrp); + return FALSE; + } + rp = rrGetScrPriv(pScreen); + rp->rrGetInfo = xf86RandR12GetInfo; + rp->rrSetConfig = xf86RandR12SetConfig; + + randrp->virtualX = -1; + randrp->virtualY = -1; + randrp->mmWidth = pScreen->mmWidth; + randrp->mmHeight = pScreen->mmHeight; + + randrp->rotation = RR_Rotate_0; /* initial rotated mode */ + + randrp->supported_rotations = RR_Rotate_0; + + randrp->maxX = randrp->maxY = 0; + + pScreen->devPrivates[xf86RandR12Index].ptr = randrp; + +#if RANDR_12_INTERFACE + if (!xf86RandR12Init12 (pScreen)) + return FALSE; +#endif + return TRUE; +} + +void +xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) +{ + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + randrp->supported_rotations = rotations; +} + +void +xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y) +{ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + + if (xf86RandR12Generation != serverGeneration || + XF86RANDRINFO(pScreen)->virtualX == -1) + { + *x = pScrn->virtualX; + *y = pScrn->virtualY; + } else { + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + + *x = randrp->virtualX; + *y = randrp->virtualY; + } +} + +#if RANDR_12_INTERFACE static Bool xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) { @@ -455,103 +574,111 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) static Bool xf86RandR12CrtcSet (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - RRModePtr randr_mode, - int x, - int y, - Rotation rotation, - int num_randr_outputs, - RROutputPtr *randr_outputs) + RRCrtcPtr randr_crtc, + RRModePtr randr_mode, + int x, + int y, + Rotation rotation, + int num_randr_outputs, + RROutputPtr *randr_outputs) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86CrtcPtr crtc = randr_crtc->devPrivate; - DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL; - Bool changed = FALSE; - Bool pos_changed; - int o, ro; - xf86CrtcPtr *save_crtcs; - Bool save_enabled = crtc->enabled; - int ret; - - save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr)); - if ((mode != NULL) != crtc->enabled) - changed = TRUE; - else if (mode && !xf86ModesEqual (&crtc->curMode, mode)) + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86CrtcPtr crtc = randr_crtc->devPrivate; + DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL; + Bool changed = FALSE; + Bool pos_changed; + int o, ro; + xf86CrtcPtr *save_crtcs; + Bool save_enabled = crtc->enabled; + int ret; + + save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr)); + if ((mode != NULL) != crtc->enabled) changed = TRUE; - - pos_changed = changed; - if (x != crtc->x || y != crtc->y) - pos_changed = TRUE; - - for (o = 0; o < config->num_output; o++) { - xf86OutputPtr output = config->output[o]; - xf86CrtcPtr new_crtc; - - save_crtcs[o] = output->crtc; - - if (output->crtc == crtc) - new_crtc = NULL; - else - new_crtc = output->crtc; - - for (ro = 0; ro < num_randr_outputs; ro++) - if (output->randr_output == randr_outputs[ro]) { - new_crtc = crtc; - break; - } - if (new_crtc != output->crtc) { - changed = TRUE; - output->crtc = new_crtc; + else if (mode && !xf86ModesEqual (&crtc->curMode, mode)) + changed = TRUE; + + pos_changed = changed; + if (x != crtc->x || y != crtc->y) + pos_changed = TRUE; + + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr output = config->output[o]; + xf86CrtcPtr new_crtc; + + save_crtcs[o] = output->crtc; + + if (output->crtc == crtc) + new_crtc = NULL; + else + new_crtc = output->crtc; + + for (ro = 0; ro < num_randr_outputs; ro++) + if (output->randr_output == randr_outputs[ro]) { + new_crtc = crtc; + break; + } + if (new_crtc != output->crtc) { + changed = TRUE; + output->crtc = new_crtc; + } } - } - - /* got to set the modes in here */ - if (changed) { - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); - RADEONInfoPtr info = RADEONPTR(pScrn); - RADEONCrtcPrivatePtr pRcrtc; - crtc->enabled = mode != NULL; - - if (info->accelOn) - RADEON_SYNC(info, pScrn); - - if (mode) { - if (pRcrtc->crtc_id == 0) - ret = RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg); - else if (pRcrtc->crtc_id == 1) - ret = RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg); - - if (!ret) { - crtc->enabled = save_enabled; - for (o = 0; o < config->num_output; o++) { - xf86OutputPtr output = config->output[o]; - output->crtc = save_crtcs[o]; + + /* got to set the modes in here */ + if (changed) { + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONCrtcPrivatePtr pRcrtc; + crtc->enabled = mode != NULL; + + if (info->accelOn) + RADEON_SYNC(info, pScrn); + + if (mode) { + if (pRcrtc->crtc_id == 0) + ret = RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg); + else if (pRcrtc->crtc_id == 1) + ret = RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg); + + if (!ret) { + crtc->enabled = save_enabled; + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr output = config->output[o]; + output->crtc = save_crtcs[o]; + } + DEALLOCATE_LOCAL(save_crtcs); + return FALSE; + } + crtc->desiredMode = *mode; + + pScrn->vtSema = TRUE; + RADEONBlank(pScrn); + RADEONRestoreMode(pScrn, &info->ModeReg); + RADEONUnblank(pScrn); + + if (info->DispPriority) + RADEONInitDispBandwidth(pScrn); } - DEALLOCATE_LOCAL(save_crtcs); - return FALSE; - } - crtc->desiredMode = *mode; - - pScrn->vtSema = TRUE; - RADEONBlank(pScrn); - RADEONRestoreMode(pScrn, &info->ModeReg); - RADEONUnblank(pScrn); - - if (info->DispPriority) - RADEONInitDispBandwidth(pScrn); } - } - DEALLOCATE_LOCAL(save_crtcs); - return RADEONRandRCrtcNotify(randr_crtc); + DEALLOCATE_LOCAL(save_crtcs); + return xf86RandR12CrtcNotify (randr_crtc); } static Bool xf86RandR12CrtcSetGamma (ScreenPtr pScreen, - RRCrtcPtr crtc) + RRCrtcPtr randr_crtc) { - return FALSE; + xf86CrtcPtr crtc = randr_crtc->devPrivate; + + if (crtc->funcs->gamma_set == NULL) + return FALSE; + + crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen, + randr_crtc->gammaBlue, randr_crtc->gammaSize); + + return TRUE; } /** @@ -599,8 +726,8 @@ xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes) modeInfo.modeFlags = mode->Flags; rrmode = RRModeGet (&modeInfo, mode->name); - rrmode->devPrivate = mode; if (rrmode) { + rrmode->devPrivate = mode; rrmodes[nmode++] = rrmode; npreferred += pref; } @@ -624,11 +751,11 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); RROutputPtr *clones; RRCrtcPtr *crtcs; - int ncrtc; - int o, c, l; + int ncrtc; + int o, c, l; RRCrtcPtr randr_crtc; - int nclone; - + int nclone; + clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr)); crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr)); for (o = 0; o < config->num_output; o++) @@ -658,7 +785,7 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen) output->mm_height); xf86RROutputSetModes (output->randr_output, output->probed_modes); - switch (output->status = (*output->funcs->detect)(output)) { + switch (output->status) { case XF86OutputStatusConnected: RROutputSetConnection (output->randr_output, RR_Connected); break; @@ -704,536 +831,94 @@ xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86ProbeOutputModes (pScrn); + xf86ProbeOutputModes (pScrn, 0, 0); xf86SetScrnInfoModes (pScrn); - return RADEONRandRSetInfo12 (pScrn); -} - -extern const char *ConnectorTypeName[], *ConnectorTypeNameATOM[]; - -Bool -RADEONRandRCreateScreenResources (ScreenPtr pScreen) -{ -#if RANDR_12_INTERFACE - if (RADEONRandRCreateScreenResources12 (pScreen)) - return TRUE; -#endif - return FALSE; -} - -static Bool -xf86RandR12CreateObjects12(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - int c, o; - if (!RRInit()) - return FALSE; - - - /* - * Configure crtcs - */ - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - - crtc->randr_crtc = RRCrtcCreate (crtc); - RRCrtcAttachScreen (crtc->randr_crtc, pScreen); - RRCrtcGammaSetSize (crtc->randr_crtc, 256); - } - - /* - * Configure outputs - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - output->randr_output = RROutputCreate (output->name, - strlen (output->name), - output); - RROutputAttachScreen (output->randr_output, pScreen); - } - - return TRUE; + return xf86RandR12SetInfo12 (pScreen); } static Bool -xf86RandRCreateScreenResources12 (ScreenPtr pScreen) +xf86RandR12CreateObjects12 (ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); int c; - int width, height; + int o; + + if (!RRInit ()) + return FALSE; /* - * Compute width of screen + * Configure crtcs */ - width = 0; height = 0; for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - int crtc_width = crtc->x + crtc->curMode.HDisplay; - int crtc_height = crtc->y + crtc->curMode.VDisplay; + xf86CrtcPtr crtc = config->crtc[c]; - if (crtc->enabled && crtc_width > width) - width = crtc_width; - if (crtc->enabled && crtc_height > height) - height = crtc_height; + crtc->randr_crtc = RRCrtcCreate (crtc); + RRCrtcAttachScreen (crtc->randr_crtc, pScreen); + RRCrtcGammaSetSize (crtc->randr_crtc, 256); } - - if (width && height) + /* + * Configure outputs + */ + for (o = 0; o < config->num_output; o++) { - int mmWidth, mmHeight; - - mmWidth = pScreen->mmWidth; - mmHeight = pScreen->mmHeight; - if (width != pScreen->width) - mmWidth = mmWidth * width / pScreen->width; - if (height != pScreen->height) - mmHeight = mmHeight * height / pScreen->height; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Setting screen physical size to %d x %d\n", - mmWidth, mmHeight); - xf86RandR12ScreenSetSize (pScreen, - width, - height, - mmWidth, - mmHeight); + xf86OutputPtr output = config->output[o]; + + output->randr_output = RROutputCreate (output->name, + strlen (output->name), + output); + RROutputAttachScreen (output->randr_output, pScreen); } + return TRUE; +} + +static Bool +xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) +{ + int c; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); for (c = 0; c < config->num_crtc; c++) xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); - 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; } -Bool -RADEONRandRInit (ScreenPtr pScreen, int rotation) +static void +xf86RandR12PointerMoved (int scrnIndex, int x, int y) { - rrScrPrivPtr rp; - XF86RandRInfoPtr randrp; - -#ifdef PANORAMIX - /* XXX disable RandR when using Xinerama */ - if (!noPanoramiXExtension) - return TRUE; -#endif - if (xf86RandR12Generation != serverGeneration) - { - xf86RandR12Index = AllocateScreenPrivateIndex(); - xf86RandR12Generation = serverGeneration; - } - - randrp = xalloc (sizeof (XF86RandRInfoRec)); - if (!randrp) - return FALSE; - - if (!RRScreenInit(pScreen)) - { - xfree (randrp); - return FALSE; - } - rp = rrGetScrPriv(pScreen); - // rp->rrGetInfo = RADEONRandRGetInfo; - // rp->rrSetConfig = RADEONRandRSetConfig; - - randrp->virtualX = -1; - randrp->virtualY = -1; - randrp->mmWidth = pScreen->mmWidth; - randrp->mmHeight = pScreen->mmHeight; - - randrp->rotation = RR_Rotate_0; /* initial rotated mode */ - - randrp->supported_rotations = rotation; - - randrp->maxX = randrp->maxY = 0; - - pScreen->devPrivates[xf86RandR12Index].ptr = randrp; - -#if RANDR_12_INTERFACE - if (!RADEONRandRInit12 (pScreen)) - return FALSE; -#endif - return TRUE; } -Bool -RADEONRandRInit12(ScreenPtr pScreen) +static Bool +xf86RandR12Init12 (ScreenPtr pScreen) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - rrScrPrivPtr rp = rrGetScrPriv(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + rrScrPrivPtr rp = rrGetScrPriv(pScreen); rp->rrGetInfo = xf86RandR12GetInfo12; rp->rrScreenSetSize = xf86RandR12ScreenSetSize; rp->rrCrtcSet = xf86RandR12CrtcSet; rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma; - rp->rrSetConfig = NULL; - // memset (rp->modes, '\0', sizeof (rp->modes)); - pScrn->PointerMoved = RADEONRandRPointerMoved; - - if (!xf86RandR12CreateObjects12 (pScreen)) - return FALSE; - /* - * Configure output modes - */ - if (!xf86RandR12SetInfo12 (pScreen)) - return FALSE; - return TRUE; -} - -static RRModePtr -RADEONRRDefaultMode (RROutputPtr output) -{ - RRModePtr target_mode = NULL; - int target_diff = 0; - int mmHeight; - int num_modes; - int m; - - num_modes = output->numPreferred ? output->numPreferred : output->numModes; - mmHeight = output->mmHeight; - if (!mmHeight) - mmHeight = 203; /* 768 pixels at 96dpi */ - /* - * Pick a mode closest to 96dpi - */ - for (m = 0; m < num_modes; m++) - { - RRModePtr mode = output->modes[m]; - int dpi; - int diff; - - dpi = (mode->mode.height * 254) / (mmHeight * 10); - diff = dpi - 96; - diff = diff < 0 ? -diff : diff; - if (target_mode == NULL || diff < target_diff) - { - target_mode = mode; - target_diff = diff; - } - } - return target_mode; -} - -static RRModePtr -RADEONClosestMode (RROutputPtr output, RRModePtr match) -{ - RRModePtr target_mode = NULL; - int target_diff = 0; - int m; - - /* - * Pick a mode closest to the specified mode - */ - for (m = 0; m < output->numModes; m++) - { - RRModePtr mode = output->modes[m]; - int dx, dy; - int diff; - - /* exact matches are preferred */ - if (mode == match) - return mode; - - dx = match->mode.width - mode->mode.width; - dy = match->mode.height - mode->mode.height; - diff = dx * dx + dy * dy; - if (target_mode == NULL || diff < target_diff) - { - target_mode = mode; - target_diff = diff; - } - } - return target_mode; -} - -static int -RADEONRRPickCrtcs (RROutputPtr *outputs, - RRCrtcPtr *best_crtcs, - RRModePtr *modes, - int num_outputs, - int n) -{ - int c, o, l; - RROutputPtr output; - RRCrtcPtr crtc; - RRCrtcPtr *crtcs; - RRCrtcPtr best_crtc; - int best_score; - int score; - int my_score; - - if (n == num_outputs) - return 0; - output = outputs[n]; - - /* - * Compute score with this output disabled - */ - best_crtcs[n] = NULL; - best_crtc = NULL; - best_score = RADEONRRPickCrtcs (outputs, best_crtcs, modes, num_outputs, n+1); - if (modes[n] == NULL) - return best_score; - - crtcs = xalloc (num_outputs * sizeof (RRCrtcPtr)); - if (!crtcs) - return best_score; - - my_score = 1; - /* Score outputs that are known to be connected higher */ - if (output->connection == RR_Connected) - my_score++; - /* Score outputs with preferred modes higher */ - if (output->numPreferred) - my_score++; - /* - * Select a crtc for this output and - * then attempt to configure the remaining - * outputs - */ - for (c = 0; c < output->numCrtcs; c++) - { - crtc = output->crtcs[c]; - /* - * Check to see if some other output is - * using this crtc - */ - for (o = 0; o < n; o++) - if (best_crtcs[o] == crtc) - break; - if (o < n) - { - /* - * If the two outputs desire the same mode, - * see if they can be cloned - */ - if (modes[o] == modes[n]) - { - for (l = 0; l < output->numClones; l++) - if (output->clones[l] == outputs[o]) - break; - if (l == output->numClones) - continue; /* nope, try next CRTC */ - } - else - continue; /* different modes, can't clone */ - } - crtcs[n] = crtc; - memcpy (crtcs, best_crtcs, n * sizeof (RRCrtcPtr)); - score = my_score + RADEONRRPickCrtcs (outputs, crtcs, modes, - num_outputs, n+1); - if (score >= best_score) - { - best_crtc = crtc; - best_score = score; - memcpy (best_crtcs, crtcs, num_outputs * sizeof (RRCrtcPtr)); - } - } - xfree (crtcs); - return best_score; -} - -static Bool -RADEONRRInitialConfiguration (RROutputPtr *outputs, - RRCrtcPtr *crtcs, - RRModePtr *modes, - int num_outputs) -{ - int o; - RRModePtr target_mode = NULL; + rp->rrSetConfig = NULL; + pScrn->PointerMoved = xf86RandR12PointerMoved; + if (!xf86RandR12CreateObjects12 (pScreen)) + return FALSE; - for (o = 0; o < num_outputs; o++) - modes[o] = NULL; - /* - * Let outputs with preferred modes drive screen size + * Configure output modes */ - for (o = 0; o < num_outputs; o++) - { - RROutputPtr output = outputs[o]; - - if (output->connection != RR_Disconnected && output->numPreferred) - { - target_mode = RADEONRRDefaultMode (output); - if (target_mode) - { - modes[o] = target_mode; - break; - } - } - } - if (!target_mode) - { - for (o = 0; o < num_outputs; o++) - { - RROutputPtr output = outputs[o]; - if (output->connection != RR_Disconnected) - { - target_mode = RADEONRRDefaultMode (output); - if (target_mode) - { - modes[o] = target_mode; - break; - } - } - } - } - for (o = 0; o < num_outputs; o++) - { - RROutputPtr output = outputs[o]; - - if (output->connection != RR_Disconnected && !modes[o]) - modes[o] = RADEONClosestMode (output, target_mode); - } - - if (!RADEONRRPickCrtcs (outputs, crtcs, modes, num_outputs, 0)) + if (!xf86RandR12SetInfo12 (pScreen)) return FALSE; - return TRUE; } -/* - * Compute the virtual size necessary to place all of the available - * crtcs in a panorama configuration - */ - -static void -RADEONRRDefaultScreenLimits (RROutputPtr *outputs, int num_outputs, - RRCrtcPtr *crtcs, int num_crtc, - int *widthp, int *heightp) -{ - int width = 0, height = 0; - int o; - int c; - int m; - int s; - - for (c = 0; c < num_crtc; c++) - { - RRCrtcPtr crtc = crtcs[c]; - int crtc_width = 1600, crtc_height = 1200; - - for (o = 0; o < num_outputs; o++) - { - RROutputPtr output = outputs[o]; - - for (s = 0; s < output->numCrtcs; s++) - if (output->crtcs[s] == crtc) - break; - if (s == output->numCrtcs) - continue; - for (m = 0; m < output->numModes; m++) - { - RRModePtr mode = output->modes[m]; - if (mode->mode.width > crtc_width) - crtc_width = mode->mode.width; - if (mode->mode.height > crtc_width) - crtc_height = mode->mode.height; - } - } - width += crtc_width; - if (crtc_height > height) - height = crtc_height; - } - *widthp = width; - *heightp = height; -} - -#if 0 -Bool -RADEONRandRPreInit(ScrnInfoPtr pScrn) -{ - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); -#if RANDR_12_INTERFACE - RROutputPtr outputs[RADEON_MAX_CONNECTOR]; - RRCrtcPtr output_crtcs[RADEON_MAX_CONNECTOR]; - RRModePtr output_modes[RADEON_MAX_CONNECTOR]; - RRCrtcPtr crtcs[RADEON_MAX_CRTC]; -#endif - int conn, crtc; - int o,c; - int width, height; - - RADEONProbeOutputModes(pScrn); - -#if RANDR_12_INTERFACE - if (!xf86RandRCreateObjects12(pScrn)) - return FALSE; - - if (!RADEONRandRSetInfo12(pScrn)) - return FALSE; - -#endif - - /* - * With RandR info set up, let RandR choose - * the initial configuration - */ - for (o = 0; o < RADEON_MAX_CONNECTOR; o++) - outputs[o] = pRADEONEnt->pOutput[o]->randr_output; - for (c = 0; c < RADEON_MAX_CRTC; c++) - crtcs[c] = pRADEONEnt->pCrtc[c]->randr_crtc; - - if (!RADEONRRInitialConfiguration (outputs, output_crtcs, output_modes, - RADEON_MAX_CONNECTOR)) - return FALSE; - - RADEONRRDefaultScreenLimits (outputs, RADEON_MAX_CONNECTOR, - crtcs, RADEON_MAX_CRTC, - &width, &height); - - if (width > pScrn->virtualX) - pScrn->virtualX = width; - if (height > pScrn->virtualY) - pScrn->virtualY = height; - - for (o = 0; o < RADEON_MAX_CONNECTOR; o++) - { - RRModePtr randr_mode = output_modes[o]; - DisplayModePtr mode; - RRCrtcPtr randr_crtc = output_crtcs[o]; - int pipe; - Bool enabled; - - if (randr_mode) - mode = (DisplayModePtr) randr_mode->devPrivate; - else - mode = NULL; - if (randr_crtc) - { - pipe = (int) randr_crtc->devPrivate; - enabled = TRUE; - } - else - { - pipe = 0; - enabled = FALSE; - } - // if (mode) - // pRADEON->pipes[pipe].desiredMode = *mode; - // pRADEON->output[o].pipe = pipe; - // pRADEON->output[o].enabled = enabled; - } - - RADEON_set_xf86_modes_from_outputs(pScrn); - RADEON_set_default_screen_size(pScrn); - - return TRUE; -} -#endif #endif Bool diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c index 76b03f5c..7414d34d 100644 --- a/src/radeon_xf86Crtc.c +++ b/src/radeon_xf86Crtc.c @@ -5,21 +5,21 @@ * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H @@ -34,10 +34,12 @@ #include "xf86DDC.h" //#include "i.h" #include "radeon_xf86Crtc.h" +#include "radeon_xf86Modes.h" #include "X11/extensions/render.h" #define DPMS_SERVER #include "X11/extensions/dpms.h" +#include "X11/Xatom.h" /* * Initialize xf86CrtcConfig structure @@ -124,6 +126,79 @@ xf86CrtcDestroy (xf86CrtcPtr crtc) /* * Output functions */ + +extern XF86ConfigPtr xf86configptr; + +typedef enum { + OPTION_PREFERRED_MODE, + OPTION_POSITION, + OPTION_BELOW, + OPTION_RIGHT_OF, + OPTION_ABOVE, + OPTION_LEFT_OF, + OPTION_ENABLE, + OPTION_DISABLE, + OPTION_MIN_CLOCK, + OPTION_MAX_CLOCK, +} OutputOpts; + +static OptionInfoRec xf86OutputOptions[] = { + {OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE }, + {OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE }, + {OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE }, + {OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE }, + {OPTION_ABOVE, "Above", OPTV_STRING, {0}, FALSE }, + {OPTION_LEFT_OF, "LeftOf", OPTV_STRING, {0}, FALSE }, + {OPTION_ENABLE, "Enable", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_DISABLE, "Disable", OPTV_BOOLEAN, {0}, FALSE }, + {OPTION_MIN_CLOCK, "MinClock", OPTV_FREQ, {0}, FALSE }, + {OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE }, + {-1, NULL, OPTV_NONE, {0}, FALSE }, +}; + +static void +xf86OutputSetMonitor (xf86OutputPtr output) +{ + char *option_name; + static const char monitor_prefix[] = "monitor-"; + char *monitor; + + if (output->options) + xfree (output->options); + + output->options = xnfalloc (sizeof (xf86OutputOptions)); + memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions)); + + option_name = xnfalloc (strlen (monitor_prefix) + + strlen (output->name) + 1); + strcpy (option_name, monitor_prefix); + strcat (option_name, output->name); + monitor = xf86findOptionValue (output->scrn->options, option_name); + if (!monitor) + monitor = output->name; + else + xf86MarkOptionUsedByName (output->scrn->options, option_name); + xfree (option_name); + output->conf_monitor = xf86findMonitor (monitor, + xf86configptr->conf_monitor_lst); + if (output->conf_monitor) + xf86ProcessOptions (output->scrn->scrnIndex, + output->conf_monitor->mon_option_lst, + output->options); +} + +static Bool +xf86OutputEnabled (xf86OutputPtr output) +{ + /* Check to see if this output was disabled in the config file */ + if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE || + xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE) + { + return FALSE; + } + return TRUE; +} + xf86OutputPtr xf86OutputCreate (ScrnInfoPtr scrn, const xf86OutputFuncsRec *funcs, @@ -144,6 +219,8 @@ xf86OutputCreate (ScrnInfoPtr scrn, #ifdef RANDR_12_INTERFACE output->randr_output = NULL; #endif + xf86OutputSetMonitor (output); + if (xf86_config->output) outputs = xrealloc (xf86_config->output, (xf86_config->num_output + 1) * sizeof (xf86OutputPtr)); @@ -154,24 +231,28 @@ xf86OutputCreate (ScrnInfoPtr scrn, xfree (output); return NULL; } + xf86_config->output = outputs; xf86_config->output[xf86_config->num_output++] = output; + return output; } -void +Bool xf86OutputRename (xf86OutputPtr output, const char *name) { int len = strlen(name); char *newname = xalloc (len + 1); if (!newname) - return; /* so sorry... */ + return FALSE; /* so sorry... */ strcpy (newname, name); if (output->name != (char *) (output + 1)) xfree (output->name); output->name = newname; + xf86OutputSetMonitor (output); + return TRUE; } void @@ -348,7 +429,9 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, * If the two outputs desire the same mode, * see if they can be cloned */ - if (xf86ModesEqual (modes[o], modes[n])) + if (xf86ModesEqual (modes[o], modes[n]) && + config->output[o]->initial_x == config->output[n]->initial_x && + config->output[o]->initial_y == config->output[n]->initial_y) { for (l = 0; l < config->num_output; l++) if (output->possible_clones & (1 << l)) @@ -362,7 +445,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, crtcs[n] = crtc; memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr)); score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height); - if (score >= best_score) + if (score > best_score) { best_crtc = crtc; best_score = score; @@ -376,7 +459,8 @@ xf86PickCrtcs (ScrnInfoPtr pScrn, /* * Compute the virtual size necessary to place all of the available - * crtcs in a panorama configuration + * crtcs in the specified configuration and also large enough to + * resize any crtc to the largest available mode */ static void @@ -391,7 +475,13 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) for (c = 0; c < config->num_crtc; c++) { int crtc_width = 0, crtc_height = 0; + xf86CrtcPtr crtc = config->crtc[c]; + if (crtc->enabled) + { + crtc_width = crtc->x + crtc->desiredMode.HDisplay; + crtc_height = crtc->y + crtc->desiredMode.VDisplay; + } for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; @@ -409,7 +499,8 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) } } } - width += crtc_width; + if (crtc_width > width) + width = crtc_width; if (crtc_height > height) height = crtc_height; } @@ -421,6 +512,186 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp) *heightp = height; } +#define POSITION_UNSET -100000 + +static Bool +xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int o; + int min_x, min_y; + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->initial_x = output->initial_y = POSITION_UNSET; + } + + /* + * Loop until all outputs are set + */ + for (;;) + { + Bool any_set = FALSE; + Bool keep_going = FALSE; + + for (o = 0; o < config->num_output; o++) + { + static const OutputOpts relations[] = { + OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF + }; + xf86OutputPtr output = config->output[o]; + xf86OutputPtr relative; + char *relative_name; + char *position; + OutputOpts relation; + int r; + + if (output->initial_x != POSITION_UNSET) + continue; + position = xf86GetOptValString (output->options, + OPTION_POSITION); + /* + * Absolute position wins + */ + if (position) + { + int x, y; + if (sscanf (position, "%d %d", &x, &y) == 2) + { + output->initial_x = x; + output->initial_y = y; + } + else + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Output %s position not of form \"x y\"\n", + output->name); + output->initial_x = output->initial_y = 0; + } + any_set = TRUE; + continue; + } + /* + * Next comes relative positions + */ + relation = 0; + relative_name = NULL; + for (r = 0; r < 4; r++) + { + relation = relations[r]; + relative_name = xf86GetOptValString (output->options, + relation); + if (relative_name) + break; + } + if (relative_name) + { + int or; + relative = NULL; + for (or = 0; or < config->num_output; or++) + { + xf86OutputPtr out_rel = config->output[or]; + XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor; + char *name; + + if (rel_mon) + name = rel_mon->mon_identifier; + else + name = out_rel->name; + if (!strcmp (relative_name, name)) + { + relative = config->output[or]; + break; + } + } + if (!relative) + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Cannot position output %s relative to unknown output %s\n", + output->name, relative_name); + output->initial_x = 0; + output->initial_y = 0; + any_set = TRUE; + continue; + } + if (relative->initial_x == POSITION_UNSET) + { + keep_going = TRUE; + continue; + } + output->initial_x = relative->initial_x; + output->initial_y = relative->initial_y; + switch (relation) { + case OPTION_BELOW: + output->initial_y += modes[or]->VDisplay; + break; + case OPTION_RIGHT_OF: + output->initial_x += modes[or]->HDisplay; + break; + case OPTION_ABOVE: + output->initial_y -= modes[o]->VDisplay; + break; + case OPTION_LEFT_OF: + output->initial_x -= modes[o]->HDisplay; + break; + default: + break; + } + any_set = TRUE; + continue; + } + + /* Nothing set, just stick them at 0,0 */ + output->initial_x = 0; + output->initial_y = 0; + any_set = TRUE; + } + if (!keep_going) + break; + if (!any_set) + { + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + if (output->initial_x == POSITION_UNSET) + { + xf86DrvMsg (pScrn->scrnIndex, X_ERROR, + "Output position loop. Moving %s to 0,0\n", + output->name); + output->initial_x = output->initial_y = 0; + break; + } + } + } + } + + /* + * normalize positions + */ + min_x = 1000000; + min_y = 1000000; + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + if (output->initial_x < min_x) + min_x = output->initial_x; + if (output->initial_y < min_y) + min_y = output->initial_y; + } + + for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + + output->initial_x -= min_x; + output->initial_y -= min_y; + } + return TRUE; +} + /* * XXX walk the monitor mode list and prune out duplicates that * are inserted by xf86DDCMonitorSet. In an ideal world, that @@ -440,39 +711,270 @@ xf86PruneDuplicateMonitorModes (MonPtr Monitor) { next = clone->next; if (xf86ModesEqual (master, clone)) + { + if (Monitor->Last == clone) + Monitor->Last = clone->prev; xf86DeleteMode (&Monitor->Modes, clone); + } + } + } +} + +/** Return - 0 + if a should be earlier, same or later than b in list + */ +static int +i830xf86ModeCompare (DisplayModePtr a, DisplayModePtr b) +{ + int diff; + + diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0); + if (diff) + return diff; + diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay; + if (diff) + return diff; + diff = b->Clock - a->Clock; + return diff; +} + +/** + * Insertion sort input in-place and return the resulting head + */ +static DisplayModePtr +i830xf86SortModes (DisplayModePtr input) +{ + DisplayModePtr output = NULL, i, o, n, *op, prev; + + /* sort by preferred status and pixel area */ + while (input) + { + i = input; + input = input->next; + for (op = &output; (o = *op); op = &o->next) + if (i830xf86ModeCompare (o, i) > 0) + break; + i->next = *op; + *op = i; + } + /* prune identical modes */ + for (o = output; o && (n = o->next); o = n) + { + if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n)) + { + o->next = n->next; + xfree (n->name); + xfree (n); + n = o; } } + /* hook up backward links */ + prev = NULL; + for (o = output; o; o = o->next) + { + o->prev = prev; + prev = o; + } + return output; } +#define DEBUG_REPROBE 1 + void -xf86ProbeOutputModes (ScrnInfoPtr pScrn) +xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - Bool properties_set = FALSE; int o; + if (maxX == 0 || maxY == 0) + xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY); + /* Elide duplicate modes before defaulting code uses them */ xf86PruneDuplicateMonitorModes (pScrn->monitor); /* Probe the list of modes for each output. */ for (o = 0; o < config->num_output; o++) { - xf86OutputPtr output = config->output[o]; - DisplayModePtr mode; - + xf86OutputPtr output = config->output[o]; + DisplayModePtr mode; + DisplayModePtr config_modes = NULL, output_modes, default_modes; + char *preferred_mode; + xf86MonPtr edid_monitor; + XF86ConfMonitorPtr conf_monitor; + MonRec mon_rec; + int min_clock = 0; + int max_clock = 0; + double clock; + enum { sync_config, sync_edid, sync_default } sync_source = sync_default; + while (output->probed_modes != NULL) xf86DeleteMode(&output->probed_modes, output->probed_modes); - output->probed_modes = (*output->funcs->get_modes) (output); + /* + * Check connection status + */ + output->status = (*output->funcs->detect)(output); - /* Set the DDC properties to whatever first output has DDC information. + if (output->status == XF86OutputStatusDisconnected) + continue; + + memset (&mon_rec, '\0', sizeof (mon_rec)); + + conf_monitor = output->conf_monitor; + + if (conf_monitor) + { + int i; + + for (i = 0; i < conf_monitor->mon_n_hsync; i++) + { + mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo; + mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi; + mon_rec.nHsync++; + sync_source = sync_config; + } + for (i = 0; i < conf_monitor->mon_n_vrefresh; i++) + { + mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo; + mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi; + mon_rec.nVrefresh++; + sync_source = sync_config; + } + config_modes = i830xf86GetMonitorModes (pScrn, conf_monitor); + } + + output_modes = (*output->funcs->get_modes) (output); + + edid_monitor = output->MonInfo; + + if (edid_monitor) + { + int i; + Bool set_hsync = mon_rec.nHsync == 0; + Bool set_vrefresh = mon_rec.nVrefresh == 0; + + for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++) + { + if (edid_monitor->det_mon[i].type == DS_RANGES) + { + struct monitor_ranges *ranges = &edid_monitor->det_mon[i].section.ranges; + if (set_hsync && ranges->max_h) + { + mon_rec.hsync[mon_rec.nHsync].lo = ranges->min_h; + mon_rec.hsync[mon_rec.nHsync].hi = ranges->max_h; + mon_rec.nHsync++; + if (sync_source == sync_default) + sync_source = sync_edid; + } + if (set_vrefresh && ranges->max_v) + { + mon_rec.vrefresh[mon_rec.nVrefresh].lo = ranges->min_v; + mon_rec.vrefresh[mon_rec.nVrefresh].hi = ranges->max_v; + mon_rec.nVrefresh++; + if (sync_source == sync_default) + sync_source = sync_edid; + } + if (ranges->max_clock > max_clock) + max_clock = ranges->max_clock; + } + } + } + + if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK, + OPTUNITS_KHZ, &clock)) + min_clock = (int) clock; + if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK, + OPTUNITS_KHZ, &clock)) + max_clock = (int) clock; + + /* + * These limits will end up setting a 1024x768@60Hz mode by default, + * which seems like a fairly good mode to use when nothing else is + * specified */ - if (output->MonInfo != NULL && !properties_set) { - xf86SetDDCproperties(pScrn, output->MonInfo); - properties_set = TRUE; + if (mon_rec.nHsync == 0) + { + mon_rec.hsync[0].lo = 31.0; + mon_rec.hsync[0].hi = 55.0; + mon_rec.nHsync = 1; + } + if (mon_rec.nVrefresh == 0) + { + mon_rec.vrefresh[0].lo = 58.0; + mon_rec.vrefresh[0].hi = 62.0; + mon_rec.nVrefresh = 1; } + default_modes = RADEONxf86GetDefaultModes (output->interlaceAllowed, + output->doubleScanAllowed); + + if (sync_source == sync_config) + { + /* + * Check output and config modes against sync range from config file + */ + RADEONxf86ValidateModesSync (pScrn, output_modes, &mon_rec); + RADEONxf86ValidateModesSync (pScrn, config_modes, &mon_rec); + } + /* + * Check default modes against sync range + */ + RADEONxf86ValidateModesSync (pScrn, default_modes, &mon_rec); + /* + * Check default modes against monitor max clock + */ + if (max_clock) + RADEONxf86ValidateModesClocks(pScrn, default_modes, + &min_clock, &max_clock, 1); + + output->probed_modes = NULL; + output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes); + output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes); + output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes); + + /* + * Check all modes against max size + */ + if (maxX && maxY) + RADEONxf86ValidateModesSize (pScrn, output->probed_modes, + maxX, maxY, 0); + + /* + * Check all modes against output + */ + for (mode = output->probed_modes; mode != NULL; mode = mode->next) + if (mode->status == MODE_OK) + mode->status = (*output->funcs->mode_valid)(output, mode); + + RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes, TRUE); + + output->probed_modes = i830xf86SortModes (output->probed_modes); + + /* Check for a configured preference for a particular mode */ + preferred_mode = xf86GetOptValString (output->options, + OPTION_PREFERRED_MODE); + if (preferred_mode) + { + for (mode = output->probed_modes; mode; mode = mode->next) + { + if (!strcmp (preferred_mode, mode->name)) + { + if (mode != output->probed_modes) + { + if (mode->prev) + mode->prev->next = mode->next; + if (mode->next) + mode->next->prev = mode->prev; + mode->next = output->probed_modes; + output->probed_modes->prev = mode; + mode->prev = NULL; + output->probed_modes = mode; + } + mode->type |= M_T_PREFERRED; + break; + } + } + } + #ifdef DEBUG_REPROBE if (output->probed_modes != NULL) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -515,7 +1017,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn) xf86OutputPtr output; xf86CrtcPtr crtc; DisplayModePtr last, mode; - int originalVirtualX, originalVirtualY; output = config->output[config->compat_output]; if (!output->crtc) @@ -543,31 +1044,23 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn) /* Set pScrn->modes to the mode list for the 'compat' output */ pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes); - xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY); - - /* Disable modes in the XFree86 DDX list that are larger than the current - * virtual size. - */ - RADEONxf86ValidateModesSize(pScrn, pScrn->modes, - originalVirtualX, originalVirtualY, - pScrn->displayWidth); - - /* Strip out anything that we threw out for virtualX/Y. */ - RADEONxf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE); - for (mode = pScrn->modes; mode; mode = mode->next) if (xf86ModesEqual (mode, &crtc->desiredMode)) break; - - /* For some reason, pScrn->modes is circular, unlike the other mode lists. - * How great is that? - */ - for (last = pScrn->modes; last && last->next; last = last->next); - last->next = pScrn->modes; - pScrn->modes->prev = last; - if (mode) - while (pScrn->modes != mode) - pScrn->modes = pScrn->modes->next; + + if (pScrn->modes != NULL) { + /* For some reason, pScrn->modes is circular, unlike the other mode + * lists. How great is that? + */ + for (last = pScrn->modes; last && last->next; last = last->next) + ; + last->next = pScrn->modes; + pScrn->modes->prev = last; + if (mode) { + while (pScrn->modes != mode) + pScrn->modes = pScrn->modes->next; + } + } pScrn->currentMode = pScrn->modes; } @@ -586,35 +1079,33 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) DisplayModePtr target_mode = NULL; xf86CrtcPtr *crtcs; DisplayModePtr *modes; - int width, height; + Bool *enabled; + int width; + int height; - xf86ProbeOutputModes (pScrn); - - if (pScrn->display->virtualX == 0) - { - /* - * Expand virtual size to cover potential mode switches - */ - xf86DefaultScreenLimits (pScrn, &width, &height); - - pScrn->display->virtualX = width; - pScrn->display->virtualY = height; - } - else - { + if (pScrn->display->virtualX) width = pScrn->display->virtualX; + else + width = config->maxWidth; + if (pScrn->display->virtualY) height = pScrn->display->virtualY; - } - if (width > pScrn->virtualX) - pScrn->virtualX = width; - if (height > pScrn->virtualY) - pScrn->virtualY = height; - + else + height = config->maxHeight; + + xf86ProbeOutputModes (pScrn, width, height); + crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr)); modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr)); + enabled = xnfcalloc (config->num_output, sizeof (Bool)); for (o = 0; o < config->num_output; o++) + { + xf86OutputPtr output = config->output[o]; + modes[o] = NULL; + enabled[o] = (xf86OutputEnabled (output) && + output->status != XF86OutputStatusDisconnected); + } /* * Let outputs with preferred modes drive screen size @@ -623,7 +1114,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) { xf86OutputPtr output = config->output[o]; - if (output->status != XF86OutputStatusDisconnected && + if (enabled[o] && xf86OutputHasPreferredMode (output, width, height)) { target_mode = xf86DefaultMode (output, width, height); @@ -640,7 +1131,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; - if (output->status != XF86OutputStatusDisconnected) + if (enabled[o]) { target_mode = xf86DefaultMode (output, width, height); if (target_mode) @@ -656,10 +1147,23 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) { xf86OutputPtr output = config->output[o]; - if (output->status != XF86OutputStatusDisconnected && !modes[o]) + if (enabled[o] && !modes[o]) modes[o] = xf86ClosestMode (output, target_mode, width, height); } + /* + * Set the position of each output + */ + if (!xf86InitialOutputPositions (pScrn, modes)) + { + xfree (crtcs); + xfree (modes); + return FALSE; + } + + /* + * Assign CRTCs to fit output configuration + */ if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height)) { xfree (crtcs); @@ -679,7 +1183,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) crtc->enabled = FALSE; memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode)); } - + /* * Set initial configuration */ @@ -693,13 +1197,28 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn) { crtc->desiredMode = *mode; crtc->enabled = TRUE; - crtc->x = 0; - crtc->y = 0; + crtc->x = output->initial_x; + crtc->y = output->initial_y; output->crtc = crtc; - /* XXX set position; for now, we clone */ } } + if (pScrn->display->virtualX == 0) + { + /* + * Expand virtual size to cover potential mode switches + */ + xf86DefaultScreenLimits (pScrn, &width, &height); + + pScrn->display->virtualX = width; + pScrn->display->virtualY = height; + } + + if (width > pScrn->virtualX) + pScrn->virtualX = width; + if (height > pScrn->virtualY) + pScrn->virtualY = height; + /* Mirror output modes to pScrn mode list */ xf86SetScrnInfoModes (pScrn); @@ -742,3 +1261,115 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags) } } } + +#ifdef RANDR_12_INTERFACE + +#define EDID_ATOM_NAME "EDID_DATA" + +/** + * Set the RandR EDID property + */ +static void +xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len) +{ + Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE); + + /* This may get called before the RandR resources have been created */ + if (output->randr_output == NULL) + return; + + if (data_len != 0) { + RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8, + PropModeReplace, data_len, data, FALSE); + } else { + RRDeleteOutputProperty(output->randr_output, edid_atom); + } +} + +#endif + +/** + * Set the EDID information for the specified output + */ +void +i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) +{ + ScrnInfoPtr pScrn = output->scrn; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; +#ifdef RANDR_12_INTERFACE + int size; +#endif + + if (output->MonInfo != NULL) + xfree(output->MonInfo); + + output->MonInfo = edid_mon; + + /* Debug info for now, at least */ + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name); + xf86PrintEDID(edid_mon); + + /* Set the DDC properties for the 'compat' output */ + if (output == config->output[config->compat_output]) + xf86SetDDCproperties(pScrn, edid_mon); + +#ifdef RANDR_12_INTERFACE + /* Set the RandR output properties */ + size = 0; + if (edid_mon) + { + if (edid_mon->ver.version == 1) + size = 128; + else if (edid_mon->ver.version == 2) + size = 256; + } + xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size); +#endif + + if (edid_mon) + { + /* Pull out a phyiscal size from a detailed timing if available. */ + for (i = 0; i < 4; i++) { + if (edid_mon->det_mon[i].type == DT && + edid_mon->det_mon[i].section.d_timings.h_size != 0 && + edid_mon->det_mon[i].section.d_timings.v_size != 0) + { + output->mm_width = edid_mon->det_mon[i].section.d_timings.h_size; + output->mm_height = edid_mon->det_mon[i].section.d_timings.v_size; + break; + } + } + + /* if no mm size is available from a detailed timing, check the max size field */ + if ((!output->mm_width || !output->mm_height) && + (edid_mon->features.hsize && edid_mon->features.vsize)) + { + output->mm_width = edid_mon->features.hsize * 10; + output->mm_height = edid_mon->features.vsize * 10; + } + } +} + +/** + * Return the list of modes supported by the EDID information + * stored in 'output' + */ +DisplayModePtr +i830_xf86OutputGetEDIDModes (xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + xf86MonPtr edid_mon = output->MonInfo; + + if (!edid_mon) + return NULL; + return xf86DDCGetModes(pScrn->scrnIndex, edid_mon); +} + +xf86MonPtr +i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) +{ + ScrnInfoPtr pScrn = output->scrn; + + return xf86DoEDID_DDC2 (pScrn->scrnIndex, pDDCBus); +} diff --git a/src/radeon_xf86Crtc.h b/src/radeon_xf86Crtc.h index 174647f2..2f534f80 100644 --- a/src/radeon_xf86Crtc.h +++ b/src/radeon_xf86Crtc.h @@ -25,6 +25,15 @@ #include <edid.h> #include "randrstr.h" #include "radeon_xf86Modes.h" +#include "xf86Parser.h" + +/* Compat definitions for older X Servers. */ +#ifndef M_T_PREFERRED +#define M_T_PREFERRED 0x08 +#endif +#ifndef M_T_DRIVER +#define M_T_DRIVER 0x40 +#endif typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr; typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr; @@ -80,6 +89,11 @@ typedef struct _xf86CrtcFuncs { DisplayModePtr mode, DisplayModePtr adjusted_mode); + /* Set the color ramps for the CRTC to the given values. */ + void + (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, + int size); + /** * Clean up driver-specific bits of the crtc */ @@ -260,6 +274,17 @@ struct _xf86Output { * Possible outputs to share the same CRTC as a mask of output indices */ CARD32 possible_clones; + + /** + * Whether this output can support interlaced modes + */ + Bool interlaceAllowed; + + /** + * Whether this output can support double scan modes + */ + Bool doubleScanAllowed; + /** * List of available modes on this output. * @@ -269,6 +294,21 @@ struct _xf86Output { DisplayModePtr probed_modes; /** + * Options parsed from the related monitor section + */ + OptionInfoPtr options; + + /** + * Configured monitor section + */ + XF86ConfMonitorPtr conf_monitor; + + /** + * Desired initial position + */ + int initial_x, initial_y; + + /** * Current connection status * * This indicates whether a monitor is known to be connected @@ -379,14 +419,14 @@ xf86OutputCreate (ScrnInfoPtr scrn, const xf86OutputFuncsRec *funcs, const char *name); -void +Bool xf86OutputRename (xf86OutputPtr output, const char *name); void xf86OutputDestroy (xf86OutputPtr output); void -xf86ProbeOutputModes (ScrnInfoPtr pScrn); +xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY); void xf86SetScrnInfoModes (ScrnInfoPtr pScrn); @@ -396,5 +436,21 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn); void xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags); + +/** + * Set the EDID information for the specified output + */ +void +i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon); + +/** + * Return the list of modes supported by the EDID information + * stored in 'output' + */ +DisplayModePtr +i830_xf86OutputGetEDIDModes (xf86OutputPtr output); + +xf86MonPtr +i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus); #endif /* _XF86CRTC_H_ */ diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c index e75ac796..fa7f97ae 100644 --- a/src/radeon_xf86Modes.c +++ b/src/radeon_xf86Modes.c @@ -39,448 +39,23 @@ #include "xf86.h" #include "radeon.h" #include "radeon_xf86Modes.h" +#include "xf86Priv.h" - -#include <math.h> - -#define rint(x) floor(x) - -#define MARGIN_PERCENT 1.8 /* % of active vertical image */ -#define CELL_GRAN 8.0 /* assumed character cell granularity */ -#define MIN_PORCH 1 /* minimum front porch */ -#define V_SYNC_RQD 3 /* width of vsync in lines */ -#define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */ -#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */ -#define M 600.0 /* blanking formula gradient */ -#define C 40.0 /* blanking formula offset */ -#define K 128.0 /* blanking formula scaling factor */ -#define J 20.0 /* blanking formula scaling factor */ - -/* C' and M' are part of the Blanking Duty Cycle computation */ - -#define C_PRIME (((C - J) * K/256.0) + J) -#define M_PRIME (K/256.0 * M) - -DisplayModePtr -RADEONGetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins) -{ - float h_pixels_rnd; - float v_lines_rnd; - float v_field_rate_rqd; - float top_margin; - float bottom_margin; - float interlace; - float h_period_est; - float vsync_plus_bp; - float v_back_porch; - float total_v_lines; - float v_field_rate_est; - float h_period; - float v_field_rate; - float v_frame_rate; - float left_margin; - float right_margin; - float total_active_pixels; - float ideal_duty_cycle; - float h_blank; - float total_pixels; - float pixel_freq; - float h_freq; - - float h_sync; - float h_front_porch; - float v_odd_front_porch_lines; - DisplayModePtr m; - - m = xnfcalloc(sizeof(DisplayModeRec), 1); - - - /* 1. In order to give correct results, the number of horizontal - * pixels requested is first processed to ensure that it is divisible - * by the character size, by rounding it to the nearest character - * cell boundary: - * - * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND]) - */ - - h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN; - - - /* 2. If interlace is requested, the number of vertical lines assumed - * by the calculation must be halved, as the computation calculates - * the number of vertical lines per field. In either case, the - * number of lines is rounded to the nearest integer. - * - * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0), - * ROUND([V LINES],0)) - */ - - v_lines_rnd = interlaced ? - rint((float) v_lines) / 2.0 : - rint((float) v_lines); - - /* 3. Find the frame rate required: - * - * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2, - * [I/P FREQ RQD]) - */ - - v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq); - - /* 4. Find number of lines in Top margin: - * - * [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y", - * ROUND(([MARGIN%]/100*[V LINES RND]),0), - * 0) - */ - - top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0); - - /* 5. Find number of lines in Bottom margin: - * - * [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y", - * ROUND(([MARGIN%]/100*[V LINES RND]),0), - * 0) - */ - - bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0); - - /* 6. If interlace is required, then set variable [INTERLACE]=0.5: - * - * [INTERLACE]=(IF([INT RQD?]="y",0.5,0)) - */ - - interlace = interlaced ? 0.5 : 0.0; - - /* 7. Estimate the Horizontal period - * - * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) / - * ([V LINES RND] + (2*[TOP MARGIN (LINES)]) + - * [MIN PORCH RND]+[INTERLACE]) * 1000000 - */ - - h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0)) - / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace) - * 1000000.0); - - /* 8. Find the number of lines in V sync + back porch: - * - * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0) - */ - - vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est); - - /* 9. Find the number of lines in V back porch alone: - * - * [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND] - * - * XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]? - */ - - v_back_porch = vsync_plus_bp - V_SYNC_RQD; - - /* 10. Find the total number of lines in Vertical field period: - * - * [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] + - * [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] + - * [MIN PORCH RND] - */ - - total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp + - interlace + MIN_PORCH; - - /* 11. Estimate the Vertical field frequency: - * - * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000 - */ - - v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0; - - /* 12. Find the actual horizontal period: - * - * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST]) - */ - - h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est); - - /* 13. Find the actual Vertical field frequency: - * - * [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000 - */ - - v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0; - - /* 14. Find the Vertical frame frequency: - * - * [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE])) - */ - - v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate; - - /* 15. Find number of pixels in left margin: - * - * [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", - * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / - * [CELL GRAN RND]),0)) * [CELL GRAN RND], - * 0)) - */ - - left_margin = margins ? - rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : - 0.0; - - /* 16. Find number of pixels in right margin: - * - * [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", - * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / - * [CELL GRAN RND]),0)) * [CELL GRAN RND], - * 0)) - */ - - right_margin = margins ? - rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : - 0.0; - - /* 17. Find total number of active pixels in image and left and right - * margins: - * - * [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] + - * [RIGHT MARGIN (PIXELS)] - */ - - total_active_pixels = h_pixels_rnd + left_margin + right_margin; - - /* 18. Find the ideal blanking duty cycle from the blanking duty cycle - * equation: - * - * [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000) - */ - - ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0); - - /* 19. Find the number of pixels in the blanking time to the nearest - * double character cell: - * - * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] * - * [IDEAL DUTY CYCLE] / - * (100-[IDEAL DUTY CYCLE]) / - * (2*[CELL GRAN RND])), 0)) - * * (2*[CELL GRAN RND]) - */ - - h_blank = rint(total_active_pixels * - ideal_duty_cycle / - (100.0 - ideal_duty_cycle) / - (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN); - - /* 20. Find total number of pixels: - * - * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)] - */ - - total_pixels = total_active_pixels + h_blank; - - /* 21. Find pixel clock frequency: - * - * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD] - */ - - pixel_freq = total_pixels / h_period; - - /* 22. Find horizontal frequency: - * - * [H FREQ] = 1000 / [H PERIOD] - */ - - h_freq = 1000.0 / h_period; - - - /* Stage 1 computations are now complete; I should really pass - the results to another function and do the Stage 2 - computations, but I only need a few more values so I'll just - append the computations here for now */ - - - - /* 17. Find the number of pixels in the horizontal sync period: - * - * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] / - * [CELL GRAN RND]),0))*[CELL GRAN RND] - */ - - h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN; - - /* 18. Find the number of pixels in the horizontal front porch period: - * - * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)] - */ - - h_front_porch = (h_blank / 2.0) - h_sync; - - /* 36. Find the number of lines in the odd front porch period: - * - * [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE]) - */ - - v_odd_front_porch_lines = MIN_PORCH + interlace; - - /* finally, pack the results in the DisplayMode struct */ - - m->HDisplay = (int) (h_pixels_rnd); - m->HSyncStart = (int) (h_pixels_rnd + h_front_porch); - m->HSyncEnd = (int) (h_pixels_rnd + h_front_porch + h_sync); - m->HTotal = (int) (total_pixels); - - m->VDisplay = (int) (v_lines_rnd); - m->VSyncStart = (int) (v_lines_rnd + v_odd_front_porch_lines); - m->VSyncEnd = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD); - m->VTotal = (int) (total_v_lines); - - m->Clock = (int)(pixel_freq * 1000); - m->SynthClock = m->Clock; - m->HSync = h_freq; - m->VRefresh = v_frame_rate /* freq */; - - RADEONxf86SetModeDefaultName(m); - - return (m); -} - -void -RADEONPrintModes(ScrnInfoPtr scrp) -{ - DisplayModePtr p; - float hsync, refresh = 0; - char *desc, *desc2, *prefix, *uprefix; - - if (scrp == NULL) - return; - - xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d " - "(pitch %d)\n", scrp->virtualX, scrp->virtualY, - scrp->displayWidth); - - p = scrp->modes; - if (p == NULL) - return; - - do { - desc = desc2 = ""; - if (p->HSync > 0.0) - hsync = p->HSync; - else if (p->HTotal > 0) - hsync = (float)p->Clock / (float)p->HTotal; - else - hsync = 0.0; - if (p->VTotal > 0) - refresh = hsync * 1000.0 / p->VTotal; - if (p->Flags & V_INTERLACE) { - refresh *= 2.0; - desc = " (I)"; - } - if (p->Flags & V_DBLSCAN) { - refresh /= 2.0; - desc = " (D)"; - } - if (p->VScan > 1) { - refresh /= p->VScan; - desc2 = " (VScan)"; - } - if (p->VRefresh > 0.0) - refresh = p->VRefresh; - if (p->type & M_T_BUILTIN) - prefix = "Built-in mode"; - else if (p->type & M_T_DEFAULT) - prefix = "Default mode"; - else - prefix = "Mode"; - if (p->type & M_T_USERDEF) - uprefix = "*"; - else - uprefix = " "; - if (p->name) - xf86DrvMsg(scrp->scrnIndex, X_CONFIG, - "%s%s \"%s\"\n", uprefix, prefix, p->name); - else - xf86DrvMsg(scrp->scrnIndex, X_PROBED, - "%s%s %dx%d (unnamed)\n", - uprefix, prefix, p->HDisplay, p->VDisplay); - p = p->next; - } while (p != NULL && p != scrp->modes); -} - -/* This function will sort all modes according to their resolution. - * Highest resolution first. - */ -void -RADEONxf86SortModes(DisplayModePtr new, DisplayModePtr *first, - DisplayModePtr *last) -{ - DisplayModePtr p; - - p = *last; - while (p) { - if (((new->HDisplay < p->HDisplay) && - (new->VDisplay < p->VDisplay)) || - ((new->HDisplay * new->VDisplay) < (p->HDisplay * p->VDisplay)) || - ((new->HDisplay == p->HDisplay) && - (new->VDisplay == p->VDisplay) && - (new->Clock < p->Clock))) { - - if (p->next) - p->next->prev = new; - new->prev = p; - new->next = p->next; - p->next = new; - if (!(new->next)) - *last = new; - break; - } - if (!p->prev) { - new->prev = NULL; - new->next = p; - p->prev = new; - *first = new; - break; - } - p = p->prev; - } - - if (!*first) { - *first = new; - new->prev = NULL; - new->next = NULL; - *last = new; - } -} - -DisplayModePtr -RADEONGetModeListTail(DisplayModePtr pModeList) -{ - DisplayModePtr last; - - if (pModeList == NULL) - return NULL; - - for (last = pModeList; last->next != NULL; last = last->next) - ; - - return last; -} +extern XF86ConfigPtr xf86configptr; /** * @file this file contains symbols from xf86Mode.c and friends that are static * there but we still want to use. We need to come up with better API here. */ - +#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) /** * Calculates the horizontal sync rate of a mode. * * Exact copy of xf86Mode.c's. */ double -RADEONxf86ModeHSync(DisplayModePtr mode) +xf86ModeHSync(DisplayModePtr mode) { double hsync = 0.0; @@ -498,7 +73,7 @@ RADEONxf86ModeHSync(DisplayModePtr mode) * Exact copy of xf86Mode.c's. */ double -RADEONxf86ModeVRefresh(DisplayModePtr mode) +xf86ModeVRefresh(DisplayModePtr mode) { double refresh = 0.0; @@ -516,14 +91,9 @@ RADEONxf86ModeVRefresh(DisplayModePtr mode) return refresh; } -/** - * Sets a default mode name of <width>x<height>x<refresh> on a mode. - * - * The refresh rate doesn't contain decimals, as that's expected to be - * unimportant from the user's perspective for non-custom modelines. - */ +/** Sets a default mode name of <width>x<height> on a mode. */ void -RADEONxf86SetModeDefaultName(DisplayModePtr mode) +xf86SetModeDefaultName(DisplayModePtr mode) { if (mode->name != NULL) xfree(mode->name); @@ -532,7 +102,7 @@ RADEONxf86SetModeDefaultName(DisplayModePtr mode) } /* - * RADEONxf86SetModeCrtc + * xf86SetModeCrtc * * Initialises the Crtc parameters for a mode. The initialisation includes * adjustments for interlaced and double scan modes. @@ -540,7 +110,7 @@ RADEONxf86SetModeDefaultName(DisplayModePtr mode) * Exact copy of xf86Mode.c's. */ void -RADEONxf86SetModeCrtc(DisplayModePtr p, int adjustFlags) +xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) { if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN)) return; @@ -625,7 +195,7 @@ RADEONxf86SetModeCrtc(DisplayModePtr p, int adjustFlags) * Allocates and returns a copy of pMode, including pointers within pMode. */ DisplayModePtr -RADEONxf86DuplicateMode(DisplayModePtr pMode) +xf86DuplicateMode(DisplayModePtr pMode) { DisplayModePtr pNew; @@ -634,7 +204,7 @@ RADEONxf86DuplicateMode(DisplayModePtr pMode) pNew->next = NULL; pNew->prev = NULL; if (pNew->name == NULL) { - RADEONxf86SetModeDefaultName(pMode); + xf86SetModeDefaultName(pMode); } else { pNew->name = xnfstrdup(pMode->name); } @@ -649,7 +219,7 @@ RADEONxf86DuplicateMode(DisplayModePtr pMode) * \param modeList doubly-linked mode list */ DisplayModePtr -RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) +xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) { DisplayModePtr first = NULL, last = NULL; DisplayModePtr mode; @@ -657,7 +227,7 @@ RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) for (mode = modeList; mode != NULL; mode = mode->next) { DisplayModePtr new; - new = RADEONxf86DuplicateMode(mode); + new = xf86DuplicateMode(mode); /* Insert pNew into modeList */ if (last) { @@ -683,7 +253,7 @@ RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) * This isn't in xf86Modes.c, but it might deserve to be there. */ Bool -RADEONModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2) +xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2) { if (pMode1->Clock == pMode2->Clock && pMode1->HDisplay == pMode2->HDisplay && @@ -719,7 +289,7 @@ add(char **p, char *new) * Convenient VRefresh printing was added, though, compared to xf86Mode.c */ void -PrintModeline(int scrnIndex,DisplayModePtr mode) +xf86PrintModeline(int scrnIndex,DisplayModePtr mode) { char tmp[256]; char *flags = xnfcalloc(1, 1); @@ -751,9 +321,10 @@ PrintModeline(int scrnIndex,DisplayModePtr mode) mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal, mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, - mode->VTotal, flags, RADEONxf86ModeHSync(mode)); + mode->VTotal, flags, xf86ModeHSync(mode)); xfree(flags); } +#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */ /** * Marks as bad any modes with unsupported flags. @@ -827,8 +398,8 @@ RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, bad = TRUE; for (i = 0; i < mon->nHsync; i++) { - if (RADEONxf86ModeHSync(mode) >= mon->hsync[i].lo && - RADEONxf86ModeHSync(mode) <= mon->hsync[i].hi) + if (xf86ModeHSync(mode) >= mon->hsync[i].lo && + xf86ModeHSync(mode) <= mon->hsync[i].hi) { bad = FALSE; } @@ -838,8 +409,8 @@ RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList, bad = TRUE; for (i = 0; i < mon->nVrefresh; i++) { - if (RADEONxf86ModeVRefresh(mode) >= mon->vrefresh[i].lo && - RADEONxf86ModeVRefresh(mode) <= mon->vrefresh[i].hi) + if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo && + xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi) { bad = FALSE; } @@ -959,3 +530,144 @@ RADEONxf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList, } } +/** + * Adds the new mode into the mode list, and returns the new list + * + * \param modes doubly-linked mode list. + */ +DisplayModePtr +xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new) +{ + if (modes == NULL) + return new; + + if (new) { + DisplayModePtr mode = modes; + + while (mode->next) + mode = mode->next; + + mode->next = new; + new->prev = mode; + } + + return modes; +} + +/** + * Build a mode list from a list of config file modes + */ +static DisplayModePtr +RADEONxf86GetConfigModes (XF86ConfModeLinePtr conf_mode) +{ + DisplayModePtr head = NULL, prev = NULL, mode; + + for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next) + { + mode = xalloc(sizeof(DisplayModeRec)); + if (!mode) + continue; + mode->name = xstrdup(conf_mode->ml_identifier); + if (!mode->name) + { + xfree (mode); + continue; + } + + memset(mode,'\0',sizeof(DisplayModeRec)); + mode->type = 0; + mode->Clock = conf_mode->ml_clock; + mode->HDisplay = conf_mode->ml_hdisplay; + mode->HSyncStart = conf_mode->ml_hsyncstart; + mode->HSyncEnd = conf_mode->ml_hsyncend; + mode->HTotal = conf_mode->ml_htotal; + mode->VDisplay = conf_mode->ml_vdisplay; + mode->VSyncStart = conf_mode->ml_vsyncstart; + mode->VSyncEnd = conf_mode->ml_vsyncend; + mode->VTotal = conf_mode->ml_vtotal; + mode->Flags = conf_mode->ml_flags; + mode->HSkew = conf_mode->ml_hskew; + mode->VScan = conf_mode->ml_vscan; + + mode->prev = prev; + mode->next = NULL; + if (prev) + prev->next = mode; + else + head = mode; + prev = mode; + } + return head; +} + + +/** + * Build a mode list from a monitor configuration + */ +DisplayModePtr +RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) +{ + DisplayModePtr modes = NULL; + XF86ConfModesLinkPtr modes_link; + + if (!conf_monitor) + return NULL; + + /* + * first we collect the mode lines from the UseModes directive + */ + for (modes_link = conf_monitor->mon_modes_sect_lst; + modes_link; + modes_link = modes_link->list.next) + { + /* If this modes link hasn't been resolved, go look it up now */ + if (!modes_link->ml_modes) + modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str, + xf86configptr->conf_modes_lst); + if (modes_link->ml_modes) + modes = xf86ModesAdd (modes, + RADEONxf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst)); + } + + return xf86ModesAdd (modes, + RADEONxf86GetConfigModes (conf_monitor->mon_modeline_lst)); +} + +/** + * Build a mode list containing all of the default modes + */ +DisplayModePtr +RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed) +{ + DisplayModePtr head = NULL, prev = NULL, mode; + int i; + + for (i = 0; xf86DefaultModes[i].name != NULL; i++) + { + DisplayModePtr defMode = &xf86DefaultModes[i]; + + if (!interlaceAllowed && (defMode->Flags & V_INTERLACE)) + continue; + if (!doubleScanAllowed && (defMode->Flags & V_DBLSCAN)) + continue; + + mode = xalloc(sizeof(DisplayModeRec)); + if (!mode) + continue; + memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec)); + mode->name = xstrdup(xf86DefaultModes[i].name); + if (!mode->name) + { + xfree (mode); + continue; + } + mode->prev = prev; + mode->next = NULL; + if (prev) + prev->next = mode; + else + head = mode; + prev = mode; + } + return head; +} diff --git a/src/radeon_xf86Modes.h b/src/radeon_xf86Modes.h index ddf3be82..8e23997a 100644 --- a/src/radeon_xf86Modes.h +++ b/src/radeon_xf86Modes.h @@ -25,26 +25,39 @@ * */ -double -RADEONxf86ModeHSync(DisplayModePtr mode); - -double -RADEONxf86ModeVRefresh(DisplayModePtr mode); - -DisplayModePtr -RADEONxf86DuplicateMode(DisplayModePtr pMode); - -DisplayModePtr -RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList); - -void -RADEONxf86SetModeDefaultName(DisplayModePtr mode); - -void -RADEONxf86SetModeCrtc(DisplayModePtr p, int adjustFlags); - -Bool -RADEONModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); +#ifndef _RADEON_XF86MODES_H_ +#define _RADEON_XF86MODES_H_ +#include "xorgVersion.h" +#include "xf86Parser.h" + +#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) +double RADEON_xf86ModeHSync(DisplayModePtr mode); +double RADEON_xf86ModeVRefresh(DisplayModePtr mode); +DisplayModePtr RADEON_xf86DuplicateMode(DisplayModePtr pMode); +DisplayModePtr RADEON_xf86DuplicateModes(ScrnInfoPtr pScrn, + DisplayModePtr modeList); +void RADEON_xf86SetModeDefaultName(DisplayModePtr mode); +void RADEON_xf86SetModeCrtc(DisplayModePtr p, int adjustFlags); +Bool RADEON_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); +void RADEON_xf86PrintModeline(int scrnIndex,DisplayModePtr mode); +DisplayModePtr RADEON_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new); + +DisplayModePtr RADEON_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); +DisplayModePtr RADEON_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, + Bool Reduced, Bool Interlaced); + +#define xf86ModeHSync RADEON_xf86ModeHSync +#define xf86ModeVRefresh RADEON_xf86ModeVRefresh +#define xf86DuplicateMode RADEON_xf86DuplicateMode +#define xf86DuplicateModes RADEON_xf86DuplicateModes +#define xf86SetModeDefaultName RADEON_xf86SetModeDefaultName +#define xf86SetModeCrtc RADEON_xf86SetModeCrtc +#define xf86ModesEqual RADEON_xf86ModesEqual +#define xf86PrintModeline RADEON_xf86PrintModeline +#define xf86ModesAdd RADEON_xf86ModesAdd +#define xf86DDCGetModes RADEON_xf86DDCGetModes +#define xf86CVTMode RADEON_xf86CVTMode +#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */ void RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, @@ -73,26 +86,10 @@ RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, void RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList); -void -PrintModeline(int scrnIndex,DisplayModePtr mode); - -extern DisplayModeRec RADEONxf86DefaultModes[]; - -void -RADEONPrintModes(ScrnInfoPtr scrp); - DisplayModePtr -RADEONGetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins); - -void -RADEONxf86SortModes(DisplayModePtr new, DisplayModePtr *first, - DisplayModePtr *last); +RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor); DisplayModePtr -RADEONGetVESAEstablishedMode(ScrnInfoPtr pScrn, int i); +RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed); -DisplayModePtr -RADEONGetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc); - -DisplayModePtr -RADEONGetModeListTail(DisplayModePtr pModeList); +#endif diff --git a/src/xf86Optrec.h b/src/xf86Optrec.h new file mode 100644 index 00000000..183b8572 --- /dev/null +++ b/src/xf86Optrec.h @@ -0,0 +1,112 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2001 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* + * This file contains the Option Record that is passed between the Parser, + * and Module setup procs. + */ +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#ifndef _xf86Optrec_h_ +#define _xf86Optrec_h_ +#include <stdio.h> + +/* + * all records that need to be linked lists should contain a GenericList as + * their first field. + */ +typedef struct generic_list_rec +{ + void *next; +} +GenericListRec, *GenericListPtr, *glp; + +/* + * All options are stored using this data type. + */ +typedef struct +{ + GenericListRec list; + char *opt_name; + char *opt_val; + int opt_used; + char *opt_comment; +} +XF86OptionRec, *XF86OptionPtr; + + +XF86OptionPtr xf86addNewOption(XF86OptionPtr head, char *name, char *val); +XF86OptionPtr xf86optionListDup(XF86OptionPtr opt); +void xf86optionListFree(XF86OptionPtr opt); +char *xf86optionName(XF86OptionPtr opt); +char *xf86optionValue(XF86OptionPtr opt); +XF86OptionPtr xf86newOption(char *name, char *value); +XF86OptionPtr xf86nextOption(XF86OptionPtr list); +XF86OptionPtr xf86findOption(XF86OptionPtr list, const char *name); +char *xf86findOptionValue(XF86OptionPtr list, const char *name); +int xf86findOptionBoolean (XF86OptionPtr, const char *, int); +XF86OptionPtr xf86optionListCreate(const char **options, int count, int used); +XF86OptionPtr xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail); +char *xf86configStrdup (const char *s); +int xf86nameCompare (const char *s1, const char *s2); +char *xf86uLongToString(unsigned long i); +void xf86debugListOptions(XF86OptionPtr); +XF86OptionPtr xf86parseOption(XF86OptionPtr head); +void xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs); + + +#endif /* _xf86Optrec_h_ */ diff --git a/src/xf86Parser.h b/src/xf86Parser.h new file mode 100644 index 00000000..a6829273 --- /dev/null +++ b/src/xf86Parser.h @@ -0,0 +1,483 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* + * This file contains the external interfaces for the XFree86 configuration + * file parser. + */ +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#ifndef _xf86Parser_h_ +#define _xf86Parser_h_ + +#include "xf86Optrec.h" + +#define HAVE_PARSER_DECLS + +typedef struct +{ + char *file_logfile; + char *file_rgbpath; + char *file_modulepath; + char *file_inputdevs; + char *file_fontpath; + char *file_comment; +} +XF86ConfFilesRec, *XF86ConfFilesPtr; + +/* Values for load_type */ +#define XF86_LOAD_MODULE 0 +#define XF86_LOAD_DRIVER 1 + +typedef struct +{ + GenericListRec list; + int load_type; + char *load_name; + XF86OptionPtr load_opt; + char *load_comment; + int ignore; +} +XF86LoadRec, *XF86LoadPtr; + +typedef struct +{ + XF86LoadPtr mod_load_lst; + char *mod_comment; +} +XF86ConfModuleRec, *XF86ConfModulePtr; + +#define CONF_IMPLICIT_KEYBOARD "Implicit Core Keyboard" + +#define CONF_IMPLICIT_POINTER "Implicit Core Pointer" + +#define XF86CONF_PHSYNC 0x0001 +#define XF86CONF_NHSYNC 0x0002 +#define XF86CONF_PVSYNC 0x0004 +#define XF86CONF_NVSYNC 0x0008 +#define XF86CONF_INTERLACE 0x0010 +#define XF86CONF_DBLSCAN 0x0020 +#define XF86CONF_CSYNC 0x0040 +#define XF86CONF_PCSYNC 0x0080 +#define XF86CONF_NCSYNC 0x0100 +#define XF86CONF_HSKEW 0x0200 /* hskew provided */ +#define XF86CONF_BCAST 0x0400 +#define XF86CONF_CUSTOM 0x0800 /* timing numbers customized by editor */ +#define XF86CONF_VSCAN 0x1000 + +typedef struct +{ + GenericListRec list; + char *ml_identifier; + int ml_clock; + int ml_hdisplay; + int ml_hsyncstart; + int ml_hsyncend; + int ml_htotal; + int ml_vdisplay; + int ml_vsyncstart; + int ml_vsyncend; + int ml_vtotal; + int ml_vscan; + int ml_flags; + int ml_hskew; + char *ml_comment; +} +XF86ConfModeLineRec, *XF86ConfModeLinePtr; + +typedef struct +{ + GenericListRec list; + char *vp_identifier; + XF86OptionPtr vp_option_lst; + char *vp_comment; +} +XF86ConfVideoPortRec, *XF86ConfVideoPortPtr; + +typedef struct +{ + GenericListRec list; + char *va_identifier; + char *va_vendor; + char *va_board; + char *va_busid; + char *va_driver; + XF86OptionPtr va_option_lst; + XF86ConfVideoPortPtr va_port_lst; + char *va_fwdref; + char *va_comment; +} +XF86ConfVideoAdaptorRec, *XF86ConfVideoAdaptorPtr; + +#define CONF_MAX_HSYNC 8 +#define CONF_MAX_VREFRESH 8 + +typedef struct +{ + float hi, lo; +} +parser_range; + +typedef struct +{ + int red, green, blue; +} +parser_rgb; + +typedef struct +{ + GenericListRec list; + char *modes_identifier; + XF86ConfModeLinePtr mon_modeline_lst; + char *modes_comment; +} +XF86ConfModesRec, *XF86ConfModesPtr; + +typedef struct +{ + GenericListRec list; + char *ml_modes_str; + XF86ConfModesPtr ml_modes; +} +XF86ConfModesLinkRec, *XF86ConfModesLinkPtr; + +typedef struct +{ + GenericListRec list; + char *mon_identifier; + char *mon_vendor; + char *mon_modelname; + int mon_width; /* in mm */ + int mon_height; /* in mm */ + XF86ConfModeLinePtr mon_modeline_lst; + int mon_n_hsync; + parser_range mon_hsync[CONF_MAX_HSYNC]; + int mon_n_vrefresh; + parser_range mon_vrefresh[CONF_MAX_VREFRESH]; + float mon_gamma_red; + float mon_gamma_green; + float mon_gamma_blue; + XF86OptionPtr mon_option_lst; + XF86ConfModesLinkPtr mon_modes_sect_lst; + char *mon_comment; +} +XF86ConfMonitorRec, *XF86ConfMonitorPtr; + +#define CONF_MAXDACSPEEDS 4 +#define CONF_MAXCLOCKS 128 + +typedef struct +{ + GenericListRec list; + char *dev_identifier; + char *dev_vendor; + char *dev_board; + char *dev_chipset; + char *dev_busid; + char *dev_card; + char *dev_driver; + char *dev_ramdac; + int dev_dacSpeeds[CONF_MAXDACSPEEDS]; + int dev_videoram; + int dev_textclockfreq; + unsigned long dev_bios_base; + unsigned long dev_mem_base; + unsigned long dev_io_base; + char *dev_clockchip; + int dev_clocks; + int dev_clock[CONF_MAXCLOCKS]; + int dev_chipid; + int dev_chiprev; + int dev_irq; + int dev_screen; + XF86OptionPtr dev_option_lst; + char *dev_comment; +} +XF86ConfDeviceRec, *XF86ConfDevicePtr; + +typedef struct +{ + GenericListRec list; + char *mode_name; +} +XF86ModeRec, *XF86ModePtr; + +typedef struct +{ + GenericListRec list; + int disp_frameX0; + int disp_frameY0; + int disp_virtualX; + int disp_virtualY; + int disp_depth; + int disp_bpp; + char *disp_visual; + parser_rgb disp_weight; + parser_rgb disp_black; + parser_rgb disp_white; + XF86ModePtr disp_mode_lst; + XF86OptionPtr disp_option_lst; + char *disp_comment; +} +XF86ConfDisplayRec, *XF86ConfDisplayPtr; + +typedef struct +{ + XF86OptionPtr flg_option_lst; + char *flg_comment; +} +XF86ConfFlagsRec, *XF86ConfFlagsPtr; + +typedef struct +{ + GenericListRec list; + char *al_adaptor_str; + XF86ConfVideoAdaptorPtr al_adaptor; +} +XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr; + +typedef struct +{ + GenericListRec list; + char *scrn_identifier; + char *scrn_obso_driver; + int scrn_defaultdepth; + int scrn_defaultbpp; + int scrn_defaultfbbpp; + char *scrn_monitor_str; + XF86ConfMonitorPtr scrn_monitor; + char *scrn_device_str; + XF86ConfDevicePtr scrn_device; + XF86ConfAdaptorLinkPtr scrn_adaptor_lst; + XF86ConfDisplayPtr scrn_display_lst; + XF86OptionPtr scrn_option_lst; + char *scrn_comment; +} +XF86ConfScreenRec, *XF86ConfScreenPtr; + +typedef struct +{ + GenericListRec list; + char *inp_identifier; + char *inp_driver; + XF86OptionPtr inp_option_lst; + char *inp_comment; +} +XF86ConfInputRec, *XF86ConfInputPtr; + +typedef struct +{ + GenericListRec list; + XF86ConfInputPtr iref_inputdev; + char *iref_inputdev_str; + XF86OptionPtr iref_option_lst; +} +XF86ConfInputrefRec, *XF86ConfInputrefPtr; + +/* Values for adj_where */ +#define CONF_ADJ_OBSOLETE -1 +#define CONF_ADJ_ABSOLUTE 0 +#define CONF_ADJ_RIGHTOF 1 +#define CONF_ADJ_LEFTOF 2 +#define CONF_ADJ_ABOVE 3 +#define CONF_ADJ_BELOW 4 +#define CONF_ADJ_RELATIVE 5 + +typedef struct +{ + GenericListRec list; + int adj_scrnum; + XF86ConfScreenPtr adj_screen; + char *adj_screen_str; + XF86ConfScreenPtr adj_top; + char *adj_top_str; + XF86ConfScreenPtr adj_bottom; + char *adj_bottom_str; + XF86ConfScreenPtr adj_left; + char *adj_left_str; + XF86ConfScreenPtr adj_right; + char *adj_right_str; + int adj_where; + int adj_x; + int adj_y; + char *adj_refscreen; +} +XF86ConfAdjacencyRec, *XF86ConfAdjacencyPtr; + +typedef struct +{ + GenericListRec list; + char *inactive_device_str; + XF86ConfDevicePtr inactive_device; +} +XF86ConfInactiveRec, *XF86ConfInactivePtr; + +typedef struct +{ + GenericListRec list; + char *lay_identifier; + XF86ConfAdjacencyPtr lay_adjacency_lst; + XF86ConfInactivePtr lay_inactive_lst; + XF86ConfInputrefPtr lay_input_lst; + XF86OptionPtr lay_option_lst; + char *lay_comment; +} +XF86ConfLayoutRec, *XF86ConfLayoutPtr; + +typedef struct +{ + GenericListRec list; + char *vs_name; + char *vs_identifier; + XF86OptionPtr vs_option_lst; + char *vs_comment; +} +XF86ConfVendSubRec, *XF86ConfVendSubPtr; + +typedef struct +{ + GenericListRec list; + char *vnd_identifier; + XF86OptionPtr vnd_option_lst; + XF86ConfVendSubPtr vnd_sub_lst; + char *vnd_comment; +} +XF86ConfVendorRec, *XF86ConfVendorPtr; + +typedef struct +{ + GenericListRec list; + int buf_count; + int buf_size; + char *buf_flags; + char *buf_comment; +} +XF86ConfBuffersRec, *XF86ConfBuffersPtr; + +typedef struct +{ + char *dri_group_name; + int dri_group; + int dri_mode; + XF86ConfBuffersPtr dri_buffers_lst; + char *dri_comment; +} +XF86ConfDRIRec, *XF86ConfDRIPtr; + +typedef struct +{ + XF86OptionPtr ext_option_lst; + char *extensions_comment; +} +XF86ConfExtensionsRec, *XF86ConfExtensionsPtr; + +typedef struct +{ + XF86ConfFilesPtr conf_files; + XF86ConfModulePtr conf_modules; + XF86ConfFlagsPtr conf_flags; + XF86ConfVideoAdaptorPtr conf_videoadaptor_lst; + XF86ConfModesPtr conf_modes_lst; + XF86ConfMonitorPtr conf_monitor_lst; + XF86ConfDevicePtr conf_device_lst; + XF86ConfScreenPtr conf_screen_lst; + XF86ConfInputPtr conf_input_lst; + XF86ConfLayoutPtr conf_layout_lst; + XF86ConfVendorPtr conf_vendor_lst; + XF86ConfDRIPtr conf_dri; + XF86ConfExtensionsPtr conf_extensions; + char *conf_comment; +} +XF86ConfigRec, *XF86ConfigPtr; + +typedef struct +{ + int token; /* id of the token */ + char *name; /* pointer to the LOWERCASED name */ +} +xf86ConfigSymTabRec, *xf86ConfigSymTabPtr; + +/* + * prototypes for public functions + */ +extern const char *xf86openConfigFile (const char *, const char *, + const char *); +extern void xf86setBuiltinConfig(const char *config[]); +extern XF86ConfigPtr xf86readConfigFile (void); +extern void xf86closeConfigFile (void); +extern void xf86freeConfig (XF86ConfigPtr p); +extern int xf86writeConfigFile (const char *, XF86ConfigPtr); +XF86ConfDevicePtr xf86findDevice(const char *ident, XF86ConfDevicePtr p); +XF86ConfLayoutPtr xf86findLayout(const char *name, XF86ConfLayoutPtr list); +XF86ConfMonitorPtr xf86findMonitor(const char *ident, XF86ConfMonitorPtr p); +XF86ConfModesPtr xf86findModes(const char *ident, XF86ConfModesPtr p); +XF86ConfModeLinePtr xf86findModeLine(const char *ident, XF86ConfModeLinePtr p); +XF86ConfScreenPtr xf86findScreen(const char *ident, XF86ConfScreenPtr p); +XF86ConfInputPtr xf86findInput(const char *ident, XF86ConfInputPtr p); +XF86ConfInputPtr xf86findInputByDriver(const char *driver, XF86ConfInputPtr p); +XF86ConfVendorPtr xf86findVendor(const char *name, XF86ConfVendorPtr list); +XF86ConfVideoAdaptorPtr xf86findVideoAdaptor(const char *ident, + XF86ConfVideoAdaptorPtr p); + +GenericListPtr xf86addListItem(GenericListPtr head, GenericListPtr c_new); +int xf86itemNotSublist(GenericListPtr list_1, GenericListPtr list_2); + +int xf86pathIsAbsolute(const char *path); +int xf86pathIsSafe(const char *path); +char *xf86addComment(char *cur, char *add); + +#endif /* _xf86Parser_h_ */ |