Пример #1
0
int
ProcRRSetCrtcTransform (ClientPtr client)
{
    REQUEST(xRRSetCrtcTransformReq);
    RRCrtcPtr		    crtc;
    PictTransform	    transform;
    struct pixman_f_transform f_transform, f_inverse;
    char		    *filter;
    int			    nbytes;
    xFixed		    *params;
    int			    nparams;

    REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    PictTransform_from_xRenderTransform (&transform, &stuff->transform);
    pixman_f_transform_from_pixman_transform (&f_transform, &transform);
    if (!pixman_f_transform_invert (&f_inverse, &f_transform))
	return BadMatch;

    filter = (char *) (stuff + 1);
    nbytes = stuff->nbytesFilter;
    params = (xFixed *) (filter + pad_to_int32(nbytes));
    nparams = ((xFixed *) stuff + client->req_len) - params;
    if (nparams < 0)
	return BadLength;

    return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse,
			       filter, nbytes, params, nparams);
}
Пример #2
0
int
ProcRRSetCrtcGamma (ClientPtr client)
{
    REQUEST(xRRSetCrtcGammaReq);
    RRCrtcPtr			crtc;
    unsigned long		len;
    CARD16			*red, *green, *blue;
    
    REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
    
    len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq));
    if (len < (stuff->size * 3 + 1) >> 1)
	return BadLength;

    if (stuff->size != crtc->gammaSize)
	return BadMatch;
    
    red = (CARD16 *) (stuff + 1);
    green = red + crtc->gammaSize;
    blue = green + crtc->gammaSize;
    
    RRCrtcGammaSet (crtc, red, green, blue);

    return Success;
}
Пример #3
0
int
ProcRRGetCrtcGammaSize (ClientPtr client)
{
    REQUEST(xRRGetCrtcGammaSizeReq);
    xRRGetCrtcGammaSizeReply	reply;
    RRCrtcPtr			crtc;
    int				n;

    REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* Gamma retrieval failed, any better error? */
    if (!RRCrtcGammaGet(crtc))
        return RRErrorBase + BadRRCrtc;

    reply.type = X_Reply;
    reply.sequenceNumber = client->sequence;
    reply.length = 0;
    reply.size = crtc->gammaSize;
    if (client->swapped) {
	swaps (&reply.sequenceNumber, n);
	swapl (&reply.length, n);
	swaps (&reply.size, n);
    }
    WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply);
    return Success;
}
Пример #4
0
static int
proc_present_query_capabilities (ClientPtr client)
{
    REQUEST(xPresentQueryCapabilitiesReq);
    xPresentQueryCapabilitiesReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
    };
    WindowPtr   window;
    RRCrtcPtr   crtc = NULL;
    int         r;

    REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq);
    r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess);
    switch (r) {
    case Success:
        crtc = present_get_crtc(window);
        break;
    case BadWindow:
        VERIFY_RR_CRTC(stuff->target, crtc, DixGetAttrAccess);
        break;
    default:
        return r;
    }

    rep.capabilities = present_query_capabilities(crtc);

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.capabilities);
    }
    WriteToClient(client, sizeof(rep), &rep);
    return Success;
}

static int (*proc_present_vector[PresentNumberRequests]) (ClientPtr) = {
    proc_present_query_version,            /* 0 */
    proc_present_pixmap,                   /* 1 */
    proc_present_notify_msc,               /* 2 */
    proc_present_select_input,             /* 3 */
    proc_present_query_capabilities,       /* 4 */
};

int
proc_present_dispatch(ClientPtr client)
{
    REQUEST(xReq);
    if (stuff->data >= PresentNumberRequests || !proc_present_vector[stuff->data])
        return BadRequest;
    return (*proc_present_vector[stuff->data]) (client);
}
Пример #5
0
int
ProcRRGetCrtcTransform (ClientPtr client)
{
    REQUEST(xRRGetCrtcTransformReq);
    xRRGetCrtcTransformReply	*reply;
    RRCrtcPtr			crtc;
    int				n, nextra;
    RRTransformPtr		current, pending;
    char			*extra;

    REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    pending = &crtc->client_pending_transform;
    current = &crtc->client_current_transform;

    nextra = (transform_filter_length (pending) +
	      transform_filter_length (current));

    reply = malloc(sizeof (xRRGetCrtcTransformReply) + nextra);
    if (!reply)
	return BadAlloc;

    extra = (char *) (reply + 1);
    reply->type = X_Reply;
    reply->sequenceNumber = client->sequence;
    reply->length = bytes_to_int32(CrtcTransformExtra + nextra);

    reply->hasTransforms = crtc->transforms;

    transform_encode (client, &reply->pendingTransform, &pending->transform);
    extra += transform_filter_encode (client, extra,
				      &reply->pendingNbytesFilter,
				      &reply->pendingNparamsFilter,
				      pending);

    transform_encode (client, &reply->currentTransform, &current->transform);
    extra += transform_filter_encode (client, extra,
				      &reply->currentNbytesFilter,
				      &reply->currentNparamsFilter,
				      current);

    if (client->swapped) {
	swaps (&reply->sequenceNumber, n);
	swapl (&reply->length, n);
    }
    WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply);
    free(reply);
    return Success;
}
Пример #6
0
int
ProcRRGetCrtcGamma (ClientPtr client)
{
    REQUEST(xRRGetCrtcGammaReq);
    xRRGetCrtcGammaReply	reply;
    RRCrtcPtr			crtc;
    int				n;
    unsigned long		len;
    char			*extra = NULL;
    
    REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* Gamma retrieval failed, any better error? */
    if (!RRCrtcGammaGet(crtc))
        return RRErrorBase + BadRRCrtc;

    len = crtc->gammaSize * 3 * 2;
    
    if (crtc->gammaSize) {
	extra = malloc(len);
	if (!extra)
	    return BadAlloc;
    }

    reply.type = X_Reply;
    reply.sequenceNumber = client->sequence;
    reply.length = bytes_to_int32(len);
    reply.size = crtc->gammaSize;
    if (client->swapped) {
	swaps (&reply.sequenceNumber, n);
	swapl (&reply.length, n);
	swaps (&reply.size, n);
    }
    WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply);
    if (crtc->gammaSize)
    {
	memcpy(extra, crtc->gammaRed, len);
	client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write;
	WriteSwappedDataToClient (client, len, extra);
	free(extra);
    }
    return Success;
}
Пример #7
0
int
ProcRRGetPanning (ClientPtr client)
{
    REQUEST(xRRGetPanningReq);
    xRRGetPanningReply	rep;
    RRCrtcPtr		crtc;
    ScreenPtr		pScreen;
    rrScrPrivPtr	pScrPriv;
    BoxRec		total;
    BoxRec		tracking;
    INT16		border[4];
    int			n;
    
    REQUEST_SIZE_MATCH(xRRGetPanningReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* All crtcs must be associated with screens before client
     * requests are processed
     */
    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    if (!pScrPriv)
	return RRErrorBase + BadRRCrtc;

    memset(&rep, 0, sizeof(rep));
    rep.type = X_Reply;
    rep.status = RRSetConfigSuccess;
    rep.sequenceNumber = client->sequence;
    rep.length = 1;
    rep.timestamp = pScrPriv->lastSetTime.milliseconds;

    if (pScrPriv->rrGetPanning &&
	pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border)) {
	rep.left          = total.x1;
	rep.top           = total.y1;
	rep.width         = total.x2 - total.x1;
	rep.height        = total.y2 - total.y1;
	rep.track_left    = tracking.x1;
	rep.track_top     = tracking.y1;
	rep.track_width   = tracking.x2 - tracking.x1;
	rep.track_height  = tracking.y2 - tracking.y1;
	rep.border_left   = border[0];
	rep.border_top    = border[1];
	rep.border_right  = border[2];
	rep.border_bottom = border[3];
    }

    if (client->swapped) {
	swaps(&rep.sequenceNumber, n);
	swapl(&rep.length, n);
	swaps(&rep.timestamp, n);
	swaps(&rep.left, n);
	swaps(&rep.top, n);
	swaps(&rep.width, n);
	swaps(&rep.height, n);
	swaps(&rep.track_left, n);
	swaps(&rep.track_top, n);
	swaps(&rep.track_width, n);
	swaps(&rep.track_height, n);
	swaps(&rep.border_left, n);
	swaps(&rep.border_top, n);
	swaps(&rep.border_right, n);
	swaps(&rep.border_bottom, n);
    }
    WriteToClient(client, sizeof(xRRGetPanningReply), (char *)&rep);
    return Success;
}
Пример #8
0
int
ProcRRSetCrtcConfig (ClientPtr client)
{
    REQUEST(xRRSetCrtcConfigReq);
    xRRSetCrtcConfigReply   rep;
    ScreenPtr		    pScreen;
    rrScrPrivPtr	    pScrPriv;
    RRCrtcPtr		    crtc;
    RRModePtr		    mode;
    int			    numOutputs;
    RROutputPtr		    *outputs = NULL;
    RROutput		    *outputIds;
    TimeStamp		    configTime;
    TimeStamp		    time;
    Rotation		    rotation;
    int			    rc, i, j;
    
    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
    numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq)));
    
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);

    if (stuff->mode == None)
    {
	mode = NULL;
	if (numOutputs > 0)
	    return BadMatch;
    }
    else
    {
	VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess);
	if (numOutputs == 0)
	    return BadMatch;
    }
    if (numOutputs)
    {
	outputs = malloc(numOutputs * sizeof (RROutputPtr));
	if (!outputs)
	    return BadAlloc;
    }
    else
	outputs = NULL;
    
    outputIds = (RROutput *) (stuff + 1);
    for (i = 0; i < numOutputs; i++)
    {
	rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i],
				     RROutputType, client, DixSetAttrAccess);
	if (rc != Success)
	{
	    free(outputs);
	    return rc;
	}
	/* validate crtc for this output */
	for (j = 0; j < outputs[i]->numCrtcs; j++)
	    if (outputs[i]->crtcs[j] == crtc)
		break;
	if (j == outputs[i]->numCrtcs)
	{
	    free(outputs);
	    return BadMatch;
	}
	/* validate mode for this output */
	for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
	{
	    RRModePtr	m = (j < outputs[i]->numModes ? 
			     outputs[i]->modes[j] :
			     outputs[i]->userModes[j - outputs[i]->numModes]);
	    if (m == mode)
		break;
	}
	if (j == outputs[i]->numModes + outputs[i]->numUserModes)
	{
	    free(outputs);
	    return BadMatch;
	}
    }
    /* validate clones */
    for (i = 0; i < numOutputs; i++)
    {
	for (j = 0; j < numOutputs; j++)
	{
	    int k;
	    if (i == j)
		continue;
	    for (k = 0; k < outputs[i]->numClones; k++)
	    {
		if (outputs[i]->clones[k] == outputs[j])
		    break;
	    }
	    if (k == outputs[i]->numClones)
	    {
		free(outputs);
		return BadMatch;
	    }
	}
    }

    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);
    
    time = ClientTimeToServerTime(stuff->timestamp);
    configTime = ClientTimeToServerTime(stuff->configTimestamp);
    
    if (!pScrPriv)
    {
	time = currentTime;
	rep.status = RRSetConfigFailed;
	goto sendReply;
    }
    
    /*
     * Validate requested rotation
     */
    rotation = (Rotation) stuff->rotation;

    /* test the rotation bits only! */
    switch (rotation & 0xf) {
    case RR_Rotate_0:
    case RR_Rotate_90:
    case RR_Rotate_180:
    case RR_Rotate_270:
	break;
    default:
	/*
	 * Invalid rotation
	 */
	client->errorValue = stuff->rotation;
	free(outputs);
	return BadValue;
    }

    if (mode)
    {
	if ((~crtc->rotations) & rotation)
	{
	    /*
	     * requested rotation or reflection not supported by screen
	     */
	    client->errorValue = stuff->rotation;
	    free(outputs);
	    return BadMatch;
	}
    
#ifdef RANDR_12_INTERFACE
	/*
	 * Check screen size bounds if the DDX provides a 1.2 interface
	 * for setting screen size. Else, assume the CrtcSet sets
	 * the size along with the mode. If the driver supports transforms,
	 * then it must allow crtcs to display a subset of the screen, so
	 * only do this check for drivers without transform support.
	 */
	if (pScrPriv->rrScreenSetSize && !crtc->transforms)
	{
	    int source_width;
	    int	source_height;
	    PictTransform transform;
	    struct pixman_f_transform f_transform, f_inverse;

	    RRTransformCompute (stuff->x, stuff->y,
				mode->mode.width, mode->mode.height,
				rotation,
				&crtc->client_pending_transform,
				&transform, &f_transform, &f_inverse);

	    RRModeGetScanoutSize (mode, &transform, &source_width, &source_height);
	    if (stuff->x + source_width > pScreen->width)
	    {
		client->errorValue = stuff->x;
		free(outputs);
		return BadValue;
	    }
	    
	    if (stuff->y + source_height > pScreen->height)
	    {
		client->errorValue = stuff->y;
		free(outputs);
		return BadValue;
	    }
	}
#endif
    }
    
    if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y,
		   rotation, numOutputs, outputs))
    {
	rep.status = RRSetConfigFailed;
	goto sendReply;
    }
    rep.status = RRSetConfigSuccess;
    pScrPriv->lastSetTime = time;
    
sendReply:
    free(outputs);
    
    rep.type = X_Reply;
    /* rep.status has already been filled in */
    rep.length = 0;
    rep.sequenceNumber = client->sequence;
    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;

    if (client->swapped) 
    {
	int n;
    	swaps(&rep.sequenceNumber, n);
    	swapl(&rep.length, n);
	swapl(&rep.newTimestamp, n);
    }
    WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep);
    
    return Success;
}
Пример #9
0
int
ProcRRGetCrtcInfo (ClientPtr client)
{
    REQUEST(xRRGetCrtcInfoReq);
    xRRGetCrtcInfoReply	rep;
    RRCrtcPtr			crtc;
    CARD8			*extra;
    unsigned long		extraLen;
    ScreenPtr			pScreen;
    rrScrPrivPtr		pScrPriv;
    RRModePtr			mode;
    RROutput			*outputs;
    RROutput			*possible;
    int				i, j, k, n;
    int				width, height;
    BoxRec			panned_area;
    
    REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* All crtcs must be associated with screens before client
     * requests are processed
     */
    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    mode = crtc->mode;
    
    rep.type = X_Reply;
    rep.status = RRSetConfigSuccess;
    rep.sequenceNumber = client->sequence;
    rep.length = 0;
    rep.timestamp = pScrPriv->lastSetTime.milliseconds;
    if (pScrPriv->rrGetPanning &&
	pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) &&
	(panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
    {
 	rep.x = panned_area.x1;
	rep.y = panned_area.y1;
	rep.width = panned_area.x2 - panned_area.x1;
	rep.height = panned_area.y2 - panned_area.y1;
    }
    else
    {
	RRCrtcGetScanoutSize (crtc, &width, &height);
	rep.x = crtc->x;
	rep.y = crtc->y;
	rep.width = width;
	rep.height = height;
    }
    rep.mode = mode ? mode->mode.id : 0;
    rep.rotation = crtc->rotation;
    rep.rotations = crtc->rotations;
    rep.nOutput = crtc->numOutputs;
    k = 0;
    for (i = 0; i < pScrPriv->numOutputs; i++)
	for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
	    if (pScrPriv->outputs[i]->crtcs[j] == crtc)
		k++;
    rep.nPossibleOutput = k;
    
    rep.length = rep.nOutput + rep.nPossibleOutput;

    extraLen = rep.length << 2;
    if (extraLen)
    {
	extra = malloc(extraLen);
	if (!extra)
	    return BadAlloc;
    }
    else
	extra = NULL;

    outputs = (RROutput *) extra;
    possible = (RROutput *) (outputs + rep.nOutput);
    
    for (i = 0; i < crtc->numOutputs; i++)
    {
	outputs[i] = crtc->outputs[i]->id;
	if (client->swapped)
	    swapl (&outputs[i], n);
    }
    k = 0;
    for (i = 0; i < pScrPriv->numOutputs; i++)
	for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
	    if (pScrPriv->outputs[i]->crtcs[j] == crtc)
	    {
		possible[k] = pScrPriv->outputs[i]->id;
		if (client->swapped)
		    swapl (&possible[k], n);
		k++;
	    }
    
    if (client->swapped) {
	swaps(&rep.sequenceNumber, n);
	swapl(&rep.length, n);
	swapl(&rep.timestamp, n);
	swaps(&rep.x, n);
	swaps(&rep.y, n);
	swaps(&rep.width, n);
	swaps(&rep.height, n);
	swapl(&rep.mode, n);
	swaps(&rep.rotation, n);
	swaps(&rep.rotations, n);
	swaps(&rep.nOutput, n);
	swaps(&rep.nPossibleOutput, n);
    }
    WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep);
    if (extraLen)
    {
	WriteToClient (client, extraLen, (char *) extra);
	free(extra);
    }
    
    return Success;
}
Пример #10
0
int
ProcRRSetPanning (ClientPtr client)
{
    REQUEST(xRRSetPanningReq);
    xRRSetPanningReply	rep;
    RRCrtcPtr		crtc;
    ScreenPtr		pScreen;
    rrScrPrivPtr	pScrPriv;
    TimeStamp		time;
    BoxRec		total;
    BoxRec		tracking;
    INT16		border[4];
    int			n;
    
    REQUEST_SIZE_MATCH(xRRSetPanningReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* All crtcs must be associated with screens before client
     * requests are processed
     */
    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    if (!pScrPriv) {
	time = currentTime;
	rep.status = RRSetConfigFailed;
	goto sendReply;
    }
    
    time = ClientTimeToServerTime(stuff->timestamp);
    
    if (!pScrPriv->rrGetPanning)
	return RRErrorBase + BadRRCrtc;

    total.x1    = stuff->left;
    total.y1    = stuff->top;
    total.x2    = total.x1 + stuff->width;
    total.y2    = total.y1 + stuff->height;
    tracking.x1 = stuff->track_left;
    tracking.y1 = stuff->track_top;
    tracking.x2 = tracking.x1 + stuff->track_width;
    tracking.y2 = tracking.y1 + stuff->track_height;
    border[0]   = stuff->border_left;
    border[1]   = stuff->border_top;
    border[2]   = stuff->border_right;
    border[3]   = stuff->border_bottom;

    if (! pScrPriv->rrSetPanning (pScreen, crtc, &total, &tracking, border))
	return BadMatch;

    pScrPriv->lastSetTime = time;

    rep.status = RRSetConfigSuccess;

sendReply:
    rep.type = X_Reply;
    rep.sequenceNumber = client->sequence;
    rep.length = 0;
    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;

    if (client->swapped) {
	swaps(&rep.sequenceNumber, n);
	swapl(&rep.length, n);
	swaps(&rep.newTimestamp, n);
    }
    WriteToClient(client, sizeof(xRRSetPanningReply), (char *)&rep);
    return Success;
}