protocol-xigetselectedevents.c revision 35c4bbdf
1/** 2 * Copyright © 2009 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 XIGetSelectedEvents request. 30 * 31 * Tests include: 32 * BadWindow on wrong window. 33 * Zero-length masks if no masks are set. 34 * Valid masks for valid devices. 35 * Masks set on non-existent devices are not returned. 36 * 37 * Note that this test is not connected to the XISelectEvents request. 38 */ 39#include <stdint.h> 40#include <X11/X.h> 41#include <X11/Xproto.h> 42#include <X11/extensions/XI2proto.h> 43#include "inputstr.h" 44#include "windowstr.h" 45#include "extinit.h" /* for XInputExtensionInit */ 46#include "scrnintstr.h" 47#include "xiselectev.h" 48#include "exevents.h" 49 50#include "protocol-common.h" 51 52static void reply_XIGetSelectedEvents(ClientPtr client, int len, char *data, 53 void *userdata); 54static void reply_XIGetSelectedEvents_data(ClientPtr client, int len, 55 char *data, void *userdata); 56 57struct { 58 int num_masks_expected; 59 unsigned char mask[MAXDEVICES][XI2LASTEVENT]; /* intentionally bigger */ 60 int mask_len; 61} test_data; 62 63/* dixLookupWindow requires a lot of setup not necessary for this test. 64 * Simple wrapper that returns either one of the fake root window or the 65 * fake client window. If the requested ID is neither of those wanted, 66 * return whatever the real dixLookupWindow does. 67 */ 68int 69__wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access) 70{ 71 if (id == root.drawable.id) { 72 *win = &root; 73 return Success; 74 } 75 else if (id == window.drawable.id) { 76 *win = &window; 77 return Success; 78 } 79 80 return __real_dixLookupWindow(win, id, client, access); 81} 82 83/* AddResource is called from XISetSEventMask, we don't need this */ 84Bool 85__wrap_AddResource(XID id, RESTYPE type, void *value) 86{ 87 return TRUE; 88} 89 90static void 91reply_XIGetSelectedEvents(ClientPtr client, int len, char *data, void *userdata) 92{ 93 xXIGetSelectedEventsReply *rep = (xXIGetSelectedEventsReply *) data; 94 95 if (client->swapped) { 96 swapl(&rep->length); 97 swaps(&rep->sequenceNumber); 98 swaps(&rep->num_masks); 99 } 100 101 reply_check_defaults(rep, len, XIGetSelectedEvents); 102 103 assert(rep->num_masks == test_data.num_masks_expected); 104 105 reply_handler = reply_XIGetSelectedEvents_data; 106} 107 108static void 109reply_XIGetSelectedEvents_data(ClientPtr client, int len, char *data, 110 void *userdata) 111{ 112 int i; 113 xXIEventMask *mask; 114 unsigned char *bitmask; 115 116 mask = (xXIEventMask *) data; 117 for (i = 0; i < test_data.num_masks_expected; i++) { 118 if (client->swapped) { 119 swaps(&mask->deviceid); 120 swaps(&mask->mask_len); 121 } 122 123 assert(mask->deviceid < 6); 124 assert(mask->mask_len <= (((XI2LASTEVENT + 8) / 8) + 3) / 4); 125 126 bitmask = (unsigned char *) &mask[1]; 127 assert(memcmp(bitmask, 128 test_data.mask[mask->deviceid], mask->mask_len * 4) == 0); 129 130 mask = 131 (xXIEventMask *) ((char *) mask + mask->mask_len * 4 + 132 sizeof(xXIEventMask)); 133 } 134 135} 136 137static void 138request_XIGetSelectedEvents(xXIGetSelectedEventsReq * req, int error) 139{ 140 int rc; 141 ClientRec client; 142 143 client = init_client(req->length, req); 144 145 reply_handler = reply_XIGetSelectedEvents; 146 147 rc = ProcXIGetSelectedEvents(&client); 148 assert(rc == error); 149 150 reply_handler = reply_XIGetSelectedEvents; 151 client.swapped = TRUE; 152 swapl(&req->win); 153 swaps(&req->length); 154 rc = SProcXIGetSelectedEvents(&client); 155 assert(rc == error); 156} 157 158static void 159test_XIGetSelectedEvents(void) 160{ 161 int i, j; 162 xXIGetSelectedEventsReq request; 163 ClientRec client = init_client(0, NULL); 164 unsigned char *mask; 165 DeviceIntRec dev; 166 167 request_init(&request, XIGetSelectedEvents); 168 169 printf("Testing for BadWindow on invalid window.\n"); 170 request.win = None; 171 request_XIGetSelectedEvents(&request, BadWindow); 172 173 printf("Testing for zero-length (unset) masks.\n"); 174 /* No masks set yet */ 175 test_data.num_masks_expected = 0; 176 request.win = ROOT_WINDOW_ID; 177 request_XIGetSelectedEvents(&request, Success); 178 179 request.win = CLIENT_WINDOW_ID; 180 request_XIGetSelectedEvents(&request, Success); 181 182 memset(test_data.mask, 0, sizeof(test_data.mask)); 183 184 printf("Testing for valid masks\n"); 185 memset(&dev, 0, sizeof(dev)); /* dev->id is enough for XISetEventMask */ 186 request.win = ROOT_WINDOW_ID; 187 188 /* devices 6 - MAXDEVICES don't exist, they mustn't be included in the 189 * reply even if a mask is set */ 190 for (j = 0; j < MAXDEVICES; j++) { 191 test_data.num_masks_expected = min(j + 1, devices.num_devices + 2); 192 dev.id = j; 193 mask = test_data.mask[j]; 194 /* bits one-by-one */ 195 for (i = 0; i < XI2LASTEVENT; i++) { 196 SetBit(mask, i); 197 XISetEventMask(&dev, &root, &client, (i + 8) / 8, mask); 198 request_XIGetSelectedEvents(&request, Success); 199 ClearBit(mask, i); 200 } 201 202 /* all valid mask bits */ 203 for (i = 0; i < XI2LASTEVENT; i++) { 204 SetBit(mask, i); 205 XISetEventMask(&dev, &root, &client, (i + 8) / 8, mask); 206 request_XIGetSelectedEvents(&request, Success); 207 } 208 } 209 210 printf("Testing removing all masks\n"); 211 /* Unset all masks one-by-one */ 212 for (j = MAXDEVICES - 1; j >= 0; j--) { 213 if (j < devices.num_devices + 2) 214 test_data.num_masks_expected--; 215 216 mask = test_data.mask[j]; 217 memset(mask, 0, XI2LASTEVENT); 218 219 dev.id = j; 220 XISetEventMask(&dev, &root, &client, 0, NULL); 221 222 request_XIGetSelectedEvents(&request, Success); 223 } 224} 225 226int 227main(int argc, char **argv) 228{ 229 init_simple(); 230 231 test_XIGetSelectedEvents(); 232 233 return 0; 234} 235