diff --git a/src/i830_crt.c b/src/i830_crt.c index 3be10ecc..85c25de1 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -328,38 +328,6 @@ i830_crt_detect(xf86OutputPtr output) return XF86OutputStatusUnknown; } -static DisplayModePtr -i830_crt_get_modes(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - DisplayModePtr modes; - MonRec fixed_mon; - - modes = i830_ddc_get_modes(output); - if (modes != NULL) - return modes; - - if ((*output->funcs->detect)(output) == XF86OutputStatusDisconnected) - return NULL; - - /* We've got a potentially-connected monitor that we can't DDC. Return a - * fixed set of VESA plus user modes for a presumed multisync monitor with - * some reasonable limits. - */ - fixed_mon.nHsync = 1; - fixed_mon.hsync[0].lo = 31.0; - fixed_mon.hsync[0].hi = 100.0; - fixed_mon.nVrefresh = 1; - fixed_mon.vrefresh[0].lo = 50.0; - fixed_mon.vrefresh[0].hi = 70.0; - - modes = xf86DuplicateModes(pScrn, pScrn->monitor->Modes); - i830xf86ValidateModesSync(pScrn, modes, &fixed_mon); - i830xf86PruneInvalidModes(pScrn, &modes, TRUE); - - return modes; -} - static void i830_crt_destroy (xf86OutputPtr output) { @@ -375,7 +343,7 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = { .mode_fixup = i830_crt_mode_fixup, .mode_set = i830_crt_mode_set, .detect = i830_crt_detect, - .get_modes = i830_crt_get_modes, + .get_modes = i830_ddc_get_modes, .destroy = i830_crt_destroy }; diff --git a/src/i830_display.h b/src/i830_display.h index 8a982abc..5517d27c 100644 --- a/src/i830_display.h +++ b/src/i830_display.h @@ -42,14 +42,3 @@ xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output); void i830ReleaseLoadDetectPipe(xf86OutputPtr output); Bool i830PipeInUse(xf86CrtcPtr crtc); void i830_crtc_init(ScrnInfoPtr pScrn, int pipe); - -/** @{ - */ -#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) -DisplayModePtr i830_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); -DisplayModePtr i830_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, - Bool Reduced, Bool Interlaced); -#define xf86DDCGetModes i830_xf86DDCGetModes -#define xf86CVTMode i830_xf86CVTMode -#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2) */ -/** @} */ diff --git a/src/i830_lvds.c b/src/i830_lvds.c index b682b27f..fe964136 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -127,7 +127,19 @@ i830_lvds_restore(xf86OutputPtr output) static int i830_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) { - return MODE_OK; + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + DisplayModePtr pFixedMode = pI830->panel_fixed_mode; + + if (pFixedMode) + { + if (pMode->HDisplay > pFixedMode->HDisplay) + return MODE_PANEL; + if (pMode->VDisplay > pFixedMode->VDisplay) + return MODE_PANEL; + } + + return MODE_OK; } static Bool @@ -236,14 +248,37 @@ i830_lvds_detect(xf86OutputPtr output) static DisplayModePtr i830_lvds_get_modes(xf86OutputPtr output) { - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - DisplayModePtr modes; + I830OutputPrivatePtr intel_output = output->driver_private; + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + xf86MonPtr edid_mon; + DisplayModePtr modes; - modes = i830_ddc_get_modes(output); + edid_mon = i830_xf86OutputGetEDID (output, intel_output->pDDCBus); + i830_xf86OutputSetEDID (output, edid_mon); + + modes = i830_xf86OutputGetEDIDModes (output); if (modes != NULL) return modes; + if (!output->MonInfo) + { + edid_mon = xcalloc (1, sizeof (xf86Monitor)); + if (edid_mon) + { + /* Set wide sync ranges so we get all modes + * handed to valid_mode for checking + */ + edid_mon->det_mon[0].type = DS_RANGES; + edid_mon->det_mon[0].section.ranges.min_v = 0; + edid_mon->det_mon[0].section.ranges.max_v = 200; + edid_mon->det_mon[0].section.ranges.min_h = 0; + edid_mon->det_mon[0].section.ranges.max_h = 200; + + output->MonInfo = edid_mon; + } + } + if (pI830->panel_fixed_mode != NULL) return xf86DuplicateMode(pI830->panel_fixed_mode); diff --git a/src/i830_modes.c b/src/i830_modes.c index 42ee79df..b4e22c35 100644 --- a/src/i830_modes.c +++ b/src/i830_modes.c @@ -55,98 +55,16 @@ #include "i830_xf86Modes.h" #include -#define DEBUG_REPROBE 1 - -#ifdef RANDR_12_INTERFACE - -#define EDID_ATOM_NAME "EDID_DATA" - -static void -i830_ddc_set_edid_property(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 - -/** - * Generic get_modes function using DDC, used by many outputs. - */ DisplayModePtr -i830_ddc_get_modes(xf86OutputPtr output) +i830_ddc_get_modes (xf86OutputPtr output) { - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - xf86MonPtr ddc_mon; - DisplayModePtr ddc_modes, mode; - int i; + I830OutputPrivatePtr intel_output = output->driver_private; + xf86MonPtr edid_mon; + DisplayModePtr modes; - ddc_mon = xf86DoEDID_DDC2(pScrn->scrnIndex, intel_output->pDDCBus); - if (ddc_mon == NULL) { -#ifdef RANDR_12_INTERFACE - i830_ddc_set_edid_property(output, NULL, 0); -#endif - return NULL; - } - - if (output->MonInfo != NULL) - xfree(output->MonInfo); - output->MonInfo = ddc_mon; - -#ifdef RANDR_12_INTERFACE - if (output->MonInfo->ver.version == 1) { - i830_ddc_set_edid_property(output, ddc_mon->rawData, 128); - } else if (output->MonInfo->ver.version == 2) { - i830_ddc_set_edid_property(output, ddc_mon->rawData, 256); - } else { - i830_ddc_set_edid_property(output, NULL, 0); - } -#endif - - /* Debug info for now, at least */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name); - xf86PrintEDID(output->MonInfo); - - ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, ddc_mon); - - /* Strip out any modes that can't be supported on this output. */ - for (mode = ddc_modes; mode != NULL; mode = mode->next) { - int status = (*output->funcs->mode_valid)(output, mode); - - if (status != MODE_OK) - mode->status = status; - } - i830xf86PruneInvalidModes(pScrn, &ddc_modes, TRUE); - - /* Pull out a phyiscal size from a detailed timing if available. */ - for (i = 0; i < 4; i++) { - if (ddc_mon->det_mon[i].type == DT && - ddc_mon->det_mon[i].section.d_timings.h_size != 0 && - ddc_mon->det_mon[i].section.d_timings.v_size != 0) - { - output->mm_width = ddc_mon->det_mon[i].section.d_timings.h_size; - output->mm_height = ddc_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) && - (ddc_mon->features.hsize && ddc_mon->features.vsize)) - { - output->mm_width = ddc_mon->features.hsize * 10; - output->mm_height = ddc_mon->features.vsize * 10; - } - - return ddc_modes; + edid_mon = i830_xf86OutputGetEDID (output, intel_output->pDDCBus); + i830_xf86OutputSetEDID (output, edid_mon); + + modes = i830_xf86OutputGetEDIDModes (output); + return modes; } diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c index 0c482a2e..763df435 100644 --- a/src/i830_xf86Crtc.c +++ b/src/i830_xf86Crtc.c @@ -32,9 +32,14 @@ #include "xf86.h" #include "xf86DDC.h" -#include "i830.h" +/*#include "i830.h" */ #include "i830_xf86Crtc.h" +#include "i830_xf86Modes.h" +#include "i830_randr.h" #include "X11/extensions/render.h" +#define DPMS_SERVER +#include "X11/extensions/dpms.h" +#include "X11/Xatom.h" /* * Initialize xf86CrtcConfig structure @@ -121,6 +126,29 @@ xf86CrtcDestroy (xf86CrtcPtr crtc) /* * Output functions */ + +extern XF86ConfigPtr xf86configptr; + +static void +xf86OutputSetMonitor (xf86OutputPtr output) +{ + char *option_name; + static const char monitor_prefix[] = "monitor-"; + char *monitor; + + 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); + free (option_name); + output->conf_monitor = xf86findMonitor (monitor, xf86configptr->conf_monitor_lst); +} + xf86OutputPtr xf86OutputCreate (ScrnInfoPtr scrn, const xf86OutputFuncsRec *funcs, @@ -151,8 +179,11 @@ xf86OutputCreate (ScrnInfoPtr scrn, xfree (output); return NULL; } + xf86_config->output = outputs; xf86_config->output[xf86_config->num_output++] = output; + + xf86OutputSetMonitor (output); return output; } @@ -169,6 +200,7 @@ xf86OutputRename (xf86OutputPtr output, const char *name) if (output->name != (char *) (output + 1)) xfree (output->name); output->name = newname; + xf86OutputSetMonitor (output); } void @@ -446,12 +478,61 @@ xf86PruneDuplicateMonitorModes (MonPtr Monitor) } } +/** 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, *op, prev; + + 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; + } + /* 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) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - Bool properties_set = FALSE; int o; + int virtualX, virtualY; + + xf86RandR12GetOriginalVirtualSize (pScrn, &virtualX, &virtualY); /* Elide duplicate modes before defaulting code uses them */ xf86PruneDuplicateMonitorModes (pScrn->monitor); @@ -459,21 +540,127 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn) /* 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; + XF86ConfMonitorPtr conf_monitor = output->conf_monitor; + xf86MonPtr edid_monitor = output->MonInfo; + MonRec mon_rec; + while (output->probed_modes != NULL) xf86DeleteMode(&output->probed_modes, output->probed_modes); - output->probed_modes = (*output->funcs->get_modes) (output); + if (output->status == XF86OutputStatusDisconnected) + continue; - /* Set the DDC properties to whatever first output has DDC information. - */ - if (output->MonInfo != NULL && !properties_set) { - xf86SetDDCproperties(pScrn, output->MonInfo); - properties_set = TRUE; + memset (&mon_rec, '\0', sizeof (mon_rec)); + 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++; + } + 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++; + } } + 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 (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++; + } + } + } + } + /* + * 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 (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; + } + + output->probed_modes = NULL; + if (conf_monitor) + output->probed_modes = xf86ModesAdd (output->probed_modes, + i830xf86GetMonitorModes (pScrn, conf_monitor)); + output->probed_modes = xf86ModesAdd (output->probed_modes, + (*output->funcs->get_modes) (output)); + output->probed_modes = xf86ModesAdd (output->probed_modes, + i830xf86GetDefaultModes ()); + + i830xf86ValidateModesSize (pScrn, output->probed_modes, virtualX, virtualY, 0); + i830xf86ValidateModesSync (pScrn, output->probed_modes, &mon_rec); + + /* Strip out any modes that can't be supported on this output. */ + for (mode = output->probed_modes; mode != NULL; mode = mode->next) + if (mode->status == MODE_OK) + mode->status = (*output->funcs->mode_valid)(output, mode); + + i830xf86PruneInvalidModes(pScrn, &output->probed_modes, TRUE); + + output->probed_modes = i830xf86SortModes (output->probed_modes); + + /* Check for a configured preference for a particular mode */ + if (conf_monitor) + { + char *preferred_mode = xf86findOptionValue (conf_monitor->mon_option_lst, + "Preferred Mode"); + + if (preferred_mode) + { + for (mode = output->probed_modes; mode; mode = mode->next) + if (!strcmp (preferred_mode, mode->name)) + break; + if (mode && 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; + } + } + } + #ifdef DEBUG_REPROBE if (output->probed_modes != NULL) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -747,3 +934,112 @@ 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, size; + + 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/i830_xf86Crtc.h b/src/i830_xf86Crtc.h index 9294ccc2..168d89d8 100644 --- a/src/i830_xf86Crtc.h +++ b/src/i830_xf86Crtc.h @@ -25,6 +25,7 @@ #include #include "randrstr.h" #include "i830_xf86Modes.h" +#include "xf86Parser.h" typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr; typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr; @@ -288,6 +289,12 @@ struct _xf86Output { /** Output name */ char *name; + /** Configured monitor name */ + char *monitor_name; + + /** Monitor information from config file */ + XF86ConfMonitorPtr conf_monitor; + /** output-specific functions */ const xf86OutputFuncsRec *funcs; @@ -396,5 +403,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/i830_xf86Modes.c b/src/i830_xf86Modes.c index 1afda951..58a6e6f9 100644 --- a/src/i830_xf86Modes.c +++ b/src/i830_xf86Modes.c @@ -39,6 +39,9 @@ #include "xf86.h" #include "i830.h" #include "i830_xf86Modes.h" +#include "xf86Priv.h" + +extern XF86ConfigPtr xf86configptr; /** * @file this file contains symbols from xf86Mode.c and friends that are static @@ -550,3 +553,110 @@ xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new) return modes; } + +/** + * Build a mode list from a list of config file modes + */ +static DisplayModePtr +i830xf86GetConfigModes (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 +i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor) +{ + DisplayModePtr modes = NULL; + XF86ConfModesLinkPtr modes_link; + + /* + * 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, + i830xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst)); + } + + return xf86ModesAdd (modes, + i830xf86GetConfigModes (conf_monitor->mon_modeline_lst)); +} + +/** + * Build a mode list containing all of the default modes + */ +DisplayModePtr +i830xf86GetDefaultModes (void) +{ + DisplayModePtr head = NULL, prev = NULL, mode; + int i; + + for (i = 0; xf86DefaultModes[i].name != NULL; i++) + { + 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/i830_xf86Modes.h b/src/i830_xf86Modes.h index 98300039..280743bd 100644 --- a/src/i830_xf86Modes.h +++ b/src/i830_xf86Modes.h @@ -28,6 +28,7 @@ #ifndef _I830_XF86MODES_H_ #define _I830_XF86MODES_H_ #include "xorgVersion.h" +#include "xf86Parser.h" #if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) double i830_xf86ModeHSync(DisplayModePtr mode); @@ -41,6 +42,10 @@ Bool i830_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2); void i830_xf86PrintModeline(int scrnIndex,DisplayModePtr mode); DisplayModePtr i830_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new); +DisplayModePtr i830_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); +DisplayModePtr i830_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, + Bool Reduced, Bool Interlaced); + #define xf86ModeHSync i830_xf86ModeHSync #define xf86ModeVRefresh i830_xf86ModeVRefresh #define xf86DuplicateMode i830_xf86DuplicateMode @@ -50,6 +55,8 @@ DisplayModePtr i830_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new); #define xf86ModesEqual i830_xf86ModesEqual #define xf86PrintModeline i830_xf86PrintModeline #define xf86ModesAdd i830_xf86ModesAdd +#define xf86DDCGetModes i830_xf86DDCGetModes +#define xf86CVTMode i830_xf86CVTMode #endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */ void @@ -79,4 +86,10 @@ i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, void i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList); +DisplayModePtr +i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor); + +DisplayModePtr +i830xf86GetDefaultModes (void); + #endif /* _I830_XF86MODES_H_ */