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 24ed6184dfSmrg/* Test relies on assert() */ 25ed6184dfSmrg#undef NDEBUG 26ed6184dfSmrg 2735c4bbdfSmrg#ifdef HAVE_DIX_CONFIG_H 2835c4bbdfSmrg#include <dix-config.h> 2935c4bbdfSmrg#endif 3035c4bbdfSmrg 3135c4bbdfSmrg/* 3235c4bbdfSmrg * Protocol testing for XIPassiveGrab request. 3335c4bbdfSmrg */ 3435c4bbdfSmrg#include <stdint.h> 3535c4bbdfSmrg#include <X11/X.h> 3635c4bbdfSmrg#include <X11/Xproto.h> 3735c4bbdfSmrg#include <X11/extensions/XI2proto.h> 3835c4bbdfSmrg#include "inputstr.h" 3935c4bbdfSmrg#include "windowstr.h" 4035c4bbdfSmrg#include "scrnintstr.h" 4135c4bbdfSmrg#include "xipassivegrab.h" 4235c4bbdfSmrg#include "exevents.h" 4335c4bbdfSmrg#include "exglobals.h" 4435c4bbdfSmrg 4535c4bbdfSmrg#include "protocol-common.h" 4635c4bbdfSmrg 475a7dfde8Smrgextern ClientRec client_window; 4835c4bbdfSmrgstatic ClientRec client_request; 4935c4bbdfSmrg 5035c4bbdfSmrg#define N_MODS 7 5135c4bbdfSmrgstatic uint32_t modifiers[N_MODS] = { 1, 2, 3, 4, 5, 6, 7 }; 5235c4bbdfSmrg 531b5d61b8Smrgstatic struct test_data { 5435c4bbdfSmrg int num_modifiers; 5535c4bbdfSmrg} testdata; 5635c4bbdfSmrg 5735c4bbdfSmrgint __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev, 5835c4bbdfSmrg DeviceIntPtr modifier_device, int button, 5935c4bbdfSmrg GrabParameters *param, enum InputLevel grabtype, 6035c4bbdfSmrg GrabMask *mask); 611b5d61b8Smrgint __real_GrabButton(ClientPtr client, DeviceIntPtr dev, 621b5d61b8Smrg DeviceIntPtr modifier_device, int button, 631b5d61b8Smrg GrabParameters *param, enum InputLevel grabtype, 641b5d61b8Smrg GrabMask *mask); 6535c4bbdfSmrgstatic void reply_XIPassiveGrabDevice_data(ClientPtr client, int len, 6635c4bbdfSmrg char *data, void *closure); 6735c4bbdfSmrg 6835c4bbdfSmrgint 6935c4bbdfSmrg__wrap_GrabButton(ClientPtr client, DeviceIntPtr dev, 7035c4bbdfSmrg DeviceIntPtr modifier_device, int button, 7135c4bbdfSmrg GrabParameters *param, enum InputLevel grabtype, 7235c4bbdfSmrg GrabMask *mask) 7335c4bbdfSmrg{ 741b5d61b8Smrg if (!enable_GrabButton_wrap) 751b5d61b8Smrg __real_GrabButton(client, dev, modifier_device, button, param, grabtype, mask); 761b5d61b8Smrg 7735c4bbdfSmrg /* Fail every odd modifier */ 7835c4bbdfSmrg if (param->modifiers % 2) 7935c4bbdfSmrg return BadAccess; 8035c4bbdfSmrg 8135c4bbdfSmrg return Success; 8235c4bbdfSmrg} 8335c4bbdfSmrg 8435c4bbdfSmrgstatic void 8535c4bbdfSmrgreply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *closure) 8635c4bbdfSmrg{ 8735c4bbdfSmrg xXIPassiveGrabDeviceReply *rep = (xXIPassiveGrabDeviceReply *) data; 8835c4bbdfSmrg 8935c4bbdfSmrg if (client->swapped) { 9035c4bbdfSmrg swaps(&rep->sequenceNumber); 9135c4bbdfSmrg swapl(&rep->length); 9235c4bbdfSmrg swaps(&rep->num_modifiers); 9335c4bbdfSmrg 9435c4bbdfSmrg testdata.num_modifiers = rep->num_modifiers; 9535c4bbdfSmrg } 9635c4bbdfSmrg 9735c4bbdfSmrg reply_check_defaults(rep, len, XIPassiveGrabDevice); 9835c4bbdfSmrg 9935c4bbdfSmrg /* ProcXIPassiveGrabDevice sends the data in two batches, let the second 10035c4bbdfSmrg * handler handle the modifier data */ 10135c4bbdfSmrg if (rep->num_modifiers > 0) 10235c4bbdfSmrg reply_handler = reply_XIPassiveGrabDevice_data; 10335c4bbdfSmrg} 10435c4bbdfSmrg 10535c4bbdfSmrgstatic void 10635c4bbdfSmrgreply_XIPassiveGrabDevice_data(ClientPtr client, int len, char *data, 10735c4bbdfSmrg void *closure) 10835c4bbdfSmrg{ 10935c4bbdfSmrg int i; 11035c4bbdfSmrg 11135c4bbdfSmrg xXIGrabModifierInfo *mods = (xXIGrabModifierInfo *) data; 11235c4bbdfSmrg 11335c4bbdfSmrg for (i = 0; i < testdata.num_modifiers; i++, mods++) { 11435c4bbdfSmrg if (client->swapped) 11535c4bbdfSmrg swapl(&mods->modifiers); 11635c4bbdfSmrg 11735c4bbdfSmrg /* 1 - 7 is the range we use for the global modifiers array 11835c4bbdfSmrg * above */ 11935c4bbdfSmrg assert(mods->modifiers > 0); 12035c4bbdfSmrg assert(mods->modifiers <= 7); 12135c4bbdfSmrg assert(mods->modifiers % 2 == 1); /* because we fail odd ones */ 12235c4bbdfSmrg assert(mods->status != Success); 12335c4bbdfSmrg assert(mods->pad0 == 0); 12435c4bbdfSmrg assert(mods->pad1 == 0); 12535c4bbdfSmrg } 12635c4bbdfSmrg 12735c4bbdfSmrg reply_handler = reply_XIPassiveGrabDevice; 12835c4bbdfSmrg} 12935c4bbdfSmrg 13035c4bbdfSmrgstatic void 13135c4bbdfSmrgrequest_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req, 13235c4bbdfSmrg int error, int errval) 13335c4bbdfSmrg{ 13435c4bbdfSmrg int rc; 13535c4bbdfSmrg int local_modifiers; 13635c4bbdfSmrg int mask_len; 13735c4bbdfSmrg 13835c4bbdfSmrg client_request.req_len = req->length; 13935c4bbdfSmrg rc = ProcXIPassiveGrabDevice(&client_request); 14035c4bbdfSmrg assert(rc == error); 14135c4bbdfSmrg 14235c4bbdfSmrg if (rc != Success) 14335c4bbdfSmrg assert(client_request.errorValue == errval); 14435c4bbdfSmrg 14535c4bbdfSmrg client_request.swapped = TRUE; 14635c4bbdfSmrg swaps(&req->length); 14735c4bbdfSmrg swapl(&req->time); 14835c4bbdfSmrg swapl(&req->grab_window); 14935c4bbdfSmrg swapl(&req->cursor); 15035c4bbdfSmrg swapl(&req->detail); 15135c4bbdfSmrg swaps(&req->deviceid); 15235c4bbdfSmrg local_modifiers = req->num_modifiers; 15335c4bbdfSmrg swaps(&req->num_modifiers); 15435c4bbdfSmrg mask_len = req->mask_len; 15535c4bbdfSmrg swaps(&req->mask_len); 15635c4bbdfSmrg 15735c4bbdfSmrg while (local_modifiers--) { 15835c4bbdfSmrg CARD32 *mod = (CARD32 *) (req + 1) + mask_len + local_modifiers; 15935c4bbdfSmrg 16035c4bbdfSmrg swapl(mod); 16135c4bbdfSmrg } 16235c4bbdfSmrg 16335c4bbdfSmrg rc = SProcXIPassiveGrabDevice(&client_request); 16435c4bbdfSmrg assert(rc == error); 16535c4bbdfSmrg 16635c4bbdfSmrg if (rc != Success) 16735c4bbdfSmrg assert(client_request.errorValue == errval); 16835c4bbdfSmrg} 16935c4bbdfSmrg 17035c4bbdfSmrgstatic unsigned char *data[4096]; /* the request buffer */ 17135c4bbdfSmrgstatic void 17235c4bbdfSmrgtest_XIPassiveGrabDevice(void) 17335c4bbdfSmrg{ 17435c4bbdfSmrg int i; 17535c4bbdfSmrg xXIPassiveGrabDeviceReq *request = (xXIPassiveGrabDeviceReq *) data; 17635c4bbdfSmrg unsigned char *mask; 17735c4bbdfSmrg 17835c4bbdfSmrg request_init(request, XIPassiveGrabDevice); 17935c4bbdfSmrg 18035c4bbdfSmrg request->grab_window = CLIENT_WINDOW_ID; 18135c4bbdfSmrg 18235c4bbdfSmrg reply_handler = reply_XIPassiveGrabDevice; 18335c4bbdfSmrg client_request = init_client(request->length, request); 18435c4bbdfSmrg 18535c4bbdfSmrg printf("Testing invalid device\n"); 18635c4bbdfSmrg request->deviceid = 12; 18735c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, BadDevice, 18835c4bbdfSmrg request->deviceid); 18935c4bbdfSmrg 19035c4bbdfSmrg printf("Testing invalid length\n"); 19135c4bbdfSmrg request->length -= 2; 19235c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, BadLength, 19335c4bbdfSmrg client_request.errorValue); 19435c4bbdfSmrg /* re-init request since swapped length test leaves some values swapped */ 19535c4bbdfSmrg request_init(request, XIPassiveGrabDevice); 19635c4bbdfSmrg request->grab_window = CLIENT_WINDOW_ID; 19735c4bbdfSmrg request->deviceid = XIAllMasterDevices; 19835c4bbdfSmrg 19935c4bbdfSmrg printf("Testing invalid grab types\n"); 200ed6184dfSmrg for (i = XIGrabtypeGestureSwipeBegin + 1; i < 0xFF; i++) { 20135c4bbdfSmrg request->grab_type = i; 20235c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, BadValue, 20335c4bbdfSmrg request->grab_type); 20435c4bbdfSmrg } 20535c4bbdfSmrg 20635c4bbdfSmrg printf("Testing invalid grab type + detail combinations\n"); 20735c4bbdfSmrg request->grab_type = XIGrabtypeEnter; 20835c4bbdfSmrg request->detail = 1; 20935c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, BadValue, 21035c4bbdfSmrg request->detail); 21135c4bbdfSmrg 21235c4bbdfSmrg request->grab_type = XIGrabtypeFocusIn; 21335c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, BadValue, 21435c4bbdfSmrg request->detail); 21535c4bbdfSmrg 21635c4bbdfSmrg request->detail = 0; 21735c4bbdfSmrg 21835c4bbdfSmrg printf("Testing invalid masks\n"); 21935c4bbdfSmrg mask = (unsigned char *) &request[1]; 22035c4bbdfSmrg 22135c4bbdfSmrg request->mask_len = bytes_to_int32(XI2LASTEVENT + 1); 22235c4bbdfSmrg request->length += request->mask_len; 22335c4bbdfSmrg SetBit(mask, XI2LASTEVENT + 1); 22435c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, BadValue, 22535c4bbdfSmrg XI2LASTEVENT + 1); 22635c4bbdfSmrg 22735c4bbdfSmrg ClearBit(mask, XI2LASTEVENT + 1); 22835c4bbdfSmrg 22935c4bbdfSmrg /* tested all special cases now, test a few valid cases */ 23035c4bbdfSmrg 23135c4bbdfSmrg /* no modifiers */ 23235c4bbdfSmrg request->deviceid = XIAllDevices; 23335c4bbdfSmrg request->grab_type = XIGrabtypeButton; 23435c4bbdfSmrg request->detail = XIAnyButton; 23535c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, Success, 0); 23635c4bbdfSmrg 23735c4bbdfSmrg /* Set a few random masks to make sure we handle modifiers correctly */ 23835c4bbdfSmrg SetBit(mask, XI_ButtonPress); 23935c4bbdfSmrg SetBit(mask, XI_KeyPress); 24035c4bbdfSmrg SetBit(mask, XI_Enter); 24135c4bbdfSmrg 24235c4bbdfSmrg /* some modifiers */ 24335c4bbdfSmrg request->num_modifiers = N_MODS; 24435c4bbdfSmrg request->length += N_MODS; 24535c4bbdfSmrg memcpy((uint32_t *) (request + 1) + request->mask_len, modifiers, 24635c4bbdfSmrg sizeof(modifiers)); 24735c4bbdfSmrg request_XIPassiveGrabDevice(&client_request, request, Success, 0); 24835c4bbdfSmrg} 24935c4bbdfSmrg 25035c4bbdfSmrgint 2511b5d61b8Smrgprotocol_xipassivegrabdevice_test(void) 25235c4bbdfSmrg{ 25335c4bbdfSmrg init_simple(); 25435c4bbdfSmrg 25535c4bbdfSmrg test_XIPassiveGrabDevice(); 25635c4bbdfSmrg 25735c4bbdfSmrg return 0; 25835c4bbdfSmrg} 259