Ejemplo n.º 1
0
static RROutputPtr
rdpRRAddOutput(rdpPtr dev, const char *aname, int x, int y, int width, int height)
{
    RRModePtr mode;
    RRCrtcPtr crtc;
    RROutputPtr output;
    xRRModeInfo modeInfo;
    char name[64];

    sprintf (name, "%dx%d", width, height);
    memset (&modeInfo, 0, sizeof(modeInfo));
    modeInfo.width = width;
    modeInfo.height = height;
    modeInfo.nameLength = strlen(name);
    mode = RRModeGet(&modeInfo, name);
    if (mode == 0)
    {
        LLOGLN(0, ("rdpRRAddOutput: RRModeGet failed"));
        return 0;
    }

    crtc = RRCrtcCreate(dev->pScreen, NULL);
    if (crtc == 0)
    {
        LLOGLN(0, ("rdpRRAddOutput: RRCrtcCreate failed"));
        RRModeDestroy(mode);
        return 0;
    }
    output = RROutputCreate(dev->pScreen, aname, strlen(aname), NULL);
    if (output == 0)
    {
        LLOGLN(0, ("rdpRRAddOutput: RROutputCreate failed"));
        RRCrtcDestroy(crtc);
        RRModeDestroy(mode);
        return 0;
    }
    if (!RROutputSetClones(output, NULL, 0))
    {
        LLOGLN(0, ("rdpRRAddOutput: RROutputSetClones failed"));
    }
    if (!RROutputSetModes(output, &mode, 1, 0))
    {
        LLOGLN(0, ("rdpRRAddOutput: RROutputSetModes failed"));
    }
    if (!RROutputSetCrtcs(output, &crtc, 1))
    {
        LLOGLN(0, ("rdpRRAddOutput: RROutputSetCrtcs failed"));
    }
    if (!RROutputSetConnection(output, RR_Connected))
    {
        LLOGLN(0, ("rdpRRAddOutput: RROutputSetConnection failed"));
    }
    RRCrtcNotify(crtc, mode, x, y, RR_Rotate_0, NULL, 1, &output);

    dev->output[dev->extra_outputs] = output;
    dev->crtc[dev->extra_outputs] = crtc;
    dev->extra_outputs++;

    return output;
}
Ejemplo n.º 2
0
static RRModePtr
RROldModeAdd (RROutputPtr output, RRScreenSizePtr size, int refresh)
{
    ScreenPtr	pScreen = output->pScreen;
    rrScrPriv(pScreen);
    xRRModeInfo	modeInfo;
    char	name[100];
    RRModePtr	mode;
    int		i;
    RRModePtr   *modes;
    
    memset (&modeInfo, '\0', sizeof (modeInfo));
    sprintf (name, "%dx%d", size->width, size->height);
    
    modeInfo.width = size->width;
    modeInfo.height = size->height;
    modeInfo.hTotal = size->width;
    modeInfo.vTotal = size->height;
    modeInfo.dotClock = ((CARD32) size->width * (CARD32) size->height *
			 (CARD32) refresh);
    modeInfo.nameLength = strlen (name);
    mode = RRModeGet (&modeInfo, name);
    if (!mode)
	return NULL;
    for (i = 0; i < output->numModes; i++)
	if (output->modes[i] == mode)
	{
	    RRModeDestroy (mode);
	    return mode;
	}
    
    if (output->numModes)
	modes = xrealloc (output->modes, 
			  (output->numModes + 1) * sizeof (RRModePtr));
    else
	modes = xalloc (sizeof (RRModePtr));
    if (!modes)
    {
	RRModeDestroy (mode);
	FreeResource (mode->mode.id, 0);
	return NULL;
    }
    modes[output->numModes++] = mode;
    output->modes = modes;
    output->changed = TRUE;
    pScrPriv->changed = TRUE;
    pScrPriv->configChanged = TRUE;
    return mode;
}
Ejemplo n.º 3
0
static int
RRCrtcDestroyResource (pointer value, XID pid)
{
    RRCrtcPtr	crtc = (RRCrtcPtr) value;
    ScreenPtr	pScreen = crtc->pScreen;

    if (pScreen)
    {
	rrScrPriv(pScreen);
	int		i;
    
	for (i = 0; i < pScrPriv->numCrtcs; i++)
	{
	    if (pScrPriv->crtcs[i] == crtc)
	    {
		memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
			 (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr));
		--pScrPriv->numCrtcs;
		break;
	    }
	}
    }
    free(crtc->gammaRed);
    if (crtc->mode)
	RRModeDestroy (crtc->mode);
    free(crtc);
    return 1;
}
Ejemplo n.º 4
0
int
RROutputDeleteUserMode(RROutputPtr output, RRModePtr mode)
{
    int m;

    /* Find this mode in the user mode list */
    for (m = 0; m < output->numUserModes; m++) {
        RRModePtr e = output->userModes[m];

        if (mode == e)
            break;
    }
    /* Not there, access error */
    if (m == output->numUserModes)
        return BadAccess;

    /* make sure the mode isn't active for this output */
    if (output->crtc && output->crtc->mode == mode)
        return BadMatch;

    memmove(output->userModes + m, output->userModes + m + 1,
            (output->numUserModes - m - 1) * sizeof(RRModePtr));
    output->numUserModes--;
    RRModeDestroy(mode);
    return Success;
}
Ejemplo n.º 5
0
static int
RROutputDestroyResource(void *value, XID pid)
{
    RROutputPtr output = (RROutputPtr) value;
    ScreenPtr pScreen = output->pScreen;
    int m;

    if (pScreen) {
        rrScrPriv(pScreen);
        int i;

        if (pScrPriv->primaryOutput == output)
            pScrPriv->primaryOutput = NULL;

        for (i = 0; i < pScrPriv->numOutputs; i++) {
            if (pScrPriv->outputs[i] == output) {
                memmove(pScrPriv->outputs + i, pScrPriv->outputs + i + 1,
                        (pScrPriv->numOutputs - (i + 1)) * sizeof(RROutputPtr));
                --pScrPriv->numOutputs;
                break;
            }
        }

        RRResourcesChanged(pScreen);
    }
    if (output->modes) {
        for (m = 0; m < output->numModes; m++)
            RRModeDestroy(output->modes[m]);
        free(output->modes);
    }

    for (m = 0; m < output->numUserModes; m++)
        RRModeDestroy(output->userModes[m]);
    free(output->userModes);

    free(output->crtcs);
    free(output->clones);
    RRDeleteAllOutputProperties(output);
    free(output);
    return 1;
}
int
ProcRRCreateMode (ClientPtr client)
{
    REQUEST(xRRCreateModeReq);
    xRRCreateModeReply	rep;
    WindowPtr		pWin;
    ScreenPtr		pScreen;
    rrScrPrivPtr	pScrPriv;
    xRRModeInfo		*modeInfo;
    long		units_after;
    char		*name;
    int			error, rc;
    RRModePtr		mode;

    REQUEST_AT_LEAST_SIZE (xRRCreateModeReq);
    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;

    pScreen = pWin->drawable.pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    modeInfo = &stuff->modeInfo;
    name = (char *) (stuff + 1);
    units_after = (stuff->length - bytes_to_int32(sizeof (xRRCreateModeReq)));

    /* check to make sure requested name fits within the data provided */
    if (bytes_to_int32(modeInfo->nameLength) > units_after)
        return BadLength;

    mode = RRModeCreateUser (pScreen, modeInfo, name, &error);
    if (!mode)
        return error;

    rep.type = X_Reply;
    rep.pad0 = 0;
    rep.sequenceNumber = client->sequence;
    rep.length = 0;
    rep.mode = mode->mode.id;
    if (client->swapped)
    {
        int n;
        swaps(&rep.sequenceNumber, n);
        swapl(&rep.length, n);
        swapl(&rep.mode, n);
    }
    WriteToClient(client, sizeof(xRRCreateModeReply), (char *)&rep);
    /* Drop out reference to this mode */
    RRModeDestroy (mode);
    return client->noClientException;
}
Ejemplo n.º 7
0
Bool
RROutputSetModes(RROutputPtr output,
                 RRModePtr * modes, int numModes, int numPreferred)
{
    RRModePtr *newModes;
    int i;

    if (numModes == output->numModes && numPreferred == output->numPreferred) {
        for (i = 0; i < numModes; i++)
            if (output->modes[i] != modes[i])
                break;
        if (i == numModes) {
            for (i = 0; i < numModes; i++)
                RRModeDestroy(modes[i]);
            return TRUE;
        }
    }

    if (numModes) {
        newModes = malloc(numModes * sizeof(RRModePtr));
        if (!newModes)
            return FALSE;
    }
    else
        newModes = NULL;
    if (output->modes) {
        for (i = 0; i < output->numModes; i++)
            RRModeDestroy(output->modes[i]);
        free(output->modes);
    }
    memcpy(newModes, modes, numModes * sizeof(RRModePtr));
    output->modes = newModes;
    output->numModes = numModes;
    output->numPreferred = numPreferred;
    RROutputChanged(output, TRUE);
    return TRUE;
}
Ejemplo n.º 8
0
/*
 * Notify the extension that the Crtc has been reconfigured,
 * the driver calls this whenever it has updated the mode
 */
Bool
RRCrtcNotify (RRCrtcPtr	    crtc,
	      RRModePtr	    mode,
	      int	    x,
	      int	    y,
	      Rotation	    rotation,
	      RRTransformPtr transform,
	      int	    numOutputs,
	      RROutputPtr   *outputs)
{
    int	    i, j;
    
    /*
     * Check to see if any of the new outputs were
     * not in the old list and mark them as changed
     */
    for (i = 0; i < numOutputs; i++)
    {
	for (j = 0; j < crtc->numOutputs; j++)
	    if (outputs[i] == crtc->outputs[j])
		break;
	if (j == crtc->numOutputs)
	{
	    outputs[i]->crtc = crtc;
	    RROutputChanged (outputs[i], FALSE);
	    RRCrtcChanged (crtc, FALSE);
	}
    }
    /*
     * Check to see if any of the old outputs are
     * not in the new list and mark them as changed
     */
    for (j = 0; j < crtc->numOutputs; j++)
    {
	for (i = 0; i < numOutputs; i++)
	    if (outputs[i] == crtc->outputs[j])
		break;
	if (i == numOutputs)
	{
	    if (crtc->outputs[j]->crtc == crtc)
		crtc->outputs[j]->crtc = NULL;
	    RROutputChanged (crtc->outputs[j], FALSE);
	    RRCrtcChanged (crtc, FALSE);
	}
    }
    /*
     * Reallocate the crtc output array if necessary
     */
    if (numOutputs != crtc->numOutputs)
    {
	RROutputPtr *newoutputs;
	
	if (numOutputs)
	{
	    if (crtc->numOutputs)
		newoutputs = realloc(crtc->outputs,
				    numOutputs * sizeof (RROutputPtr));
	    else
		newoutputs = malloc(numOutputs * sizeof (RROutputPtr));
	    if (!newoutputs)
		return FALSE;
	}
	else
	{
	    free(crtc->outputs);
	    newoutputs = NULL;
	}
	crtc->outputs = newoutputs;
	crtc->numOutputs = numOutputs;
    }
    /*
     * Copy the new list of outputs into the crtc
     */
    memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr));
    /*
     * Update remaining crtc fields
     */
    if (mode != crtc->mode)
    {
	if (crtc->mode)
	    RRModeDestroy (crtc->mode);
	crtc->mode = mode;
	if (mode != NULL)
	    mode->refcnt++;
	RRCrtcChanged (crtc, TRUE);
    }
    if (x != crtc->x)
    {
	crtc->x = x;
	RRCrtcChanged (crtc, TRUE);
    }
    if (y != crtc->y)
    {
	crtc->y = y;
	RRCrtcChanged (crtc, TRUE);
    }
    if (rotation != crtc->rotation)
    {
	crtc->rotation = rotation;
	RRCrtcChanged (crtc, TRUE);
    }
    if (!RRTransformEqual (transform, &crtc->client_current_transform)) {
	RRTransformCopy (&crtc->client_current_transform, transform);
	RRCrtcChanged (crtc, TRUE);
    }
    if (crtc->changed && mode)
    {
	RRTransformCompute (x, y,
			    mode->mode.width, mode->mode.height,
			    rotation,
			    &crtc->client_current_transform,
			    &crtc->transform, &crtc->f_transform,
			    &crtc->f_inverse);
    }
    return TRUE;
}
static int
RRModeDestroyResource (pointer value, XID pid)
{
    RRModeDestroy ((RRModePtr) value);
    return 1;
}
Ejemplo n.º 10
0
int
ProcRRCreateMode(ClientPtr client)
{
    REQUEST(xRRCreateModeReq);
    xRRCreateModeReply rep;
    WindowPtr pWin;
    ScreenPtr pScreen;
    xRRModeInfo *modeInfo;
    long units_after;
    char *name;
    int error, rc;
    RRModePtr mode;

    REQUEST_AT_LEAST_SIZE(xRRCreateModeReq);
    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;

    pScreen = pWin->drawable.pScreen;

    modeInfo = &stuff->modeInfo;
    name = (char *) (stuff + 1);
    units_after = (stuff->length - bytes_to_int32(sizeof(xRRCreateModeReq)));

    /* check to make sure requested name fits within the data provided */
    if (bytes_to_int32(modeInfo->nameLength) > units_after)
        return BadLength;

    mode = RRModeCreateUser(pScreen, modeInfo, name, &error);
    if (!mode)
        return error;

    rep = (xRRCreateModeReply) {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .mode = mode->mode.id
	};
    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.mode);
    }
    WriteToClient(client, sizeof(xRRCreateModeReply), &rep);
    /* Drop out reference to this mode */
    RRModeDestroy(mode);
    return Success;
}

int
ProcRRDestroyMode(ClientPtr client)
{
    REQUEST(xRRDestroyModeReq);
    RRModePtr mode;

    REQUEST_SIZE_MATCH(xRRDestroyModeReq);
    VERIFY_RR_MODE(stuff->mode, mode, DixDestroyAccess);

    if (!mode->userScreen)
        return BadMatch;
    if (mode->refcnt > 1)
        return BadAccess;
    FreeResource(stuff->mode, 0);
    return Success;
}
Ejemplo n.º 11
0
static Bool vncRandRScreenSetSize(ScreenPtr pScreen,
                                  CARD16 width, CARD16 height,
                                  CARD32 mmWidth, CARD32 mmHeight)
{
    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
    vfbFramebufferInfo fb;
    rrScrPrivPtr rp = rrGetScrPriv(pScreen);
    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
    void *pbits;
    Bool ret;
    int oldwidth, oldheight, oldmmWidth, oldmmHeight;

    /* Prevent updates while we fiddle */
    xf86SetRootClip(pScreen, FALSE);

    /* Store current state in case we fail */
    oldwidth = pScreen->width;
    oldheight = pScreen->height;
    oldmmWidth = pScreen->mmWidth;
    oldmmHeight = pScreen->mmHeight;

    /* Then set the new dimensions */
    pScreen->width = width;
    pScreen->height = height;
    pScreen->mmWidth = mmWidth;
    pScreen->mmHeight = mmHeight;

    /* Allocate a new framebuffer */
    memset(&fb, 0, sizeof(vfbFramebufferInfo));

    fb.width = pScreen->width;
    fb.height = pScreen->height;
    fb.depth = pvfb->fb.depth;

    pbits = vfbAllocateFramebufferMemory(&fb);
    if (!pbits) {
        /* Allocation failed. Restore old state */
        pScreen->width = oldwidth;
        pScreen->height = oldheight;
        pScreen->mmWidth = oldmmWidth;
        pScreen->mmHeight = oldmmHeight;

        xf86SetRootClip(pScreen, TRUE);

        return FALSE;
    }

    /* Update root pixmap with the new dimensions and buffer */
    ret = pScreen->ModifyPixmapHeader(rootPixmap, fb.width, fb.height,
                                      -1, -1, fb.paddedBytesWidth, pbits);
    if (!ret) {
        /* Update failed. Free the new framebuffer and restore old state */
        vfbFreeFramebufferMemory(&fb);

        pScreen->width = oldwidth;
        pScreen->height = oldheight;
        pScreen->mmWidth = oldmmWidth;
        pScreen->mmHeight = oldmmHeight;

        xf86SetRootClip(pScreen, TRUE);

        return FALSE;
    }

    /* Free the old framebuffer and keep the info about the new one */
    vfbFreeFramebufferMemory(&pvfb->fb);
    memcpy(&pvfb->fb, &fb, sizeof(vfbFramebufferInfo));

    /* Let VNC get the new framebuffer (actual update is in vncHooks.cc) */
    vncFbptr[pScreen->myNum] = pbits;
    vncFbstride[pScreen->myNum] = fb.paddedWidth;

    /* Restore ability to update screen, now with new dimensions */
    xf86SetRootClip(pScreen, TRUE);

    /*
     * Let RandR know we changed something (it doesn't assume that
     * TRUE means something changed for some reason...).
     */
    RRScreenSizeNotify(pScreen);

    /* Crop all CRTCs to the new screen */
    for (int i = 0;i < rp->numCrtcs;i++) {
        RRCrtcPtr crtc;
        RRModePtr mode;

        crtc = rp->crtcs[i];

        /* Disabled? */
        if (crtc->mode == NULL)
            continue;

        /* Fully inside? */
        if ((crtc->x + crtc->mode->mode.width <= width) &&
            (crtc->y + crtc->mode->mode.height <= height))
            continue;

        /* Fully outside? */
        if ((crtc->x >= width) || (crtc->y >= height)) {
            /* Disable it */
            ret = vncRandRCrtcSet(pScreen, crtc, NULL,
                                  crtc->x, crtc->y, crtc->rotation, 0, NULL);
            if (!ret)
                ErrorF("Warning: Unable to disable CRTC that is outside of new screen dimensions");
            continue;
        }

        /* Just needs to be resized to a temporary mode */
        mode = vncRandRModeGet(width - crtc->x, height - crtc->y);
        if (mode == NULL) {
            ErrorF("Warning: Unable to create custom mode for %dx%d",
                   width - crtc->x, height - crtc->y);
            continue;
        }

        ret = vncRandRCrtcSet(pScreen, crtc, mode,
                              crtc->x, crtc->y, crtc->rotation,
                              crtc->numOutputs, crtc->outputs);
        RRModeDestroy(mode);
        if (!ret)
            ErrorF("Warning: Unable to crop CRTC to new screen dimensions");
    }

    return TRUE;
}