diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Config.c | 29 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Mode.c | 15 | ||||
-rw-r--r-- | hw/xfree86/common/xf86str.h | 2 | ||||
-rw-r--r-- | hw/xfree86/utils/Makefile.am | 1 | ||||
-rw-r--r-- | hw/xfree86/utils/cvt/Makefile.am | 44 | ||||
-rw-r--r-- | hw/xfree86/utils/cvt/cvt.c | 532 | ||||
-rw-r--r-- | hw/xfree86/utils/cvt/cvt.man.pre | 41 |
9 files changed, 681 insertions, 7 deletions
@@ -1,3 +1,26 @@ +2005-12-28 Luc Verhaegen <libv@skynet.be> + + * configure.ac: + * hw/xfree86/common/xf86Config.c: (GenerateDriverlist), + (configMonitor), (configExtensions), (xf86HandleConfigFile): + * hw/xfree86/common/xf86Mode.c: (xf86ModeStatusToString), + (xf86CheckModeForMonitor): + * hw/xfree86/common/xf86str.h: + * hw/xfree86/utils/Makefile.am: + * hw/xfree86/utils/cvt/Makefile.am: + * hw/xfree86/utils/cvt/cvt.c: (add), (PrintModeline), + (xf86CVTMode), (xf86CVTCheckStandard), (PrintUsage), + (PrintComment), (main): + * hw/xfree86/utils/cvt/cvt.man.pre: + Bug #5153: standalone CVT modeline generator. + - add hw/xfree86/utils/cvt/, cvt.c, cvt.man.pre and Makefile.am. + - Adjust configure.ac and hw/xfree86/utils/Makefile.am for cvt. + - Add MonPtr->reducedblanking and Option "ReducedBlanking" to the + Monitor section. + - Check for reduced blanking in xf86CheckModeForMonitor and disallow + modes with less than 25% blanking otherwise. + - Fix some warnings in hw/xfree86/common/xf86Config.c. + 2005-12-28 Eric Anholt <anholt@FreeBSD.org> * render/filter.c: (SetPictureFilter): diff --git a/configure.ac b/configure.ac index 2709bc656..fb72b9cf4 100644 --- a/configure.ac +++ b/configure.ac @@ -1586,6 +1586,7 @@ hw/xfree86/xf8_16bpp/Makefile hw/xfree86/xf8_32bpp/Makefile hw/xfree86/xf8_32wid/Makefile hw/xfree86/utils/Makefile +hw/xfree86/utils/cvt/Makefile hw/xfree86/utils/gtf/Makefile hw/xfree86/utils/ioport/Makefile hw/xfree86/utils/kbd_mode/Makefile diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index f4b44e67d..aded9132d 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -1,4 +1,4 @@ -/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86Config.c,v 1.8 2005/05/18 10:31:53 eich Exp $ */ +/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Config.c,v 1.21 2005/12/20 21:34:21 ajax Exp $ */ /* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Config.c,v 3.276 2003/10/08 14:58:26 dawes Exp $ */ @@ -505,7 +505,7 @@ GenerateDriverlist(char * dirname, char * drivernames) { #ifdef XFree86LOADER char **ret; - char *subdirs[] = { dirname, NULL }; + const char *subdirs[] = { dirname, NULL }; static const char *patlist[] = {"(.*)_drv\\.so", "(.*)_drv\\.o", NULL}; ret = LoaderListDirs(subdirs, patlist); @@ -2139,6 +2139,17 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, return TRUE; } +typedef enum { + MON_REDUCEDBLANKING +} MonitorValues; + +static OptionInfoRec MonitorOptions[] = { + { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN, + {0}, FALSE }, + { -1, NULL, OPTV_NONE, + {0}, FALSE }, +}; + static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor) { @@ -2160,6 +2171,7 @@ configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor) monitorp->gamma = zeros; monitorp->widthmm = conf_monitor->mon_width; monitorp->heightmm = conf_monitor->mon_height; + monitorp->reducedblanking = FALSE; monitorp->options = conf_monitor->mon_option_lst; /* @@ -2279,6 +2291,11 @@ configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor) return FALSE; } + /* Check wether this Monitor accepts Reduced Blanking modelines */ + xf86ProcessOptions(-1, monitorp->options, MonitorOptions); + + xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING, + &monitorp->reducedblanking); return TRUE; } @@ -2452,14 +2469,14 @@ configDRI(XF86ConfDRIPtr drip) } #endif +/* Extension enable/disable in miinitext.c */ +extern Bool EnableDisableExtension(char *name, Bool enable); + static Bool configExtensions(XF86ConfExtensionsPtr conf_ext) { XF86OptionPtr o; - /* Extension enable/disable in miinitext.c */ - extern Bool EnableDisableExtension(char *name, Bool enable); - if (conf_ext && conf_ext->ext_option_lst) { for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) { char *name = xf86OptionName(o); @@ -2673,7 +2690,7 @@ xf86HandleConfigFile(Bool autoconfig) scanptr = xf86ConfigLayout.screens->screen->device->busID; } if (scanptr) { - int bus, device, func, stroffset = 0; + int bus, device, func; if (strncmp(scanptr, "PCI:", 4) != 0) { xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n" "\tIgnoring IsolateDevice option.\n"); diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c index 7328b1b76..618f3f33e 100644 --- a/hw/xfree86/common/xf86Mode.c +++ b/hw/xfree86/common/xf86Mode.c @@ -1,4 +1,4 @@ -/* $XdotOrg: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.4 2005/05/18 10:31:53 eich Exp $ */ +/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Mode.c,v 1.7 2005/07/03 08:53:42 daniels Exp $ */ /* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.69 2003/10/08 14:58:28 dawes Exp $ */ /* * Copyright (c) 1997-2003 by The XFree86 Project, Inc. @@ -165,6 +165,8 @@ xf86ModeStatusToString(ModeStatus status) return "all modes must have the same height"; case MODE_ONE_SIZE: return "all modes must have the same resolution"; + case MODE_NO_REDUCED: + return "monitor doesn't support reduced blanking"; case MODE_BAD: return "unknown reason"; case MODE_ERROR: @@ -814,6 +816,17 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor) if (mode->Flags & V_INTERLACE) mode->CrtcVTotal = mode->VTotal |= 1; + /* Check wether this mode has acceptable blanking */ + if (((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) { + + /* Is this a CVT Reduced blanking mode? */ + if ((mode->HTotal - mode->HDisplay) != 160) + return MODE_HBLANK_NARROW; + + if (!monitor->reducedblanking) + return MODE_NO_REDUCED; + } + return MODE_OK; } diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h index 82faaaac1..b939282ee 100644 --- a/hw/xfree86/common/xf86str.h +++ b/hw/xfree86/common/xf86str.h @@ -115,6 +115,7 @@ typedef enum { MODE_ONE_WIDTH, /* only one width is supported */ MODE_ONE_HEIGHT, /* only one height is supported */ MODE_ONE_SIZE, /* only one resolution is supported */ + MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */ MODE_BAD = -2, /* unspecified reason */ MODE_ERROR = -1 /* error condition */ } ModeStatus; @@ -206,6 +207,7 @@ typedef struct { int heightmm; pointer options; pointer DDC; + Bool reducedblanking; /* Allow CVT reduced blanking modes? */ } MonRec, *MonPtr; /* the list of clock ranges */ diff --git a/hw/xfree86/utils/Makefile.am b/hw/xfree86/utils/Makefile.am index 3384c3f61..38f90b4ae 100644 --- a/hw/xfree86/utils/Makefile.am +++ b/hw/xfree86/utils/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS = \ gtf \ + cvt \ ioport \ kbd_mode \ pcitweak \ diff --git a/hw/xfree86/utils/cvt/Makefile.am b/hw/xfree86/utils/cvt/Makefile.am new file mode 100644 index 000000000..9dcff80a3 --- /dev/null +++ b/hw/xfree86/utils/cvt/Makefile.am @@ -0,0 +1,44 @@ +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# +# 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, and/or sell copies of the Software, and to permit persons +# to whom the Software is furnished to do so, provided that the above +# copyright notice(s) and this permission notice appear in all copies of +# the Software and that both the above copyright notice(s) and this +# permission notice appear in supporting documentation. +# +# 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 +# OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. +# +# Except as contained in this notice, the name of a copyright holder +# shall not be used in advertising or otherwise to promote the sale, use +# or other dealings in this Software without prior written authorization +# of the copyright holder. +# + +bin_PROGRAMS = cvt + +INCLUDES = $(XORG_INCS) +DUMMYLIB_SRCDIR = $(XFREE86_SRCDIR)/dummylib + +cvt_SOURCES = cvt.c +cvt_CFLAGS = $(XORG_CFLAGS) +cvt_LDADD = ../../dummylib/libdummy-nonserver.a + +man1_MANS = cvt.man + +CLEANFILES = $(man1_MANS) + +include $(top_srcdir)/cpprules.in + +EXTRA_DIST = cvt.man.pre diff --git a/hw/xfree86/utils/cvt/cvt.c b/hw/xfree86/utils/cvt/cvt.c new file mode 100644 index 000000000..3c3f38a6a --- /dev/null +++ b/hw/xfree86/utils/cvt/cvt.c @@ -0,0 +1,532 @@ +/* + * Copyright (c) 2005 by Luc Verhaegen. + * 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). + */ + +/* + * Calculate VESA CVT standard timing modelines. + * + * My own copyright is added. This is only there for the standalone version. + * I don't want to polute the xf86Mode.c license. + * + */ +#include "xf86.h" + + +/* + * Grabbed from xf86Mode.c from the Xorg tree. Hence the copyright and license. + * + * Altered for stdout printing. + */ +static void +add(char **p, char *new) +{ + *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2); + strcat(*p, " "); + strcat(*p, new); +} + +static void +PrintModeline(DisplayModePtr mode) +{ + char tmp[256]; + char *flags = xnfcalloc(1, 1); + + if (mode->HSkew) { + snprintf(tmp, 256, "hskew %i", mode->HSkew); + add(&flags, tmp); + } + if (mode->VScan) { + snprintf(tmp, 256, "vscan %i", mode->VScan); + add(&flags, tmp); + } + if (mode->Flags & V_INTERLACE) add(&flags, "interlace"); + if (mode->Flags & V_CSYNC) add(&flags, "composite"); + if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan"); + if (mode->Flags & V_BCAST) add(&flags, "bcast"); + if (mode->Flags & V_PHSYNC) add(&flags, "+hsync"); + if (mode->Flags & V_NHSYNC) add(&flags, "-hsync"); + if (mode->Flags & V_PVSYNC) add(&flags, "+vsync"); + if (mode->Flags & V_NVSYNC) add(&flags, "-vsync"); + if (mode->Flags & V_PCSYNC) add(&flags, "+csync"); + if (mode->Flags & V_NCSYNC) add(&flags, "-csync"); +#if 0 + if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2"); +#endif + + printf("Modeline \"%s\" %6.2f %i %i %i %i %i %i %i %i%s\n", + mode->name, mode->Clock/1000., mode->HDisplay, + mode->HSyncStart, mode->HSyncEnd, mode->HTotal, + mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, + mode->VTotal, flags); + xfree(flags); +} + + +/* + * New code... Well, somewhat. + */ + + +/* + * These calculations are stolen from the CVT calculation spreadsheet written + * by Graham Loveridge. He seems to be claiming no copyright and there seems to + * be no license attached to this. He apparently just wants to see his name + * mentioned. + * + * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls + * + * Comments and structure corresponds to the comments and structure of the xls. + * This should ease importing of future changes to the standard (not very + * likely though). + * + * About margins; i'm sure that they are to be the bit between HDisplay and + * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and + * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking + * outside sync "margin" for some reason. Since we prefer seeing proper + * blanking instead of the overscan colour, and since the Crtc* values will + * probably get altered after us, we will disable margins altogether. With + * these calculations, Margins will plainly expand H/VDisplay, and we don't + * want that. + * + */ +static DisplayModeRec * +xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, + Bool Interlaced) +{ + DisplayModeRec *Mode = xnfalloc(sizeof(DisplayModeRec)); + + /* 1) top/bottom margin size (% of height) - default: 1.8 */ +#define CVT_MARGIN_PERCENTAGE 1.8 + + /* 2) character cell horizontal granularity (pixels) - default 8 */ +#define CVT_H_GRANULARITY 8 + + /* 4) Minimum vertical porch (lines) - default 3 */ +#define CVT_MIN_V_PORCH 3 + + /* 4) Minimum number of vertical back porch lines - default 6 */ +#define CVT_MIN_V_BPORCH 6 + + /* Pixel Clock step (kHz) */ +#define CVT_CLOCK_STEP 250 + + Bool Margins = FALSE; + float VFieldRate, HPeriod; + int HDisplayRnd, HMargin; + int VDisplayRnd, VMargin, VSync; + float Interlace; /* Please rename this */ + + /* CVT default is 60.0Hz */ + if (!VRefresh) + VRefresh = 60.0; + + /* 1. Required field rate */ + if (Interlaced) + VFieldRate = VRefresh * 2; + else + VFieldRate = VRefresh; + + /* 2. Horizontal pixels */ + HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY); + + /* 3. Determine left and right borders */ + if (Margins) { + /* right margin is actually exactly the same as left */ + HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); + HMargin -= HMargin % CVT_H_GRANULARITY; + } else + HMargin = 0; + + /* 4. Find total active pixels */ + Mode->HDisplay = HDisplayRnd + 2*HMargin; + + /* 5. Find number of lines per field */ + if (Interlaced) + VDisplayRnd = VDisplay / 2; + else + VDisplayRnd = VDisplay; + + /* 6. Find top and bottom margins */ + /* nope. */ + if (Margins) + /* top and bottom margins are equal again. */ + VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); + else + VMargin = 0; + + Mode->VDisplay = VDisplay + 2*VMargin; + + /* 7. Interlace */ + if (Interlaced) + Interlace = 0.5; + else + Interlace = 0.0; + + /* Determine VSync Width from aspect ratio */ + if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) + VSync = 4; + else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) + VSync = 5; + else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) + VSync = 6; + else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) + VSync = 7; + else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)) + VSync = 7; + else /* Custom */ + VSync = 10; + + if (!Reduced) { /* simplified GTF calculation */ + + /* 4) Minimum time of vertical sync + back porch interval (µs) + * default 550.0 */ +#define CVT_MIN_VSYNC_BP 550.0 + + /* 3) Nominal HSync width (% of line period) - default 8 */ +#define CVT_HSYNC_PERCENTAGE 8 + + float HBlankPercentage; + int VSyncAndBackPorch, VBackPorch; + int HBlank; + + /* 8. Estimated Horizontal period */ + HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / + (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace); + + /* 9. Find number of lines in sync + backporch */ + if (((int)(CVT_MIN_VSYNC_BP / HPeriod) + 1) < (VSync + CVT_MIN_V_PORCH)) + VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH; + else + VSyncAndBackPorch = (int)(CVT_MIN_VSYNC_BP / HPeriod) + 1; + + /* 10. Find number of lines in back porch */ + VBackPorch = VSyncAndBackPorch - VSync; + + /* 11. Find total number of lines in vertical field */ + Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace + + CVT_MIN_V_PORCH; + + /* 5) Definition of Horizontal blanking time limitation */ + /* Gradient (%/kHz) - default 600 */ +#define CVT_M_FACTOR 600 + + /* Offset (%) - default 40 */ +#define CVT_C_FACTOR 40 + + /* Blanking time scaling factor - default 128 */ +#define CVT_K_FACTOR 128 + + /* Scaling factor weighting - default 20 */ +#define CVT_J_FACTOR 20 + +#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 +#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ + CVT_J_FACTOR + + /* 12. Find ideal blanking duty cycle from formula */ + HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod/1000.0; + + /* 13. Blanking time */ + if (HBlankPercentage < 20) + HBlankPercentage = 20; + + HBlank = Mode->HDisplay * HBlankPercentage/(100.0 - HBlankPercentage); + HBlank -= HBlank % (2*CVT_H_GRANULARITY); + + /* 14. Find total number of pixels in a line. */ + Mode->HTotal = Mode->HDisplay + HBlank; + + /* Fill in HSync values */ + Mode->HSyncEnd = Mode->HDisplay + HBlank / 2; + + Mode->HSyncStart = Mode->HSyncEnd - + (Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100; + Mode->HSyncStart += CVT_H_GRANULARITY - + Mode->HSyncStart % CVT_H_GRANULARITY; + + /* Fill in VSync values */ + Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH; + Mode->VSyncEnd = Mode->VSyncStart + VSync; + + } else { /* Reduced blanking */ + /* Minimum vertical blanking interval time (µs) - default 460 */ +#define CVT_RB_MIN_VBLANK 460.0 + + /* Fixed number of clocks for horizontal sync */ +#define CVT_RB_H_SYNC 32.0 + + /* Fixed number of clocks for horizontal blanking */ +#define CVT_RB_H_BLANK 160.0 + + /* Fixed number of lines for vertical front porch - default 3 */ +#define CVT_RB_VFPORCH 3 + + int VBILines; + + /* 8. Estimate Horizontal period. */ + HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / + (VDisplayRnd + 2*VMargin); + + /* 9. Find number of lines in vertical blanking */ + VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1; + + /* 10. Check if vertical blanking is sufficient */ + if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH)) + VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH; + + /* 11. Find total number of lines in vertical field */ + Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines; + + /* 12. Find total number of pixels in a line */ + Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK; + + /* Fill in HSync values */ + Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2; + Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC; + + /* Fill in VSync values */ + Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH; + Mode->VSyncEnd = Mode->VSyncStart + VSync; + } + + /* 15/13. Find pixel clock frequency (kHz for xf86) */ + Mode->Clock = Mode->HTotal * 1000.0 / HPeriod; + Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP; + + /* 16/14. Find actual Horizontal Frequency (kHz) */ + Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal); + + /* 17/15. Find actual Field rate */ + Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / + ((float) (Mode->HTotal * Mode->VTotal)); + + /* 18/16. Find actual vertical frame frequency */ + /* ignore - just set the mode flag for interlaced */ + if (Interlaced) + Mode->VTotal *= 2; + + /* Fill in Mode parameters */ + { + char Name[256]; + Name[0] = 0; + if (Reduced) + snprintf(Name, 256, "%dx%dR", HDisplay, VDisplay); + else + snprintf(Name, 256, "%dx%d_%.2f", HDisplay, VDisplay, VRefresh); + Mode->name = xnfalloc(strlen(Name) + 1); + memcpy(Mode->name, Name, strlen(Name)); + } + + if (Reduced) + Mode->Flags |= V_PHSYNC | V_NVSYNC; + else + Mode->Flags |= V_NHSYNC | V_PVSYNC; + + if (Interlaced) + Mode->Flags |= V_INTERLACE; + + return Mode; +} + + +/* + * Quickly check wether this is a CVT standard mode. + */ +static Bool +xf86CVTCheckStandard(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, + Bool Verbose) +{ + Bool IsCVT = TRUE; + + if ((!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) || + (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) || + (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) || + (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) || + (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))) + ; + else { + if (Verbose) + fprintf(stderr, "Warning: Aspect Ratio is not CVT standard.\n"); + IsCVT = FALSE; + } + + if ((VRefresh != 50.0) && (VRefresh != 60.0) && + (VRefresh != 75.0) && (VRefresh != 85.0)) { + if (Verbose) + fprintf(stderr, "Warning: Refresh Rate is not CVT standard " + "(50, 60, 75 or 85Hz).\n"); + IsCVT = FALSE; + } + + return IsCVT; +} + + +/* + * I'm not documenting --interlaced for obvious reasons, even though I did + * implement it. I also can't deny having looked at gtf here. + */ +static void +PrintUsage(char *Name) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "usage: %s [-v|--verbose] [-r|--reduced] X Y [refresh]\n", + Name); + fprintf(stderr, "\n"); + fprintf(stderr, " -v|--verbose : Warn about CVT standard adherance.\n"); + fprintf(stderr, " -r|--reduced : Create a mode with reduced blanking " + "(default: normal blanking).\n"); + fprintf(stderr, " X : Desired horizontal resolution " + "(multiple of 8, required).\n"); + fprintf(stderr, " Y : Desired vertical resolution (required).\n"); + fprintf(stderr, " refresh : Desired refresh rate (default: 60.0Hz).\n"); + fprintf(stderr, "\n"); + + fprintf(stderr, "Calculates VESA CVT (Common Video Timing) modelines for" + " use with X.\n"); +} + + +/* + * + */ +static void +PrintComment(DisplayModeRec *Mode, Bool CVT, Bool Reduced) +{ + printf("# %dx%d %.2f Hz ", Mode->HDisplay, Mode->VDisplay, Mode->VRefresh); + + if (CVT) { + printf("(CVT %.2fM", + ((float) Mode->HDisplay * Mode->VDisplay) / 1000000.0); + + if (!(Mode->VDisplay % 3) && + ((Mode->VDisplay * 4 / 3) == Mode->HDisplay)) + printf("3"); + else if (!(Mode->VDisplay % 9) && + ((Mode->VDisplay * 16 / 9) == Mode->HDisplay)) + printf("9"); + else if (!(Mode->VDisplay % 10) && + ((Mode->VDisplay * 16 / 10) == Mode->HDisplay)) + printf("A"); + else if (!(Mode->VDisplay % 4) && + ((Mode->VDisplay * 5 / 4) == Mode->HDisplay)) + printf("4"); + else if (!(Mode->VDisplay % 9) && + ((Mode->VDisplay * 15 / 9) == Mode->HDisplay)) + printf("9"); + + if (Reduced) + printf("-R"); + + printf(") "); + } else + printf("(CVT) "); + + printf("hsync: %.2f kHz; ", Mode->HSync); + printf("pclk: %.2f MHz", ((float ) Mode->Clock) / 1000.0); + + printf("\n"); +} + + +/* + * + */ +int +main (int argc, char *argv[]) +{ + DisplayModeRec *Mode; + int HDisplay = 0, VDisplay = 0; + float VRefresh = 0.0; + Bool Reduced = FALSE, Verbose = FALSE, IsCVT; + Bool Interlaced = FALSE; + int n; + + if ((argc < 3) || (argc > 7)) { + PrintUsage(argv[0]); + return 0; + } + + /* This doesn't filter out bad flags properly. Bad flags get passed down + * to atoi/atof, which then return 0, so that these variables can get + * filled next time round. So this is just a cosmetic problem. + */ + for (n = 1; n < argc; n++) { + if (!strcmp(argv[n], "-r") || !strcmp(argv[n], "--reduced")) + Reduced = TRUE; + else if (!strcmp(argv[n], "-i") || !strcmp(argv[n], "--interlaced")) + Interlaced = TRUE; + else if (!strcmp(argv[n], "-v") || !strcmp(argv[n], "--verbose")) + Verbose = TRUE; + else if (!strcmp(argv[n], "-h") || !strcmp(argv[n], "--help")) { + PrintUsage(argv[0]); + return 0; + } else if (!HDisplay) + HDisplay = atoi(argv[n]); + else if (!VDisplay) + VDisplay = atoi(argv[n]); + else if (!VRefresh) + VRefresh = atof(argv[n]); + else { + PrintUsage(argv[0]); + return 0; + } + } + + if (!HDisplay || !VDisplay) { + PrintUsage(argv[0]); + return 0; + } + + /* Default to 60.0Hz */ + if (!VRefresh) + VRefresh = 60.0; + + /* Enforce hard limitation */ + if (HDisplay % 8) { + fprintf(stderr, "\nERROR: Horizontal Resolution needs to be a " + "multiple of 8.\n"); + PrintUsage(argv[0]); + return 0; + } + + if (Reduced && (VRefresh != 60.0)) { + fprintf(stderr, "\nERROR: 60Hz refresh rate required for reduced" + " blanking.\n"); + PrintUsage(argv[0]); + return 0; + } + + IsCVT = xf86CVTCheckStandard(HDisplay, VDisplay, VRefresh, Reduced, Verbose); + + Mode = xf86CVTMode(HDisplay, VDisplay, VRefresh, Reduced, Interlaced); + + PrintComment(Mode, IsCVT, Reduced); + PrintModeline(Mode); + + return 0; +} diff --git a/hw/xfree86/utils/cvt/cvt.man.pre b/hw/xfree86/utils/cvt/cvt.man.pre new file mode 100644 index 000000000..95f11cb6e --- /dev/null +++ b/hw/xfree86/utils/cvt/cvt.man.pre @@ -0,0 +1,41 @@ +.\" $XFree86$ +.TH CVT 1 __vendorversion__ +.SH NAME +cvt - calculate VESA CVT mode lines +.SH SYNOPSIS +.B cvt +.RB [ \-v | \-\-verbose ] +.RB [ \-r | \-\-reduced ] +.I h-resolution +.I v-resolution +.RB [ refresh ] +.SH DESCRIPTION +.I Cvt +is a utility for calculating VESA Common Video Timing modes. Given the +desired horizontal and vertical resolutions, a modeline adhering to the CVT +standard is printed. This modeline can be included in __xservername__ +.B __xconfigfile__(__filemansuffix__) +. + +.SH OPTIONS +.TP 8 +.BR refresh +Provide a vertical refresh rate in kHz. The CVT standard prefers either 50.0, +60.0, 75.0 or 85.0kHz. The default is 60.0kHz. +.TP 8 +.BR \-v | \-\-verbose +Warn verbosely when a given mode does not completely correspond with CVT +standards. +.TP 8 +.BR \-r | \-\-reduced +Create a mode with reduced blanking. This allows for higher frequency signals, +with a lower or equal dotclock. Not for Cathode Ray Tube based displays though. + +.SH "SEE ALSO" +__xconfigfile__(__filemansuffix__) +.SH AUTHOR +Luc Verhaegen. +.PP +This program is based on the Common Video Timing sample implementation +written by Graham Loveridge. This file is publically available at +<http://www.vesa.org/Public/CVT/CVTd6r1.xls>. CVT is a VESA trademark. |