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