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