input.c revision 6747b715
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#include <stdint.h>
29#include <X11/X.h>
30#include "misc.h"
31#include "resource.h"
32#include <X11/Xproto.h>
33#include <X11/extensions/XI2proto.h>
34#include <X11/Xatom.h>
35#include "windowstr.h"
36#include "inputstr.h"
37#include "eventconvert.h"
38#include "exevents.h"
39#include "dixgrabs.h"
40#include "eventstr.h"
41#include <glib.h>
42
43/**
44 * Init a device with axes.
45 * Verify values set on the device.
46 *
47 * Result: All axes set to default values (usually 0).
48 */
49static void dix_init_valuators(void)
50{
51    DeviceIntRec dev;
52    ValuatorClassPtr val;
53    const int num_axes = 2;
54    int i;
55    Atom atoms[MAX_VALUATORS] = { 0 };
56
57
58    memset(&dev, 0, sizeof(DeviceIntRec));
59    dev.type = MASTER_POINTER; /* claim it's a master to stop ptracccel */
60
61    g_assert(InitValuatorClassDeviceStruct(NULL, 0, atoms, 0, 0) == FALSE);
62    g_assert(InitValuatorClassDeviceStruct(&dev, num_axes, atoms, 0, Absolute));
63
64    val = dev.valuator;
65    g_assert(val);
66    g_assert(val->numAxes == num_axes);
67    g_assert(val->numMotionEvents == 0);
68    g_assert(val->mode == Absolute);
69    g_assert(val->axisVal);
70
71    for (i = 0; i < num_axes; i++)
72    {
73        g_assert(val->axisVal[i] == 0);
74        g_assert(val->axes->min_value == NO_AXIS_LIMITS);
75        g_assert(val->axes->max_value == NO_AXIS_LIMITS);
76    }
77
78    g_assert(dev.last.numValuators == num_axes);
79}
80
81/* just check the known success cases, and that error cases set the client's
82 * error value correctly. */
83static void dix_check_grab_values(void)
84{
85    ClientRec client;
86    GrabParameters param;
87    int rc;
88
89    memset(&client, 0, sizeof(client));
90
91    param.grabtype = GRABTYPE_CORE;
92    param.this_device_mode = GrabModeSync;
93    param.other_devices_mode = GrabModeSync;
94    param.modifiers = AnyModifier;
95    param.ownerEvents = FALSE;
96
97    rc = CheckGrabValues(&client, &param);
98    g_assert(rc == Success);
99
100    param.this_device_mode = GrabModeAsync;
101    rc = CheckGrabValues(&client, &param);
102    g_assert(rc == Success);
103
104    param.this_device_mode = GrabModeAsync + 1;
105    rc = CheckGrabValues(&client, &param);
106    g_assert(rc == BadValue);
107    g_assert(client.errorValue == param.this_device_mode);
108    g_assert(client.errorValue == GrabModeAsync + 1);
109
110    param.this_device_mode = GrabModeSync;
111    param.other_devices_mode = GrabModeAsync;
112    rc = CheckGrabValues(&client, &param);
113    g_assert(rc == Success);
114
115    param.other_devices_mode = GrabModeAsync + 1;
116    rc = CheckGrabValues(&client, &param);
117    g_assert(rc == BadValue);
118    g_assert(client.errorValue == param.other_devices_mode);
119    g_assert(client.errorValue == GrabModeAsync + 1);
120
121    param.other_devices_mode = GrabModeSync;
122
123    param.modifiers = 1 << 13;
124    rc = CheckGrabValues(&client, &param);
125    g_assert(rc == BadValue);
126    g_assert(client.errorValue == param.modifiers);
127    g_assert(client.errorValue == (1 << 13));
128
129
130    param.modifiers = AnyModifier;
131    param.ownerEvents = TRUE;
132    rc = CheckGrabValues(&client, &param);
133    g_assert(rc == Success);
134
135    param.ownerEvents = 3;
136    rc = CheckGrabValues(&client, &param);
137    g_assert(rc == BadValue);
138    g_assert(client.errorValue == param.ownerEvents);
139    g_assert(client.errorValue == 3);
140}
141
142
143/**
144 * Convert various internal events to the matching core event and verify the
145 * parameters.
146 */
147static void dix_event_to_core(int type)
148{
149    DeviceEvent ev;
150    xEvent core;
151    int time;
152    int x, y;
153    int rc;
154    int state;
155    int detail;
156    const int ROOT_WINDOW_ID = 0x100;
157
158    /* EventToCore memsets the event to 0 */
159#define test_event() \
160    g_assert(rc == Success); \
161    g_assert(core.u.u.type == type); \
162    g_assert(core.u.u.detail == detail); \
163    g_assert(core.u.keyButtonPointer.time == time); \
164    g_assert(core.u.keyButtonPointer.rootX == x); \
165    g_assert(core.u.keyButtonPointer.rootY == y); \
166    g_assert(core.u.keyButtonPointer.state == state); \
167    g_assert(core.u.keyButtonPointer.eventX == 0); \
168    g_assert(core.u.keyButtonPointer.eventY == 0); \
169    g_assert(core.u.keyButtonPointer.root == ROOT_WINDOW_ID); \
170    g_assert(core.u.keyButtonPointer.event == 0); \
171    g_assert(core.u.keyButtonPointer.child == 0); \
172    g_assert(core.u.keyButtonPointer.sameScreen == FALSE);
173
174    x = 0;
175    y = 0;
176    time = 12345;
177    state = 0;
178    detail = 0;
179
180    ev.header   = 0xFF;
181    ev.length   = sizeof(DeviceEvent);
182    ev.time     = time;
183    ev.root_y   = x;
184    ev.root_x   = y;
185    ev.root     = ROOT_WINDOW_ID;
186    ev.corestate = state;
187    ev.detail.key = detail;
188
189    ev.type = type;
190    ev.detail.key = 0;
191    rc = EventToCore((InternalEvent*)&ev, &core);
192    test_event();
193
194    x = 1;
195    y = 2;
196    ev.root_x = x;
197    ev.root_y = y;
198    rc = EventToCore((InternalEvent*)&ev, &core);
199    test_event();
200
201    x = 0x7FFF;
202    y = 0x7FFF;
203    ev.root_x = x;
204    ev.root_y = y;
205    rc = EventToCore((InternalEvent*)&ev, &core);
206    test_event();
207
208    x = 0x8000; /* too high */
209    y = 0x8000; /* too high */
210    ev.root_x = x;
211    ev.root_y = y;
212    rc = EventToCore((InternalEvent*)&ev, &core);
213    g_assert(core.u.keyButtonPointer.rootX != x);
214    g_assert(core.u.keyButtonPointer.rootY != y);
215
216    x = 0x7FFF;
217    y = 0x7FFF;
218    ev.root_x = x;
219    ev.root_y = y;
220    time = 0;
221    ev.time = time;
222    rc = EventToCore((InternalEvent*)&ev, &core);
223    test_event();
224
225    detail = 1;
226    ev.detail.key = detail;
227    rc = EventToCore((InternalEvent*)&ev, &core);
228    test_event();
229
230    detail = 0xFF; /* highest value */
231    ev.detail.key = detail;
232    rc = EventToCore((InternalEvent*)&ev, &core);
233    test_event();
234
235    detail = 0xFFF; /* too big */
236    ev.detail.key = detail;
237    rc = EventToCore((InternalEvent*)&ev, &core);
238    g_assert(rc == BadMatch);
239
240    detail = 0xFF; /* too big */
241    ev.detail.key = detail;
242    state = 0xFFFF; /* highest value */
243    ev.corestate = state;
244    rc = EventToCore((InternalEvent*)&ev, &core);
245    test_event();
246
247    state = 0x10000; /* too big */
248    ev.corestate = state;
249    rc = EventToCore((InternalEvent*)&ev, &core);
250    g_assert(core.u.keyButtonPointer.state != state);
251    g_assert(core.u.keyButtonPointer.state == (state & 0xFFFF));
252
253#undef test_event
254}
255
256static void dix_event_to_core_conversion(void)
257{
258    DeviceEvent ev;
259    xEvent core;
260    int rc;
261
262    ev.header   = 0xFF;
263    ev.length   = sizeof(DeviceEvent);
264
265    ev.type     = 0;
266    rc = EventToCore((InternalEvent*)&ev, &core);
267    g_assert(rc == BadImplementation);
268
269    ev.type     = 1;
270    rc = EventToCore((InternalEvent*)&ev, &core);
271    g_assert(rc == BadImplementation);
272
273    ev.type     = ET_ProximityOut + 1;
274    rc = EventToCore((InternalEvent*)&ev, &core);
275    g_assert(rc == BadImplementation);
276
277    ev.type     = ET_ProximityIn;
278    rc = EventToCore((InternalEvent*)&ev, &core);
279    g_assert(rc == BadMatch);
280
281    ev.type     = ET_ProximityOut;
282    rc = EventToCore((InternalEvent*)&ev, &core);
283    g_assert(rc == BadMatch);
284
285    dix_event_to_core(ET_KeyPress);
286    dix_event_to_core(ET_KeyRelease);
287    dix_event_to_core(ET_ButtonPress);
288    dix_event_to_core(ET_ButtonRelease);
289    dix_event_to_core(ET_Motion);
290}
291
292static void xi2_struct_sizes(void)
293{
294#define compare(req) \
295    g_assert(sizeof(req) == sz_##req);
296
297    compare(xXIQueryVersionReq);
298    compare(xXIWarpPointerReq);
299    compare(xXIChangeCursorReq);
300    compare(xXIChangeHierarchyReq);
301    compare(xXISetClientPointerReq);
302    compare(xXIGetClientPointerReq);
303    compare(xXISelectEventsReq);
304    compare(xXIQueryVersionReq);
305    compare(xXIQueryDeviceReq);
306    compare(xXISetFocusReq);
307    compare(xXIGetFocusReq);
308    compare(xXIGrabDeviceReq);
309    compare(xXIUngrabDeviceReq);
310    compare(xXIAllowEventsReq);
311    compare(xXIPassiveGrabDeviceReq);
312    compare(xXIPassiveUngrabDeviceReq);
313    compare(xXIListPropertiesReq);
314    compare(xXIChangePropertyReq);
315    compare(xXIDeletePropertyReq);
316    compare(xXIGetPropertyReq);
317    compare(xXIGetSelectedEventsReq);
318#undef compare
319}
320
321
322static void dix_grab_matching(void)
323{
324    DeviceIntRec xi_all_devices, xi_all_master_devices, dev1, dev2;
325    GrabRec a, b;
326    BOOL rc;
327
328    memset(&a, 0, sizeof(a));
329    memset(&b, 0, sizeof(b));
330
331    /* different grabtypes must fail */
332    a.grabtype = GRABTYPE_CORE;
333    b.grabtype = GRABTYPE_XI2;
334    rc = GrabMatchesSecond(&a, &b, FALSE);
335    g_assert(rc == FALSE);
336    rc = GrabMatchesSecond(&b, &a, FALSE);
337    g_assert(rc == FALSE);
338
339    a.grabtype = GRABTYPE_XI;
340    b.grabtype = GRABTYPE_XI2;
341    rc = GrabMatchesSecond(&a, &b, FALSE);
342    g_assert(rc == FALSE);
343    rc = GrabMatchesSecond(&b, &a, FALSE);
344    g_assert(rc == FALSE);
345
346    a.grabtype = GRABTYPE_XI;
347    b.grabtype = GRABTYPE_CORE;
348    rc = GrabMatchesSecond(&a, &b, FALSE);
349    g_assert(rc == FALSE);
350    rc = GrabMatchesSecond(&b, &a, FALSE);
351    g_assert(rc == FALSE);
352
353    /* XI2 grabs for different devices must fail, regardless of ignoreDevice
354     * XI2 grabs for master devices must fail against a slave */
355    memset(&xi_all_devices, 0, sizeof(DeviceIntRec));
356    memset(&xi_all_master_devices, 0, sizeof(DeviceIntRec));
357    memset(&dev1, 0, sizeof(DeviceIntRec));
358    memset(&dev2, 0, sizeof(DeviceIntRec));
359
360    xi_all_devices.id = XIAllDevices;
361    xi_all_master_devices.id = XIAllMasterDevices;
362    dev1.id = 10;
363    dev1.type = SLAVE;
364    dev2.id = 11;
365    dev2.type = SLAVE;
366
367    inputInfo.all_devices = &xi_all_devices;
368    inputInfo.all_master_devices = &xi_all_master_devices;
369    a.grabtype = GRABTYPE_XI2;
370    b.grabtype = GRABTYPE_XI2;
371    a.device = &dev1;
372    b.device = &dev2;
373
374    rc = GrabMatchesSecond(&a, &b, FALSE);
375    g_assert(rc == FALSE);
376
377    a.device = &dev2;
378    b.device = &dev1;
379    rc = GrabMatchesSecond(&a, &b, FALSE);
380    g_assert(rc == FALSE);
381    rc = GrabMatchesSecond(&a, &b, TRUE);
382    g_assert(rc == FALSE);
383
384    a.device = inputInfo.all_master_devices;
385    b.device = &dev1;
386    rc = GrabMatchesSecond(&a, &b, FALSE);
387    g_assert(rc == FALSE);
388    rc = GrabMatchesSecond(&a, &b, TRUE);
389    g_assert(rc == FALSE);
390
391    a.device = &dev1;
392    b.device = inputInfo.all_master_devices;
393    rc = GrabMatchesSecond(&a, &b, FALSE);
394    g_assert(rc == FALSE);
395    rc = GrabMatchesSecond(&a, &b, TRUE);
396    g_assert(rc == FALSE);
397
398    /* ignoreDevice FALSE must fail for different devices for CORE and XI */
399    a.grabtype = GRABTYPE_XI;
400    b.grabtype = GRABTYPE_XI;
401    a.device = &dev1;
402    b.device = &dev2;
403    a.modifierDevice = &dev1;
404    b.modifierDevice = &dev1;
405    rc = GrabMatchesSecond(&a, &b, FALSE);
406    g_assert(rc == FALSE);
407
408    a.grabtype = GRABTYPE_CORE;
409    b.grabtype = GRABTYPE_CORE;
410    a.device = &dev1;
411    b.device = &dev2;
412    a.modifierDevice = &dev1;
413    b.modifierDevice = &dev1;
414    rc = GrabMatchesSecond(&a, &b, FALSE);
415    g_assert(rc == FALSE);
416
417    /* ignoreDevice FALSE must fail for different modifier devices for CORE
418     * and XI */
419    a.grabtype = GRABTYPE_XI;
420    b.grabtype = GRABTYPE_XI;
421    a.device = &dev1;
422    b.device = &dev1;
423    a.modifierDevice = &dev1;
424    b.modifierDevice = &dev2;
425    rc = GrabMatchesSecond(&a, &b, FALSE);
426    g_assert(rc == FALSE);
427
428    a.grabtype = GRABTYPE_CORE;
429    b.grabtype = GRABTYPE_CORE;
430    a.device = &dev1;
431    b.device = &dev1;
432    a.modifierDevice = &dev1;
433    b.modifierDevice = &dev2;
434    rc = GrabMatchesSecond(&a, &b, FALSE);
435    g_assert(rc == FALSE);
436
437    /* different event type must fail */
438    a.grabtype = GRABTYPE_XI2;
439    b.grabtype = GRABTYPE_XI2;
440    a.device = &dev1;
441    b.device = &dev1;
442    a.modifierDevice = &dev1;
443    b.modifierDevice = &dev1;
444    a.type = XI_KeyPress;
445    b.type = XI_KeyRelease;
446    rc = GrabMatchesSecond(&a, &b, FALSE);
447    g_assert(rc == FALSE);
448    rc = GrabMatchesSecond(&a, &b, TRUE);
449    g_assert(rc == FALSE);
450
451    a.grabtype = GRABTYPE_CORE;
452    b.grabtype = GRABTYPE_CORE;
453    a.device = &dev1;
454    b.device = &dev1;
455    a.modifierDevice = &dev1;
456    b.modifierDevice = &dev1;
457    a.type = XI_KeyPress;
458    b.type = XI_KeyRelease;
459    rc = GrabMatchesSecond(&a, &b, FALSE);
460    g_assert(rc == FALSE);
461    rc = GrabMatchesSecond(&a, &b, TRUE);
462    g_assert(rc == FALSE);
463
464    a.grabtype = GRABTYPE_XI;
465    b.grabtype = GRABTYPE_XI;
466    a.device = &dev1;
467    b.device = &dev1;
468    a.modifierDevice = &dev1;
469    b.modifierDevice = &dev1;
470    a.type = XI_KeyPress;
471    b.type = XI_KeyRelease;
472    rc = GrabMatchesSecond(&a, &b, FALSE);
473    g_assert(rc == FALSE);
474    rc = GrabMatchesSecond(&a, &b, TRUE);
475    g_assert(rc == FALSE);
476
477    /* different modifiers must fail */
478    a.grabtype = GRABTYPE_XI2;
479    b.grabtype = GRABTYPE_XI2;
480    a.device = &dev1;
481    b.device = &dev1;
482    a.modifierDevice = &dev1;
483    b.modifierDevice = &dev1;
484    a.type = XI_KeyPress;
485    b.type = XI_KeyPress;
486    a.modifiersDetail.exact = 1;
487    b.modifiersDetail.exact = 2;
488    rc = GrabMatchesSecond(&a, &b, FALSE);
489    g_assert(rc == FALSE);
490    rc = GrabMatchesSecond(&b, &a, FALSE);
491    g_assert(rc == FALSE);
492
493    a.grabtype = GRABTYPE_CORE;
494    b.grabtype = GRABTYPE_CORE;
495    rc = GrabMatchesSecond(&a, &b, FALSE);
496    g_assert(rc == FALSE);
497    rc = GrabMatchesSecond(&b, &a, FALSE);
498    g_assert(rc == FALSE);
499
500    a.grabtype = GRABTYPE_XI;
501    b.grabtype = GRABTYPE_XI;
502    rc = GrabMatchesSecond(&a, &b, FALSE);
503    g_assert(rc == FALSE);
504    rc = GrabMatchesSecond(&b, &a, FALSE);
505    g_assert(rc == FALSE);
506
507    /* AnyModifier must fail for XI2 */
508    a.grabtype = GRABTYPE_XI2;
509    b.grabtype = GRABTYPE_XI2;
510    a.modifiersDetail.exact = AnyModifier;
511    b.modifiersDetail.exact = 1;
512    rc = GrabMatchesSecond(&a, &b, FALSE);
513    g_assert(rc == FALSE);
514    rc = GrabMatchesSecond(&b, &a, FALSE);
515    g_assert(rc == FALSE);
516
517    /* XIAnyModifier must fail for CORE and XI */
518    a.grabtype = GRABTYPE_XI;
519    b.grabtype = GRABTYPE_XI;
520    a.modifiersDetail.exact = XIAnyModifier;
521    b.modifiersDetail.exact = 1;
522    rc = GrabMatchesSecond(&a, &b, FALSE);
523    g_assert(rc == FALSE);
524    rc = GrabMatchesSecond(&b, &a, FALSE);
525    g_assert(rc == FALSE);
526
527    a.grabtype = GRABTYPE_CORE;
528    b.grabtype = GRABTYPE_CORE;
529    a.modifiersDetail.exact = XIAnyModifier;
530    b.modifiersDetail.exact = 1;
531    rc = GrabMatchesSecond(&a, &b, FALSE);
532    g_assert(rc == FALSE);
533    rc = GrabMatchesSecond(&b, &a, FALSE);
534    g_assert(rc == FALSE);
535
536    /* different detail must fail */
537    a.grabtype = GRABTYPE_XI2;
538    b.grabtype = GRABTYPE_XI2;
539    a.detail.exact = 1;
540    b.detail.exact = 2;
541    a.modifiersDetail.exact = 1;
542    b.modifiersDetail.exact = 1;
543    rc = GrabMatchesSecond(&a, &b, FALSE);
544    g_assert(rc == FALSE);
545    rc = GrabMatchesSecond(&b, &a, FALSE);
546    g_assert(rc == FALSE);
547
548    a.grabtype = GRABTYPE_XI;
549    b.grabtype = GRABTYPE_XI;
550    rc = GrabMatchesSecond(&a, &b, FALSE);
551    g_assert(rc == FALSE);
552    rc = GrabMatchesSecond(&b, &a, FALSE);
553    g_assert(rc == FALSE);
554
555    a.grabtype = GRABTYPE_CORE;
556    b.grabtype = GRABTYPE_CORE;
557    rc = GrabMatchesSecond(&a, &b, FALSE);
558    g_assert(rc == FALSE);
559    rc = GrabMatchesSecond(&b, &a, FALSE);
560    g_assert(rc == FALSE);
561
562    /* detail of AnyModifier must fail */
563    a.grabtype = GRABTYPE_XI2;
564    b.grabtype = GRABTYPE_XI2;
565    a.detail.exact = AnyModifier;
566    b.detail.exact = 1;
567    a.modifiersDetail.exact = 1;
568    b.modifiersDetail.exact = 1;
569    rc = GrabMatchesSecond(&a, &b, FALSE);
570    g_assert(rc == FALSE);
571    rc = GrabMatchesSecond(&b, &a, FALSE);
572    g_assert(rc == FALSE);
573
574    a.grabtype = GRABTYPE_CORE;
575    b.grabtype = GRABTYPE_CORE;
576    rc = GrabMatchesSecond(&a, &b, FALSE);
577    g_assert(rc == FALSE);
578    rc = GrabMatchesSecond(&b, &a, FALSE);
579    g_assert(rc == FALSE);
580
581    a.grabtype = GRABTYPE_XI;
582    b.grabtype = GRABTYPE_XI;
583    rc = GrabMatchesSecond(&a, &b, FALSE);
584    g_assert(rc == FALSE);
585    rc = GrabMatchesSecond(&b, &a, FALSE);
586    g_assert(rc == FALSE);
587
588    /* detail of XIAnyModifier must fail */
589    a.grabtype = GRABTYPE_XI2;
590    b.grabtype = GRABTYPE_XI2;
591    a.detail.exact = XIAnyModifier;
592    b.detail.exact = 1;
593    a.modifiersDetail.exact = 1;
594    b.modifiersDetail.exact = 1;
595    rc = GrabMatchesSecond(&a, &b, FALSE);
596    g_assert(rc == FALSE);
597    rc = GrabMatchesSecond(&b, &a, FALSE);
598    g_assert(rc == FALSE);
599
600    a.grabtype = GRABTYPE_CORE;
601    b.grabtype = GRABTYPE_CORE;
602    rc = GrabMatchesSecond(&a, &b, FALSE);
603    g_assert(rc == FALSE);
604    rc = GrabMatchesSecond(&b, &a, FALSE);
605    g_assert(rc == FALSE);
606
607    a.grabtype = GRABTYPE_XI;
608    b.grabtype = GRABTYPE_XI;
609    rc = GrabMatchesSecond(&a, &b, FALSE);
610    g_assert(rc == FALSE);
611    rc = GrabMatchesSecond(&b, &a, FALSE);
612    g_assert(rc == FALSE);
613
614    /* XIAnyModifier or AnyModifer must succeed */
615    a.grabtype = GRABTYPE_XI2;
616    b.grabtype = GRABTYPE_XI2;
617    a.detail.exact = 1;
618    b.detail.exact = 1;
619    a.modifiersDetail.exact = XIAnyModifier;
620    b.modifiersDetail.exact = 1;
621    rc = GrabMatchesSecond(&a, &b, FALSE);
622    g_assert(rc == TRUE);
623    rc = GrabMatchesSecond(&b, &a, FALSE);
624    g_assert(rc == TRUE);
625
626    a.grabtype = GRABTYPE_CORE;
627    b.grabtype = GRABTYPE_CORE;
628    a.detail.exact = 1;
629    b.detail.exact = 1;
630    a.modifiersDetail.exact = AnyModifier;
631    b.modifiersDetail.exact = 1;
632    rc = GrabMatchesSecond(&a, &b, FALSE);
633    g_assert(rc == TRUE);
634    rc = GrabMatchesSecond(&b, &a, FALSE);
635    g_assert(rc == TRUE);
636
637    a.grabtype = GRABTYPE_XI;
638    b.grabtype = GRABTYPE_XI;
639    a.detail.exact = 1;
640    b.detail.exact = 1;
641    a.modifiersDetail.exact = AnyModifier;
642    b.modifiersDetail.exact = 1;
643    rc = GrabMatchesSecond(&a, &b, FALSE);
644    g_assert(rc == TRUE);
645    rc = GrabMatchesSecond(&b, &a, FALSE);
646    g_assert(rc == TRUE);
647
648    /* AnyKey or XIAnyKeycode must succeed */
649    a.grabtype = GRABTYPE_XI2;
650    b.grabtype = GRABTYPE_XI2;
651    a.detail.exact = XIAnyKeycode;
652    b.detail.exact = 1;
653    a.modifiersDetail.exact = 1;
654    b.modifiersDetail.exact = 1;
655    rc = GrabMatchesSecond(&a, &b, FALSE);
656    g_assert(rc == TRUE);
657    rc = GrabMatchesSecond(&b, &a, FALSE);
658    g_assert(rc == TRUE);
659
660    a.grabtype = GRABTYPE_CORE;
661    b.grabtype = GRABTYPE_CORE;
662    a.detail.exact = AnyKey;
663    b.detail.exact = 1;
664    a.modifiersDetail.exact = 1;
665    b.modifiersDetail.exact = 1;
666    rc = GrabMatchesSecond(&a, &b, FALSE);
667    g_assert(rc == TRUE);
668    rc = GrabMatchesSecond(&b, &a, FALSE);
669    g_assert(rc == TRUE);
670
671    a.grabtype = GRABTYPE_XI;
672    b.grabtype = GRABTYPE_XI;
673    a.detail.exact = AnyKey;
674    b.detail.exact = 1;
675    a.modifiersDetail.exact = 1;
676    b.modifiersDetail.exact = 1;
677    rc = GrabMatchesSecond(&a, &b, FALSE);
678    g_assert(rc == TRUE);
679    rc = GrabMatchesSecond(&b, &a, FALSE);
680    g_assert(rc == TRUE);
681}
682
683static void include_byte_padding_macros(void)
684{
685    int i;
686    g_test_message("Testing bits_to_bytes()");
687
688    /* the macros don't provide overflow protection */
689    for (i = 0; i < INT_MAX - 7; i++)
690    {
691        int expected_bytes;
692        expected_bytes = (i + 7)/8;
693
694        g_assert(bits_to_bytes(i) >= i/8);
695        g_assert((bits_to_bytes(i) * 8) - i <= 7);
696    }
697
698    g_test_message("Testing bytes_to_int32()");
699    for (i = 0; i < INT_MAX - 3; i++)
700    {
701        int expected_4byte;
702        expected_4byte = (i + 3)/4;
703
704        g_assert(bytes_to_int32(i) <= i);
705        g_assert((bytes_to_int32(i) * 4) - i <= 3);
706    }
707
708    g_test_message("Testing pad_to_int32");
709
710    for (i = 0; i < INT_MAX - 3; i++)
711    {
712        int expected_bytes;
713        expected_bytes = ((i + 3)/4) * 4;
714
715        g_assert(pad_to_int32(i) >= i);
716        g_assert(pad_to_int32(i) - i <= 3);
717    }
718
719}
720
721static void xi_unregister_handlers(void)
722{
723    DeviceIntRec dev;
724    int handler;
725
726    memset(&dev, 0, sizeof(dev));
727
728    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
729    g_assert(handler == 1);
730    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
731    g_assert(handler == 2);
732    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
733    g_assert(handler == 3);
734
735    g_test_message("Unlinking from front.");
736
737    XIUnregisterPropertyHandler(&dev, 4); /* NOOP */
738    g_assert(dev.properties.handlers->id == 3);
739    XIUnregisterPropertyHandler(&dev, 3);
740    g_assert(dev.properties.handlers->id == 2);
741    XIUnregisterPropertyHandler(&dev, 2);
742    g_assert(dev.properties.handlers->id == 1);
743    XIUnregisterPropertyHandler(&dev, 1);
744    g_assert(dev.properties.handlers == NULL);
745
746    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
747    g_assert(handler == 4);
748    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
749    g_assert(handler == 5);
750    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
751    g_assert(handler == 6);
752    XIUnregisterPropertyHandler(&dev, 3); /* NOOP */
753    g_assert(dev.properties.handlers->next->next->next == NULL);
754    XIUnregisterPropertyHandler(&dev, 4);
755    g_assert(dev.properties.handlers->next->next == NULL);
756    XIUnregisterPropertyHandler(&dev, 5);
757    g_assert(dev.properties.handlers->next == NULL);
758    XIUnregisterPropertyHandler(&dev, 6);
759    g_assert(dev.properties.handlers == NULL);
760
761    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
762    g_assert(handler == 7);
763    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
764    g_assert(handler == 8);
765    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
766    g_assert(handler == 9);
767
768    XIDeleteAllDeviceProperties(&dev);
769    g_assert(dev.properties.handlers == NULL);
770    XIUnregisterPropertyHandler(&dev, 7); /* NOOP */
771
772}
773
774static void cmp_attr_fields(InputAttributes *attr1,
775                            InputAttributes *attr2)
776{
777    char **tags1, **tags2;
778
779    g_assert(attr1 && attr2);
780    g_assert(attr1 != attr2);
781    g_assert(attr1->flags == attr2->flags);
782
783    if (attr1->product != NULL)
784    {
785        g_assert(attr1->product != attr2->product);
786        g_assert(strcmp(attr1->product, attr2->product) == 0);
787    } else
788        g_assert(attr2->product == NULL);
789
790    if (attr1->vendor != NULL)
791    {
792        g_assert(attr1->vendor != attr2->vendor);
793        g_assert(strcmp(attr1->vendor, attr2->vendor) == 0);
794    } else
795        g_assert(attr2->vendor == NULL);
796
797    if (attr1->device != NULL)
798    {
799        g_assert(attr1->device != attr2->device);
800        g_assert(strcmp(attr1->device, attr2->device) == 0);
801    } else
802        g_assert(attr2->device == NULL);
803
804    if (attr1->pnp_id != NULL)
805    {
806        g_assert(attr1->pnp_id != attr2->pnp_id);
807        g_assert(strcmp(attr1->pnp_id, attr2->pnp_id) == 0);
808    } else
809        g_assert(attr2->pnp_id == NULL);
810
811    if (attr1->usb_id != NULL)
812    {
813        g_assert(attr1->usb_id != attr2->usb_id);
814        g_assert(strcmp(attr1->usb_id, attr2->usb_id) == 0);
815    } else
816        g_assert(attr2->usb_id == NULL);
817
818    tags1 = attr1->tags;
819    tags2 = attr2->tags;
820
821    /* if we don't have any tags, skip the tag checking bits */
822    if (!tags1)
823    {
824        g_assert(!tags2);
825        return;
826    }
827
828    /* Don't lug around empty arrays */
829    g_assert(*tags1);
830    g_assert(*tags2);
831
832    /* check for identical content, but duplicated */
833    while (*tags1)
834    {
835        g_assert(*tags1 != *tags2);
836        g_assert(strcmp(*tags1, *tags2) == 0);
837        tags1++;
838        tags2++;
839    }
840
841    /* ensure tags1 and tags2 have the same no of elements */
842    g_assert(!*tags2);
843
844    /* check for not sharing memory */
845    tags1 = attr1->tags;
846    while (*tags1)
847    {
848        tags2 = attr2->tags;
849        while (*tags2)
850            g_assert(*tags1 != *tags2++);
851
852        tags1++;
853    }
854}
855
856static void dix_input_attributes(void)
857{
858    InputAttributes orig = {0};
859    InputAttributes *new;
860    char *tags[4] = {"tag1", "tag2", "tag2", NULL};
861
862    new = DuplicateInputAttributes(NULL);
863    g_assert(!new);
864
865    new = DuplicateInputAttributes(&orig);
866    g_assert(memcmp(&orig, new, sizeof(InputAttributes)) == 0);
867
868    orig.product = "product name";
869    new = DuplicateInputAttributes(&orig);
870    cmp_attr_fields(&orig, new);
871    FreeInputAttributes(new);
872
873    orig.vendor = "vendor name";
874    new = DuplicateInputAttributes(&orig);
875    cmp_attr_fields(&orig, new);
876    FreeInputAttributes(new);
877
878    orig.device = "device path";
879    new = DuplicateInputAttributes(&orig);
880    cmp_attr_fields(&orig, new);
881    FreeInputAttributes(new);
882
883    orig.pnp_id = "PnPID";
884    new = DuplicateInputAttributes(&orig);
885    cmp_attr_fields(&orig, new);
886    FreeInputAttributes(new);
887
888    orig.usb_id = "USBID";
889    new = DuplicateInputAttributes(&orig);
890    cmp_attr_fields(&orig, new);
891    FreeInputAttributes(new);
892
893    orig.flags = 0xF0;
894    new = DuplicateInputAttributes(&orig);
895    cmp_attr_fields(&orig, new);
896    FreeInputAttributes(new);
897
898    orig.tags = tags;
899    new = DuplicateInputAttributes(&orig);
900    cmp_attr_fields(&orig, new);
901    FreeInputAttributes(new);
902}
903
904
905int main(int argc, char** argv)
906{
907    g_test_init(&argc, &argv,NULL);
908    g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
909
910    g_test_add_func("/dix/input/attributes", dix_input_attributes);
911    g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
912    g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
913    g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
914    g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
915    g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
916    g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
917    g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
918
919
920    return g_test_run();
921}
922