Initial panel fitting changes
Basic support for panel fitting.
This commit is contained in:
parent
402fbd3622
commit
05cf07071e
|
|
@ -225,6 +225,24 @@ This method attempts to use the native registers where possible, resorting to th
|
|||
.TP 4
|
||||
On some system, the kernel may provide a backlight control driver. In that case, using the kernel interfaces is preferable, as the same driver may respond to hotkey events or external APIs.
|
||||
|
||||
.PP
|
||||
.B PANEL_FITTING
|
||||
- control LCD panel fitting
|
||||
.TP 2
|
||||
By default, the driver will attempt to upscale resolutions smaller than the LCD's native size while preserving the aspect ratio. Other modes are available however:
|
||||
.PP
|
||||
.B CENTER
|
||||
.TP 4
|
||||
Simply center the image on-screen, without scaling.
|
||||
.PP
|
||||
.B FULL_ASPECT
|
||||
.TP 4
|
||||
The default mode. Try to upscale the image to the screen size, while preserving aspect ratio. May result in letterboxing or pillar-boxing with some resolutions.
|
||||
.PP
|
||||
.B FULL
|
||||
.TP 4
|
||||
Upscale the image to the native screen size without regard to aspect ratio. In this mode, the full screen image may appear distorted in some resolutions.
|
||||
|
||||
.SS "TV"
|
||||
Integrated TV output. Available properties include:
|
||||
|
||||
|
|
|
|||
|
|
@ -871,8 +871,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define PFIT_CONTROL 0x61230
|
||||
# define PFIT_ENABLE (1 << 31)
|
||||
# define PFIT_PIPE_MASK (3 << 29)
|
||||
# define PFIT_PIPE_SHIFT 29
|
||||
/* Pre-965 */
|
||||
# define VERT_INTERP_DISABLE (0 << 10)
|
||||
# define VERT_INTERP_BILINEAR (1 << 10)
|
||||
# define VERT_INTERP_MASK (3 << 10)
|
||||
|
|
@ -882,12 +881,30 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
# define HORIZ_INTERP_MASK (3 << 6)
|
||||
# define HORIZ_AUTO_SCALE (1 << 5)
|
||||
# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
|
||||
/* 965+ */
|
||||
# define PFIT_PIPE_MASK (3 << 29)
|
||||
# define PFIT_PIPE_SHIFT 29
|
||||
# define PFIT_SCALING_MODE_MASK (7 << 26)
|
||||
# define PFIT_SCALING_AUTO (0 << 26)
|
||||
# define PFIT_SCALING_PROGRAMMED (1 << 26)
|
||||
# define PFIT_SCALING_PILLAR (2 << 26)
|
||||
# define PFIT_SCALING_LETTER (3 << 26)
|
||||
# define PFIT_FILTER_SELECT_MASK (3 << 24)
|
||||
# define PFIT_FILTER_FUZZY (0 << 24)
|
||||
# define PFIT_FILTER_CRISP (1 << 24)
|
||||
# define PFIT_FILTER_MEDIAN (2 << 24)
|
||||
|
||||
#define PFIT_PGM_RATIOS 0x61234
|
||||
/* Pre-965 */
|
||||
# define PFIT_VERT_SCALE_SHIFT 20
|
||||
# define PFIT_VERT_SCALE_MASK 0xfff00000
|
||||
# define PFIT_HORIZ_SCALE_SHIFT 4
|
||||
# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
|
||||
|
||||
#define PFIT_AUTO_RATIOS 0x61238
|
||||
/* 965+ */
|
||||
# define PFIT_VERT_SCALE_SHIFT_965 16
|
||||
# define PFIT_VERT_SCALE_MASK_965 0x1fff0000
|
||||
# define PFIT_HORIZ_SCALE_SHIFT_965 0
|
||||
# define PFIT_HORIZ_SCALE_MASK_965 0x00001fff
|
||||
|
||||
#define DPLL_A 0x06014
|
||||
#define DPLL_B 0x06018
|
||||
|
|
|
|||
370
src/i830_lvds.c
370
src/i830_lvds.c
|
|
@ -44,12 +44,25 @@
|
|||
#include "i830_display.h"
|
||||
#include "X11/Xatom.h"
|
||||
|
||||
/*
|
||||
* Three panel fitting modes:
|
||||
* CENTER - center image on screen, don't scale
|
||||
* FULL_ASPECT - scale image to fit screen, but preserve aspect ratio
|
||||
* FULL - scale image to fit screen without regard to aspect ratio
|
||||
*/
|
||||
enum pfit_mode {
|
||||
CENTER = 0,
|
||||
FULL_ASPECT,
|
||||
FULL,
|
||||
};
|
||||
|
||||
struct i830_lvds_priv {
|
||||
/* The BIOS's fixed timings for the LVDS */
|
||||
DisplayModePtr panel_fixed_mode;
|
||||
|
||||
/* The panel needs dithering enabled */
|
||||
Bool panel_wants_dither;
|
||||
Bool need_border;
|
||||
|
||||
/* restore backlight to this value */
|
||||
int backlight_duty_cycle;
|
||||
|
|
@ -57,6 +70,9 @@ struct i830_lvds_priv {
|
|||
void (*set_backlight)(xf86OutputPtr output, int level);
|
||||
int (*get_backlight)(xf86OutputPtr output);
|
||||
int backlight_max;
|
||||
enum pfit_mode fitting_mode;
|
||||
uint32_t pfit_control;
|
||||
uint32_t pfit_pgm_ratios;
|
||||
};
|
||||
|
||||
#define BACKLIGHT_CLASS "/sys/class/backlight"
|
||||
|
|
@ -481,7 +497,13 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
|||
ScrnInfoPtr pScrn = output->scrn;
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
uint32_t pfit_control = 0, pfit_pgm_ratios = 0;
|
||||
float panel_ratio, desired_ratio, vert_scale, horiz_scale;
|
||||
float horiz_ratio, vert_ratio;
|
||||
int left_border = 0, right_border = 0, top_border = 0, bottom_border = 0;
|
||||
int i;
|
||||
Bool border = 0;
|
||||
|
||||
for (i = 0; i < xf86_config->num_output; i++) {
|
||||
xf86OutputPtr other_output = xf86_config->output[i];
|
||||
|
|
@ -500,24 +522,207 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we don't have a panel mode there's not much we can do */
|
||||
if (dev_priv->panel_fixed_mode == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* If we have timings from the BIOS for the panel, put them in
|
||||
* to the adjusted mode. The CRTC will be set up for this mode,
|
||||
* with the panel scaling set up to source from the H/VDisplay
|
||||
* of the original mode.
|
||||
*/
|
||||
if (dev_priv->panel_fixed_mode != NULL) {
|
||||
adjusted_mode->HDisplay = dev_priv->panel_fixed_mode->HDisplay;
|
||||
adjusted_mode->HSyncStart = dev_priv->panel_fixed_mode->HSyncStart;
|
||||
adjusted_mode->HSyncEnd = dev_priv->panel_fixed_mode->HSyncEnd;
|
||||
adjusted_mode->HTotal = dev_priv->panel_fixed_mode->HTotal;
|
||||
adjusted_mode->VDisplay = dev_priv->panel_fixed_mode->VDisplay;
|
||||
adjusted_mode->VSyncStart = dev_priv->panel_fixed_mode->VSyncStart;
|
||||
adjusted_mode->VSyncEnd = dev_priv->panel_fixed_mode->VSyncEnd;
|
||||
adjusted_mode->VTotal = dev_priv->panel_fixed_mode->VTotal;
|
||||
adjusted_mode->Clock = dev_priv->panel_fixed_mode->Clock;
|
||||
xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
|
||||
adjusted_mode->HDisplay = dev_priv->panel_fixed_mode->HDisplay;
|
||||
adjusted_mode->HSyncStart = dev_priv->panel_fixed_mode->HSyncStart;
|
||||
adjusted_mode->HSyncEnd = dev_priv->panel_fixed_mode->HSyncEnd;
|
||||
adjusted_mode->HTotal = dev_priv->panel_fixed_mode->HTotal;
|
||||
adjusted_mode->VDisplay = dev_priv->panel_fixed_mode->VDisplay;
|
||||
adjusted_mode->VSyncStart = dev_priv->panel_fixed_mode->VSyncStart;
|
||||
adjusted_mode->VSyncEnd = dev_priv->panel_fixed_mode->VSyncEnd;
|
||||
adjusted_mode->VTotal = dev_priv->panel_fixed_mode->VTotal;
|
||||
adjusted_mode->Clock = dev_priv->panel_fixed_mode->Clock;
|
||||
xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
|
||||
|
||||
/* Native modes don't need fitting */
|
||||
if (adjusted_mode->HDisplay == mode->HDisplay &&
|
||||
adjusted_mode->VDisplay == mode->VDisplay) {
|
||||
pfit_control = 0;
|
||||
pfit_pgm_ratios = 0;
|
||||
border = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Basic panel fitting options */
|
||||
if (!IS_I965G(pI830)) {
|
||||
if (dev_priv->panel_wants_dither)
|
||||
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
|
||||
} else {
|
||||
pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) |
|
||||
PFIT_FILTER_FUZZY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deal with panel fitting options. Figure out how to stretch the image
|
||||
* based on its aspect ratio & the current panel fitting mode.
|
||||
*/
|
||||
panel_ratio = (float)adjusted_mode->HDisplay /
|
||||
(float)adjusted_mode->VDisplay;
|
||||
desired_ratio = (float)mode->HDisplay /
|
||||
(float)mode->VDisplay;
|
||||
|
||||
/*
|
||||
* Enable automatic panel scaling for non-native modes so that they fill
|
||||
* the screen. Should be enabled before the pipe is enabled, according to
|
||||
* register description and PRM.
|
||||
*/
|
||||
/* Change the value here to see the borders for debugging */
|
||||
OUTREG(BCLRPAT_A, 0);
|
||||
OUTREG(BCLRPAT_B, 0);
|
||||
switch (dev_priv->fitting_mode) {
|
||||
case CENTER:
|
||||
/*
|
||||
* For centered modes, we have to calculate border widths & heights and
|
||||
* modify the values programmed into the CRTC. Also need to make sure
|
||||
* LVDS borders are enabled (see i830_display.c).
|
||||
*/
|
||||
left_border =
|
||||
(dev_priv->panel_fixed_mode->HDisplay - mode->HDisplay) / 2;
|
||||
right_border = left_border;
|
||||
if (mode->HDisplay & 1)
|
||||
right_border++;
|
||||
top_border =
|
||||
(dev_priv->panel_fixed_mode->VDisplay - mode->VDisplay) / 2;
|
||||
bottom_border = top_border;
|
||||
if (mode->VDisplay & 1)
|
||||
bottom_border++;
|
||||
|
||||
/* Set active & border values */
|
||||
adjusted_mode->CrtcHDisplay = mode->HDisplay;
|
||||
adjusted_mode->CrtcHBlankStart = mode->HDisplay + right_border - 1;
|
||||
adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHTotal -
|
||||
left_border - 1;
|
||||
adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart;
|
||||
adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHBlankEnd;
|
||||
adjusted_mode->CrtcVDisplay = mode->VDisplay;
|
||||
adjusted_mode->CrtcVBlankStart = mode->VDisplay + bottom_border - 1;
|
||||
adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVTotal -
|
||||
top_border - 1;
|
||||
adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart;
|
||||
adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVBlankEnd;
|
||||
border = 1;
|
||||
break;
|
||||
case FULL_ASPECT:
|
||||
/* Scale but preserve aspect ratio */
|
||||
pfit_control |= PFIT_ENABLE;
|
||||
if (IS_I965G(pI830)) {
|
||||
/*
|
||||
* 965+ is easy, it does everything in hw
|
||||
*/
|
||||
if (panel_ratio > desired_ratio)
|
||||
pfit_control |= PFIT_SCALING_PILLAR;
|
||||
else if (panel_ratio < desired_ratio)
|
||||
pfit_control |= PFIT_SCALING_LETTER;
|
||||
else
|
||||
pfit_control |= PFIT_SCALING_AUTO;
|
||||
} else {
|
||||
/*
|
||||
* For earlier chips we have to calculate the scaling ratio
|
||||
* by hand and program it into the PFIT_PGM_RATIOS reg.
|
||||
*/
|
||||
uint32_t horiz_bits, vert_bits, bits = 12;
|
||||
|
||||
horiz_ratio = ((float)mode->HDisplay) /
|
||||
((float)adjusted_mode->HDisplay);
|
||||
vert_ratio = ((float)mode->VDisplay) /
|
||||
((float)adjusted_mode->VDisplay);
|
||||
|
||||
horiz_scale = ((float)adjusted_mode->HDisplay) /
|
||||
((float)mode->HDisplay);
|
||||
vert_scale = ((float)adjusted_mode->VDisplay) /
|
||||
((float)mode->VDisplay);
|
||||
|
||||
/* Retain aspect ratio */
|
||||
if (panel_ratio > desired_ratio) { /* Pillar */
|
||||
unsigned long scaled_width = (float)mode->HDisplay * vert_scale;
|
||||
|
||||
horiz_ratio = vert_ratio;
|
||||
pfit_control |= VERT_AUTO_SCALE | VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR;
|
||||
|
||||
/* Pillar will have left/right borders */
|
||||
left_border = (dev_priv->panel_fixed_mode->HDisplay -
|
||||
scaled_width) / 2;
|
||||
right_border = left_border;
|
||||
if (mode->HDisplay & 1) /* odd resolutions */
|
||||
right_border++;
|
||||
|
||||
adjusted_mode->CrtcHDisplay = scaled_width;
|
||||
adjusted_mode->CrtcHBlankStart = scaled_width +
|
||||
right_border - 1;
|
||||
adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHTotal -
|
||||
left_border - 1;
|
||||
adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart;
|
||||
adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHBlankEnd;
|
||||
border = 1;
|
||||
} else if (panel_ratio < desired_ratio) { /* Letter */
|
||||
unsigned long scaled_height = (float)mode->VDisplay *
|
||||
horiz_scale;
|
||||
|
||||
vert_ratio = horiz_ratio;
|
||||
pfit_control |= HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
|
||||
HORIZ_INTERP_BILINEAR;
|
||||
|
||||
/* Letterbox will have top/bottom borders */
|
||||
top_border = (dev_priv->panel_fixed_mode->VDisplay -
|
||||
mode->VDisplay) / 2;
|
||||
bottom_border = top_border;
|
||||
if (mode->VDisplay & 1)
|
||||
bottom_border++;
|
||||
|
||||
adjusted_mode->CrtcVDisplay = scaled_height;
|
||||
adjusted_mode->CrtcVBlankStart = scaled_height +
|
||||
bottom_border - 1;
|
||||
adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVTotal -
|
||||
top_border - 1;
|
||||
adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart;
|
||||
adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVBlankEnd;
|
||||
border = 1;
|
||||
} else { /* Aspects match, let hw scale both directions */
|
||||
pfit_control |= VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR;
|
||||
}
|
||||
|
||||
horiz_bits = 0.5 + (1 << bits) * horiz_ratio;
|
||||
vert_bits = 0.5 + (1 << bits) * vert_ratio;
|
||||
|
||||
pfit_pgm_ratios = (((vert_bits << PFIT_VERT_SCALE_SHIFT) &
|
||||
PFIT_VERT_SCALE_MASK) |
|
||||
((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) &
|
||||
PFIT_HORIZ_SCALE_MASK));
|
||||
}
|
||||
break;
|
||||
case FULL:
|
||||
/*
|
||||
* Full scaling, even if it changes the aspect ratio. Fortunately
|
||||
* this is all done for us in hw.
|
||||
*/
|
||||
pfit_control |= PFIT_ENABLE;
|
||||
if (IS_I965G(pI830))
|
||||
pfit_control |= PFIT_SCALING_AUTO;
|
||||
else
|
||||
pfit_control |= VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR;
|
||||
break;
|
||||
default:
|
||||
/* shouldn't happen */
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "error: bad fitting mode\n");
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
dev_priv->pfit_control = pfit_control;
|
||||
dev_priv->pfit_pgm_ratios = pfit_pgm_ratios;
|
||||
dev_priv->need_border = border;
|
||||
|
||||
/* XXX: It would be nice to support lower refresh rates on the
|
||||
* panels to reduce power consumption, and perhaps match the
|
||||
* user's requested refresh rate.
|
||||
|
|
@ -526,6 +731,28 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_lvds_prepare(xf86OutputPtr output)
|
||||
{
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_lvds_priv *dev_priv = intel_output->dev_priv;
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
uint32_t lvds;
|
||||
|
||||
lvds = INREG(LVDS);
|
||||
|
||||
i830_lvds_dpms(output, DPMSModeOff);
|
||||
/*
|
||||
* ->prepare will be called after the CRTC is off but before
|
||||
* we set the mode, so program the PFIT regs here.
|
||||
*/
|
||||
if (dev_priv->need_border)
|
||||
OUTREG(LVDS, lvds | LVDS_BORDER_ENABLE);
|
||||
else
|
||||
OUTREG(LVDS, lvds & (~LVDS_BORDER_ENABLE));
|
||||
}
|
||||
|
||||
static void
|
||||
i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
|
|
@ -534,35 +761,14 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
|||
struct i830_lvds_priv *dev_priv = intel_output->dev_priv;
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private;
|
||||
uint32_t pfit_control;
|
||||
|
||||
/* The LVDS pin pair will already have been turned on in
|
||||
* i830_crtc_mode_set since it has a large impact on the DPLL settings.
|
||||
/*
|
||||
* PFIT must be enabled/disabled while LVDS is on but pipes are still off
|
||||
*/
|
||||
|
||||
/* Enable automatic panel scaling for non-native modes so that they fill
|
||||
* the screen. Should be enabled before the pipe is enabled, according to
|
||||
* register description and PRM.
|
||||
*/
|
||||
if (mode->HDisplay != adjusted_mode->HDisplay ||
|
||||
mode->VDisplay != adjusted_mode->VDisplay)
|
||||
{
|
||||
pfit_control = PFIT_ENABLE |
|
||||
VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR;
|
||||
} else {
|
||||
pfit_control = 0;
|
||||
}
|
||||
|
||||
if (!IS_I965G(pI830)) {
|
||||
if (dev_priv->panel_wants_dither)
|
||||
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
|
||||
} else {
|
||||
pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
|
||||
}
|
||||
|
||||
OUTREG(PFIT_CONTROL, pfit_control);
|
||||
OUTREG(PFIT_PGM_RATIOS, dev_priv->pfit_pgm_ratios);
|
||||
OUTREG(PFIT_CONTROL, dev_priv->pfit_control);
|
||||
/* It's harmless to turn on the LVDS if it's already on */
|
||||
i830_lvds_dpms(output, DPMSModeOn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -653,6 +859,17 @@ static char *backlight_control_names[] = {
|
|||
static Atom backlight_control_atom;
|
||||
static Atom backlight_control_name_atoms[NUM_BACKLIGHT_CONTROL_METHODS];
|
||||
|
||||
#define PANEL_FITTING_NAME "PANEL_FITTING"
|
||||
#define NUM_PANEL_FITTING_TYPES 3
|
||||
static char *panel_fitting_names[] = {
|
||||
"center",
|
||||
"full_aspect",
|
||||
"full",
|
||||
};
|
||||
static Atom panel_fitting_atom;
|
||||
static Atom panel_fitting_name_atoms[NUM_PANEL_FITTING_TYPES];
|
||||
|
||||
|
||||
static int
|
||||
i830_backlight_control_lookup(char *name)
|
||||
{
|
||||
|
|
@ -709,6 +926,18 @@ i830_lvds_set_backlight_control(xf86OutputPtr output)
|
|||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
i830_panel_fitting_lookup(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_PANEL_FITTING_TYPES; i++)
|
||||
if (!strcmp(name, panel_fitting_names[i]))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif /* RANDR_12_INTERFACE */
|
||||
|
||||
static void
|
||||
|
|
@ -775,6 +1004,33 @@ i830_lvds_create_resources(xf86OutputPtr output)
|
|||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"failed to set backlight control, %d\n", err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Panel fitting control
|
||||
*/
|
||||
panel_fitting_atom = MakeAtom(PANEL_FITTING_NAME,
|
||||
sizeof(PANEL_FITTING_NAME) - 1, TRUE);
|
||||
for (i = 0; i < NUM_PANEL_FITTING_TYPES; i++) {
|
||||
panel_fitting_name_atoms[i] = MakeAtom(panel_fitting_names[i],
|
||||
strlen(panel_fitting_names[i]),
|
||||
TRUE);
|
||||
}
|
||||
err = RRConfigureOutputProperty(output->randr_output,
|
||||
panel_fitting_atom, TRUE, FALSE, FALSE,
|
||||
NUM_PANEL_FITTING_TYPES,
|
||||
(INT32 *)panel_fitting_name_atoms);
|
||||
if (err != 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"RRConfigureOutputProperty error, %d\n", err);
|
||||
}
|
||||
err = RRChangeOutputProperty(output->randr_output, panel_fitting_atom,
|
||||
XA_ATOM, 32, PropModeReplace, 1,
|
||||
&panel_fitting_name_atoms[dev_priv->fitting_mode],
|
||||
FALSE, TRUE);
|
||||
if (err != 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"failed to set panel fitting mode, %d\n", err);
|
||||
}
|
||||
#endif /* RANDR_12_INTERFACE */
|
||||
}
|
||||
|
||||
|
|
@ -846,6 +1102,36 @@ i830_lvds_set_property(xf86OutputPtr output, Atom property,
|
|||
"RRChangeOutputProperty error, %d\n", ret);
|
||||
}
|
||||
return TRUE;
|
||||
} else if (property == panel_fitting_atom) {
|
||||
Atom atom;
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
|
||||
return FALSE;
|
||||
|
||||
memcpy(&atom, value->data, 4);
|
||||
name = NameForAtom(atom);
|
||||
|
||||
ret = i830_panel_fitting_lookup(name);
|
||||
if (ret < 0)
|
||||
return FALSE;
|
||||
|
||||
dev_priv->fitting_mode = ret;
|
||||
|
||||
if (output->crtc) {
|
||||
xf86CrtcPtr crtc = output->crtc;
|
||||
if (crtc->enabled) {
|
||||
if (!xf86CrtcSetMode(crtc, &crtc->desiredMode,
|
||||
crtc->desiredRotation,
|
||||
crtc->desiredX, crtc->desiredY)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"Failed to set mode after panel fitting change!\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
@ -886,7 +1172,7 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = {
|
|||
.restore = i830_lvds_restore,
|
||||
.mode_valid = i830_lvds_mode_valid,
|
||||
.mode_fixup = i830_lvds_mode_fixup,
|
||||
.prepare = i830_output_prepare,
|
||||
.prepare = i830_lvds_prepare,
|
||||
.mode_set = i830_lvds_mode_set,
|
||||
.commit = i830_output_commit,
|
||||
.detect = i830_lvds_detect,
|
||||
|
|
@ -1075,6 +1361,12 @@ i830_lvds_init(ScrnInfoPtr pScrn)
|
|||
|
||||
dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output);
|
||||
|
||||
/*
|
||||
* Default to filling the whole screen if the mode is less than the
|
||||
* native size, without breaking aspect ratio.
|
||||
*/
|
||||
dev_priv->fitting_mode = FULL_ASPECT;
|
||||
|
||||
return;
|
||||
|
||||
disable_exit:
|
||||
|
|
|
|||
Loading…
Reference in New Issue