protocol-xipassivegrabdevice.c revision 35c4bbdf
135c4bbdfSmrg/**
235c4bbdfSmrg * Copyright © 2011 Red Hat, Inc.
335c4bbdfSmrg *
435c4bbdfSmrg *  Permission is hereby granted, free of charge, to any person obtaining a
535c4bbdfSmrg *  copy of this software and associated documentation files (the "Software"),
635c4bbdfSmrg *  to deal in the Software without restriction, including without limitation
735c4bbdfSmrg *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
835c4bbdfSmrg *  and/or sell copies of the Software, and to permit persons to whom the
935c4bbdfSmrg *  Software is furnished to do so, subject to the following conditions:
1035c4bbdfSmrg *
1135c4bbdfSmrg *  The above copyright notice and this permission notice (including the next
1235c4bbdfSmrg *  paragraph) shall be included in all copies or substantial portions of the
1335c4bbdfSmrg *  Software.
1435c4bbdfSmrg *
1535c4bbdfSmrg *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1635c4bbdfSmrg *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1735c4bbdfSmrg *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1835c4bbdfSmrg *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1935c4bbdfSmrg *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2035c4bbdfSmrg *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2135c4bbdfSmrg *  DEALINGS IN THE SOFTWARE.
2235c4bbdfSmrg */
2335c4bbdfSmrg
2435c4bbdfSmrg#ifdef HAVE_DIX_CONFIG_H
2535c4bbdfSmrg#include <dix-config.h>
2635c4bbdfSmrg#endif
2735c4bbdfSmrg
2835c4bbdfSmrg/*
2935c4bbdfSmrg * Protocol testing for XIPassiveGrab request.
3035c4bbdfSmrg */
3135c4bbdfSmrg#include <stdint.h>
3235c4bbdfSmrg#include <X11/X.h>
3335c4bbdfSmrg#include <X11/Xproto.h>
3435c4bbdfSmrg#include <X11/extensions/XI2proto.h>
3535c4bbdfSmrg#include "inputstr.h"
3635c4bbdfSmrg#include "windowstr.h"
3735c4bbdfSmrg#include "scrnintstr.h"
3835c4bbdfSmrg#include "xipassivegrab.h"
3935c4bbdfSmrg#include "exevents.h"
4035c4bbdfSmrg#include "exglobals.h"
4135c4bbdfSmrg
4235c4bbdfSmrg#include "protocol-common.h"
4335c4bbdfSmrg
4435c4bbdfSmrgstatic ClientRec client_request;
4535c4bbdfSmrg
4635c4bbdfSmrg#define N_MODS 7
4735c4bbdfSmrgstatic uint32_t modifiers[N_MODS] = { 1, 2, 3, 4, 5, 6, 7 };
4835c4bbdfSmrg
4935c4bbdfSmrgstruct test_data {
5035c4bbdfSmrg    int num_modifiers;
5135c4bbdfSmrg} testdata;
5235c4bbdfSmrg
5335c4bbdfSmrgint __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev,
5435c4bbdfSmrg                      DeviceIntPtr modifier_device, int button,
5535c4bbdfSmrg                      GrabParameters *param, enum InputLevel grabtype,
5635c4bbdfSmrg                      GrabMask *mask);
5735c4bbdfSmrgstatic void reply_XIPassiveGrabDevice_data(ClientPtr client, int len,
5835c4bbdfSmrg                                           char *data, void *closure);
5935c4bbdfSmrg
6035c4bbdfSmrgint
6135c4bbdfSmrg__wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access)
6235c4bbdfSmrg{
6335c4bbdfSmrg    if (id == root.drawable.id) {
6435c4bbdfSmrg        *win = &root;
6535c4bbdfSmrg        return Success;
6635c4bbdfSmrg    }
6735c4bbdfSmrg    else if (id == window.drawable.id) {
6835c4bbdfSmrg        *win = &window;
6935c4bbdfSmrg        return Success;
7035c4bbdfSmrg    }
7135c4bbdfSmrg
7235c4bbdfSmrg    return __real_dixLookupWindow(win, id, client, access);
7335c4bbdfSmrg}
7435c4bbdfSmrg
7535c4bbdfSmrgint
7635c4bbdfSmrg__wrap_GrabButton(ClientPtr client, DeviceIntPtr dev,
7735c4bbdfSmrg                  DeviceIntPtr modifier_device, int button,
7835c4bbdfSmrg                  GrabParameters *param, enum InputLevel grabtype,
7935c4bbdfSmrg                  GrabMask *mask)
8035c4bbdfSmrg{
8135c4bbdfSmrg    /* Fail every odd modifier */
8235c4bbdfSmrg    if (param->modifiers % 2)
8335c4bbdfSmrg        return BadAccess;
8435c4bbdfSmrg
8535c4bbdfSmrg    return Success;
8635c4bbdfSmrg}
8735c4bbdfSmrg
8835c4bbdfSmrgstatic void
8935c4bbdfSmrgreply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *closure)
9035c4bbdfSmrg{
9135c4bbdfSmrg    xXIPassiveGrabDeviceReply *rep = (xXIPassiveGrabDeviceReply *) data;
9235c4bbdfSmrg
9335c4bbdfSmrg    if (client->swapped) {
9435c4bbdfSmrg        swaps(&rep->sequenceNumber);
9535c4bbdfSmrg        swapl(&rep->length);
9635c4bbdfSmrg        swaps(&rep->num_modifiers);
9735c4bbdfSmrg
9835c4bbdfSmrg        testdata.num_modifiers = rep->num_modifiers;
9935c4bbdfSmrg    }
10035c4bbdfSmrg
10135c4bbdfSmrg    reply_check_defaults(rep, len, XIPassiveGrabDevice);
10235c4bbdfSmrg
10335c4bbdfSmrg    /* ProcXIPassiveGrabDevice sends the data in two batches, let the second
10435c4bbdfSmrg     * handler handle the modifier data */
10535c4bbdfSmrg    if (rep->num_modifiers > 0)
10635c4bbdfSmrg        reply_handler = reply_XIPassiveGrabDevice_data;
10735c4bbdfSmrg}
10835c4bbdfSmrg
10935c4bbdfSmrgstatic void
11035c4bbdfSmrgreply_XIPassiveGrabDevice_data(ClientPtr client, int len, char *data,
11135c4bbdfSmrg                               void *closure)
11235c4bbdfSmrg{
11335c4bbdfSmrg    int i;
11435c4bbdfSmrg
11535c4bbdfSmrg    xXIGrabModifierInfo *mods = (xXIGrabModifierInfo *) data;
11635c4bbdfSmrg
11735c4bbdfSmrg    for (i = 0; i < testdata.num_modifiers; i++, mods++) {
11835c4bbdfSmrg        if (client->swapped)
11935c4bbdfSmrg            swapl(&mods->modifiers);
12035c4bbdfSmrg
12135c4bbdfSmrg        /* 1 - 7 is the range we use for the global modifiers array
12235c4bbdfSmrg         * above */
12335c4bbdfSmrg        assert(mods->modifiers > 0);
12435c4bbdfSmrg        assert(mods->modifiers <= 7);
12535c4bbdfSmrg        assert(mods->modifiers % 2 == 1);       /* because we fail odd ones */
12635c4bbdfSmrg        assert(mods->status != Success);
12735c4bbdfSmrg        assert(mods->pad0 == 0);
12835c4bbdfSmrg        assert(mods->pad1 == 0);
12935c4bbdfSmrg    }
13035c4bbdfSmrg
13135c4bbdfSmrg    reply_handler = reply_XIPassiveGrabDevice;
13235c4bbdfSmrg}
13335c4bbdfSmrg
13435c4bbdfSmrgstatic void
13535c4bbdfSmrgrequest_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
13635c4bbdfSmrg                            int error, int errval)
13735c4bbdfSmrg{
13835c4bbdfSmrg    int rc;
13935c4bbdfSmrg    int local_modifiers;
14035c4bbdfSmrg    int mask_len;
14135c4bbdfSmrg
14235c4bbdfSmrg    client_request.req_len = req->length;
14335c4bbdfSmrg    rc = ProcXIPassiveGrabDevice(&client_request);
14435c4bbdfSmrg    assert(rc == error);
14535c4bbdfSmrg
14635c4bbdfSmrg    if (rc != Success)
14735c4bbdfSmrg        assert(client_request.errorValue == errval);
14835c4bbdfSmrg
14935c4bbdfSmrg    client_request.swapped = TRUE;
15035c4bbdfSmrg    swaps(&req->length);
15135c4bbdfSmrg    swapl(&req->time);
15235c4bbdfSmrg    swapl(&req->grab_window);
15335c4bbdfSmrg    swapl(&req->cursor);
15435c4bbdfSmrg    swapl(&req->detail);
15535c4bbdfSmrg    swaps(&req->deviceid);
15635c4bbdfSmrg    local_modifiers = req->num_modifiers;
15735c4bbdfSmrg    swaps(&req->num_modifiers);
15835c4bbdfSmrg    mask_len = req->mask_len;
15935c4bbdfSmrg    swaps(&req->mask_len);
16035c4bbdfSmrg
16135c4bbdfSmrg    while (local_modifiers--) {
16235c4bbdfSmrg        CARD32 *mod = (CARD32 *) (req + 1) + mask_len + local_modifiers;
16335c4bbdfSmrg
16435c4bbdfSmrg        swapl(mod);
16535c4bbdfSmrg    }
16635c4bbdfSmrg
16735c4bbdfSmrg    rc = SProcXIPassiveGrabDevice(&client_request);
16835c4bbdfSmrg    assert(rc == error);
16935c4bbdfSmrg
17035c4bbdfSmrg    if (rc != Success)
17135c4bbdfSmrg        assert(client_request.errorValue == errval);
17235c4bbdfSmrg}
17335c4bbdfSmrg
17435c4bbdfSmrgstatic unsigned char *data[4096];       /* the request buffer */
17535c4bbdfSmrgstatic void
17635c4bbdfSmrgtest_XIPassiveGrabDevice(void)
17735c4bbdfSmrg{
17835c4bbdfSmrg    int i;
17935c4bbdfSmrg    xXIPassiveGrabDeviceReq *request = (xXIPassiveGrabDeviceReq *) data;
18035c4bbdfSmrg    unsigned char *mask;
18135c4bbdfSmrg
18235c4bbdfSmrg    request_init(request, XIPassiveGrabDevice);
18335c4bbdfSmrg
18435c4bbdfSmrg    request->grab_window = CLIENT_WINDOW_ID;
18535c4bbdfSmrg
18635c4bbdfSmrg    reply_handler = reply_XIPassiveGrabDevice;
18735c4bbdfSmrg    client_request = init_client(request->length, request);
18835c4bbdfSmrg
18935c4bbdfSmrg    printf("Testing invalid device\n");
19035c4bbdfSmrg    request->deviceid = 12;
19135c4bbdfSmrg    request_XIPassiveGrabDevice(&client_request, request, BadDevice,
19235c4bbdfSmrg                                request->deviceid);
19335c4bbdfSmrg
19435c4bbdfSmrg    printf("Testing invalid length\n");
19535c4bbdfSmrg    request->length -= 2;
19635c4bbdfSmrg    request_XIPassiveGrabDevice(&client_request, request, BadLength,
19735c4bbdfSmrg                                client_request.errorValue);
19835c4bbdfSmrg    /* re-init request since swapped length test leaves some values swapped */
19935c4bbdfSmrg    request_init(request, XIPassiveGrabDevice);
20035c4bbdfSmrg    request->grab_window = CLIENT_WINDOW_ID;
20135c4bbdfSmrg    request->deviceid = XIAllMasterDevices;
20235c4bbdfSmrg
20335c4bbdfSmrg    printf("Testing invalid grab types\n");
20435c4bbdfSmrg    for (i = XIGrabtypeTouchBegin + 1; i < 0xFF; i++) {
20535c4bbdfSmrg        request->grab_type = i;
20635c4bbdfSmrg        request_XIPassiveGrabDevice(&client_request, request, BadValue,
20735c4bbdfSmrg                                    request->grab_type);
20835c4bbdfSmrg    }
20935c4bbdfSmrg
21035c4bbdfSmrg    printf("Testing invalid grab type + detail combinations\n");
21135c4bbdfSmrg    request->grab_type = XIGrabtypeEnter;
21235c4bbdfSmrg    request->detail = 1;
21335c4bbdfSmrg    request_XIPassiveGrabDevice(&client_request, request, BadValue,
21435c4bbdfSmrg                                request->detail);
21535c4bbdfSmrg
21635c4bbdfSmrg    request->grab_type = XIGrabtypeFocusIn;
21735c4bbdfSmrg    request_XIPassiveGrabDevice(&client_request, request, BadValue,
21835c4bbdfSmrg                                request->detail);
21935c4bbdfSmrg
22035c4bbdfSmrg    request->detail = 0;
22135c4bbdfSmrg
22235c4bbdfSmrg    printf("Testing invalid masks\n");
22335c4bbdfSmrg    mask = (unsigned char *) &request[1];
22435c4bbdfSmrg
22535c4bbdfSmrg    request->mask_len = bytes_to_int32(XI2LASTEVENT + 1);
22635c4bbdfSmrg    request->length += request->mask_len;
22735c4bbdfSmrg    SetBit(mask, XI2LASTEVENT + 1);
22835c4bbdfSmrg    request_XIPassiveGrabDevice(&client_request, request, BadValue,
22935c4bbdfSmrg                                XI2LASTEVENT + 1);
23035c4bbdfSmrg
23135c4bbdfSmrg    ClearBit(mask, XI2LASTEVENT + 1);
23235c4bbdfSmrg
23335c4bbdfSmrg    /* tested all special cases now, test a few valid cases */
23435c4bbdfSmrg
23535c4bbdfSmrg    /* no modifiers */
23635c4bbdfSmrg    request->deviceid = XIAllDevices;
23735c4bbdfSmrg    request->grab_type = XIGrabtypeButton;
23835c4bbdfSmrg    request->detail = XIAnyButton;
23935c4bbdfSmrg    request_XIPassiveGrabDevice(&client_request, request, Success, 0);
24035c4bbdfSmrg
24135c4bbdfSmrg    /* Set a few random masks to make sure we handle modifiers correctly */
24235c4bbdfSmrg    SetBit(mask, XI_ButtonPress);
24335c4bbdfSmrg    SetBit(mask, XI_KeyPress);
24435c4bbdfSmrg    SetBit(mask, XI_Enter);
24535c4bbdfSmrg
24635c4bbdfSmrg    /* some modifiers */
24735c4bbdfSmrg    request->num_modifiers = N_MODS;
24835c4bbdfSmrg    request->length += N_MODS;
24935c4bbdfSmrg    memcpy((uint32_t *) (request + 1) + request->mask_len, modifiers,
25035c4bbdfSmrg           sizeof(modifiers));
25135c4bbdfSmrg    request_XIPassiveGrabDevice(&client_request, request, Success, 0);
25235c4bbdfSmrg}
25335c4bbdfSmrg
25435c4bbdfSmrgint
25535c4bbdfSmrgmain(int argc, char **argv)
25635c4bbdfSmrg{
25735c4bbdfSmrg    init_simple();
25835c4bbdfSmrg
25935c4bbdfSmrg    test_XIPassiveGrabDevice();
26035c4bbdfSmrg
26135c4bbdfSmrg    return 0;
26235c4bbdfSmrg}
263