2 * Copyright © 2009 Red Hat, Inc.
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:
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
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.
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
30 #include <X11/Xproto.h>
31 #include <X11/extensions/XI2proto.h>
32 #include <X11/Xatom.h>
35 #include "exglobals.h"
36 #include "scrnintstr.h"
39 #include "xiquerydevice.h"
41 #include "protocol-common.h"
43 * Protocol testing for XIQueryDevice request and reply.
46 * Wrap WriteToClient to intercept server's reply. ProcXIQueryDevice returns
47 * data in two batches, once for the request, once for the trailing data
48 * with the device information.
49 * Repeatedly test with varying deviceids and check against data in reply.
54 int num_devices_in_reply
;
57 static void reply_XIQueryDevice_data(ClientPtr client
, int len
, char *data
,
59 static void reply_XIQueryDevice(ClientPtr client
, int len
, char *data
,
62 /* reply handling for the first bytes that constitute the reply */
64 reply_XIQueryDevice(ClientPtr client
, int len
, char *data
, void *userdata
)
66 xXIQueryDeviceReply
*rep
= (xXIQueryDeviceReply
*) data
;
67 struct test_data
*querydata
= (struct test_data
*) userdata
;
69 if (client
->swapped
) {
71 swaps(&rep
->sequenceNumber
);
72 swaps(&rep
->num_devices
);
75 reply_check_defaults(rep
, len
, XIQueryDevice
);
77 if (querydata
->which_device
== XIAllDevices
)
78 assert(rep
->num_devices
== devices
.num_devices
);
79 else if (querydata
->which_device
== XIAllMasterDevices
)
80 assert(rep
->num_devices
== devices
.num_master_devices
);
82 assert(rep
->num_devices
== 1);
84 querydata
->num_devices_in_reply
= rep
->num_devices
;
85 reply_handler
= reply_XIQueryDevice_data
;
88 /* reply handling for the trailing bytes that constitute the device info */
90 reply_XIQueryDevice_data(ClientPtr client
, int len
, char *data
, void *closure
)
93 struct test_data
*querydata
= (struct test_data
*) closure
;
96 xXIDeviceInfo
*info
= (xXIDeviceInfo
*) data
;
99 for (i
= 0; i
< querydata
->num_devices_in_reply
; i
++) {
100 if (client
->swapped
) {
101 swaps(&info
->deviceid
);
102 swaps(&info
->attachment
);
104 swaps(&info
->num_classes
);
105 swaps(&info
->name_len
);
108 if (querydata
->which_device
> XIAllMasterDevices
)
109 assert(info
->deviceid
== querydata
->which_device
);
111 assert(info
->deviceid
>= 2); /* 0 and 1 is reserved */
113 switch (info
->deviceid
) {
116 assert(info
->use
== XIMasterPointer
);
117 assert(info
->attachment
== devices
.vck
->id
);
118 assert(info
->num_classes
== 3); /* 2 axes + button */
122 assert(info
->use
== XIMasterKeyboard
);
123 assert(info
->attachment
== devices
.vcp
->id
);
124 assert(info
->num_classes
== 1);
128 assert(info
->use
== XISlavePointer
);
129 assert(info
->attachment
== devices
.vcp
->id
);
130 assert(info
->num_classes
== 7); /* 4 axes + button + 2 scroll */
132 case 5: /* keyboard */
134 assert(info
->use
== XISlaveKeyboard
);
135 assert(info
->attachment
== devices
.vck
->id
);
136 assert(info
->num_classes
== 1);
140 /* We shouldn't get here */
144 assert(info
->enabled
== dev
->enabled
);
145 assert(info
->name_len
== strlen(dev
->name
));
146 assert(strncmp((char *) &info
[1], dev
->name
, info
->name_len
) == 0);
149 (xXIAnyInfo
*) ((char *) &info
[1] + ((info
->name_len
+ 3) / 4) * 4);
150 for (j
= 0; j
< info
->num_classes
; j
++) {
151 if (client
->swapped
) {
154 swaps(&any
->sourceid
);
157 switch (info
->deviceid
) {
158 case 3: /* VCK and kbd have the same properties */
162 xXIKeyInfo
*ki
= (xXIKeyInfo
*) any
;
163 XkbDescPtr xkb
= devices
.vck
->key
->xkbInfo
->desc
;
167 swaps(&ki
->num_keycodes
);
169 assert(any
->type
== XIKeyClass
);
170 assert(ki
->num_keycodes
==
171 (xkb
->max_key_code
- xkb
->min_key_code
+ 1));
172 assert(any
->length
== (2 + ki
->num_keycodes
));
174 kc
= (uint32_t *) &ki
[1];
175 for (k
= 0; k
< ki
->num_keycodes
; k
++, kc
++) {
179 assert(*kc
>= xkb
->min_key_code
);
180 assert(*kc
<= xkb
->max_key_code
);
186 assert(any
->type
== XIButtonClass
||
187 any
->type
== XIValuatorClass
||
188 any
->type
== XIScrollClass
);
190 if (any
->type
== XIScrollClass
) {
191 xXIScrollInfo
*si
= (xXIScrollInfo
*) any
;
193 if (client
->swapped
) {
195 swaps(&si
->scroll_type
);
196 swapl(&si
->increment
.integral
);
197 swapl(&si
->increment
.frac
);
199 assert(si
->length
== 6);
200 assert(si
->number
== 2 || si
->number
== 3);
201 if (si
->number
== 2) {
202 assert(si
->scroll_type
== XIScrollTypeVertical
);
205 if (si
->number
== 3) {
206 assert(si
->scroll_type
== XIScrollTypeHorizontal
);
207 assert(si
->flags
& XIScrollFlagPreferred
);
208 assert(!(si
->flags
& ~XIScrollFlagPreferred
));
211 assert(si
->increment
.integral
== si
->number
);
212 /* protocol-common.c sets up increments of 2.4 and 3.5 */
213 assert(si
->increment
.frac
> 0.3 * (1ULL << 32));
214 assert(si
->increment
.frac
< 0.6 * (1ULL << 32));
219 case 2: /* VCP and mouse have the same properties except for scroll */
221 if (info
->deviceid
== 2) /* VCP */
222 assert(any
->type
== XIButtonClass
||
223 any
->type
== XIValuatorClass
);
225 if (any
->type
== XIButtonClass
) {
227 xXIButtonInfo
*bi
= (xXIButtonInfo
*) any
;
230 swaps(&bi
->num_buttons
);
232 assert(bi
->num_buttons
== devices
.vcp
->button
->numButtons
);
234 l
= 2 + bi
->num_buttons
+
235 bytes_to_int32(bits_to_bytes(bi
->num_buttons
));
236 assert(bi
->length
== l
);
238 else if (any
->type
== XIValuatorClass
) {
239 xXIValuatorInfo
*vi
= (xXIValuatorInfo
*) any
;
241 if (client
->swapped
) {
244 swapl(&vi
->min
.integral
);
245 swapl(&vi
->min
.frac
);
246 swapl(&vi
->max
.integral
);
247 swapl(&vi
->max
.frac
);
248 swapl(&vi
->resolution
);
251 assert(vi
->length
== 11);
252 assert(vi
->number
>= 0 && vi
->number
< 4);
253 if (info
->deviceid
== 2) /* VCP */
254 assert(vi
->number
< 2);
256 assert(vi
->mode
== XIModeRelative
);
257 /* device was set up as relative, so standard
259 assert(vi
->min
.integral
== -1);
260 assert(vi
->min
.frac
== 0);
261 assert(vi
->max
.integral
== -1);
262 assert(vi
->max
.frac
== 0);
263 assert(vi
->resolution
== 0);
268 any
= (xXIAnyInfo
*) (((char *) any
) + any
->length
* 4);
271 info
= (xXIDeviceInfo
*) any
;
276 request_XIQueryDevice(struct test_data
*querydata
, int deviceid
, int error
)
280 xXIQueryDeviceReq request
;
282 request_init(&request
, XIQueryDevice
);
283 client
= init_client(request
.length
, &request
);
284 reply_handler
= reply_XIQueryDevice
;
286 querydata
->which_device
= deviceid
;
288 request
.deviceid
= deviceid
;
289 rc
= ProcXIQueryDevice(&client
);
293 assert(client
.errorValue
== deviceid
);
295 reply_handler
= reply_XIQueryDevice
;
297 client
.swapped
= TRUE
;
298 swaps(&request
.length
);
299 swaps(&request
.deviceid
);
300 rc
= SProcXIQueryDevice(&client
);
304 assert(client
.errorValue
== deviceid
);
308 test_XIQueryDevice(void)
311 xXIQueryDeviceReq request
;
312 struct test_data data
;
314 reply_handler
= reply_XIQueryDevice
;
316 request_init(&request
, XIQueryDevice
);
318 printf("Testing XIAllDevices.\n");
319 request_XIQueryDevice(&data
, XIAllDevices
, Success
);
320 printf("Testing XIAllMasterDevices.\n");
321 request_XIQueryDevice(&data
, XIAllMasterDevices
, Success
);
323 printf("Testing existing device ids.\n");
324 for (i
= 2; i
< 6; i
++)
325 request_XIQueryDevice(&data
, i
, Success
);
327 printf("Testing non-existing device ids.\n");
328 for (i
= 6; i
<= 0xFFFF; i
++)
329 request_XIQueryDevice(&data
, i
, BadDevice
);
331 reply_handler
= NULL
;
336 main(int argc
, char **argv
)
340 test_XIQueryDevice();