xref: /OK3568_Linux_fs/external/xserver/test/xi2/protocol-xipassivegrabdevice.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /**
2  * Copyright © 2011 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 XIPassiveGrab request.
30  */
31 #include <stdint.h>
32 #include <X11/X.h>
33 #include <X11/Xproto.h>
34 #include <X11/extensions/XI2proto.h>
35 #include "inputstr.h"
36 #include "windowstr.h"
37 #include "scrnintstr.h"
38 #include "xipassivegrab.h"
39 #include "exevents.h"
40 #include "exglobals.h"
41 
42 #include "protocol-common.h"
43 
44 extern ClientRec client_window;
45 static ClientRec client_request;
46 
47 #define N_MODS 7
48 static uint32_t modifiers[N_MODS] = { 1, 2, 3, 4, 5, 6, 7 };
49 
50 static struct test_data {
51     int num_modifiers;
52 } testdata;
53 
54 int __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev,
55                       DeviceIntPtr modifier_device, int button,
56                       GrabParameters *param, enum InputLevel grabtype,
57                       GrabMask *mask);
58 int __real_GrabButton(ClientPtr client, DeviceIntPtr dev,
59                       DeviceIntPtr modifier_device, int button,
60                       GrabParameters *param, enum InputLevel grabtype,
61                       GrabMask *mask);
62 static void reply_XIPassiveGrabDevice_data(ClientPtr client, int len,
63                                            char *data, void *closure);
64 
65 int
__wrap_GrabButton(ClientPtr client,DeviceIntPtr dev,DeviceIntPtr modifier_device,int button,GrabParameters * param,enum InputLevel grabtype,GrabMask * mask)66 __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev,
67                   DeviceIntPtr modifier_device, int button,
68                   GrabParameters *param, enum InputLevel grabtype,
69                   GrabMask *mask)
70 {
71     if (!enable_GrabButton_wrap)
72         __real_GrabButton(client, dev, modifier_device, button, param, grabtype, mask);
73 
74     /* Fail every odd modifier */
75     if (param->modifiers % 2)
76         return BadAccess;
77 
78     return Success;
79 }
80 
81 static void
reply_XIPassiveGrabDevice(ClientPtr client,int len,char * data,void * closure)82 reply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *closure)
83 {
84     xXIPassiveGrabDeviceReply *rep = (xXIPassiveGrabDeviceReply *) data;
85 
86     if (client->swapped) {
87         swaps(&rep->sequenceNumber);
88         swapl(&rep->length);
89         swaps(&rep->num_modifiers);
90 
91         testdata.num_modifiers = rep->num_modifiers;
92     }
93 
94     reply_check_defaults(rep, len, XIPassiveGrabDevice);
95 
96     /* ProcXIPassiveGrabDevice sends the data in two batches, let the second
97      * handler handle the modifier data */
98     if (rep->num_modifiers > 0)
99         reply_handler = reply_XIPassiveGrabDevice_data;
100 }
101 
102 static void
reply_XIPassiveGrabDevice_data(ClientPtr client,int len,char * data,void * closure)103 reply_XIPassiveGrabDevice_data(ClientPtr client, int len, char *data,
104                                void *closure)
105 {
106     int i;
107 
108     xXIGrabModifierInfo *mods = (xXIGrabModifierInfo *) data;
109 
110     for (i = 0; i < testdata.num_modifiers; i++, mods++) {
111         if (client->swapped)
112             swapl(&mods->modifiers);
113 
114         /* 1 - 7 is the range we use for the global modifiers array
115          * above */
116         assert(mods->modifiers > 0);
117         assert(mods->modifiers <= 7);
118         assert(mods->modifiers % 2 == 1);       /* because we fail odd ones */
119         assert(mods->status != Success);
120         assert(mods->pad0 == 0);
121         assert(mods->pad1 == 0);
122     }
123 
124     reply_handler = reply_XIPassiveGrabDevice;
125 }
126 
127 static void
request_XIPassiveGrabDevice(ClientPtr client,xXIPassiveGrabDeviceReq * req,int error,int errval)128 request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req,
129                             int error, int errval)
130 {
131     int rc;
132     int local_modifiers;
133     int mask_len;
134 
135     client_request.req_len = req->length;
136     rc = ProcXIPassiveGrabDevice(&client_request);
137     assert(rc == error);
138 
139     if (rc != Success)
140         assert(client_request.errorValue == errval);
141 
142     client_request.swapped = TRUE;
143     swaps(&req->length);
144     swapl(&req->time);
145     swapl(&req->grab_window);
146     swapl(&req->cursor);
147     swapl(&req->detail);
148     swaps(&req->deviceid);
149     local_modifiers = req->num_modifiers;
150     swaps(&req->num_modifiers);
151     mask_len = req->mask_len;
152     swaps(&req->mask_len);
153 
154     while (local_modifiers--) {
155         CARD32 *mod = (CARD32 *) (req + 1) + mask_len + local_modifiers;
156 
157         swapl(mod);
158     }
159 
160     rc = SProcXIPassiveGrabDevice(&client_request);
161     assert(rc == error);
162 
163     if (rc != Success)
164         assert(client_request.errorValue == errval);
165 }
166 
167 static unsigned char *data[4096];       /* the request buffer */
168 static void
test_XIPassiveGrabDevice(void)169 test_XIPassiveGrabDevice(void)
170 {
171     int i;
172     xXIPassiveGrabDeviceReq *request = (xXIPassiveGrabDeviceReq *) data;
173     unsigned char *mask;
174 
175     request_init(request, XIPassiveGrabDevice);
176 
177     request->grab_window = CLIENT_WINDOW_ID;
178 
179     reply_handler = reply_XIPassiveGrabDevice;
180     client_request = init_client(request->length, request);
181 
182     printf("Testing invalid device\n");
183     request->deviceid = 12;
184     request_XIPassiveGrabDevice(&client_request, request, BadDevice,
185                                 request->deviceid);
186 
187     printf("Testing invalid length\n");
188     request->length -= 2;
189     request_XIPassiveGrabDevice(&client_request, request, BadLength,
190                                 client_request.errorValue);
191     /* re-init request since swapped length test leaves some values swapped */
192     request_init(request, XIPassiveGrabDevice);
193     request->grab_window = CLIENT_WINDOW_ID;
194     request->deviceid = XIAllMasterDevices;
195 
196     printf("Testing invalid grab types\n");
197     for (i = XIGrabtypeTouchBegin + 1; i < 0xFF; i++) {
198         request->grab_type = i;
199         request_XIPassiveGrabDevice(&client_request, request, BadValue,
200                                     request->grab_type);
201     }
202 
203     printf("Testing invalid grab type + detail combinations\n");
204     request->grab_type = XIGrabtypeEnter;
205     request->detail = 1;
206     request_XIPassiveGrabDevice(&client_request, request, BadValue,
207                                 request->detail);
208 
209     request->grab_type = XIGrabtypeFocusIn;
210     request_XIPassiveGrabDevice(&client_request, request, BadValue,
211                                 request->detail);
212 
213     request->detail = 0;
214 
215     printf("Testing invalid masks\n");
216     mask = (unsigned char *) &request[1];
217 
218     request->mask_len = bytes_to_int32(XI2LASTEVENT + 1);
219     request->length += request->mask_len;
220     SetBit(mask, XI2LASTEVENT + 1);
221     request_XIPassiveGrabDevice(&client_request, request, BadValue,
222                                 XI2LASTEVENT + 1);
223 
224     ClearBit(mask, XI2LASTEVENT + 1);
225 
226     /* tested all special cases now, test a few valid cases */
227 
228     /* no modifiers */
229     request->deviceid = XIAllDevices;
230     request->grab_type = XIGrabtypeButton;
231     request->detail = XIAnyButton;
232     request_XIPassiveGrabDevice(&client_request, request, Success, 0);
233 
234     /* Set a few random masks to make sure we handle modifiers correctly */
235     SetBit(mask, XI_ButtonPress);
236     SetBit(mask, XI_KeyPress);
237     SetBit(mask, XI_Enter);
238 
239     /* some modifiers */
240     request->num_modifiers = N_MODS;
241     request->length += N_MODS;
242     memcpy((uint32_t *) (request + 1) + request->mask_len, modifiers,
243            sizeof(modifiers));
244     request_XIPassiveGrabDevice(&client_request, request, Success, 0);
245 }
246 
247 int
protocol_xipassivegrabdevice_test(void)248 protocol_xipassivegrabdevice_test(void)
249 {
250     init_simple();
251 
252     test_XIPassiveGrabDevice();
253 
254     return 0;
255 }
256