示例#1
0
int
ProcXSendExtensionEvent(ClientPtr client)
{
    int ret;
    DeviceIntPtr dev;
    xEvent *first;
    XEventClass *list;
    struct tmask tmp[EMASKSIZE];

    REQUEST(xSendExtensionEventReq);
    REQUEST_AT_LEAST_SIZE(xSendExtensionEventReq);

    if (stuff->length != bytes_to_int32(sizeof(xSendExtensionEventReq)) + stuff->count +
	(stuff->num_events * bytes_to_int32(sizeof(xEvent))))
	return BadLength;

    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixWriteAccess);
    if (ret != Success)
	return ret;

    /* The client's event type must be one defined by an extension. */

    first = ((xEvent *) & stuff[1]);
    if (!((EXTENSION_EVENT_BASE <= first->u.u.type) &&
	  (first->u.u.type < lastEvent))) {
	client->errorValue = first->u.u.type;
	return BadValue;
    }

    list = (XEventClass *) (first + stuff->num_events);
    if ((ret = CreateMaskFromList(client, list, stuff->count, tmp, dev,
				  X_SendExtensionEvent)) != Success)
	return ret;

    ret = (SendEvent(client, dev, stuff->destination,
		     stuff->propagate, (xEvent *) & stuff[1],
		     tmp[stuff->deviceid].mask, stuff->num_events));

    return ret;
}
示例#2
0
int
ProcXGrabDevice(ClientPtr client)
{
    int rc;
    xGrabDeviceReply rep;
    DeviceIntPtr dev;
    GrabMask mask;
    struct tmask tmp[EMASKSIZE];

    REQUEST(xGrabDeviceReq);
    REQUEST_AT_LEAST_SIZE(xGrabDeviceReq);

    if (stuff->length !=
        bytes_to_int32(sizeof(xGrabDeviceReq)) + stuff->event_count)
        return BadLength;

    rep = (xGrabDeviceReply) {
        .repType = X_Reply,
        .RepType = X_GrabDevice,
        .sequenceNumber = client->sequence,
        .length = 0,
    };

    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
    if (rc != Success)
        return rc;

    if ((rc = CreateMaskFromList(client, (XEventClass *) &stuff[1],
                                 stuff->event_count, tmp, dev,
                                 X_GrabDevice)) != Success)
        return rc;

    mask.xi = tmp[stuff->deviceid].mask;

    rc = GrabDevice(client, dev, stuff->other_devices_mode,
                    stuff->this_device_mode, stuff->grabWindow,
                    stuff->ownerEvents, stuff->time,
                    &mask, XI, None, None, &rep.status);

    if (rc != Success)
        return rc;

    WriteReplyToClient(client, sizeof(xGrabDeviceReply), &rep);
    return Success;
}

/***********************************************************************
 *
 * This procedure creates an event mask from a list of XEventClasses.
 *
 * Procedure is as follows:
 * An XEventClass is (deviceid << 8 | eventtype). For each entry in the list,
 * get the device. Then run through all available event indices (those are
 * set when XI starts up) and binary OR's the device's mask to whatever the
 * event mask for the given event type was.
 * If an error occurs, it is sent to the client. Errors are generated if
 *  - if the device given in the event classs is invalid
 *  - if the device in the class list is not the device given as parameter (no
 *  error if parameter is NULL)
 *
 * mask has to be size EMASKSIZE and pre-allocated.
 *
 * @param client The client to send the error to (if one occurs)
 * @param list List of event classes as sent from the client.
 * @param count Number of elements in list.
 * @param mask Preallocated mask (size EMASKSIZE).
 * @param dev The device we're creating masks for.
 * @param req The request we're processing. Used to fill in error fields.
 */

int
CreateMaskFromList(ClientPtr client, XEventClass * list, int count,
                   struct tmask *mask, DeviceIntPtr dev, int req)
{
    int rc, i, j;
    int device;
    DeviceIntPtr tdev;

    memset(mask, 0, EMASKSIZE * sizeof(struct tmask));

    for (i = 0; i < count; i++, list++) {
        device = *list >> 8;
        if (device > 255)
            return BadClass;

        rc = dixLookupDevice(&tdev, device, client, DixUseAccess);
        if (rc != BadDevice && rc != Success)
            return rc;
        if (rc == BadDevice || (dev != NULL && tdev != dev))
            return BadClass;

        for (j = 0; j < ExtEventIndex; j++)
            if (EventInfo[j].type == (*list & 0xff)) {
                mask[device].mask |= EventInfo[j].mask;
                mask[device].dev = (Pointer) tdev;
                break;
            }
    }
    return Success;
}
示例#3
0
int _X_COLD
SProcXSendExtensionEvent(ClientPtr client)
{
    CARD32 *p;
    int i;
    xEvent eventT = { .u.u.type = 0 };
    xEvent *eventP;
    EventSwapPtr proc;

    REQUEST(xSendExtensionEventReq);
    swaps(&stuff->length);
    REQUEST_AT_LEAST_SIZE(xSendExtensionEventReq);
    swapl(&stuff->destination);
    swaps(&stuff->count);

    if (stuff->length !=
        bytes_to_int32(sizeof(xSendExtensionEventReq)) + stuff->count +
        bytes_to_int32(stuff->num_events * sizeof(xEvent)))
        return BadLength;

    eventP = (xEvent *) &stuff[1];
    for (i = 0; i < stuff->num_events; i++, eventP++) {
        if (eventP->u.u.type == GenericEvent) {
            client->errorValue = eventP->u.u.type;
            return BadValue;
        }

        proc = EventSwapVector[eventP->u.u.type & 0177];
        /* no swapping proc; invalid event type? */
        if (proc == NotImplemented) {
            client->errorValue = eventP->u.u.type;
            return BadValue;
        }
        (*proc) (eventP, &eventT);
        *eventP = eventT;
    }

    p = (CARD32 *) (((xEvent *) &stuff[1]) + stuff->num_events);
    SwapLongs(p, stuff->count);
    return (ProcXSendExtensionEvent(client));
}

/***********************************************************************
 *
 * Send an event to some client, as if it had come from an extension input
 * device.
 *
 */

int
ProcXSendExtensionEvent(ClientPtr client)
{
    int ret, i;
    DeviceIntPtr dev;
    xEvent *first;
    XEventClass *list;
    struct tmask tmp[EMASKSIZE];

    REQUEST(xSendExtensionEventReq);
    REQUEST_AT_LEAST_SIZE(xSendExtensionEventReq);

    if (stuff->length !=
        bytes_to_int32(sizeof(xSendExtensionEventReq)) + stuff->count +
        (stuff->num_events * bytes_to_int32(sizeof(xEvent))))
        return BadLength;

    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixWriteAccess);
    if (ret != Success)
        return ret;

    if (stuff->num_events == 0)
        return ret;

    /* The client's event type must be one defined by an extension. */

    first = ((xEvent *) &stuff[1]);
    for (i = 0; i < stuff->num_events; i++) {
        if (!((EXTENSION_EVENT_BASE <= first[i].u.u.type) &&
            (first[i].u.u.type < lastEvent))) {
            client->errorValue = first[i].u.u.type;
            return BadValue;
        }
    }

    list = (XEventClass *) (first + stuff->num_events);
    if ((ret = CreateMaskFromList(client, list, stuff->count, tmp, dev,
                                  X_SendExtensionEvent)) != Success)
        return ret;

    ret = (SendEvent(client, dev, stuff->destination,
                     stuff->propagate, (xEvent *) &stuff[1],
                     tmp[stuff->deviceid].mask, stuff->num_events));

    return ret;
}