Example #1
0
static Bool
xf86RandR12CrtcSet (ScreenPtr	pScreen,
		  RRCrtcPtr	randr_crtc,
		  RRModePtr	randr_mode,
		  int		x,
		  int		y,
		  Rotation	rotation,
		  int		num_randr_outputs,
		  RROutputPtr	*randr_outputs)
{
    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
    Bool		changed = FALSE;
    int			o, ro;
    xf86CrtcPtr		*save_crtcs;
    Bool		save_enabled = crtc->enabled;

    save_crtcs = ALLOCATE_LOCAL(config->num_output * sizeof (xf86CrtcPtr));
    if ((randr_mode != NULL) != crtc->enabled)
	changed = TRUE;
    else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
	changed = TRUE;
    
    if (rotation != crtc->rotation)
	changed = TRUE;

    if (x != crtc->x || y != crtc->y)
	changed = TRUE;
    for (o = 0; o < config->num_output; o++) 
    {
	xf86OutputPtr  output = config->output[o];
	xf86CrtcPtr    new_crtc;

	save_crtcs[o] = output->crtc;
	
	if (output->crtc == crtc)
	    new_crtc = NULL;
	else
	    new_crtc = output->crtc;
	for (ro = 0; ro < num_randr_outputs; ro++) 
	    if (output->randr_output == randr_outputs[ro])
	    {
		new_crtc = crtc;
		break;
	    }
	if (new_crtc != output->crtc)
	{
	    changed = TRUE;
	    output->crtc = new_crtc;
	}
    }
    for (ro = 0; ro < num_randr_outputs; ro++) 
        if (randr_outputs[ro]->pendingProperties)
	    changed = TRUE;

    /* XXX need device-independent mode setting code through an API */
    if (changed)
    {
	crtc->enabled = randr_mode != NULL;

	if (randr_mode)
	{
	    DisplayModeRec  mode;

	    xf86RandRModeConvert (pScrn, randr_mode, &mode);
	    if (!xf86CrtcSetMode (crtc, &mode, rotation, x, y))
	    {
		crtc->enabled = save_enabled;
		for (o = 0; o < config->num_output; o++)
		{
		    xf86OutputPtr	output = config->output[o];
		    output->crtc = save_crtcs[o];
		}
		DEALLOCATE_LOCAL(save_crtcs);
		return FALSE;
	    }
	    /*
	     * Save the last successful setting for EnterVT
	     */
	    crtc->desiredMode = mode;
	    crtc->desiredRotation = rotation;
	    crtc->desiredX = x;
	    crtc->desiredY = y;
	}
	xf86DisableUnusedFunctions (pScrn);
    }
    DEALLOCATE_LOCAL(save_crtcs);
    return xf86RandR12CrtcNotify (randr_crtc);
}
static Bool
G80SorSetProperty(xf86OutputPtr output, Atom prop, RRPropertyValuePtr val)
{
    G80OutputPrivPtr pPriv = output->driver_private;

    if(prop == properties.dither.atom) {
        INT32 i;

        if(val->type != XA_INTEGER || val->format != 32 || val->size != 1)
            return FALSE;

        i = *(INT32*)val->data;
        if(i < properties.dither.range[0] || i > properties.dither.range[1])
            return FALSE;

        G80CrtcSetDither(output->crtc, i, TRUE);
    } else if(prop == properties.scale.atom) {
        const char *s;
        enum G80ScaleMode oldScale, scale;
        int i;
        const struct {
            const char *name;
            enum G80ScaleMode scale;
        } modes[] = {
            { "off",    G80_SCALE_OFF },
            { "aspect", G80_SCALE_ASPECT },
            { "fill",   G80_SCALE_FILL },
            { "center", G80_SCALE_CENTER },
            { NULL,     0 },
        };

        if(val->type != XA_STRING || val->format != 8)
            return FALSE;
        s = (char*)val->data;

        for(i = 0; modes[i].name; i++) {
            const char *name = modes[i].name;
            const int len = strlen(name);

            if(val->size == len && !strncmp(name, s, len)) {
                scale = modes[i].scale;
                break;
            }
        }
        if(!modes[i].name)
            return FALSE;
        if(scale == G80_SCALE_OFF && pPriv->panelType == LVDS)
            // LVDS requires scaling
            return FALSE;

        oldScale = pPriv->scale;
        pPriv->scale = scale;
        if(output->crtc) {
            xf86CrtcPtr crtc = output->crtc;

            if(!xf86CrtcSetMode(crtc, &crtc->desiredMode, crtc->desiredRotation,
                                crtc->desiredX, crtc->desiredY)) {
                xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
                           "Failed to set scaling to %s for output %s\n",
                           modes[i].name, output->name);

                // Restore old scale and try again.
                pPriv->scale = oldScale;
                if(!xf86CrtcSetMode(crtc, &crtc->desiredMode,
                                    crtc->desiredRotation, crtc->desiredX,
                                    crtc->desiredY)) {
                    xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
                               "Failed to restore old scaling for output %s\n",
                               output->name);
                }

                return FALSE;
            }
        }
    }

    return TRUE;
}