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