1706f2543Smrg/** 2706f2543Smrg * Copyright © 2009 Red Hat, Inc. 3706f2543Smrg * 4706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5706f2543Smrg * copy of this software and associated documentation files (the "Software"), 6706f2543Smrg * to deal in the Software without restriction, including without limitation 7706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 9706f2543Smrg * Software is furnished to do so, subject to the following conditions: 10706f2543Smrg * 11706f2543Smrg * The above copyright notice and this permission notice (including the next 12706f2543Smrg * paragraph) shall be included in all copies or substantial portions of the 13706f2543Smrg * Software. 14706f2543Smrg * 15706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18706f2543Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19706f2543Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20706f2543Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21706f2543Smrg * DEALINGS IN THE SOFTWARE. 22706f2543Smrg */ 23706f2543Smrg 24706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 25706f2543Smrg#include <dix-config.h> 26706f2543Smrg#endif 27706f2543Smrg 28706f2543Smrg/* 29706f2543Smrg * Protocol testing for XIWarpPointer request. 30706f2543Smrg */ 31706f2543Smrg#include <stdint.h> 32706f2543Smrg#include <X11/X.h> 33706f2543Smrg#include <X11/Xproto.h> 34706f2543Smrg#include <X11/extensions/XI2proto.h> 35706f2543Smrg#include "inputstr.h" 36706f2543Smrg#include "windowstr.h" 37706f2543Smrg#include "scrnintstr.h" 38706f2543Smrg#include "xiwarppointer.h" 39706f2543Smrg#include "exevents.h" 40706f2543Smrg 41706f2543Smrg#include "protocol-common.h" 42706f2543Smrg#include <glib.h> 43706f2543Smrg 44706f2543Smrgstatic int expected_x = SPRITE_X; 45706f2543Smrgstatic int expected_y = SPRITE_Y; 46706f2543Smrg 47706f2543Smrg/* dixLookupWindow requires a lot of setup not necessary for this test. 48706f2543Smrg * Simple wrapper that returns either one of the fake root window or the 49706f2543Smrg * fake client window. If the requested ID is neither of those wanted, 50706f2543Smrg * return whatever the real dixLookupWindow does. 51706f2543Smrg */ 52706f2543Smrgint __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access) 53706f2543Smrg{ 54706f2543Smrg if (id == root.drawable.id) 55706f2543Smrg { 56706f2543Smrg *win = &root; 57706f2543Smrg return Success; 58706f2543Smrg } else if (id == window.drawable.id) 59706f2543Smrg { 60706f2543Smrg *win = &window; 61706f2543Smrg return Success; 62706f2543Smrg } 63706f2543Smrg 64706f2543Smrg return __real_dixLookupWindow(win, id, client, access); 65706f2543Smrg} 66706f2543Smrg 67706f2543Smrg/** 68706f2543Smrg * This function overrides the one in the screen rec. 69706f2543Smrg */ 70706f2543Smrgstatic Bool ScreenSetCursorPosition(DeviceIntPtr dev, ScreenPtr screen, 71706f2543Smrg int x, int y, Bool generateEvent) 72706f2543Smrg{ 73706f2543Smrg g_assert(x == expected_x); 74706f2543Smrg g_assert(y == expected_y); 75706f2543Smrg return TRUE; 76706f2543Smrg} 77706f2543Smrg 78706f2543Smrg 79706f2543Smrgstatic void request_XIWarpPointer(ClientPtr client, xXIWarpPointerReq* req, 80706f2543Smrg int error) 81706f2543Smrg{ 82706f2543Smrg char n; 83706f2543Smrg int rc; 84706f2543Smrg 85706f2543Smrg rc = ProcXIWarpPointer(client); 86706f2543Smrg g_assert(rc == error); 87706f2543Smrg 88706f2543Smrg if (rc == BadDevice) 89706f2543Smrg g_assert(client->errorValue == req->deviceid); 90706f2543Smrg else if (rc == BadWindow) 91706f2543Smrg g_assert(client->errorValue == req->dst_win || 92706f2543Smrg client->errorValue == req->src_win); 93706f2543Smrg 94706f2543Smrg 95706f2543Smrg client->swapped = TRUE; 96706f2543Smrg 97706f2543Smrg swapl(&req->src_win, n); 98706f2543Smrg swapl(&req->dst_win, n); 99706f2543Smrg swapl(&req->src_x, n); 100706f2543Smrg swapl(&req->src_y, n); 101706f2543Smrg swapl(&req->dst_x, n); 102706f2543Smrg swapl(&req->dst_y, n); 103706f2543Smrg swaps(&req->src_width, n); 104706f2543Smrg swaps(&req->src_height, n); 105706f2543Smrg swaps(&req->deviceid, n); 106706f2543Smrg 107706f2543Smrg rc = SProcXIWarpPointer(client); 108706f2543Smrg g_assert(rc == error); 109706f2543Smrg 110706f2543Smrg if (rc == BadDevice) 111706f2543Smrg g_assert(client->errorValue == req->deviceid); 112706f2543Smrg else if (rc == BadWindow) 113706f2543Smrg g_assert(client->errorValue == req->dst_win || 114706f2543Smrg client->errorValue == req->src_win); 115706f2543Smrg 116706f2543Smrg client->swapped = FALSE; 117706f2543Smrg} 118706f2543Smrg 119706f2543Smrgstatic void test_XIWarpPointer(void) 120706f2543Smrg{ 121706f2543Smrg int i; 122706f2543Smrg ClientRec client_request; 123706f2543Smrg xXIWarpPointerReq request; 124706f2543Smrg 125706f2543Smrg memset(&request, 0, sizeof(request)); 126706f2543Smrg 127706f2543Smrg request_init(&request, XIWarpPointer); 128706f2543Smrg 129706f2543Smrg client_request = init_client(request.length, &request); 130706f2543Smrg 131706f2543Smrg request.deviceid = XIAllDevices; 132706f2543Smrg request_XIWarpPointer(&client_request, &request, BadDevice); 133706f2543Smrg 134706f2543Smrg request.deviceid = XIAllMasterDevices; 135706f2543Smrg request_XIWarpPointer(&client_request, &request, BadDevice); 136706f2543Smrg 137706f2543Smrg request.src_win = root.drawable.id; 138706f2543Smrg request.dst_win = root.drawable.id; 139706f2543Smrg request.deviceid = devices.vcp->id; 140706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 141706f2543Smrg request.deviceid = devices.vck->id; 142706f2543Smrg request_XIWarpPointer(&client_request, &request, BadDevice); 143706f2543Smrg request.deviceid = devices.mouse->id; 144706f2543Smrg request_XIWarpPointer(&client_request, &request, BadDevice); 145706f2543Smrg request.deviceid = devices.kbd->id; 146706f2543Smrg request_XIWarpPointer(&client_request, &request, BadDevice); 147706f2543Smrg 148706f2543Smrg devices.mouse->u.master = NULL; /* Float, kind-of */ 149706f2543Smrg request.deviceid = devices.mouse->id; 150706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 151706f2543Smrg 152706f2543Smrg for (i = devices.kbd->id + 1; i <= 0xFFFF; i++) 153706f2543Smrg { 154706f2543Smrg request.deviceid = i; 155706f2543Smrg request_XIWarpPointer(&client_request, &request, BadDevice); 156706f2543Smrg } 157706f2543Smrg 158706f2543Smrg request.src_win = window.drawable.id; 159706f2543Smrg request.deviceid = devices.vcp->id; 160706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 161706f2543Smrg 162706f2543Smrg request.deviceid = devices.mouse->id; 163706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 164706f2543Smrg 165706f2543Smrg request.src_win = root.drawable.id; 166706f2543Smrg request.dst_win = 0xFFFF; /* invalid window */ 167706f2543Smrg request_XIWarpPointer(&client_request, &request, BadWindow); 168706f2543Smrg 169706f2543Smrg request.src_win = 0xFFFF; /* invalid window */ 170706f2543Smrg request.dst_win = root.drawable.id; 171706f2543Smrg request_XIWarpPointer(&client_request, &request, BadWindow); 172706f2543Smrg 173706f2543Smrg request.src_win = None; 174706f2543Smrg request.dst_win = None; 175706f2543Smrg 176706f2543Smrg request.dst_y = 0; 177706f2543Smrg expected_y = SPRITE_Y; 178706f2543Smrg 179706f2543Smrg request.dst_x = 1 << 16; 180706f2543Smrg expected_x = SPRITE_X + 1; 181706f2543Smrg request.deviceid = devices.vcp->id; 182706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 183706f2543Smrg 184706f2543Smrg request.dst_x = -1 << 16; 185706f2543Smrg expected_x = SPRITE_X - 1; 186706f2543Smrg request.deviceid = devices.vcp->id; 187706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 188706f2543Smrg 189706f2543Smrg request.dst_x = 0; 190706f2543Smrg expected_x = SPRITE_X; 191706f2543Smrg 192706f2543Smrg request.dst_y = 1 << 16; 193706f2543Smrg expected_y = SPRITE_Y + 1; 194706f2543Smrg request.deviceid = devices.vcp->id; 195706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 196706f2543Smrg 197706f2543Smrg request.dst_y = -1 << 16; 198706f2543Smrg expected_y = SPRITE_Y - 1; 199706f2543Smrg request.deviceid = devices.vcp->id; 200706f2543Smrg request_XIWarpPointer(&client_request, &request, Success); 201706f2543Smrg 202706f2543Smrg /* FIXME: src_x/y checks */ 203706f2543Smrg 204706f2543Smrg client_request.req_len -= 2; /* invalid length */ 205706f2543Smrg request_XIWarpPointer(&client_request, &request, BadLength); 206706f2543Smrg} 207706f2543Smrg 208706f2543Smrgint main(int argc, char** argv) 209706f2543Smrg{ 210706f2543Smrg g_test_init(&argc, &argv,NULL); 211706f2543Smrg g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id="); 212706f2543Smrg 213706f2543Smrg init_simple(); 214706f2543Smrg screen.SetCursorPosition = ScreenSetCursorPosition; 215706f2543Smrg 216706f2543Smrg g_test_add_func("/xi2/protocol/XIWarpPointer", test_XIWarpPointer); 217706f2543Smrg 218706f2543Smrg return g_test_run(); 219706f2543Smrg} 220