xf86-video-intel: Branch 'modesetting' - 2 commits - src/i830_crt.c src/i830_display.h src/i830_lvds.c src/i830_modes.c src/i830_xf86Crtc.c src/i830_xf86Crtc.h src/i830_xf86Modes.c src/i830_xf86Modes.h

Keith Packard keithp at kemper.freedesktop.org
Fri Dec 29 02:38:33 EET 2006


 src/i830_crt.c       |   34 -----
 src/i830_display.h   |   11 -
 src/i830_lvds.c      |   45 ++++++-
 src/i830_modes.c     |  102 +---------------
 src/i830_xf86Crtc.c  |  316 +++++++++++++++++++++++++++++++++++++++++++++++++--
 src/i830_xf86Crtc.h  |   23 +++
 src/i830_xf86Modes.c |  110 +++++++++++++++++
 src/i830_xf86Modes.h |   13 ++
 8 files changed, 503 insertions(+), 151 deletions(-)

New commits:
diff-tree 2b0a997e5b4b51267fa4f6725f8a965093392434 (from parents)
Merge: bb238a8fc234a8e5e86cd2f42c58c9816a15732c 9cfbf1ceda8f153438df1ba4b1712c55cc872017
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Dec 28 16:34:38 2006 -0800

    Merge branch 'modesetting-origin' into modesetting

diff-tree bb238a8fc234a8e5e86cd2f42c58c9816a15732c (from c87462ded20904dbc6c6cbdb9547523b75fe5471)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Thu Dec 28 16:27:22 2006 -0800

    Configuration support: per-output mode lines, preferred mode.
    
    Add the modelines specified in the per-output monitor and all of the default
    modes to the list to each output. Prune the resulting list to specified sync
    limits and virtual sizes. Sort the resulting mode list on
    preferred/size/refresh.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index 3be10ec..85c25de 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
     .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 8a982ab..5517d27 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -42,14 +42,3 @@ xf86CrtcPtr i830GetLoadDetectPipe(xf86Ou
 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 b682b27..fe96413 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 42ee79d..b4e22c3 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -55,98 +55,16 @@
 #include "i830_xf86Modes.h"
 #include <randrstr.h>
 
-#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;
-
-    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;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    xf86MonPtr		    edid_mon;
+    DisplayModePtr	    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 0c482a2..763df43 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, 
     if (output->name != (char *) (output + 1))
 	xfree (output->name);
     output->name = newname;
+    xf86OutputSetMonitor (output);
 }
 
 void
@@ -446,12 +478,61 @@ xf86PruneDuplicateMonitorModes (MonPtr M
     }
 }
 
+/** 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.
+	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 at 60Hz mode by default,
+	 * which seems like a fairly good mode to use when nothing else is
+	 * specified
 	 */
-	if (output->MonInfo != NULL && !properties_set) {
-	    xf86SetDDCproperties(pScrn, output->MonInfo);
-	    properties_set = TRUE;
+	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,
 	}
     }
 }
+
+#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 9294ccc..168d89d 100644
--- a/src/i830_xf86Crtc.h
+++ b/src/i830_xf86Crtc.h
@@ -25,6 +25,7 @@
 #include <edid.h>
 #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 pS
 
 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 1afda95..58a6e6f 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, Displ
 
     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 9830003..280743b 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 
 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(Display
 #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 p
 void
 i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
 
+DisplayModePtr
+i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
+
+DisplayModePtr
+i830xf86GetDefaultModes (void);
+
 #endif /* _I830_XF86MODES_H_ */



More information about the xorg-commit mailing list