xf86-video-intel: 2 commits - src/i830_lvds.c src/i830_tv.c

Keith Packard keithp at kemper.freedesktop.org
Fri Mar 23 10:27:23 EET 2007


 src/i830_lvds.c |   11 +
 src/i830_tv.c   |  363 +++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 292 insertions(+), 82 deletions(-)

New commits:
diff-tree 26f32ef680a19e63af4b7c8c84141fe32263f298 (from f48dc501fbf74e0ac348f0b77750016597849ef4)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Fri Mar 23 01:17:58 2007 -0700

    Property size is in units, not bytes.
    
    Several places were using byte lengths instead of unit lengths for
    properties.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 8248510..a05d15d 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -334,7 +334,7 @@ i830_lvds_create_resources(xf86OutputPtr
     /* Set the current value of the backlight property */
     data = pI830->backlight_duty_cycle;
     err = RRChangeOutputProperty(output->randr_output, backlight_atom,
-				 XA_INTEGER, 32, PropModeReplace, 4, &data,
+				 XA_INTEGER, 32, PropModeReplace, 1, &data,
 				 FALSE, TRUE);
     if (err != 0) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -356,7 +356,7 @@ i830_lvds_set_property(xf86OutputPtr out
 	INT32 val;
 
 	if (value->type != XA_INTEGER || value->format != 32 ||
-	    value->size != 4)
+	    value->size != 1)
 	{
 	    return FALSE;
 	}
diff --git a/src/i830_tv.c b/src/i830_tv.c
index dc58cd6..ac521c1 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -1511,7 +1511,7 @@ i830_tv_create_resources(xf86OutputPtr o
 	/* Set the current value of the tv_format property */
 	err = RRChangeOutputProperty(output->randr_output, margin_atoms[i],
 				     XA_INTEGER, 32, PropModeReplace,
-				     4, &dev_priv->margin[i],
+				     1, &dev_priv->margin[i],
 				     FALSE, TRUE);
 	RRPostPendingProperty (output->randr_output, margin_atoms[i]);
 	if (err != 0) {
diff-tree f48dc501fbf74e0ac348f0b77750016597849ef4 (from 20b26854abdacb6dc45cba2d81d515b2e47e25f1)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Fri Mar 23 01:08:08 2007 -0700

    TV output properties: TV_FORMAT, LEFT, TOP, RIGHT, BOTTOM.
    
    Remove TV format from mode name, instead use an explicit output property and
    split the input resolution from the tv format. Add properties to set the
    blank area on all four sides of the image.

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 6f7750a..8248510 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -335,7 +335,7 @@ i830_lvds_create_resources(xf86OutputPtr
     data = pI830->backlight_duty_cycle;
     err = RRChangeOutputProperty(output->randr_output, backlight_atom,
 				 XA_INTEGER, 32, PropModeReplace, 4, &data,
-				 FALSE);
+				 FALSE, TRUE);
     if (err != 0) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "RRChangeOutputProperty error, %d\n", err);
@@ -356,7 +356,7 @@ i830_lvds_set_property(xf86OutputPtr out
 	INT32 val;
 
 	if (value->type != XA_INTEGER || value->format != 32 ||
-	    value->size != 1)
+	    value->size != 4)
 	{
 	    return FALSE;
 	}
@@ -365,8 +365,11 @@ i830_lvds_set_property(xf86OutputPtr out
 	if (val < 0 || val > i830_lvds_get_max_backlight(pScrn))
 	    return FALSE;
 
-	i830_lvds_set_backlight(pScrn, val);
-	pI830->backlight_duty_cycle = val;
+	if (val != pI830->backlight_duty_cycle)
+	{
+	    i830_lvds_set_backlight(pScrn, val);
+	    pI830->backlight_duty_cycle = val;
+	}
 	return TRUE;
     }
 
diff --git a/src/i830_tv.c b/src/i830_tv.c
index d7f4f56..dc58cd6 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -36,7 +36,9 @@
 #include "xf86.h"
 #include "i830.h"
 #include "i830_display.h"
+#include "X11/Xatom.h"
 #include <string.h>
+
 enum tv_type {
     TV_TYPE_NONE,
     TV_TYPE_UNKNOWN,
@@ -45,9 +47,16 @@ enum tv_type {
     TV_TYPE_COMPONENT
 };
 
+enum tv_margin {
+    TV_MARGIN_LEFT, TV_MARGIN_TOP,
+    TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
+};
+
 /** Private structure for the integrated TV support */
 struct i830_tv_priv {
     int type;
+    char *tv_format;
+    int margin[4];
     CARD32 save_TV_H_CTL_1;
     CARD32 save_TV_H_CTL_2;
     CARD32 save_TV_H_CTL_3;
@@ -151,6 +160,7 @@ static const CARD32 filter_table[] = {
 typedef struct {
     char *name;
     int	clock;
+    double refresh;
     CARD32 oversample;
     int hsync_end, hblank_start, hblank_end, htotal;
     Bool progressive, trilevel_sync, component_only;
@@ -215,6 +225,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name		= "NTSC-M",
 	.clock		= 107520,	
+	.refresh	= 29.97,
 	.oversample	= TV_OVERSAMPLE_8X,
 	.component_only = 0,
 	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
@@ -265,6 +276,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name		= "NTSC-443",
 	.clock		= 107520,	
+	.refresh	= 29.97,
 	.oversample	= TV_OVERSAMPLE_8X,
 	.component_only = 0,
 	/* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
@@ -314,6 +326,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name		= "NTSC-J",
 	.clock		= 107520,	
+	.refresh	= 29.97,
 	.oversample	= TV_OVERSAMPLE_8X,
 	.component_only = 0,
 
@@ -364,6 +377,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name		= "PAL-M",
 	.clock		= 107520,	
+	.refresh	= 29.97,
 	.oversample	= TV_OVERSAMPLE_8X,
 	.component_only = 0,
 
@@ -415,6 +429,7 @@ const static tv_mode_t tv_modes[] = {
 	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
 	.name	    = "PAL-N",
 	.clock		= 107520,	
+	.refresh	= 25.0,
 	.oversample	= TV_OVERSAMPLE_8X,
 	.component_only = 0,
 
@@ -467,6 +482,7 @@ const static tv_mode_t tv_modes[] = {
 	/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
 	.name	    = "PAL",
 	.clock		= 107520,	
+	.refresh	= 25.0,
 	.oversample	= TV_OVERSAMPLE_8X,
 	.component_only = 0,
 
@@ -516,6 +532,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "480p at 59.94Hz",
 	.clock 	= 107520,	
+	.refresh	= 59.94,
 	.oversample     = TV_OVERSAMPLE_4X,
 	.component_only = 1,
 
@@ -539,6 +556,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "480p at 60Hz",
 	.clock 	= 107520,	
+	.refresh	= 60.0,
 	.oversample     = TV_OVERSAMPLE_4X,
 	.component_only = 1,
 
@@ -562,6 +580,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "576p",
 	.clock 	= 107520,	
+	.refresh	= 59.94,
 	.oversample     = TV_OVERSAMPLE_4X,
 	.component_only = 1,
 
@@ -585,6 +604,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "720p at 60Hz",
 	.clock		= 148800,	
+	.refresh	= 60.0,
 	.oversample     = TV_OVERSAMPLE_2X,
 	.component_only = 1,
 
@@ -608,6 +628,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "720p at 59.94Hz",
 	.clock		= 148800,	
+	.refresh	= 59.94,
 	.oversample     = TV_OVERSAMPLE_2X,
 	.component_only = 1,
 
@@ -631,6 +652,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "720p at 50Hz",
 	.clock		= 148800,	
+	.refresh	= 50.0,
 	.oversample     = TV_OVERSAMPLE_2X,
 	.component_only = 1,
 
@@ -655,6 +677,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "1080i at 50Hz",
 	.clock		= 148800,	
+	.refresh	= 25.0,
 	.oversample     = TV_OVERSAMPLE_2X,
 	.component_only = 1,
 
@@ -680,6 +703,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "1080i at 60Hz",
 	.clock		= 148800,	
+	.refresh	= 30.0,
 	.oversample     = TV_OVERSAMPLE_2X,
 	.component_only = 1,
 
@@ -705,6 +729,7 @@ const static tv_mode_t tv_modes[] = {
     {
 	.name       = "1080i at 59.94Hz",
 	.clock		= 148800,	
+	.refresh	= 29.97,
 	.oversample     = TV_OVERSAMPLE_2X,
 	.component_only = 1,
 
@@ -895,10 +920,38 @@ i830_tv_restore(xf86OutputPtr output)
     OUTREG(TV_CTL, dev_priv->save_TV_CTL);
 }
 
+static const tv_mode_t *
+i830_tv_mode_lookup (char *tv_format)
+{
+    int			    i;
+    
+    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) 
+    {
+	const tv_mode_t	*tv_mode = &tv_modes[i];
+
+	if (xf86nameCompare (tv_format, tv_mode->name) == 0)
+	    return tv_mode;
+    }
+    return NULL;
+}
+
+static const tv_mode_t *
+i830_tv_mode_find (xf86OutputPtr output)
+{
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+
+    return i830_tv_mode_lookup (dev_priv->tv_format);
+}
+
 static int
-i830_tv_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+i830_tv_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
 {
+    const tv_mode_t	*tv_mode = i830_tv_mode_find (output);
+    
+    if (tv_mode && fabs (tv_mode->refresh - xf86ModeVRefresh (mode)) < 1.0)
 	return MODE_OK;
+    return MODE_CLOCK_RANGE;
 }
 
 
@@ -906,24 +959,24 @@ static Bool
 i830_tv_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		DisplayModePtr adjusted_mode)
 {
-	ScrnInfoPtr pScrn = output->scrn;
-	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-	int i;
-
-	for (i = 0; i < xf86_config->num_output; i++) {
-		xf86OutputPtr other_output = xf86_config->output[i];
-
-		if (other_output != output && other_output->crtc == output->crtc) {
-			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-					"Can't enable TV and another output on the same "
-					"pipe\n");
-			return FALSE;
-		}
-	}
+    ScrnInfoPtr		pScrn = output->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			i;
+    const tv_mode_t	*tv_mode = i830_tv_mode_find (output);
+
+    if (!tv_mode)
+	return FALSE;
+    
+    for (i = 0; i < xf86_config->num_output; i++) 
+    {
+	xf86OutputPtr other_output = xf86_config->output[i];
 
-	/* XXX: fill me in */
+	if (other_output != output && other_output->crtc == output->crtc)
+	    return FALSE;
+    }
 
-	return TRUE;
+    adjusted_mode->Clock = tv_mode->clock;
+    return TRUE;
 }
 
 static CARD32
@@ -973,7 +1026,7 @@ i830_tv_mode_set(xf86OutputPtr output, D
     I830OutputPrivatePtr    intel_output = output->driver_private;
     I830CrtcPrivatePtr	    intel_crtc = crtc->driver_private;
     struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-    const tv_mode_t	    *tv_mode;
+    const tv_mode_t	    *tv_mode = i830_tv_mode_find (output);
     CARD32		    tv_ctl;
     CARD32		    hctl1, hctl2, hctl3;
     CARD32		    vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -982,11 +1035,10 @@ i830_tv_mode_set(xf86OutputPtr output, D
     const video_levels_t	*video_levels;
     const color_conversion_t	*color_conversion;
     Bool burst_ena;
-    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
-	tv_mode = &tv_modes[i];
-	if (strstr(mode->name, tv_mode->name))
-	    break;	
-    }
+    
+    if (!tv_mode)
+	return;	/* can't happen (mode_prepare prevents this) */
+    
     tv_ctl = 0;
 
     switch (dev_priv->type) {
@@ -1157,6 +1209,12 @@ i830_tv_mode_set(xf86OutputPtr output, D
 	else
 	    ysize = 2*tv_mode->nbr_end + 1;
 
+	xpos += dev_priv->margin[TV_MARGIN_LEFT];
+	ypos += dev_priv->margin[TV_MARGIN_TOP];
+	xsize -= (dev_priv->margin[TV_MARGIN_LEFT] + 
+		  dev_priv->margin[TV_MARGIN_RIGHT]);
+	ysize -= (dev_priv->margin[TV_MARGIN_TOP] + 
+		  dev_priv->margin[TV_MARGIN_BOTTOM]);
 	OUTREG(TV_WIN_POS, (xpos<<16)|ypos);
 	OUTREG(TV_WIN_SIZE, (xsize<<16)|ysize);
 
@@ -1333,62 +1391,51 @@ static struct input_res {
 static DisplayModePtr
 i830_tv_get_modes(xf86OutputPtr output)
 {
-    DisplayModePtr  ret = NULL, mode_ptr;
-    int		    i, j;
-    I830OutputPrivatePtr    intel_output = output->driver_private;
-    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
-
-    for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) 
-    {
-	const tv_mode_t *tv_mode = &tv_modes[i];
-	unsigned int hactive = tv_mode->hblank_start - tv_mode->hblank_end;
-	unsigned int vactive = tv_mode->progressive
-	    ?tv_mode->nbr_end + 1: 2*(tv_mode->nbr_end + 1);
-	unsigned int htotal = tv_mode->htotal + 1;
-	unsigned int vtotal = tv_mode->progressive
-	    ?tv_mode->nbr_end + 1 + tv_mode->vi_end_f2:
-	    2*(tv_mode->nbr_end+1) + 2*(tv_mode->vi_end_f2);
+    DisplayModePtr	ret = NULL, mode_ptr;
+    int			j;
+    const tv_mode_t	*tv_mode = i830_tv_mode_find (output);
+
+    for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++)
+    {
+	struct input_res *input = &input_res_table[j];
+	unsigned int hactive_s = input->w;
+	unsigned int vactive_s = input->h;
+	
+	if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
+	    continue;
 
-	if (dev_priv->type != TV_TYPE_COMPONENT && tv_mode->component_only)
+	if (input->w > 1024 && (!tv_mode->progressive 
+				&& !tv_mode->component_only))
 	    continue;
 
-	for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++)	{
-	    struct input_res *input = &input_res_table[j];
-	    unsigned int hactive_s = input->w;
-	    unsigned int vactive_s = input->h;
-	    unsigned int htotal_s = htotal*hactive_s/hactive;
-	    unsigned int vtotal_s = vtotal*vactive_s/vactive;
-	    if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
-		continue;
-	    if (input->w > 1024 && (!tv_mode->progressive 
-			&& !tv_mode->component_only))
-		continue;
-	    mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
-	    mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
-		    strlen(input->name) + 4);
-	    sprintf(mode_ptr->name, "%s %s", tv_mode->name, input->name);
-
-	    mode_ptr->Clock = tv_mode->clock;
-
-	    mode_ptr->HDisplay = hactive_s;
-	    mode_ptr->HSyncStart = hactive_s + 1;
-	    mode_ptr->HSyncEnd = htotal_s - 20;  
-	    if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart)
-		mode_ptr->HSyncEnd = mode_ptr->HSyncStart  + 1;
-	    mode_ptr->HTotal = htotal_s;
-
-	    mode_ptr->VDisplay = vactive_s;
-	    mode_ptr->VSyncStart = vactive_s + 1;
-	    mode_ptr->VSyncEnd = vtotal_s - 20;
-	    if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart)
-		mode_ptr->VSyncEnd = mode_ptr->VSyncStart  + 1;
-	    mode_ptr->VTotal = vtotal_s;
-
-	    mode_ptr->type = M_T_DRIVER;
-	    mode_ptr->next = ret;
-	    ret = mode_ptr;
-	} 
-    }
+	mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec));
+    	mode_ptr->name = xnfalloc(strlen(tv_mode->name) + 
+				  strlen(input->name) + 4);
+	sprintf(mode_ptr->name, "%s", input->name);
+
+
+	mode_ptr->HDisplay = hactive_s;
+	mode_ptr->HSyncStart = hactive_s + 1;
+	mode_ptr->HSyncEnd = hactive_s + 64;
+	if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart)
+	    mode_ptr->HSyncEnd = mode_ptr->HSyncStart  + 1;
+	mode_ptr->HTotal = hactive_s + 96;
+
+	mode_ptr->VDisplay = vactive_s;
+	mode_ptr->VSyncStart = vactive_s + 1;
+	mode_ptr->VSyncEnd = vactive_s + 32;
+	if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart)
+	    mode_ptr->VSyncEnd = mode_ptr->VSyncStart  + 1;
+	mode_ptr->VTotal = vactive_s + 33;
+
+	mode_ptr->Clock = (int) (tv_mode->refresh * 
+				 mode_ptr->VTotal * 
+				 mode_ptr->HTotal / 1000.0);
+	
+	mode_ptr->type = M_T_DRIVER;
+	mode_ptr->next = ret;
+	ret = mode_ptr;
+    } 
 
     return ret;
 }
@@ -1400,7 +1447,145 @@ i830_tv_destroy (xf86OutputPtr output)
 	xfree (output->driver_private);
 }
 
+#ifdef RANDR_12_INTERFACE
+#define TV_FORMAT_NAME	"TV_FORMAT"
+static Atom tv_format_atom;
+static Atom margin_atoms[4];
+static char *margin_names[4] = {
+    "LEFT", "TOP", "RIGHT", "BOTTOM"
+};
+#endif /* RANDR_12_INTERFACE */
+
+static void
+i830_tv_create_resources(xf86OutputPtr output)
+{
+#ifdef RANDR_12_INTERFACE
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    struct i830_tv_priv	    *dev_priv = intel_output->dev_priv;
+    int			    err;
+    int			    i;
+
+    /* Set up the tv_format property, which takes effect on mode set
+     * and accepts strings that match exactly
+     */
+    tv_format_atom = MakeAtom(TV_FORMAT_NAME, sizeof(TV_FORMAT_NAME) - 1,
+	TRUE);
+
+    err = RRConfigureOutputProperty(output->randr_output, tv_format_atom,
+				    TRUE, FALSE, FALSE, 0, NULL);
+    
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "RRConfigureOutputProperty error, %d\n", err);
+    }
+
+    /* Set the current value of the tv_format property */
+    err = RRChangeOutputProperty(output->randr_output, tv_format_atom,
+				 XA_STRING, 8, PropModeReplace,
+				 strlen (dev_priv->tv_format),
+				 dev_priv->tv_format,
+				 FALSE, TRUE);
+    RRPostPendingProperty (output->randr_output, tv_format_atom);
+    if (err != 0) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "RRChangeOutputProperty error, %d\n", err);
+    }
+
+    for (i = 0; i < 4; i++)
+    {
+	INT32	range[2];
+	margin_atoms[i] = MakeAtom(margin_names[i], strlen (margin_names[i]),
+				   TRUE);
+
+	range[0] = 0;
+	range[1] = 100;
+	err = RRConfigureOutputProperty(output->randr_output, margin_atoms[i],
+				    TRUE, TRUE, FALSE, 2, range);
+    
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+
+	/* Set the current value of the tv_format property */
+	err = RRChangeOutputProperty(output->randr_output, margin_atoms[i],
+				     XA_INTEGER, 32, PropModeReplace,
+				     4, &dev_priv->margin[i],
+				     FALSE, TRUE);
+	RRPostPendingProperty (output->randr_output, margin_atoms[i]);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+#endif /* RANDR_12_INTERFACE */
+}
+
+static void
+i830_tv_commit (xf86OutputPtr output)
+{
+#ifdef RANDR_12_INTERFACE
+    if (output->randr_output)
+	RRPostPendingProperty (output->randr_output, tv_format_atom);
+#endif    
+    i830_output_commit (output);
+}
+
+#ifdef RANDR_12_INTERFACE
+static Bool
+i830_tv_set_property(xf86OutputPtr output, Atom property,
+		       RRPropertyValuePtr value)
+{
+    int	i;
+    
+    if (property == tv_format_atom) 
+    {
+	I830OutputPrivatePtr    intel_output = output->driver_private;
+	struct i830_tv_priv	*dev_priv = intel_output->dev_priv;
+	char			*val;
+
+	if (value->type != XA_STRING || value->format != 8)
+	    return FALSE;
+
+	val = xalloc (value->size + 1);
+	if (!val)
+	    return FALSE;
+	memcpy (val, value->data, value->size);
+	val[value->size] = '\0';
+	if (!i830_tv_mode_lookup (val))
+	{
+	    xfree (val);
+	    return FALSE;
+	}
+	xfree (dev_priv->tv_format);
+	dev_priv->tv_format = val;
+	return TRUE;
+    }
+    for (i = 0; i < 4; i++)
+    {
+	if (property == margin_atoms[i])
+	{
+	    I830OutputPrivatePtr    intel_output = output->driver_private;
+	    struct i830_tv_priv	*dev_priv = intel_output->dev_priv;
+	    INT32		val;
+
+	    if (value->type != XA_INTEGER || value->format != 32 ||
+		value->size != 1)
+		return FALSE;
+
+	    memcpy (&val, value->data, 4);
+	    dev_priv->margin[i] = val;
+	    return TRUE;
+	}
+    }
+
+    return TRUE;
+}
+#endif /* RANDR_12_INTERFACE */
+
 static const xf86OutputFuncsRec i830_tv_output_funcs = {
+    .create_resources = i830_tv_create_resources,
     .dpms = i830_tv_dpms,
     .save = i830_tv_save,
     .restore = i830_tv_restore,
@@ -1408,10 +1593,13 @@ static const xf86OutputFuncsRec i830_tv_
     .mode_fixup = i830_tv_mode_fixup,
     .prepare = i830_output_prepare,
     .mode_set = i830_tv_mode_set,
-    .commit = i830_output_commit,
+    .commit = i830_tv_commit,
     .detect = i830_tv_detect,
     .get_modes = i830_tv_get_modes,
-    .destroy = i830_tv_destroy
+    .destroy = i830_tv_destroy,
+#ifdef RANDR_12_INTERFACE
+    .set_property = i830_tv_set_property,
+#endif
 };
 
 void
@@ -1466,6 +1654,25 @@ i830_tv_init(ScrnInfoPtr pScrn)
     intel_output->dev_priv = dev_priv;
     dev_priv->type = TV_TYPE_UNKNOWN;
 
+    dev_priv->tv_format = NULL;
+    
+    /* BIOS margin values */
+    dev_priv->margin[TV_MARGIN_LEFT] = 54;
+    dev_priv->margin[TV_MARGIN_TOP] = 36;
+    dev_priv->margin[TV_MARGIN_RIGHT] = 46;
+    dev_priv->margin[TV_MARGIN_BOTTOM] = 37;
+    
+    if (output->conf_monitor)
+    {
+	char	*tv_format;
+	
+	tv_format = xf86findOptionValue (output->conf_monitor->mon_option_lst, "TV Format");
+	if (tv_format)
+	    dev_priv->tv_format = xstrdup (tv_format);
+    }
+    if (!dev_priv->tv_format)
+	dev_priv->tv_format = xstrdup (tv_modes[0].name);
+    
     output->driver_private = intel_output;
     output->interlaceAllowed = FALSE;
     output->doubleScanAllowed = FALSE;



More information about the xorg-commit mailing list