protocol-xigetselectedevents.c revision 706f2543
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#include <glib.h> 52 53static void reply_XIGetSelectedEvents(ClientPtr client, int len, char *data, void *userdata); 54static void reply_XIGetSelectedEvents_data(ClientPtr client, int len, char *data, void *userdata); 55 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 __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access) 69{ 70 if (id == root.drawable.id) 71 { 72 *win = &root; 73 return Success; 74 } else if (id == window.drawable.id) 75 { 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 __wrap_AddResource(XID id, RESTYPE type, pointer value) 85{ 86 return TRUE; 87} 88 89static void reply_XIGetSelectedEvents(ClientPtr client, int len, char *data, void *userdata) 90{ 91 xXIGetSelectedEventsReply *rep = (xXIGetSelectedEventsReply*)data; 92 93 if (client->swapped) 94 { 95 char n; 96 swapl(&rep->length, n); 97 swaps(&rep->sequenceNumber, n); 98 swaps(&rep->num_masks, n); 99 } 100 101 reply_check_defaults(rep, len, XIGetSelectedEvents); 102 103 g_assert(rep->num_masks == test_data.num_masks_expected); 104 105 reply_handler = reply_XIGetSelectedEvents_data; 106} 107 108static void reply_XIGetSelectedEvents_data(ClientPtr client, int len, char *data, void *userdata) 109{ 110 int i; 111 xXIEventMask *mask; 112 unsigned char *bitmask; 113 114 mask = (xXIEventMask*)data; 115 for (i = 0; i < test_data.num_masks_expected; i++) 116 { 117 if (client->swapped) 118 { 119 char n; 120 swaps(&mask->deviceid, n); 121 swaps(&mask->mask_len, n); 122 } 123 124 g_assert(mask->deviceid < 6); 125 g_assert(mask->mask_len <= (((XI2LASTEVENT + 8)/8) + 3)/4) ; 126 127 bitmask = (unsigned char*)&mask[1]; 128 g_assert(memcmp(bitmask, 129 test_data.mask[mask->deviceid], 130 mask->mask_len * 4) == 0); 131 132 mask = (xXIEventMask*)((char*)mask + mask->mask_len * 4 + sizeof(xXIEventMask)); 133 } 134 135 136} 137 138static void request_XIGetSelectedEvents(xXIGetSelectedEventsReq* req, int error) 139{ 140 char n; 141 int rc; 142 ClientRec client; 143 client = init_client(req->length, req); 144 145 reply_handler = reply_XIGetSelectedEvents; 146 147 rc = ProcXIGetSelectedEvents(&client); 148 g_assert(rc == error); 149 150 reply_handler = reply_XIGetSelectedEvents; 151 client.swapped = TRUE; 152 swapl(&req->win, n); 153 swaps(&req->length, n); 154 rc = SProcXIGetSelectedEvents(&client); 155 g_assert(rc == error); 156} 157 158static void test_XIGetSelectedEvents(void) 159{ 160 int i, j; 161 xXIGetSelectedEventsReq request; 162 ClientRec client = init_client(0, NULL); 163 unsigned char *mask; 164 DeviceIntRec dev; 165 166 request_init(&request, XIGetSelectedEvents); 167 168 g_test_message("Testing for BadWindow on invalid window."); 169 request.win = None; 170 request_XIGetSelectedEvents(&request, BadWindow); 171 172 g_test_message("Testing for zero-length (unset) masks."); 173 /* No masks set yet */ 174 test_data.num_masks_expected = 0; 175 request.win = ROOT_WINDOW_ID; 176 request_XIGetSelectedEvents(&request, Success); 177 178 request.win = CLIENT_WINDOW_ID; 179 request_XIGetSelectedEvents(&request, Success); 180 181 memset(test_data.mask, 0, 182 sizeof(test_data.mask)); 183 184 g_test_message("Testing for valid masks"); 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 { 192 test_data.num_masks_expected = min(j + 1, devices.num_devices + 2); 193 dev.id = j; 194 mask = test_data.mask[j]; 195 /* bits one-by-one */ 196 for (i = 0; i < XI2LASTEVENT; i++) 197 { 198 SetBit(mask, i); 199 XISetEventMask(&dev, &root, &client, (i + 8)/8, mask); 200 request_XIGetSelectedEvents(&request, Success); 201 ClearBit(mask, i); 202 } 203 204 /* all valid mask bits */ 205 for (i = 0; i < XI2LASTEVENT; i++) 206 { 207 SetBit(mask, i); 208 XISetEventMask(&dev, &root, &client, (i + 8)/8, mask); 209 request_XIGetSelectedEvents(&request, Success); 210 } 211 } 212 213 g_test_message("Testing removing all masks"); 214 /* Unset all masks one-by-one */ 215 for (j = MAXDEVICES - 1; j >= 0; j--) 216 { 217 if (j < devices.num_devices + 2) 218 test_data.num_masks_expected--; 219 220 mask = test_data.mask[j]; 221 memset(mask, 0, XI2LASTEVENT); 222 223 dev.id = j; 224 XISetEventMask(&dev, &root, &client, 0, NULL); 225 226 request_XIGetSelectedEvents(&request, Success); 227 } 228} 229 230int main(int argc, char** argv) 231{ 232 g_test_init(&argc, &argv,NULL); 233 g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id="); 234 235 init_simple(); 236 237 g_test_add_func("/xi2/protocol/XIGetSelectedEvents", test_XIGetSelectedEvents); 238 239 return g_test_run(); 240} 241 242