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