diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 458750007..57284c151 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -414,6 +414,14 @@ void xf86PruneDriverModes(ScrnInfoPtr scrp); void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags); void xf86PrintModes(ScrnInfoPtr scrp); void xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges); +double xf86ModeHSync(DisplayModePtr mode); +double xf86ModeVRefresh(DisplayModePtr mode); +void xf86SetModeDefaultName(DisplayModePtr mode); +void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags); +DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode); +DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList); +Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); +void xf86PrintModeline(int scrnIndex,DisplayModePtr mode); /* xf86Option.c */ diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c index cd57e9916..6dccf2493 100644 --- a/hw/xfree86/common/xf86Mode.c +++ b/hw/xfree86/common/xf86Mode.c @@ -366,8 +366,9 @@ xf86HandleBuiltinMode(ScrnInfoPtr scrp, return MODE_OK; } -static double -ModeHSync(DisplayModePtr mode) +/** Calculates the horizontal sync rate of a mode */ +_X_EXPORT double +xf86ModeHSync(DisplayModePtr mode) { double hsync = 0.0; @@ -379,8 +380,9 @@ ModeHSync(DisplayModePtr mode) return hsync; } -static double -ModeVRefresh(DisplayModePtr mode) +/** Calculates the vertical refresh rate of a mode */ +_X_EXPORT double +xf86ModeVRefresh(DisplayModePtr mode) { double refresh = 0.0; @@ -398,6 +400,16 @@ ModeVRefresh(DisplayModePtr mode) return refresh; } +/** Sets a default mode name of x on a mode. */ +_X_EXPORT void +xf86SetModeDefaultName(DisplayModePtr mode) +{ + if (mode->name != NULL) + xfree(mode->name); + + mode->name = XNFprintf("%dx%d", mode->HDisplay, mode->VDisplay); +} + /* * xf86LookupMode * @@ -522,7 +534,7 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, ModePrivFlags = cp->PrivFlags; break; } - refresh = ModeVRefresh(p); + refresh = xf86ModeVRefresh(p); if (p->Flags & V_INTERLACE) refresh /= INTERLACE_REFRESH_WEIGHT; if (refresh > bestRefresh) { @@ -561,7 +573,7 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, found = TRUE; if (strategy == LOOKUP_BEST_REFRESH) { - refresh = ModeVRefresh(p); + refresh = xf86ModeVRefresh(p); if (p->Flags & V_INTERLACE) refresh /= INTERLACE_REFRESH_WEIGHT; if (refresh > bestRefresh) { @@ -662,7 +674,7 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, * Initialises the Crtc parameters for a mode. The initialisation includes * adjustments for interlaced and double scan modes. */ -static void +_X_EXPORT void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) { if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN)) @@ -744,6 +756,87 @@ xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) } } +/** + * Allocates and returns a copy of pMode, including pointers within pMode. + */ +_X_EXPORT DisplayModePtr +xf86DuplicateMode(DisplayModePtr pMode) +{ + DisplayModePtr pNew; + + pNew = xnfalloc(sizeof(DisplayModeRec)); + *pNew = *pMode; + pNew->next = NULL; + pNew->prev = NULL; + if (pNew->name == NULL) { + xf86SetModeDefaultName(pMode); + } else { + pNew->name = xnfstrdup(pMode->name); + } + + return pNew; +} + +/** + * Duplicates every mode in the given list and returns a pointer to the first + * mode. + * + * \param modeList doubly-linked mode list + */ +_X_EXPORT DisplayModePtr +xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) +{ + DisplayModePtr first = NULL, last = NULL; + DisplayModePtr mode; + + for (mode = modeList; mode != NULL; mode = mode->next) { + DisplayModePtr new; + + new = xf86DuplicateMode(mode); + + /* Insert pNew into modeList */ + if (last) { + last->next = new; + new->prev = last; + } else { + first = new; + new->prev = NULL; + } + new->next = NULL; + last = new; + } + + return first; +} + +/** + * Returns true if the given modes should program to the same timings. + * + * This doesn't use Crtc values, as it might be used on ModeRecs without the + * Crtc values set. So, it's assumed that the other numbers are enough. + */ +_X_EXPORT Bool +xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2) +{ + if (pMode1->Clock == pMode2->Clock && + pMode1->HDisplay == pMode2->HDisplay && + pMode1->HSyncStart == pMode2->HSyncStart && + pMode1->HSyncEnd == pMode2->HSyncEnd && + pMode1->HTotal == pMode2->HTotal && + pMode1->HSkew == pMode2->HSkew && + pMode1->VDisplay == pMode2->VDisplay && + pMode1->VSyncStart == pMode2->VSyncStart && + pMode1->VSyncEnd == pMode2->VSyncEnd && + pMode1->VTotal == pMode2->VTotal && + pMode1->VScan == pMode2->VScan && + pMode1->Flags == pMode2->Flags) + { + return TRUE; + } else { + return FALSE; + } +} + /* * xf86CheckModeForMonitor * @@ -802,7 +895,7 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) if (monitor->nHsync > 0) { /* Check hsync against the allowed ranges */ - float hsync = ModeHSync(mode); + float hsync = xf86ModeHSync(mode); for (i = 0; i < monitor->nHsync; i++) if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) && (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE))) @@ -815,7 +908,7 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) if (monitor->nVrefresh > 0) { /* Check vrefresh against the allowed ranges */ - float vrefrsh = ModeVRefresh(mode); + float vrefrsh = xf86ModeVRefresh(mode); for (i = 0; i < monitor->nVrefresh; i++) if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) && (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE))) @@ -1043,8 +1136,8 @@ xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, / (mode->CrtcHTotal * mode->CrtcVTotal); } - mode->HSync = ModeHSync(mode); - mode->VRefresh = ModeVRefresh(mode); + mode->HSync = xf86ModeHSync(mode); + mode->VRefresh = xf86ModeVRefresh(mode); /* Assume it is OK */ return MODE_OK; @@ -1683,7 +1776,7 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, "TargetRefresh", 0.0); if (targetRefresh > 0.0) { for (p = scrp->modePool; p != NULL; p = p->next) { - if (ModeVRefresh(p) > targetRefresh * (1.0 - SYNC_TOLERANCE)) + if (xf86ModeVRefresh(p) > targetRefresh * (1.0 - SYNC_TOLERANCE)) break; } if (!p) @@ -1772,7 +1865,7 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, * If there is a target refresh rate, skip modes that * don't match up. */ - if (ModeVRefresh(q) < + if (xf86ModeVRefresh(q) < (1.0 - SYNC_TOLERANCE) * targetRefresh) continue; @@ -2068,8 +2161,8 @@ add(char **p, char *new) strcat(*p, new); } -static void -PrintModeline(int scrnIndex,DisplayModePtr mode) +_X_EXPORT void +xf86PrintModeline(int scrnIndex,DisplayModePtr mode) { char tmp[256]; char *flags = xnfcalloc(1, 1); @@ -2124,8 +2217,8 @@ xf86PrintModes(ScrnInfoPtr scrp) do { desc = desc2 = ""; - hsync = ModeHSync(p); - refresh = ModeVRefresh(p); + hsync = xf86ModeHSync(p); + refresh = xf86ModeVRefresh(p); if (p->Flags & V_INTERLACE) { desc = " (I)"; } @@ -2166,7 +2259,7 @@ xf86PrintModes(ScrnInfoPtr scrp) p->SynthClock / 1000.0, hsync, refresh, desc, desc2); } if (hsync != 0 && refresh != 0) - PrintModeline(scrp->scrnIndex,p); + xf86PrintModeline(scrp->scrnIndex,p); p = p->next; } while (p != NULL && p != scrp->modes); }