input.c revision 8223e2f2
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    SetBit(ev.valuators.mask, 0);
186    SetBit(ev.valuators.mask, 1);
187    ev.root     = ROOT_WINDOW_ID;
188    ev.corestate = state;
189    ev.detail.key = detail;
190
191    ev.type = type;
192    ev.detail.key = 0;
193    rc = EventToCore((InternalEvent*)&ev, &core);
194    test_event();
195
196    x = 1;
197    y = 2;
198    ev.root_x = x;
199    ev.root_y = y;
200    rc = EventToCore((InternalEvent*)&ev, &core);
201    test_event();
202
203    x = 0x7FFF;
204    y = 0x7FFF;
205    ev.root_x = x;
206    ev.root_y = y;
207    rc = EventToCore((InternalEvent*)&ev, &core);
208    test_event();
209
210    x = 0x8000; /* too high */
211    y = 0x8000; /* too high */
212    ev.root_x = x;
213    ev.root_y = y;
214    rc = EventToCore((InternalEvent*)&ev, &core);
215    g_assert(core.u.keyButtonPointer.rootX != x);
216    g_assert(core.u.keyButtonPointer.rootY != y);
217
218    x = 0x7FFF;
219    y = 0x7FFF;
220    ev.root_x = x;
221    ev.root_y = y;
222    time = 0;
223    ev.time = time;
224    rc = EventToCore((InternalEvent*)&ev, &core);
225    test_event();
226
227    detail = 1;
228    ev.detail.key = detail;
229    rc = EventToCore((InternalEvent*)&ev, &core);
230    test_event();
231
232    detail = 0xFF; /* highest value */
233    ev.detail.key = detail;
234    rc = EventToCore((InternalEvent*)&ev, &core);
235    test_event();
236
237    detail = 0xFFF; /* too big */
238    ev.detail.key = detail;
239    rc = EventToCore((InternalEvent*)&ev, &core);
240    g_assert(rc == BadMatch);
241
242    detail = 0xFF; /* too big */
243    ev.detail.key = detail;
244    state = 0xFFFF; /* highest value */
245    ev.corestate = state;
246    rc = EventToCore((InternalEvent*)&ev, &core);
247    test_event();
248
249    state = 0x10000; /* too big */
250    ev.corestate = state;
251    rc = EventToCore((InternalEvent*)&ev, &core);
252    g_assert(core.u.keyButtonPointer.state != state);
253    g_assert(core.u.keyButtonPointer.state == (state & 0xFFFF));
254
255#undef test_event
256}
257
258static void dix_event_to_core_conversion(void)
259{
260    DeviceEvent ev;
261    xEvent core;
262    int rc;
263
264    ev.header   = 0xFF;
265    ev.length   = sizeof(DeviceEvent);
266
267    ev.type     = 0;
268    rc = EventToCore((InternalEvent*)&ev, &core);
269    g_assert(rc == BadImplementation);
270
271    ev.type     = 1;
272    rc = EventToCore((InternalEvent*)&ev, &core);
273    g_assert(rc == BadImplementation);
274
275    ev.type     = ET_ProximityOut + 1;
276    rc = EventToCore((InternalEvent*)&ev, &core);
277    g_assert(rc == BadImplementation);
278
279    ev.type     = ET_ProximityIn;
280    rc = EventToCore((InternalEvent*)&ev, &core);
281    g_assert(rc == BadMatch);
282
283    ev.type     = ET_ProximityOut;
284    rc = EventToCore((InternalEvent*)&ev, &core);
285    g_assert(rc == BadMatch);
286
287    dix_event_to_core(ET_KeyPress);
288    dix_event_to_core(ET_KeyRelease);
289    dix_event_to_core(ET_ButtonPress);
290    dix_event_to_core(ET_ButtonRelease);
291    dix_event_to_core(ET_Motion);
292}
293
294static void xi2_struct_sizes(void)
295{
296#define compare(req) \
297    g_assert(sizeof(req) == sz_##req);
298
299    compare(xXIQueryVersionReq);
300    compare(xXIWarpPointerReq);
301    compare(xXIChangeCursorReq);
302    compare(xXIChangeHierarchyReq);
303    compare(xXISetClientPointerReq);
304    compare(xXIGetClientPointerReq);
305    compare(xXISelectEventsReq);
306    compare(xXIQueryVersionReq);
307    compare(xXIQueryDeviceReq);
308    compare(xXISetFocusReq);
309    compare(xXIGetFocusReq);
310    compare(xXIGrabDeviceReq);
311    compare(xXIUngrabDeviceReq);
312    compare(xXIAllowEventsReq);
313    compare(xXIPassiveGrabDeviceReq);
314    compare(xXIPassiveUngrabDeviceReq);
315    compare(xXIListPropertiesReq);
316    compare(xXIChangePropertyReq);
317    compare(xXIDeletePropertyReq);
318    compare(xXIGetPropertyReq);
319    compare(xXIGetSelectedEventsReq);
320#undef compare
321}
322
323
324static void dix_grab_matching(void)
325{
326    DeviceIntRec xi_all_devices, xi_all_master_devices, dev1, dev2;
327    GrabRec a, b;
328    BOOL rc;
329
330    memset(&a, 0, sizeof(a));
331    memset(&b, 0, sizeof(b));
332
333    /* different grabtypes must fail */
334    a.grabtype = GRABTYPE_CORE;
335    b.grabtype = GRABTYPE_XI2;
336    rc = GrabMatchesSecond(&a, &b, FALSE);
337    g_assert(rc == FALSE);
338    rc = GrabMatchesSecond(&b, &a, FALSE);
339    g_assert(rc == FALSE);
340
341    a.grabtype = GRABTYPE_XI;
342    b.grabtype = GRABTYPE_XI2;
343    rc = GrabMatchesSecond(&a, &b, FALSE);
344    g_assert(rc == FALSE);
345    rc = GrabMatchesSecond(&b, &a, FALSE);
346    g_assert(rc == FALSE);
347
348    a.grabtype = GRABTYPE_XI;
349    b.grabtype = GRABTYPE_CORE;
350    rc = GrabMatchesSecond(&a, &b, FALSE);
351    g_assert(rc == FALSE);
352    rc = GrabMatchesSecond(&b, &a, FALSE);
353    g_assert(rc == FALSE);
354
355    /* XI2 grabs for different devices must fail, regardless of ignoreDevice
356     * XI2 grabs for master devices must fail against a slave */
357    memset(&xi_all_devices, 0, sizeof(DeviceIntRec));
358    memset(&xi_all_master_devices, 0, sizeof(DeviceIntRec));
359    memset(&dev1, 0, sizeof(DeviceIntRec));
360    memset(&dev2, 0, sizeof(DeviceIntRec));
361
362    xi_all_devices.id = XIAllDevices;
363    xi_all_master_devices.id = XIAllMasterDevices;
364    dev1.id = 10;
365    dev1.type = SLAVE;
366    dev2.id = 11;
367    dev2.type = SLAVE;
368
369    inputInfo.all_devices = &xi_all_devices;
370    inputInfo.all_master_devices = &xi_all_master_devices;
371    a.grabtype = GRABTYPE_XI2;
372    b.grabtype = GRABTYPE_XI2;
373    a.device = &dev1;
374    b.device = &dev2;
375
376    rc = GrabMatchesSecond(&a, &b, FALSE);
377    g_assert(rc == FALSE);
378
379    a.device = &dev2;
380    b.device = &dev1;
381    rc = GrabMatchesSecond(&a, &b, FALSE);
382    g_assert(rc == FALSE);
383    rc = GrabMatchesSecond(&a, &b, TRUE);
384    g_assert(rc == FALSE);
385
386    a.device = inputInfo.all_master_devices;
387    b.device = &dev1;
388    rc = GrabMatchesSecond(&a, &b, FALSE);
389    g_assert(rc == FALSE);
390    rc = GrabMatchesSecond(&a, &b, TRUE);
391    g_assert(rc == FALSE);
392
393    a.device = &dev1;
394    b.device = inputInfo.all_master_devices;
395    rc = GrabMatchesSecond(&a, &b, FALSE);
396    g_assert(rc == FALSE);
397    rc = GrabMatchesSecond(&a, &b, TRUE);
398    g_assert(rc == FALSE);
399
400    /* ignoreDevice FALSE must fail for different devices for CORE and XI */
401    a.grabtype = GRABTYPE_XI;
402    b.grabtype = GRABTYPE_XI;
403    a.device = &dev1;
404    b.device = &dev2;
405    a.modifierDevice = &dev1;
406    b.modifierDevice = &dev1;
407    rc = GrabMatchesSecond(&a, &b, FALSE);
408    g_assert(rc == FALSE);
409
410    a.grabtype = GRABTYPE_CORE;
411    b.grabtype = GRABTYPE_CORE;
412    a.device = &dev1;
413    b.device = &dev2;
414    a.modifierDevice = &dev1;
415    b.modifierDevice = &dev1;
416    rc = GrabMatchesSecond(&a, &b, FALSE);
417    g_assert(rc == FALSE);
418
419    /* ignoreDevice FALSE must fail for different modifier devices for CORE
420     * and XI */
421    a.grabtype = GRABTYPE_XI;
422    b.grabtype = GRABTYPE_XI;
423    a.device = &dev1;
424    b.device = &dev1;
425    a.modifierDevice = &dev1;
426    b.modifierDevice = &dev2;
427    rc = GrabMatchesSecond(&a, &b, FALSE);
428    g_assert(rc == FALSE);
429
430    a.grabtype = GRABTYPE_CORE;
431    b.grabtype = GRABTYPE_CORE;
432    a.device = &dev1;
433    b.device = &dev1;
434    a.modifierDevice = &dev1;
435    b.modifierDevice = &dev2;
436    rc = GrabMatchesSecond(&a, &b, FALSE);
437    g_assert(rc == FALSE);
438
439    /* different event type must fail */
440    a.grabtype = GRABTYPE_XI2;
441    b.grabtype = GRABTYPE_XI2;
442    a.device = &dev1;
443    b.device = &dev1;
444    a.modifierDevice = &dev1;
445    b.modifierDevice = &dev1;
446    a.type = XI_KeyPress;
447    b.type = XI_KeyRelease;
448    rc = GrabMatchesSecond(&a, &b, FALSE);
449    g_assert(rc == FALSE);
450    rc = GrabMatchesSecond(&a, &b, TRUE);
451    g_assert(rc == FALSE);
452
453    a.grabtype = GRABTYPE_CORE;
454    b.grabtype = GRABTYPE_CORE;
455    a.device = &dev1;
456    b.device = &dev1;
457    a.modifierDevice = &dev1;
458    b.modifierDevice = &dev1;
459    a.type = XI_KeyPress;
460    b.type = XI_KeyRelease;
461    rc = GrabMatchesSecond(&a, &b, FALSE);
462    g_assert(rc == FALSE);
463    rc = GrabMatchesSecond(&a, &b, TRUE);
464    g_assert(rc == FALSE);
465
466    a.grabtype = GRABTYPE_XI;
467    b.grabtype = GRABTYPE_XI;
468    a.device = &dev1;
469    b.device = &dev1;
470    a.modifierDevice = &dev1;
471    b.modifierDevice = &dev1;
472    a.type = XI_KeyPress;
473    b.type = XI_KeyRelease;
474    rc = GrabMatchesSecond(&a, &b, FALSE);
475    g_assert(rc == FALSE);
476    rc = GrabMatchesSecond(&a, &b, TRUE);
477    g_assert(rc == FALSE);
478
479    /* different modifiers must fail */
480    a.grabtype = GRABTYPE_XI2;
481    b.grabtype = GRABTYPE_XI2;
482    a.device = &dev1;
483    b.device = &dev1;
484    a.modifierDevice = &dev1;
485    b.modifierDevice = &dev1;
486    a.type = XI_KeyPress;
487    b.type = XI_KeyPress;
488    a.modifiersDetail.exact = 1;
489    b.modifiersDetail.exact = 2;
490    rc = GrabMatchesSecond(&a, &b, FALSE);
491    g_assert(rc == FALSE);
492    rc = GrabMatchesSecond(&b, &a, FALSE);
493    g_assert(rc == FALSE);
494
495    a.grabtype = GRABTYPE_CORE;
496    b.grabtype = GRABTYPE_CORE;
497    rc = GrabMatchesSecond(&a, &b, FALSE);
498    g_assert(rc == FALSE);
499    rc = GrabMatchesSecond(&b, &a, FALSE);
500    g_assert(rc == FALSE);
501
502    a.grabtype = GRABTYPE_XI;
503    b.grabtype = GRABTYPE_XI;
504    rc = GrabMatchesSecond(&a, &b, FALSE);
505    g_assert(rc == FALSE);
506    rc = GrabMatchesSecond(&b, &a, FALSE);
507    g_assert(rc == FALSE);
508
509    /* AnyModifier must fail for XI2 */
510    a.grabtype = GRABTYPE_XI2;
511    b.grabtype = GRABTYPE_XI2;
512    a.modifiersDetail.exact = AnyModifier;
513    b.modifiersDetail.exact = 1;
514    rc = GrabMatchesSecond(&a, &b, FALSE);
515    g_assert(rc == FALSE);
516    rc = GrabMatchesSecond(&b, &a, FALSE);
517    g_assert(rc == FALSE);
518
519    /* XIAnyModifier must fail for CORE and XI */
520    a.grabtype = GRABTYPE_XI;
521    b.grabtype = GRABTYPE_XI;
522    a.modifiersDetail.exact = XIAnyModifier;
523    b.modifiersDetail.exact = 1;
524    rc = GrabMatchesSecond(&a, &b, FALSE);
525    g_assert(rc == FALSE);
526    rc = GrabMatchesSecond(&b, &a, FALSE);
527    g_assert(rc == FALSE);
528
529    a.grabtype = GRABTYPE_CORE;
530    b.grabtype = GRABTYPE_CORE;
531    a.modifiersDetail.exact = XIAnyModifier;
532    b.modifiersDetail.exact = 1;
533    rc = GrabMatchesSecond(&a, &b, FALSE);
534    g_assert(rc == FALSE);
535    rc = GrabMatchesSecond(&b, &a, FALSE);
536    g_assert(rc == FALSE);
537
538    /* different detail must fail */
539    a.grabtype = GRABTYPE_XI2;
540    b.grabtype = GRABTYPE_XI2;
541    a.detail.exact = 1;
542    b.detail.exact = 2;
543    a.modifiersDetail.exact = 1;
544    b.modifiersDetail.exact = 1;
545    rc = GrabMatchesSecond(&a, &b, FALSE);
546    g_assert(rc == FALSE);
547    rc = GrabMatchesSecond(&b, &a, FALSE);
548    g_assert(rc == FALSE);
549
550    a.grabtype = GRABTYPE_XI;
551    b.grabtype = GRABTYPE_XI;
552    rc = GrabMatchesSecond(&a, &b, FALSE);
553    g_assert(rc == FALSE);
554    rc = GrabMatchesSecond(&b, &a, FALSE);
555    g_assert(rc == FALSE);
556
557    a.grabtype = GRABTYPE_CORE;
558    b.grabtype = GRABTYPE_CORE;
559    rc = GrabMatchesSecond(&a, &b, FALSE);
560    g_assert(rc == FALSE);
561    rc = GrabMatchesSecond(&b, &a, FALSE);
562    g_assert(rc == FALSE);
563
564    /* detail of AnyModifier must fail */
565    a.grabtype = GRABTYPE_XI2;
566    b.grabtype = GRABTYPE_XI2;
567    a.detail.exact = AnyModifier;
568    b.detail.exact = 1;
569    a.modifiersDetail.exact = 1;
570    b.modifiersDetail.exact = 1;
571    rc = GrabMatchesSecond(&a, &b, FALSE);
572    g_assert(rc == FALSE);
573    rc = GrabMatchesSecond(&b, &a, FALSE);
574    g_assert(rc == FALSE);
575
576    a.grabtype = GRABTYPE_CORE;
577    b.grabtype = GRABTYPE_CORE;
578    rc = GrabMatchesSecond(&a, &b, FALSE);
579    g_assert(rc == FALSE);
580    rc = GrabMatchesSecond(&b, &a, FALSE);
581    g_assert(rc == FALSE);
582
583    a.grabtype = GRABTYPE_XI;
584    b.grabtype = GRABTYPE_XI;
585    rc = GrabMatchesSecond(&a, &b, FALSE);
586    g_assert(rc == FALSE);
587    rc = GrabMatchesSecond(&b, &a, FALSE);
588    g_assert(rc == FALSE);
589
590    /* detail of XIAnyModifier must fail */
591    a.grabtype = GRABTYPE_XI2;
592    b.grabtype = GRABTYPE_XI2;
593    a.detail.exact = XIAnyModifier;
594    b.detail.exact = 1;
595    a.modifiersDetail.exact = 1;
596    b.modifiersDetail.exact = 1;
597    rc = GrabMatchesSecond(&a, &b, FALSE);
598    g_assert(rc == FALSE);
599    rc = GrabMatchesSecond(&b, &a, FALSE);
600    g_assert(rc == FALSE);
601
602    a.grabtype = GRABTYPE_CORE;
603    b.grabtype = GRABTYPE_CORE;
604    rc = GrabMatchesSecond(&a, &b, FALSE);
605    g_assert(rc == FALSE);
606    rc = GrabMatchesSecond(&b, &a, FALSE);
607    g_assert(rc == FALSE);
608
609    a.grabtype = GRABTYPE_XI;
610    b.grabtype = GRABTYPE_XI;
611    rc = GrabMatchesSecond(&a, &b, FALSE);
612    g_assert(rc == FALSE);
613    rc = GrabMatchesSecond(&b, &a, FALSE);
614    g_assert(rc == FALSE);
615
616    /* XIAnyModifier or AnyModifer must succeed */
617    a.grabtype = GRABTYPE_XI2;
618    b.grabtype = GRABTYPE_XI2;
619    a.detail.exact = 1;
620    b.detail.exact = 1;
621    a.modifiersDetail.exact = XIAnyModifier;
622    b.modifiersDetail.exact = 1;
623    rc = GrabMatchesSecond(&a, &b, FALSE);
624    g_assert(rc == TRUE);
625    rc = GrabMatchesSecond(&b, &a, FALSE);
626    g_assert(rc == TRUE);
627
628    a.grabtype = GRABTYPE_CORE;
629    b.grabtype = GRABTYPE_CORE;
630    a.detail.exact = 1;
631    b.detail.exact = 1;
632    a.modifiersDetail.exact = AnyModifier;
633    b.modifiersDetail.exact = 1;
634    rc = GrabMatchesSecond(&a, &b, FALSE);
635    g_assert(rc == TRUE);
636    rc = GrabMatchesSecond(&b, &a, FALSE);
637    g_assert(rc == TRUE);
638
639    a.grabtype = GRABTYPE_XI;
640    b.grabtype = GRABTYPE_XI;
641    a.detail.exact = 1;
642    b.detail.exact = 1;
643    a.modifiersDetail.exact = AnyModifier;
644    b.modifiersDetail.exact = 1;
645    rc = GrabMatchesSecond(&a, &b, FALSE);
646    g_assert(rc == TRUE);
647    rc = GrabMatchesSecond(&b, &a, FALSE);
648    g_assert(rc == TRUE);
649
650    /* AnyKey or XIAnyKeycode must succeed */
651    a.grabtype = GRABTYPE_XI2;
652    b.grabtype = GRABTYPE_XI2;
653    a.detail.exact = XIAnyKeycode;
654    b.detail.exact = 1;
655    a.modifiersDetail.exact = 1;
656    b.modifiersDetail.exact = 1;
657    rc = GrabMatchesSecond(&a, &b, FALSE);
658    g_assert(rc == TRUE);
659    rc = GrabMatchesSecond(&b, &a, FALSE);
660    g_assert(rc == TRUE);
661
662    a.grabtype = GRABTYPE_CORE;
663    b.grabtype = GRABTYPE_CORE;
664    a.detail.exact = AnyKey;
665    b.detail.exact = 1;
666    a.modifiersDetail.exact = 1;
667    b.modifiersDetail.exact = 1;
668    rc = GrabMatchesSecond(&a, &b, FALSE);
669    g_assert(rc == TRUE);
670    rc = GrabMatchesSecond(&b, &a, FALSE);
671    g_assert(rc == TRUE);
672
673    a.grabtype = GRABTYPE_XI;
674    b.grabtype = GRABTYPE_XI;
675    a.detail.exact = AnyKey;
676    b.detail.exact = 1;
677    a.modifiersDetail.exact = 1;
678    b.modifiersDetail.exact = 1;
679    rc = GrabMatchesSecond(&a, &b, FALSE);
680    g_assert(rc == TRUE);
681    rc = GrabMatchesSecond(&b, &a, FALSE);
682    g_assert(rc == TRUE);
683}
684
685static void test_bits_to_byte(int i)
686{
687        int expected_bytes;
688        expected_bytes = (i + 7)/8;
689
690        g_assert(bits_to_bytes(i) >= i/8);
691        g_assert((bits_to_bytes(i) * 8) - i <= 7);
692        g_assert(expected_bytes == bits_to_bytes(i));
693}
694
695static void test_bytes_to_int32(int i)
696{
697        int expected_4byte;
698        expected_4byte = (i + 3)/4;
699
700        g_assert(bytes_to_int32(i) <= i);
701        g_assert((bytes_to_int32(i) * 4) - i <= 3);
702        g_assert(expected_4byte == bytes_to_int32(i));
703}
704
705static void test_pad_to_int32(int i)
706{
707        int expected_bytes;
708        expected_bytes = ((i + 3)/4) * 4;
709
710        g_assert(pad_to_int32(i) >= i);
711        g_assert(pad_to_int32(i) - i <= 3);
712        g_assert(expected_bytes == pad_to_int32(i));
713}
714static void include_byte_padding_macros(void)
715{
716    g_test_message("Testing bits_to_bytes()");
717
718    /* the macros don't provide overflow protection */
719    test_bits_to_byte(0);
720    test_bits_to_byte(1);
721    test_bits_to_byte(2);
722    test_bits_to_byte(7);
723    test_bits_to_byte(8);
724    test_bits_to_byte(0xFF);
725    test_bits_to_byte(0x100);
726    test_bits_to_byte(INT_MAX - 9);
727    test_bits_to_byte(INT_MAX - 8);
728
729    g_test_message("Testing bytes_to_int32()");
730
731    test_bytes_to_int32(0);
732    test_bytes_to_int32(1);
733    test_bytes_to_int32(2);
734    test_bytes_to_int32(7);
735    test_bytes_to_int32(8);
736    test_bytes_to_int32(0xFF);
737    test_bytes_to_int32(0x100);
738    test_bytes_to_int32(0xFFFF);
739    test_bytes_to_int32(0x10000);
740    test_bytes_to_int32(0xFFFFFF);
741    test_bytes_to_int32(0x1000000);
742    test_bytes_to_int32(INT_MAX - 4);
743    test_bytes_to_int32(INT_MAX - 3);
744
745    g_test_message("Testing pad_to_int32");
746
747    test_pad_to_int32(0);
748    test_pad_to_int32(0);
749    test_pad_to_int32(1);
750    test_pad_to_int32(2);
751    test_pad_to_int32(7);
752    test_pad_to_int32(8);
753    test_pad_to_int32(0xFF);
754    test_pad_to_int32(0x100);
755    test_pad_to_int32(0xFFFF);
756    test_pad_to_int32(0x10000);
757    test_pad_to_int32(0xFFFFFF);
758    test_pad_to_int32(0x1000000);
759    test_pad_to_int32(INT_MAX - 4);
760    test_pad_to_int32(INT_MAX - 3);
761}
762
763static void xi_unregister_handlers(void)
764{
765    DeviceIntRec dev;
766    int handler;
767
768    memset(&dev, 0, sizeof(dev));
769
770    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
771    g_assert(handler == 1);
772    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
773    g_assert(handler == 2);
774    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
775    g_assert(handler == 3);
776
777    g_test_message("Unlinking from front.");
778
779    XIUnregisterPropertyHandler(&dev, 4); /* NOOP */
780    g_assert(dev.properties.handlers->id == 3);
781    XIUnregisterPropertyHandler(&dev, 3);
782    g_assert(dev.properties.handlers->id == 2);
783    XIUnregisterPropertyHandler(&dev, 2);
784    g_assert(dev.properties.handlers->id == 1);
785    XIUnregisterPropertyHandler(&dev, 1);
786    g_assert(dev.properties.handlers == NULL);
787
788    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
789    g_assert(handler == 4);
790    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
791    g_assert(handler == 5);
792    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
793    g_assert(handler == 6);
794    XIUnregisterPropertyHandler(&dev, 3); /* NOOP */
795    g_assert(dev.properties.handlers->next->next->next == NULL);
796    XIUnregisterPropertyHandler(&dev, 4);
797    g_assert(dev.properties.handlers->next->next == NULL);
798    XIUnregisterPropertyHandler(&dev, 5);
799    g_assert(dev.properties.handlers->next == NULL);
800    XIUnregisterPropertyHandler(&dev, 6);
801    g_assert(dev.properties.handlers == NULL);
802
803    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
804    g_assert(handler == 7);
805    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
806    g_assert(handler == 8);
807    handler = XIRegisterPropertyHandler(&dev, NULL, NULL, NULL);
808    g_assert(handler == 9);
809
810    XIDeleteAllDeviceProperties(&dev);
811    g_assert(dev.properties.handlers == NULL);
812    XIUnregisterPropertyHandler(&dev, 7); /* NOOP */
813
814}
815
816static void cmp_attr_fields(InputAttributes *attr1,
817                            InputAttributes *attr2)
818{
819    char **tags1, **tags2;
820
821    g_assert(attr1 && attr2);
822    g_assert(attr1 != attr2);
823    g_assert(attr1->flags == attr2->flags);
824
825    if (attr1->product != NULL)
826    {
827        g_assert(attr1->product != attr2->product);
828        g_assert(strcmp(attr1->product, attr2->product) == 0);
829    } else
830        g_assert(attr2->product == NULL);
831
832    if (attr1->vendor != NULL)
833    {
834        g_assert(attr1->vendor != attr2->vendor);
835        g_assert(strcmp(attr1->vendor, attr2->vendor) == 0);
836    } else
837        g_assert(attr2->vendor == NULL);
838
839    if (attr1->device != NULL)
840    {
841        g_assert(attr1->device != attr2->device);
842        g_assert(strcmp(attr1->device, attr2->device) == 0);
843    } else
844        g_assert(attr2->device == NULL);
845
846    if (attr1->pnp_id != NULL)
847    {
848        g_assert(attr1->pnp_id != attr2->pnp_id);
849        g_assert(strcmp(attr1->pnp_id, attr2->pnp_id) == 0);
850    } else
851        g_assert(attr2->pnp_id == NULL);
852
853    if (attr1->usb_id != NULL)
854    {
855        g_assert(attr1->usb_id != attr2->usb_id);
856        g_assert(strcmp(attr1->usb_id, attr2->usb_id) == 0);
857    } else
858        g_assert(attr2->usb_id == NULL);
859
860    tags1 = attr1->tags;
861    tags2 = attr2->tags;
862
863    /* if we don't have any tags, skip the tag checking bits */
864    if (!tags1)
865    {
866        g_assert(!tags2);
867        return;
868    }
869
870    /* Don't lug around empty arrays */
871    g_assert(*tags1);
872    g_assert(*tags2);
873
874    /* check for identical content, but duplicated */
875    while (*tags1)
876    {
877        g_assert(*tags1 != *tags2);
878        g_assert(strcmp(*tags1, *tags2) == 0);
879        tags1++;
880        tags2++;
881    }
882
883    /* ensure tags1 and tags2 have the same no of elements */
884    g_assert(!*tags2);
885
886    /* check for not sharing memory */
887    tags1 = attr1->tags;
888    while (*tags1)
889    {
890        tags2 = attr2->tags;
891        while (*tags2)
892            g_assert(*tags1 != *tags2++);
893
894        tags1++;
895    }
896}
897
898static void dix_input_attributes(void)
899{
900    InputAttributes orig = {0};
901    InputAttributes *new;
902    char *tags[4] = {"tag1", "tag2", "tag2", NULL};
903
904    new = DuplicateInputAttributes(NULL);
905    g_assert(!new);
906
907    new = DuplicateInputAttributes(&orig);
908    g_assert(memcmp(&orig, new, sizeof(InputAttributes)) == 0);
909
910    orig.product = "product name";
911    new = DuplicateInputAttributes(&orig);
912    cmp_attr_fields(&orig, new);
913    FreeInputAttributes(new);
914
915    orig.vendor = "vendor name";
916    new = DuplicateInputAttributes(&orig);
917    cmp_attr_fields(&orig, new);
918    FreeInputAttributes(new);
919
920    orig.device = "device path";
921    new = DuplicateInputAttributes(&orig);
922    cmp_attr_fields(&orig, new);
923    FreeInputAttributes(new);
924
925    orig.pnp_id = "PnPID";
926    new = DuplicateInputAttributes(&orig);
927    cmp_attr_fields(&orig, new);
928    FreeInputAttributes(new);
929
930    orig.usb_id = "USBID";
931    new = DuplicateInputAttributes(&orig);
932    cmp_attr_fields(&orig, new);
933    FreeInputAttributes(new);
934
935    orig.flags = 0xF0;
936    new = DuplicateInputAttributes(&orig);
937    cmp_attr_fields(&orig, new);
938    FreeInputAttributes(new);
939
940    orig.tags = tags;
941    new = DuplicateInputAttributes(&orig);
942    cmp_attr_fields(&orig, new);
943    FreeInputAttributes(new);
944}
945
946
947int main(int argc, char** argv)
948{
949    g_test_init(&argc, &argv,NULL);
950    g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
951
952    g_test_add_func("/dix/input/attributes", dix_input_attributes);
953    g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
954    g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
955    g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
956    g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
957    g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
958    g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
959    g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
960
961
962    return g_test_run();
963}
964