protocol-xipassivegrabdevice.c revision 5a7dfde8
1/** 2 * Copyright © 2011 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#ifdef HAVE_DIX_CONFIG_H 25#include <dix-config.h> 26#endif 27 28/* 29 * Protocol testing for XIPassiveGrab request. 30 */ 31#include <stdint.h> 32#include <X11/X.h> 33#include <X11/Xproto.h> 34#include <X11/extensions/XI2proto.h> 35#include "inputstr.h" 36#include "windowstr.h" 37#include "scrnintstr.h" 38#include "xipassivegrab.h" 39#include "exevents.h" 40#include "exglobals.h" 41 42#include "protocol-common.h" 43 44extern ClientRec client_window; 45static ClientRec client_request; 46 47#define N_MODS 7 48static uint32_t modifiers[N_MODS] = { 1, 2, 3, 4, 5, 6, 7 }; 49 50static struct test_data { 51 int num_modifiers; 52} testdata; 53 54int __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev, 55 DeviceIntPtr modifier_device, int button, 56 GrabParameters *param, enum InputLevel grabtype, 57 GrabMask *mask); 58int __real_GrabButton(ClientPtr client, DeviceIntPtr dev, 59 DeviceIntPtr modifier_device, int button, 60 GrabParameters *param, enum InputLevel grabtype, 61 GrabMask *mask); 62static void reply_XIPassiveGrabDevice_data(ClientPtr client, int len, 63 char *data, void *closure); 64 65int 66__wrap_GrabButton(ClientPtr client, DeviceIntPtr dev, 67 DeviceIntPtr modifier_device, int button, 68 GrabParameters *param, enum InputLevel grabtype, 69 GrabMask *mask) 70{ 71 if (!enable_GrabButton_wrap) 72 __real_GrabButton(client, dev, modifier_device, button, param, grabtype, mask); 73 74 /* Fail every odd modifier */ 75 if (param->modifiers % 2) 76 return BadAccess; 77 78 return Success; 79} 80 81static void 82reply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *closure) 83{ 84 xXIPassiveGrabDeviceReply *rep = (xXIPassiveGrabDeviceReply *) data; 85 86 if (client->swapped) { 87 swaps(&rep->sequenceNumber); 88 swapl(&rep->length); 89 swaps(&rep->num_modifiers); 90 91 testdata.num_modifiers = rep->num_modifiers; 92 } 93 94 reply_check_defaults(rep, len, XIPassiveGrabDevice); 95 96 /* ProcXIPassiveGrabDevice sends the data in two batches, let the second 97 * handler handle the modifier data */ 98 if (rep->num_modifiers > 0) 99 reply_handler = reply_XIPassiveGrabDevice_data; 100} 101 102static void 103reply_XIPassiveGrabDevice_data(ClientPtr client, int len, char *data, 104 void *closure) 105{ 106 int i; 107 108 xXIGrabModifierInfo *mods = (xXIGrabModifierInfo *) data; 109 110 for (i = 0; i < testdata.num_modifiers; i++, mods++) { 111 if (client->swapped) 112 swapl(&mods->modifiers); 113 114 /* 1 - 7 is the range we use for the global modifiers array 115 * above */ 116 assert(mods->modifiers > 0); 117 assert(mods->modifiers <= 7); 118 assert(mods->modifiers % 2 == 1); /* because we fail odd ones */ 119 assert(mods->status != Success); 120 assert(mods->pad0 == 0); 121 assert(mods->pad1 == 0); 122 } 123 124 reply_handler = reply_XIPassiveGrabDevice; 125} 126 127static void 128request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req, 129 int error, int errval) 130{ 131 int rc; 132 int local_modifiers; 133 int mask_len; 134 135 client_request.req_len = req->length; 136 rc = ProcXIPassiveGrabDevice(&client_request); 137 assert(rc == error); 138 139 if (rc != Success) 140 assert(client_request.errorValue == errval); 141 142 client_request.swapped = TRUE; 143 swaps(&req->length); 144 swapl(&req->time); 145 swapl(&req->grab_window); 146 swapl(&req->cursor); 147 swapl(&req->detail); 148 swaps(&req->deviceid); 149 local_modifiers = req->num_modifiers; 150 swaps(&req->num_modifiers); 151 mask_len = req->mask_len; 152 swaps(&req->mask_len); 153 154 while (local_modifiers--) { 155 CARD32 *mod = (CARD32 *) (req + 1) + mask_len + local_modifiers; 156 157 swapl(mod); 158 } 159 160 rc = SProcXIPassiveGrabDevice(&client_request); 161 assert(rc == error); 162 163 if (rc != Success) 164 assert(client_request.errorValue == errval); 165} 166 167static unsigned char *data[4096]; /* the request buffer */ 168static void 169test_XIPassiveGrabDevice(void) 170{ 171 int i; 172 xXIPassiveGrabDeviceReq *request = (xXIPassiveGrabDeviceReq *) data; 173 unsigned char *mask; 174 175 request_init(request, XIPassiveGrabDevice); 176 177 request->grab_window = CLIENT_WINDOW_ID; 178 179 reply_handler = reply_XIPassiveGrabDevice; 180 client_request = init_client(request->length, request); 181 182 printf("Testing invalid device\n"); 183 request->deviceid = 12; 184 request_XIPassiveGrabDevice(&client_request, request, BadDevice, 185 request->deviceid); 186 187 printf("Testing invalid length\n"); 188 request->length -= 2; 189 request_XIPassiveGrabDevice(&client_request, request, BadLength, 190 client_request.errorValue); 191 /* re-init request since swapped length test leaves some values swapped */ 192 request_init(request, XIPassiveGrabDevice); 193 request->grab_window = CLIENT_WINDOW_ID; 194 request->deviceid = XIAllMasterDevices; 195 196 printf("Testing invalid grab types\n"); 197 for (i = XIGrabtypeTouchBegin + 1; i < 0xFF; i++) { 198 request->grab_type = i; 199 request_XIPassiveGrabDevice(&client_request, request, BadValue, 200 request->grab_type); 201 } 202 203 printf("Testing invalid grab type + detail combinations\n"); 204 request->grab_type = XIGrabtypeEnter; 205 request->detail = 1; 206 request_XIPassiveGrabDevice(&client_request, request, BadValue, 207 request->detail); 208 209 request->grab_type = XIGrabtypeFocusIn; 210 request_XIPassiveGrabDevice(&client_request, request, BadValue, 211 request->detail); 212 213 request->detail = 0; 214 215 printf("Testing invalid masks\n"); 216 mask = (unsigned char *) &request[1]; 217 218 request->mask_len = bytes_to_int32(XI2LASTEVENT + 1); 219 request->length += request->mask_len; 220 SetBit(mask, XI2LASTEVENT + 1); 221 request_XIPassiveGrabDevice(&client_request, request, BadValue, 222 XI2LASTEVENT + 1); 223 224 ClearBit(mask, XI2LASTEVENT + 1); 225 226 /* tested all special cases now, test a few valid cases */ 227 228 /* no modifiers */ 229 request->deviceid = XIAllDevices; 230 request->grab_type = XIGrabtypeButton; 231 request->detail = XIAnyButton; 232 request_XIPassiveGrabDevice(&client_request, request, Success, 0); 233 234 /* Set a few random masks to make sure we handle modifiers correctly */ 235 SetBit(mask, XI_ButtonPress); 236 SetBit(mask, XI_KeyPress); 237 SetBit(mask, XI_Enter); 238 239 /* some modifiers */ 240 request->num_modifiers = N_MODS; 241 request->length += N_MODS; 242 memcpy((uint32_t *) (request + 1) + request->mask_len, modifiers, 243 sizeof(modifiers)); 244 request_XIPassiveGrabDevice(&client_request, request, Success, 0); 245} 246 247int 248protocol_xipassivegrabdevice_test(void) 249{ 250 init_simple(); 251 252 test_XIPassiveGrabDevice(); 253 254 return 0; 255} 256