summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--configure.ac1
-rw-r--r--hw/xfree86/common/xf86Config.c29
-rw-r--r--hw/xfree86/common/xf86Mode.c15
-rw-r--r--hw/xfree86/common/xf86str.h2
-rw-r--r--hw/xfree86/utils/Makefile.am1
-rw-r--r--hw/xfree86/utils/cvt/Makefile.am44
-rw-r--r--hw/xfree86/utils/cvt/cvt.c532
-rw-r--r--hw/xfree86/utils/cvt/cvt.man.pre41
9 files changed, 681 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 2beb1b7ed..b302b2f26 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.