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 * *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 *  DEALINGS IN THE SOFTWARE.
21 */
22
23#ifdef HAVE_DIX_CONFIG_H
24#include <dix-config.h>
25#endif
26
27#include <stdint.h>
28#include <glib.h>
29
30#include "inputstr.h"
31#include "eventstr.h"
32#include "eventconvert.h"
33#include "exevents.h"
34#include <X11/extensions/XI2proto.h>
35
36
37static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
38                                   BOOL swap)
39{
40    int i;
41    unsigned char *ptr;
42    FP3232 *value, *raw_value;
43    int nvals = 0;
44    int bits_set;
45    int len;
46
47    if (swap)
48    {
49        char n;
50
51        swaps(&out->sequenceNumber, n);
52        swapl(&out->length, n);
53        swaps(&out->evtype, n);
54        swaps(&out->deviceid, n);
55        swapl(&out->time, n);
56        swapl(&out->detail, n);
57        swaps(&out->valuators_len, n);
58    }
59
60
61    g_assert(out->type == GenericEvent);
62    g_assert(out->extension == 0); /* IReqCode defaults to 0 */
63    g_assert(out->evtype == GetXI2Type((InternalEvent*)in));
64    g_assert(out->time == in->time);
65    g_assert(out->detail == in->detail.button);
66    g_assert(out->deviceid == in->deviceid);
67    g_assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(sizeof(in->valuators.mask))));
68    g_assert(out->flags == 0); /* FIXME: we don't set the flags yet */
69
70    ptr = (unsigned char*)&out[1];
71    bits_set = 0;
72
73    for (i = 0; out->valuators_len && i < sizeof(in->valuators.mask) * 8; i++)
74    {
75        g_assert (XIMaskIsSet(in->valuators.mask, i) == XIMaskIsSet(ptr, i));
76        if (XIMaskIsSet(in->valuators.mask, i))
77            bits_set++;
78    }
79
80    /* length is len of valuator mask (in 4-byte units) + the number of bits
81     * set. Each bit set represents 2 8-byte values, hence the
82     * 'bits_set * 4' */
83    len = out->valuators_len + bits_set * 4;
84    g_assert(out->length == len);
85
86    nvals = 0;
87
88    for (i = 0; out->valuators_len && i < MAX_VALUATORS; i++)
89    {
90        g_assert (XIMaskIsSet(in->valuators.mask, i) == XIMaskIsSet(ptr, i));
91        if (XIMaskIsSet(in->valuators.mask, i))
92        {
93            FP3232 vi, vo;
94            value = (FP3232*)(((unsigned char*)&out[1]) + out->valuators_len * 4);
95            value += nvals;
96
97            vi.integral = in->valuators.data[i];
98            vi.frac = in->valuators.data_frac[i];
99
100            vo.integral = value->integral;
101            vo.frac = value->frac;
102            if (swap)
103            {
104                char n;
105                swapl(&vo.integral, n);
106                swapl(&vo.frac, n);
107            }
108
109            g_assert(vi.integral == vo.integral);
110            g_assert(vi.frac == vo.frac);
111
112            raw_value = value + bits_set;
113
114            vi.integral = in->valuators.data_raw[i];
115            vi.frac = in->valuators.data_raw_frac[i];
116
117            vo.integral = raw_value->integral;
118            vo.frac = raw_value->frac;
119            if (swap)
120            {
121                char n;
122                swapl(&vo.integral, n);
123                swapl(&vo.frac, n);
124            }
125
126            g_assert(vi.integral == vo.integral);
127            g_assert(vi.frac == vo.frac);
128
129            nvals++;
130        }
131    }
132}
133
134static void test_XIRawEvent(RawDeviceEvent *in)
135{
136    xXIRawEvent *out, *swapped;
137    int rc;
138
139    rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
140    g_assert(rc == Success);
141
142    test_values_XIRawEvent(in, out, FALSE);
143
144    swapped = calloc(1, sizeof(xEvent) + out->length * 4);
145    XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
146    test_values_XIRawEvent(in, swapped, TRUE);
147
148    free(out);
149    free(swapped);
150}
151
152static void test_convert_XIFocusEvent(void)
153{
154    xEvent *out;
155    DeviceEvent in;
156    int rc;
157
158    in.header = ET_Internal;
159    in.type = ET_Enter;
160    rc = EventToXI2((InternalEvent*)&in, &out);
161    g_assert(rc == Success);
162    g_assert(out == NULL);
163
164    in.header = ET_Internal;
165    in.type = ET_FocusIn;
166    rc = EventToXI2((InternalEvent*)&in, &out);
167    g_assert(rc == Success);
168    g_assert(out == NULL);
169
170    in.header = ET_Internal;
171    in.type = ET_FocusOut;
172    rc = EventToXI2((InternalEvent*)&in, &out);
173    g_assert(rc == BadImplementation);
174
175    in.header = ET_Internal;
176    in.type = ET_Leave;
177    rc = EventToXI2((InternalEvent*)&in, &out);
178    g_assert(rc == BadImplementation);
179}
180
181
182static void test_convert_XIRawEvent(void)
183{
184    RawDeviceEvent in;
185    int i;
186
187    memset(&in, 0, sizeof(in));
188
189    g_test_message("Testing all event types");
190    in.header = ET_Internal;
191    in.type = ET_RawMotion;
192    test_XIRawEvent(&in);
193
194    in.header = ET_Internal;
195    in.type = ET_RawKeyPress;
196    test_XIRawEvent(&in);
197
198    in.header = ET_Internal;
199    in.type = ET_RawKeyRelease;
200    test_XIRawEvent(&in);
201
202    in.header = ET_Internal;
203    in.type = ET_RawButtonPress;
204    test_XIRawEvent(&in);
205
206    in.header = ET_Internal;
207    in.type = ET_RawButtonRelease;
208    test_XIRawEvent(&in);
209
210    g_test_message("Testing details and other fields");
211    in.detail.button = 1L;
212    test_XIRawEvent(&in);
213    in.detail.button = 1L << 8;
214    test_XIRawEvent(&in);
215    in.detail.button = 1L << 16;
216    test_XIRawEvent(&in);
217    in.detail.button = 1L << 24;
218    test_XIRawEvent(&in);
219    in.detail.button = ~0L;
220    test_XIRawEvent(&in);
221
222    in.detail.button = 0;
223
224    in.time = 1L;
225    test_XIRawEvent(&in);
226    in.time = 1L << 8;
227    test_XIRawEvent(&in);
228    in.time = 1L << 16;
229    test_XIRawEvent(&in);
230    in.time = 1L << 24;
231    test_XIRawEvent(&in);
232    in.time = ~0L;
233    test_XIRawEvent(&in);
234
235    in.deviceid = 1;
236    test_XIRawEvent(&in);
237    in.deviceid = 1 << 8;
238    test_XIRawEvent(&in);
239    in.deviceid = ~0 & 0xFF;
240    test_XIRawEvent(&in);
241
242    g_test_message("Testing valuator masks");
243    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
244    {
245        XISetMask(in.valuators.mask, i);
246        test_XIRawEvent(&in);
247        XIClearMask(in.valuators.mask, i);
248    }
249
250    for (i = 0; i < MAX_VALUATORS; i++)
251    {
252        XISetMask(in.valuators.mask, i);
253
254        in.valuators.data[i] = i;
255        in.valuators.data_raw[i] = i + 10;
256        in.valuators.data_frac[i] = i + 20;
257        in.valuators.data_raw_frac[i] = i + 30;
258        test_XIRawEvent(&in);
259        XIClearMask(in.valuators.mask, i);
260    }
261
262    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
263    {
264        XISetMask(in.valuators.mask, i);
265        test_XIRawEvent(&in);
266    }
267}
268
269static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
270                                      BOOL swap)
271{
272    int buttons, valuators;
273    int i;
274    unsigned char *ptr;
275    uint32_t flagmask = 0;
276    FP3232 *values;
277
278    if (swap) {
279        char n;
280
281        swaps(&out->sequenceNumber, n);
282        swapl(&out->length, n);
283        swaps(&out->evtype, n);
284        swaps(&out->deviceid, n);
285        swaps(&out->sourceid, n);
286        swapl(&out->time, n);
287        swapl(&out->detail, n);
288        swapl(&out->root, n);
289        swapl(&out->event, n);
290        swapl(&out->child, n);
291        swapl(&out->root_x, n);
292        swapl(&out->root_y, n);
293        swapl(&out->event_x, n);
294        swapl(&out->event_y, n);
295        swaps(&out->buttons_len, n);
296        swaps(&out->valuators_len, n);
297        swapl(&out->mods.base_mods, n);
298        swapl(&out->mods.latched_mods, n);
299        swapl(&out->mods.locked_mods, n);
300        swapl(&out->mods.effective_mods, n);
301        swapl(&out->flags, n);
302    }
303
304    g_assert(out->extension == 0); /* IReqCode defaults to 0 */
305    g_assert(out->evtype == GetXI2Type((InternalEvent*)in));
306    g_assert(out->time == in->time);
307    g_assert(out->detail == in->detail.button);
308    g_assert(out->length >= 12);
309
310    g_assert(out->deviceid == in->deviceid);
311    g_assert(out->sourceid == in->sourceid);
312
313    switch (in->type) {
314        case ET_KeyPress:
315            flagmask = XIKeyRepeat;
316            break;
317        default:
318            flagmask = 0;
319            break;
320    }
321    g_assert((out->flags & ~flagmask) == 0);
322
323    g_assert(out->root == in->root);
324    g_assert(out->event == None); /* set in FixUpEventFromWindow */
325    g_assert(out->child == None); /* set in FixUpEventFromWindow */
326
327    g_assert(out->mods.base_mods == in->mods.base);
328    g_assert(out->mods.latched_mods == in->mods.latched);
329    g_assert(out->mods.locked_mods == in->mods.locked);
330    g_assert(out->mods.effective_mods == in->mods.effective);
331
332    g_assert(out->group.base_group == in->group.base);
333    g_assert(out->group.latched_group == in->group.latched);
334    g_assert(out->group.locked_group == in->group.locked);
335    g_assert(out->group.effective_group == in->group.effective);
336
337    g_assert(out->event_x == 0); /* set in FixUpEventFromWindow */
338    g_assert(out->event_y == 0); /* set in FixUpEventFromWindow */
339
340    g_assert(out->root_x == FP1616(in->root_x, in->root_x_frac));
341    g_assert(out->root_y == FP1616(in->root_y, in->root_y_frac));
342
343    buttons = 0;
344    for (i = 0; i < bits_to_bytes(sizeof(in->buttons)); i++)
345    {
346        if (XIMaskIsSet(in->buttons, i))
347        {
348            g_assert(out->buttons_len >= bytes_to_int32(bits_to_bytes(i)));
349            buttons++;
350        }
351    }
352
353    ptr = (unsigned char*)&out[1];
354    for (i = 0; i < sizeof(in->buttons) * 8; i++)
355        g_assert(XIMaskIsSet(in->buttons, i) == XIMaskIsSet(ptr, i));
356
357
358    valuators = 0;
359    for (i = 0; i < sizeof(in->valuators.mask) * 8; i++)
360        if (XIMaskIsSet(in->valuators.mask, i))
361            valuators++;
362
363    g_assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(valuators)));
364
365    ptr += out->buttons_len * 4;
366    values = (FP3232*)(ptr + out->valuators_len * 4);
367    for (i = 0; i < sizeof(in->valuators.mask) * 8 ||
368                i < (out->valuators_len * 4) * 8; i++)
369    {
370        if (i > sizeof(in->valuators.mask) * 8)
371            g_assert(!XIMaskIsSet(ptr, i));
372        else if (i > out->valuators_len * 4 * 8)
373            g_assert(!XIMaskIsSet(in->valuators.mask, i));
374        else {
375            g_assert(XIMaskIsSet(in->valuators.mask, i) ==
376                     XIMaskIsSet(ptr, i));
377
378            if (XIMaskIsSet(ptr, i))
379            {
380                FP3232 vi, vo;
381
382                vi.integral = in->valuators.data[i];
383                vi.frac = in->valuators.data_frac[i];
384
385                vo = *values;
386
387                if (swap)
388                {
389                    char n;
390                    swapl(&vo.integral, n);
391                    swapl(&vo.frac, n);
392                }
393
394
395                g_assert(vi.integral == vo.integral);
396                g_assert(vi.frac == vo.frac);
397                values++;
398            }
399        }
400    }
401}
402
403static void test_XIDeviceEvent(DeviceEvent *in)
404{
405    xXIDeviceEvent *out, *swapped;
406    int rc;
407
408    rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
409    g_assert(rc == Success);
410
411    test_values_XIDeviceEvent(in, out, FALSE);
412
413    swapped = calloc(1, sizeof(xEvent) + out->length * 4);
414    XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
415    test_values_XIDeviceEvent(in, swapped, TRUE);
416
417    free(out);
418    free(swapped);
419}
420
421static void test_convert_XIDeviceEvent(void)
422{
423    DeviceEvent in;
424    int i;
425
426    memset(&in, 0, sizeof(in));
427
428    g_test_message("Testing simple field values");
429    in.header = ET_Internal;
430    in.type = ET_Motion;
431    in.length = sizeof(DeviceEvent);
432    in.time             = 0;
433    in.deviceid         = 1;
434    in.sourceid         = 2;
435    in.root             = 3;
436    in.root_x           = 4;
437    in.root_x_frac      = 5;
438    in.root_y           = 6;
439    in.root_y_frac      = 7;
440    in.detail.button    = 8;
441    in.mods.base        = 9;
442    in.mods.latched     = 10;
443    in.mods.locked      = 11;
444    in.mods.effective   = 11;
445    in.group.base       = 12;
446    in.group.latched    = 13;
447    in.group.locked     = 14;
448    in.group.effective  = 15;
449
450    test_XIDeviceEvent(&in);
451
452    g_test_message("Testing field ranges");
453    /* 32 bit */
454    in.detail.button = 1L;
455    test_XIDeviceEvent(&in);
456    in.detail.button = 1L << 8;
457    test_XIDeviceEvent(&in);
458    in.detail.button = 1L << 16;
459    test_XIDeviceEvent(&in);
460    in.detail.button = 1L << 24;
461    test_XIDeviceEvent(&in);
462    in.detail.button = ~0L;
463    test_XIDeviceEvent(&in);
464
465    /* 32 bit */
466    in.time = 1L;
467    test_XIDeviceEvent(&in);
468    in.time = 1L << 8;
469    test_XIDeviceEvent(&in);
470    in.time = 1L << 16;
471    test_XIDeviceEvent(&in);
472    in.time = 1L << 24;
473    test_XIDeviceEvent(&in);
474    in.time = ~0L;
475    test_XIDeviceEvent(&in);
476
477    /* 16 bit */
478    in.deviceid = 1;
479    test_XIDeviceEvent(&in);
480    in.deviceid = 1 << 8;
481    test_XIDeviceEvent(&in);
482    in.deviceid = ~0 & 0xFF;
483    test_XIDeviceEvent(&in);
484
485    /* 16 bit */
486    in.sourceid = 1;
487    test_XIDeviceEvent(&in);
488    in.deviceid = 1 << 8;
489    test_XIDeviceEvent(&in);
490    in.deviceid = ~0 & 0xFF;
491    test_XIDeviceEvent(&in);
492
493    /* 32 bit */
494    in.root = 1L;
495    test_XIDeviceEvent(&in);
496    in.root = 1L << 8;
497    test_XIDeviceEvent(&in);
498    in.root = 1L << 16;
499    test_XIDeviceEvent(&in);
500    in.root = 1L << 24;
501    test_XIDeviceEvent(&in);
502    in.root = ~0L;
503    test_XIDeviceEvent(&in);
504
505    /* 16 bit */
506    in.root_x = 1;
507    test_XIDeviceEvent(&in);
508    in.root_x = 1 << 8;
509    test_XIDeviceEvent(&in);
510    in.root_x = ~0 & 0xFF;
511    test_XIDeviceEvent(&in);
512
513    in.root_x_frac = 1;
514    test_XIDeviceEvent(&in);
515    in.root_x_frac = 1 << 8;
516    test_XIDeviceEvent(&in);
517    in.root_x_frac = ~0 & 0xFF;
518    test_XIDeviceEvent(&in);
519
520    in.root_y = 1;
521    test_XIDeviceEvent(&in);
522    in.root_y = 1 << 8;
523    test_XIDeviceEvent(&in);
524    in.root_y = ~0 & 0xFF;
525    test_XIDeviceEvent(&in);
526
527    in.root_y_frac = 1;
528    test_XIDeviceEvent(&in);
529    in.root_y_frac = 1 << 8;
530    test_XIDeviceEvent(&in);
531    in.root_y_frac = ~0 & 0xFF;
532    test_XIDeviceEvent(&in);
533
534    /* 32 bit */
535    in.mods.base = 1L;
536    test_XIDeviceEvent(&in);
537    in.mods.base = 1L << 8;
538    test_XIDeviceEvent(&in);
539    in.mods.base = 1L << 16;
540    test_XIDeviceEvent(&in);
541    in.mods.base = 1L << 24;
542    test_XIDeviceEvent(&in);
543    in.mods.base = ~0L;
544    test_XIDeviceEvent(&in);
545
546    in.mods.latched = 1L;
547    test_XIDeviceEvent(&in);
548    in.mods.latched = 1L << 8;
549    test_XIDeviceEvent(&in);
550    in.mods.latched = 1L << 16;
551    test_XIDeviceEvent(&in);
552    in.mods.latched = 1L << 24;
553    test_XIDeviceEvent(&in);
554    in.mods.latched = ~0L;
555    test_XIDeviceEvent(&in);
556
557    in.mods.locked = 1L;
558    test_XIDeviceEvent(&in);
559    in.mods.locked = 1L << 8;
560    test_XIDeviceEvent(&in);
561    in.mods.locked = 1L << 16;
562    test_XIDeviceEvent(&in);
563    in.mods.locked = 1L << 24;
564    test_XIDeviceEvent(&in);
565    in.mods.locked = ~0L;
566    test_XIDeviceEvent(&in);
567
568    in.mods.effective = 1L;
569    test_XIDeviceEvent(&in);
570    in.mods.effective = 1L << 8;
571    test_XIDeviceEvent(&in);
572    in.mods.effective = 1L << 16;
573    test_XIDeviceEvent(&in);
574    in.mods.effective = 1L << 24;
575    test_XIDeviceEvent(&in);
576    in.mods.effective = ~0L;
577    test_XIDeviceEvent(&in);
578
579    /* 8 bit */
580    in.group.base = 1;
581    test_XIDeviceEvent(&in);
582    in.group.base = ~0 & 0xFF;
583    test_XIDeviceEvent(&in);
584
585    in.group.latched = 1;
586    test_XIDeviceEvent(&in);
587    in.group.latched = ~0 & 0xFF;
588    test_XIDeviceEvent(&in);
589
590    in.group.locked = 1;
591    test_XIDeviceEvent(&in);
592    in.group.locked = ~0 & 0xFF;
593    test_XIDeviceEvent(&in);
594
595    in.mods.effective = 1;
596    test_XIDeviceEvent(&in);
597    in.mods.effective = ~0 & 0xFF;
598    test_XIDeviceEvent(&in);
599
600    g_test_message("Testing button masks");
601    for (i = 0; i < sizeof(in.buttons) * 8; i++)
602    {
603        XISetMask(in.buttons, i);
604        test_XIDeviceEvent(&in);
605        XIClearMask(in.buttons, i);
606    }
607
608    for (i = 0; i < sizeof(in.buttons) * 8; i++)
609    {
610        XISetMask(in.buttons, i);
611        test_XIDeviceEvent(&in);
612    }
613
614    g_test_message("Testing valuator masks");
615    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
616    {
617        XISetMask(in.valuators.mask, i);
618        test_XIDeviceEvent(&in);
619        XIClearMask(in.valuators.mask, i);
620    }
621
622    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
623    {
624        XISetMask(in.valuators.mask, i);
625
626        in.valuators.data[i] = i;
627        in.valuators.data_frac[i] = i + 20;
628        test_XIDeviceEvent(&in);
629        XIClearMask(in.valuators.mask, i);
630    }
631
632    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
633    {
634        XISetMask(in.valuators.mask, i);
635        test_XIDeviceEvent(&in);
636    }
637}
638
639static void test_values_XIDeviceChangedEvent(DeviceChangedEvent *in,
640                                             xXIDeviceChangedEvent *out,
641                                             BOOL swap)
642{
643    int i, j;
644    unsigned char *ptr;
645
646    if (swap)
647    {
648        char n;
649
650        swaps(&out->sequenceNumber, n);
651        swapl(&out->length, n);
652        swaps(&out->evtype, n);
653        swaps(&out->deviceid, n);
654        swaps(&out->sourceid, n);
655        swapl(&out->time, n);
656        swaps(&out->num_classes, n);
657    }
658
659    g_assert(out->type == GenericEvent);
660    g_assert(out->extension == 0); /* IReqCode defaults to 0 */
661    g_assert(out->evtype == GetXI2Type((InternalEvent*)in));
662    g_assert(out->time == in->time);
663    g_assert(out->deviceid == in->deviceid);
664    g_assert(out->sourceid == in->sourceid);
665
666    ptr = (unsigned char*)&out[1];
667    for (i = 0; i < out->num_classes; i++)
668    {
669        xXIAnyInfo* any = (xXIAnyInfo*)ptr;
670
671        if (swap)
672        {
673            char n;
674            swaps(&any->length, n);
675            swaps(&any->type, n);
676            swaps(&any->sourceid, n);
677        }
678
679        switch(any->type)
680        {
681            case XIButtonClass:
682                {
683                    xXIButtonInfo *b = (xXIButtonInfo*)any;
684                    Atom *names;
685
686                    if (swap)
687                    {
688                        char n;
689                        swaps(&b->num_buttons, n);
690                    }
691
692                    g_assert(b->length ==
693                            bytes_to_int32(sizeof(xXIButtonInfo)) +
694                            bytes_to_int32(bits_to_bytes(b->num_buttons)) +
695                            b->num_buttons);
696                    g_assert(b->num_buttons == in->buttons.num_buttons);
697
698                    names = (Atom*)((char*)&b[1] +
699                            pad_to_int32(bits_to_bytes(b->num_buttons)));
700                    for (j = 0; j < b->num_buttons; j++)
701                    {
702                        if (swap)
703                        {
704                            char n;
705                            swapl(&names[j], n);
706                        }
707                        g_assert(names[j] == in->buttons.names[j]);
708                    }
709                }
710                break;
711            case XIKeyClass:
712                {
713                    xXIKeyInfo *k = (xXIKeyInfo*)any;
714                    uint32_t *kc;
715
716                    if (swap)
717                    {
718                        char n;
719                        swaps(&k->num_keycodes, n);
720                    }
721
722                    g_assert(k->length ==
723                            bytes_to_int32(sizeof(xXIKeyInfo)) +
724                            k->num_keycodes);
725                    g_assert(k->num_keycodes == in->keys.max_keycode -
726                            in->keys.min_keycode + 1);
727
728                    kc = (uint32_t*)&k[1];
729                    for (j = 0; j < k->num_keycodes; j++)
730                    {
731                        if (swap)
732                        {
733                            char n;
734                            swapl(&kc[j], n);
735                        }
736                        g_assert(kc[j] >= in->keys.min_keycode);
737                        g_assert(kc[j] <= in->keys.max_keycode);
738                    }
739                }
740                break;
741            case XIValuatorClass:
742                {
743                    xXIValuatorInfo *v = (xXIValuatorInfo*)any;
744                    g_assert(v->length ==
745                             bytes_to_int32(sizeof(xXIValuatorInfo)));
746
747                }
748                break;
749            default:
750                g_error("Invalid class type.\n");
751                break;
752        }
753
754        ptr += any->length * 4;
755    }
756
757}
758
759static void test_XIDeviceChangedEvent(DeviceChangedEvent *in)
760{
761    xXIDeviceChangedEvent *out, *swapped;
762    int rc;
763
764    rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
765    g_assert(rc == Success);
766
767    test_values_XIDeviceChangedEvent(in, out, FALSE);
768
769    swapped = calloc(1, sizeof(xEvent) + out->length * 4);
770    XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
771    test_values_XIDeviceChangedEvent(in, swapped, TRUE);
772
773    free(out);
774    free(swapped);
775}
776
777static void test_convert_XIDeviceChangedEvent(void)
778{
779    DeviceChangedEvent in;
780    int i;
781
782    g_test_message("Testing simple field values");
783    memset(&in, 0, sizeof(in));
784    in.header = ET_Internal;
785    in.type = ET_DeviceChanged;
786    in.length = sizeof(DeviceChangedEvent);
787    in.time             = 0;
788    in.deviceid         = 1;
789    in.sourceid         = 2;
790    in.masterid         = 3;
791    in.num_valuators    = 4;
792    in.flags = DEVCHANGE_SLAVE_SWITCH | DEVCHANGE_POINTER_EVENT | DEVCHANGE_KEYBOARD_EVENT;
793
794    for (i = 0; i < MAX_BUTTONS; i++)
795        in.buttons.names[i] = i + 10;
796
797    in.keys.min_keycode = 8;
798    in.keys.max_keycode = 255;
799
800    test_XIDeviceChangedEvent(&in);
801
802    in.time = 1L;
803    test_XIDeviceChangedEvent(&in);
804    in.time = 1L << 8;
805    test_XIDeviceChangedEvent(&in);
806    in.time = 1L << 16;
807    test_XIDeviceChangedEvent(&in);
808    in.time = 1L << 24;
809    test_XIDeviceChangedEvent(&in);
810    in.time = ~0L;
811    test_XIDeviceChangedEvent(&in);
812
813    in.deviceid = 1L;
814    test_XIDeviceChangedEvent(&in);
815    in.deviceid = 1L << 8;
816    test_XIDeviceChangedEvent(&in);
817    in.deviceid = ~0 & 0xFFFF;
818    test_XIDeviceChangedEvent(&in);
819
820    in.sourceid = 1L;
821    test_XIDeviceChangedEvent(&in);
822    in.sourceid = 1L << 8;
823    test_XIDeviceChangedEvent(&in);
824    in.sourceid = ~0 & 0xFFFF;
825    test_XIDeviceChangedEvent(&in);
826
827    in.masterid = 1L;
828    test_XIDeviceChangedEvent(&in);
829    in.masterid = 1L << 8;
830    test_XIDeviceChangedEvent(&in);
831    in.masterid = ~0 & 0xFFFF;
832    test_XIDeviceChangedEvent(&in);
833
834    in.buttons.num_buttons = 0;
835    test_XIDeviceChangedEvent(&in);
836
837    in.buttons.num_buttons = 1;
838    test_XIDeviceChangedEvent(&in);
839
840    in.buttons.num_buttons = MAX_BUTTONS;
841    test_XIDeviceChangedEvent(&in);
842
843    in.keys.min_keycode = 0;
844    in.keys.max_keycode = 0;
845    test_XIDeviceChangedEvent(&in);
846
847    in.keys.max_keycode = 1 << 8;
848    test_XIDeviceChangedEvent(&in);
849
850    in.keys.max_keycode = 0xFFFC; /* highest range, above that the length
851                                     field gives up */
852    test_XIDeviceChangedEvent(&in);
853
854    in.keys.min_keycode = 1 << 8;
855    in.keys.max_keycode = 1 << 8;
856    test_XIDeviceChangedEvent(&in);
857
858    in.keys.min_keycode = 1 << 8;
859    in.keys.max_keycode = 0;
860    test_XIDeviceChangedEvent(&in);
861
862    in.num_valuators = 0;
863    test_XIDeviceChangedEvent(&in);
864
865    in.num_valuators = 1;
866    test_XIDeviceChangedEvent(&in);
867
868    in.num_valuators = MAX_VALUATORS;
869    test_XIDeviceChangedEvent(&in);
870
871    for (i = 0; i < MAX_VALUATORS; i++)
872    {
873        in.valuators[i].min = 0;
874        in.valuators[i].max = 0;
875        test_XIDeviceChangedEvent(&in);
876
877        in.valuators[i].max = 1 << 8;
878        test_XIDeviceChangedEvent(&in);
879        in.valuators[i].max = 1 << 16;
880        test_XIDeviceChangedEvent(&in);
881        in.valuators[i].max = 1 << 24;
882        test_XIDeviceChangedEvent(&in);
883        in.valuators[i].max = abs(~0);
884        test_XIDeviceChangedEvent(&in);
885
886        in.valuators[i].resolution = 1 << 8;
887        test_XIDeviceChangedEvent(&in);
888        in.valuators[i].resolution = 1 << 16;
889        test_XIDeviceChangedEvent(&in);
890        in.valuators[i].resolution = 1 << 24;
891        test_XIDeviceChangedEvent(&in);
892        in.valuators[i].resolution = abs(~0);
893        test_XIDeviceChangedEvent(&in);
894
895        in.valuators[i].name = i;
896        test_XIDeviceChangedEvent(&in);
897
898        in.valuators[i].mode = Relative;
899        test_XIDeviceChangedEvent(&in);
900
901        in.valuators[i].mode = Absolute;
902        test_XIDeviceChangedEvent(&in);
903    }
904}
905
906int main(int argc, char** argv)
907{
908    g_test_init(&argc, &argv,NULL);
909    g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
910
911    g_test_add_func("/xi2/eventconvert/XIRawEvent", test_convert_XIRawEvent);
912    g_test_add_func("/xi2/eventconvert/XIFocusEvent", test_convert_XIFocusEvent);
913    g_test_add_func("/xi2/eventconvert/XIDeviceEvent", test_convert_XIDeviceEvent);
914    g_test_add_func("/xi2/eventconvert/XIDeviceChangedEvent", test_convert_XIDeviceChangedEvent);
915
916    return g_test_run();
917}
918