Merge branch 'master' of git://git.freedesktop.org/git/xorg/xserver

This commit is contained in:
Kristian Høgsberg 2007-10-12 19:28:39 -04:00
commit 927757e102
9 changed files with 222 additions and 127 deletions

View File

@ -215,27 +215,10 @@ xf86AutoConfig(void)
{
const char **p;
char buf[1024];
struct pci_device_iterator *iter;
struct pci_device * info = NULL;
const char *driver = NULL;
ConfigStatus ret;
/* Find the primary device, and get some information about it. */
iter = pci_slot_match_iterator_create(NULL);
while ((info = pci_device_next(iter)) != NULL) {
if (xf86IsPrimaryPci(info)) {
break;
}
}
pci_iterator_destroy(iter);
if (!info) {
ErrorF("Primary device is not PCI\n");
}
if (info)
driver = videoPtrToDriverName(info);
driver = chooseVideoDriver();
AppendToConfig(BUILTIN_MODULE_SECTION);
AppendToConfig(BUILTIN_MONITOR_SECTION);
@ -301,15 +284,14 @@ xchomp(char *line)
len = strlen(line);
if (line[len - 1] == '\n' && len > 0) {
line[len - 1] = '\0';
return 0;
}
return 0;
}
GDevPtr
autoConfigDevice(GDevPtr preconf_device)
{
GDevPtr ptr = NULL;
confScreenPtr scrn = NULL;
if (!xf86configptr) {
return NULL;
@ -347,41 +329,20 @@ autoConfigDevice(GDevPtr preconf_device)
return ptr;
}
char*
chooseVideoDriver(void)
static void
matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
{
struct pci_device * info = NULL;
struct pci_device_iterator *iter;
DIR *idsdir;
FILE *fp;
struct dirent *direntry;
char *line = NULL;
char *chosen_driver = NULL;
size_t len;
ssize_t read;
char path_name[256], vendor_str[5], chip_str[5];
uint16_t vendor, chip;
int i, j;
char *matches[20]; /* If we have more than 20 drivers we're in trouble */
for (i=0 ; i<20 ; i++)
matches[i] = NULL;
/* Find the primary device, and get some information about it. */
iter = pci_slot_match_iterator_create(NULL);
while ((info = pci_device_next(iter)) != NULL) {
if (xf86IsPrimaryPci(info)) {
break;
}
}
pci_iterator_destroy(iter);
if (!info) {
ErrorF("Primary device is not PCI\n");
}
idsdir = opendir("/usr/share/xserver-xorg/pci");
if (idsdir) {
direntry = readdir(idsdir);
/* Read the directory */
@ -423,8 +384,7 @@ chooseVideoDriver(void)
chip = (int)strtol(chip_str, NULL, 16);
}
}
if (vendor == info->vendor_id &&
(chip == info->device_id || chip == -1)) {
if (vendor == match_vendor && chip == match_chip ) {
i = 0;
while (matches[i]) {
i++;
@ -457,6 +417,38 @@ chooseVideoDriver(void)
direntry = readdir(idsdir);
}
}
end:
xfree(line);
closedir(idsdir);
}
char*
chooseVideoDriver(void)
{
struct pci_device * info = NULL;
struct pci_device_iterator *iter;
char *chosen_driver = NULL;
int i;
char *matches[20]; /* If we have more than 20 drivers we're in trouble */
for (i=0 ; i<20 ; i++)
matches[i] = NULL;
/* Find the primary device, and get some information about it. */
iter = pci_slot_match_iterator_create(NULL);
while ((info = pci_device_next(iter)) != NULL) {
if (xf86IsPrimaryPci(info)) {
break;
}
}
pci_iterator_destroy(iter);
if (!info) {
ErrorF("Primary device is not PCI\n");
}
matchDriverFromFiles(matches, info->vendor_id, info->device_id);
/* TODO Handle multiple drivers claiming to support the same PCI ID */
if (matches[0]) {
@ -478,7 +470,6 @@ chooseVideoDriver(void)
xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver);
end:
i = 0;
while (matches[i]) {
if (matches[i] != chosen_driver) {
@ -486,8 +477,6 @@ chooseVideoDriver(void)
}
i++;
}
xfree(line);
closedir(idsdir);
return chosen_driver;
}

View File

@ -2134,8 +2134,12 @@ _X_EXPORT xf86MonPtr
xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
{
ScrnInfoPtr scrn = output->scrn;
xf86MonPtr mon;
return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
xf86DDCApplyQuirks (scrn->scrnIndex, pDDCBus);
return mon;
}
static char *_xf86ConnectorNames[] = { "None", "VGA", "DVI-I", "DVI-D",

View File

@ -54,6 +54,16 @@ typedef enum {
DDC_QUIRK_PREFER_LARGE_60 = 1 << 0,
/* 135MHz clock is too high, drop a bit */
DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 1,
/* Prefer the largest mode at 75 Hz */
DDC_QUIRK_PREFER_LARGE_75 = 1 << 2,
/* Convert detailed timing's horizontal from units of cm to mm */
DDC_QUIRK_DETAILED_H_IN_CM = 1 << 3,
/* Convert detailed timing's vertical from units of cm to mm */
DDC_QUIRK_DETAILED_V_IN_CM = 1 << 4,
/* Detailed timing descriptors have bogus size values, so just take the
* maximum size and use that.
*/
DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5,
} ddc_quirk_t;
static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
@ -81,6 +91,52 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
return FALSE;
}
static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #11603: Funai Electronics PM36B */
if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
DDC->vendor.prod_id == 13600)
return TRUE;
return FALSE;
}
static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #10304: "LGPhilipsLCD LP154W01-A5" */
/* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */
if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
DDC->vendor.prod_id == 0)
return TRUE;
/* Bug #11603: Funai Electronics PM36B */
if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
DDC->vendor.prod_id == 13600)
return TRUE;
return FALSE;
}
static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #11603: Funai Electronics PM36B */
if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
DDC->vendor.prod_id == 13600)
return TRUE;
return FALSE;
}
static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC)
{
/* Bug #10304: LGPhilipsLCD LP154W01-A5 */
if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
DDC->vendor.prod_id == 0)
return TRUE;
return FALSE;
}
static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
{
/* Envision Peripherals, Inc. EN-7100e. See bug #9550. */
@ -106,6 +162,22 @@ static const ddc_quirk_map_t ddc_quirks[] = {
quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH,
"Recommended 135MHz pixel clock is too high"
},
{
quirk_prefer_large_75, DDC_QUIRK_PREFER_LARGE_75,
"Detailed timing is not preferred, use largest mode at 75Hz"
},
{
quirk_detailed_h_in_cm, DDC_QUIRK_DETAILED_H_IN_CM,
"Detailed timings give horizontal size in cm."
},
{
quirk_detailed_v_in_cm, DDC_QUIRK_DETAILED_V_IN_CM,
"Detailed timings give vertical size in cm."
},
{
quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
"Detailed timings give sizes in cm."
},
{
NULL, DDC_QUIRK_NONE,
"No known quirks"
@ -303,6 +375,98 @@ DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
}
}
static ddc_quirk_t
xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose)
{
ddc_quirk_t quirks;
int i;
quirks = DDC_QUIRK_NONE;
for (i = 0; ddc_quirks[i].detect; i++) {
if (ddc_quirks[i].detect (scrnIndex, DDC)) {
if (verbose) {
xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
ddc_quirks[i].description);
}
quirks |= ddc_quirks[i].quirk;
}
}
return quirks;
}
/**
* Applies monitor-specific quirks to the decoded EDID information.
*
* Note that some quirks applying to the mode list are still implemented in
* xf86DDCGetModes.
*/
void
xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC)
{
ddc_quirk_t quirks = xf86DDCDetectQuirks (scrnIndex, DDC, FALSE);
int i;
for (i = 0; i < DET_TIMINGS; i++) {
struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
if (det_mon->type != DT)
continue;
if (quirks & DDC_QUIRK_DETAILED_H_IN_CM)
det_mon->section.d_timings.h_size *= 10;
if (quirks & DDC_QUIRK_DETAILED_V_IN_CM)
det_mon->section.d_timings.v_size *= 10;
if (quirks & DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
det_mon->section.d_timings.h_size = 10 * DDC->features.hsize;
det_mon->section.d_timings.v_size = 10 * DDC->features.vsize;
}
}
}
/**
* Walks the modes list, finding the mode with the largest area which is
* closest to the target refresh rate, and marks it as the only preferred mode.
*/
static void
xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
float target_refresh)
{
DisplayModePtr mode, best = modes;
for (mode = modes; mode; mode = mode->next)
{
mode->type &= ~M_T_PREFERRED;
if (mode == best) continue;
if (mode->HDisplay * mode->VDisplay >
best->HDisplay * best->VDisplay)
{
best = mode;
continue;
}
if (mode->HDisplay * mode->VDisplay ==
best->HDisplay * best->VDisplay)
{
double mode_refresh = xf86ModeVRefresh (mode);
double best_refresh = xf86ModeVRefresh (best);
double mode_dist = fabs(mode_refresh - target_refresh);
double best_dist = fabs(best_refresh - target_refresh);
if (mode_dist < best_dist)
{
best = mode;
continue;
}
}
}
if (best)
best->type |= M_T_PREFERRED;
}
_X_EXPORT DisplayModePtr
xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
{
@ -312,15 +476,9 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
DDC->vendor.name, DDC->vendor.prod_id);
quirks = DDC_QUIRK_NONE;
for (i = 0; ddc_quirks[i].detect; i++)
if (ddc_quirks[i].detect (scrnIndex, DDC))
{
xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
ddc_quirks[i].description);
quirks |= ddc_quirks[i].quirk;
}
quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
preferred = 0;
@ -357,32 +515,11 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
Modes = xf86ModesAdd(Modes, Mode);
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
{
DisplayModePtr best = Modes;
for (Mode = Modes; Mode; Mode = Mode->next)
{
if (Mode == best) continue;
if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
{
best = Mode;
continue;
}
if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
{
double mode_refresh = xf86ModeVRefresh (Mode);
double best_refresh = xf86ModeVRefresh (best);
double mode_dist = fabs(mode_refresh - 60.0);
double best_dist = fabs(best_refresh - 60.0);
if (mode_dist < best_dist)
{
best = Mode;
continue;
}
}
}
if (best)
best->type |= M_T_PREFERRED;
}
xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60);
if (quirks & DDC_QUIRK_PREFER_LARGE_75)
xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75);
return Modes;
}

View File

@ -95,4 +95,7 @@ xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
DisplayModePtr
xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
void
xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC);
#endif /* _XF86MODES_H_ */

View File

@ -186,8 +186,6 @@ else\
"The Inactive keyword must be followed by a Device name in quotes."
#define UNDEFINED_SCREEN_MSG \
"Undefined Screen \"%s\" referenced by ServerLayout \"%s\"."
#define UNDEFINED_MONITOR_MSG \
"Undefined Monitor \"%s\" referenced by Screen \"%s\"."
#define UNDEFINED_MODES_MSG \
"Undefined Modes Section \"%s\" referenced by Monitor \"%s\"."
#define UNDEFINED_DEVICE_MSG \
@ -204,8 +202,6 @@ else\
"This section must have an Identifier line."
#define ONLY_ONE_MSG \
"This section must have only one of either %s line."
#define UNDEFINED_DRIVER_MSG \
"Device section \"%s\" must have a Driver line."
#define UNDEFINED_INPUTDRIVER_MSG \
"InputDevice section \"%s\" must have a Driver line."
#define INVALID_GAMMA_MSG \

View File

@ -357,26 +357,6 @@ xf86freeDeviceList (XF86ConfDevicePtr ptr)
}
}
int
xf86validateDevice (XF86ConfigPtr p)
{
XF86ConfDevicePtr device = p->conf_device_lst;
if (!device) {
xf86validationError ("At least one Device section is required.");
return (FALSE);
}
while (device) {
if (!device->dev_driver) {
xf86validationError (UNDEFINED_DRIVER_MSG, device->dev_identifier);
return (FALSE);
}
device = device->list.next;
}
return (TRUE);
}
XF86ConfDevicePtr
xf86findDevice (const char *ident, XF86ConfDevicePtr p)
{

View File

@ -498,12 +498,6 @@ xf86validateScreen (XF86ConfigPtr p)
XF86ConfDevicePtr device;
XF86ConfAdaptorLinkPtr adaptor;
if (!screen)
{
xf86validationError ("At least one Screen section is required.");
return (FALSE);
}
while (screen)
{
if (screen->scrn_obso_driver && !screen->scrn_identifier)
@ -512,13 +506,7 @@ xf86validateScreen (XF86ConfigPtr p)
monitor = xf86findMonitor (screen->scrn_monitor_str, p->conf_monitor_lst);
if (screen->scrn_monitor_str)
{
if (!monitor)
{
xf86validationError (UNDEFINED_MONITOR_MSG,
screen->scrn_monitor_str, screen->scrn_identifier);
return (FALSE);
}
else
if (monitor)
{
screen->scrn_monitor = monitor;
if (!xf86validateMonitor(p, screen))

View File

@ -80,10 +80,8 @@ static xf86ConfigSymTabRec TopLevelTab[] =
static int
xf86validateConfig (XF86ConfigPtr p)
{
/*if (!xf86validateDevice (p))
return FALSE;*/
/*if (!xf86validateScreen (p))
return FALSE;*/
if (!xf86validateScreen (p))
return FALSE;
if (!xf86validateInput (p))
return FALSE;
if (!xf86validateLayout (p))

View File

@ -8,6 +8,6 @@ sdkdir=@sdkdir@
Name: xorg-server
Description: Modular X.Org X Server
Version: @PACKAGE_VERSION@
Requires.private: pixman-1
Requires: pixman-1
Cflags: -I${sdkdir}
Libs: -L${libdir}