Esempio n. 1
0
int
ProcXGetDeviceMotionEvents(ClientPtr client)
{
    INT32 *coords = NULL, *bufptr;
    xGetDeviceMotionEventsReply rep;
    unsigned long i;
    int rc, num_events, axes, size = 0;
    unsigned long nEvents;
    DeviceIntPtr dev;
    TimeStamp start, stop;
    int length = 0;
    ValuatorClassPtr v;

    REQUEST(xGetDeviceMotionEventsReq);

    REQUEST_SIZE_MATCH(xGetDeviceMotionEventsReq);
    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixReadAccess);
    if (rc != Success)
	return rc;
    v = dev->valuator;
    if (v == NULL || v->numAxes == 0)
	return BadMatch;
    if (dev->valuator->motionHintWindow)
	MaybeStopDeviceHint(dev, client);
    axes = v->numAxes;
    rep.repType = X_Reply;
    rep.RepType = X_GetDeviceMotionEvents;
    rep.sequenceNumber = client->sequence;
    rep.nEvents = 0;
    rep.axes = axes;
    rep.mode = Absolute; /* XXX we don't do relative at the moment */
    rep.length = 0;
    start = ClientTimeToServerTime(stuff->start);
    stop = ClientTimeToServerTime(stuff->stop);
    if (CompareTimeStamps(start, stop) == LATER ||
	CompareTimeStamps(start, currentTime) == LATER) {
	WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep);
	return Success;
    }
    if (CompareTimeStamps(stop, currentTime) == LATER)
	stop = currentTime;
    num_events = v->numMotionEvents;
    if (num_events) {
        size = sizeof(Time) + (axes * sizeof(INT32));
	rep.nEvents = GetMotionHistory(dev, (xTimecoord **) &coords,/* XXX */
					start.milliseconds, stop.milliseconds,
					(ScreenPtr) NULL, FALSE);
    }
    if (rep.nEvents > 0) {
	length = bytes_to_int32(rep.nEvents * size);
	rep.length = length;
    }
    nEvents = rep.nEvents;
    WriteReplyToClient(client, sizeof(xGetDeviceMotionEventsReply), &rep);
    if (nEvents) {
	if (client->swapped) {
	    bufptr = coords;
	    for (i = 0; i < nEvents * (axes + 1); i++) {
		swapl(bufptr);
		bufptr++;
	    }
	}
	WriteToClient(client, length * 4, (char *)coords);
    }
    free(coords);
    return Success;
}
int
ProcSetSelectionOwner(ClientPtr client)
{
    WindowPtr pWin = NULL;
    TimeStamp time;
    Selection *pSel;
    int rc;

    REQUEST(xSetSelectionOwnerReq);
    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);

    UpdateCurrentTime();
    time = ClientTimeToServerTime(stuff->time);

    /* If the client's time stamp is in the future relative to the server's
	time stamp, do not set the selection, just return success. */
    if (CompareTimeStamps(time, currentTime) == LATER)
    	return Success;

    if (stuff->window != None) {
	rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess);
        if (rc != Success)
            return rc;
    }
    if (!ValidAtom(stuff->selection)) {
	client->errorValue = stuff->selection;
        return BadAtom;
    }

    /*
     * First, see if the selection is already set...
     */
    rc = dixLookupSelection(&pSel, stuff->selection, client, DixSetAttrAccess);

    if (rc == Success) {
	xEvent event;

	/* If the timestamp in client's request is in the past relative
	   to the time stamp indicating the last time the owner of the
	   selection was set, do not set the selection, just return 
	   success. */
	if (CompareTimeStamps(time, pSel->lastTimeChanged) == EARLIER)
	    return Success;
	if (pSel->client && (!pWin || (pSel->client != client)))
	{
	    event.u.u.type = SelectionClear;
	    event.u.selectionClear.time = time.milliseconds;
	    event.u.selectionClear.window = pSel->window;
	    event.u.selectionClear.atom = pSel->selection;
	    TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask,
			    NoEventMask /* CantBeFiltered */, NullGrab);
	}
    }
    else if (rc == BadMatch)
    {
	/*
	 * It doesn't exist, so add it...
	 */
	pSel = xalloc(sizeof(Selection));
	if (!pSel)
	    return BadAlloc;

	pSel->selection = stuff->selection;
	pSel->devPrivates = NULL;

	/* security creation/labeling check */
	rc = XaceHookSelectionAccess(client, &pSel,
				     DixCreateAccess|DixSetAttrAccess);
	if (rc != Success) {
	    xfree(pSel);
	    return rc;
	}

	pSel->next = CurrentSelections;
	CurrentSelections = pSel;
    }
    else
	return rc;

    pSel->lastTimeChanged = time;
    pSel->window = stuff->window;
    pSel->pWin = pWin;
    pSel->client = (pWin ? client : NullClient);

    CallSelectionCallback(pSel, client, SelectionSetOwner);
    return client->noClientException;
}
Esempio n. 3
0
static int
ProcRRSelectInput (ClientPtr client)
{
    REQUEST(xRRSelectInputReq);
    rrClientPriv(client);
    RRTimesPtr	pTimes;
    WindowPtr	pWin;
    RREventPtr	pRREvent, *pHead;
    XID		clientResource;
    int		rc;

    REQUEST_SIZE_MATCH(xRRSelectInputReq);
    #ifndef NXAGENT_SERVER
    rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
    #else
    pWin = SecurityLookupWindow(stuff->window, client, SecurityWriteAccess);
    rc = pWin ? Success : BadWindow;
    #endif
    if (rc != Success)
	return rc;
    pHead = (RREventPtr *)SecurityLookupIDByType(client,
						 pWin->drawable.id, RREventType,
						 DixWriteAccess);

    if (stuff->enable & (RRScreenChangeNotifyMask|
			 RRCrtcChangeNotifyMask|
			 RROutputChangeNotifyMask)) 
    {
	ScreenPtr	pScreen = pWin->drawable.pScreen;
	rrScrPriv	(pScreen);

	pRREvent = NULL;
	if (pHead) 
	{
	    /* check for existing entry. */
	    for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next)
		if (pRREvent->client == client)
		    break;
	}

	if (!pRREvent)
	{
	    /* build the entry */
	    pRREvent = (RREventPtr) xalloc (sizeof (RREventRec));
	    if (!pRREvent)
		return BadAlloc;
	    pRREvent->next = 0;
	    pRREvent->client = client;
	    pRREvent->window = pWin;
	    pRREvent->mask = stuff->enable;
	    /*
	     * add a resource that will be deleted when
	     * the client goes away
	     */
	    clientResource = FakeClientID (client->index);
	    pRREvent->clientResource = clientResource;
	    if (!AddResource (clientResource, RRClientType, (pointer)pRREvent))
		return BadAlloc;
	    /*
	     * create a resource to contain a pointer to the list
	     * of clients selecting input.  This must be indirect as
	     * the list may be arbitrarily rearranged which cannot be
	     * done through the resource database.
	     */
	    if (!pHead)
	    {
		pHead = (RREventPtr *) xalloc (sizeof (RREventPtr));
		if (!pHead ||
		    !AddResource (pWin->drawable.id, RREventType, (pointer)pHead))
		{
		    FreeResource (clientResource, RT_NONE);
		    return BadAlloc;
		}
		*pHead = 0;
	    }
	    pRREvent->next = *pHead;
	    *pHead = pRREvent;
	}
	/*
	 * Now see if the client needs an event
	 */
	if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask))
	{
	    pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
	    if (CompareTimeStamps (pTimes->setTime, 
				   pScrPriv->lastSetTime) != 0 ||
		CompareTimeStamps (pTimes->configTime, 
				   pScrPriv->lastConfigTime) != 0)
	    {
		RRDeliverScreenEvent (client, pWin, pScreen);
	    }
	}
    }
    else if (stuff->enable == 0) 
    {
	/* delete the interest */
	if (pHead) {
	    RREventPtr pNewRREvent = 0;
	    for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) {
		if (pRREvent->client == client)
		    break;
		pNewRREvent = pRREvent;
	    }
	    if (pRREvent) {
		FreeResource (pRREvent->clientResource, RRClientType);
		if (pNewRREvent)
		    pNewRREvent->next = pRREvent->next;
		else
		    *pHead = pRREvent->next;
		xfree (pRREvent);
	    }
	}
    }
    else 
    {
	client->errorValue = stuff->enable;
	return BadValue;
    }
    return Success;
}