protocol-eventconvert.c revision 6747b715
16747b715Smrg/**
26747b715Smrg * Copyright © 2009 Red Hat, Inc.
36747b715Smrg *
46747b715Smrg *  Permission is hereby granted, free of charge, to any person obtaining a
56747b715Smrg *  copy of this software and associated documentation files (the "Software"),
66747b715Smrg *  to deal in the Software without restriction, including without limitation
76747b715Smrg *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
86747b715Smrg *  and/or sell copies of the Software, and to permit persons to whom the
96747b715Smrg *  Software is furnished to do so, subject to the following conditions:
106747b715Smrg *
116747b715Smrg *  The above copyright notice and this permission notice (including the next
126747b715Smrg *  paragraph) shall be included in all copies or substantial portions of the
136747b715Smrg *  Software.
146747b715Smrg * *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
156747b715Smrg *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
166747b715Smrg *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
176747b715Smrg *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
186747b715Smrg *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
196747b715Smrg *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
206747b715Smrg *  DEALINGS IN THE SOFTWARE.
216747b715Smrg */
226747b715Smrg
236747b715Smrg#ifdef HAVE_DIX_CONFIG_H
246747b715Smrg#include <dix-config.h>
256747b715Smrg#endif
266747b715Smrg
276747b715Smrg#include <stdint.h>
286747b715Smrg#include <glib.h>
296747b715Smrg
306747b715Smrg#include "inputstr.h"
316747b715Smrg#include "eventstr.h"
326747b715Smrg#include "eventconvert.h"
336747b715Smrg#include "exevents.h"
346747b715Smrg#include <X11/extensions/XI2proto.h>
356747b715Smrg
366747b715Smrg
376747b715Smrgstatic void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
386747b715Smrg                                   BOOL swap)
396747b715Smrg{
406747b715Smrg    int i;
416747b715Smrg    unsigned char *ptr;
426747b715Smrg    FP3232 *value, *raw_value;
436747b715Smrg    int nvals = 0;
446747b715Smrg    int bits_set;
456747b715Smrg    int len;
466747b715Smrg
476747b715Smrg    if (swap)
486747b715Smrg    {
496747b715Smrg        char n;
506747b715Smrg
516747b715Smrg        swaps(&out->sequenceNumber, n);
526747b715Smrg        swapl(&out->length, n);
536747b715Smrg        swaps(&out->evtype, n);
546747b715Smrg        swaps(&out->deviceid, n);
556747b715Smrg        swapl(&out->time, n);
566747b715Smrg        swapl(&out->detail, n);
576747b715Smrg        swaps(&out->valuators_len, n);
586747b715Smrg    }
596747b715Smrg
606747b715Smrg
616747b715Smrg    g_assert(out->type == GenericEvent);
626747b715Smrg    g_assert(out->extension == 0); /* IReqCode defaults to 0 */
636747b715Smrg    g_assert(out->evtype == GetXI2Type((InternalEvent*)in));
646747b715Smrg    g_assert(out->time == in->time);
656747b715Smrg    g_assert(out->detail == in->detail.button);
666747b715Smrg    g_assert(out->deviceid == in->deviceid);
676747b715Smrg    g_assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(sizeof(in->valuators.mask))));
686747b715Smrg    g_assert(out->flags == 0); /* FIXME: we don't set the flags yet */
696747b715Smrg
706747b715Smrg    ptr = (unsigned char*)&out[1];
716747b715Smrg    bits_set = 0;
726747b715Smrg
736747b715Smrg    for (i = 0; out->valuators_len && i < sizeof(in->valuators.mask) * 8; i++)
746747b715Smrg    {
756747b715Smrg        g_assert (XIMaskIsSet(in->valuators.mask, i) == XIMaskIsSet(ptr, i));
766747b715Smrg        if (XIMaskIsSet(in->valuators.mask, i))
776747b715Smrg            bits_set++;
786747b715Smrg    }
796747b715Smrg
806747b715Smrg    /* length is len of valuator mask (in 4-byte units) + the number of bits
816747b715Smrg     * set. Each bit set represents 2 8-byte values, hence the
826747b715Smrg     * 'bits_set * 4' */
836747b715Smrg    len = out->valuators_len + bits_set * 4;
846747b715Smrg    g_assert(out->length == len);
856747b715Smrg
866747b715Smrg    nvals = 0;
876747b715Smrg
886747b715Smrg    for (i = 0; out->valuators_len && i < MAX_VALUATORS; i++)
896747b715Smrg    {
906747b715Smrg        g_assert (XIMaskIsSet(in->valuators.mask, i) == XIMaskIsSet(ptr, i));
916747b715Smrg        if (XIMaskIsSet(in->valuators.mask, i))
926747b715Smrg        {
936747b715Smrg            FP3232 vi, vo;
946747b715Smrg            value = (FP3232*)(((unsigned char*)&out[1]) + out->valuators_len * 4);
956747b715Smrg            value += nvals;
966747b715Smrg
976747b715Smrg            vi.integral = in->valuators.data[i];
986747b715Smrg            vi.frac = in->valuators.data_frac[i];
996747b715Smrg
1006747b715Smrg            vo.integral = value->integral;
1016747b715Smrg            vo.frac = value->frac;
1026747b715Smrg            if (swap)
1036747b715Smrg            {
1046747b715Smrg                char n;
1056747b715Smrg                swapl(&vo.integral, n);
1066747b715Smrg                swapl(&vo.frac, n);
1076747b715Smrg            }
1086747b715Smrg
1096747b715Smrg            g_assert(vi.integral == vo.integral);
1106747b715Smrg            g_assert(vi.frac == vo.frac);
1116747b715Smrg
1126747b715Smrg            raw_value = value + bits_set;
1136747b715Smrg
1146747b715Smrg            vi.integral = in->valuators.data_raw[i];
1156747b715Smrg            vi.frac = in->valuators.data_raw_frac[i];
1166747b715Smrg
1176747b715Smrg            vo.integral = raw_value->integral;
1186747b715Smrg            vo.frac = raw_value->frac;
1196747b715Smrg            if (swap)
1206747b715Smrg            {
1216747b715Smrg                char n;
1226747b715Smrg                swapl(&vo.integral, n);
1236747b715Smrg                swapl(&vo.frac, n);
1246747b715Smrg            }
1256747b715Smrg
1266747b715Smrg            g_assert(vi.integral == vo.integral);
1276747b715Smrg            g_assert(vi.frac == vo.frac);
1286747b715Smrg
1296747b715Smrg            nvals++;
1306747b715Smrg        }
1316747b715Smrg    }
1326747b715Smrg}
1336747b715Smrg
1346747b715Smrgstatic void test_XIRawEvent(RawDeviceEvent *in)
1356747b715Smrg{
1366747b715Smrg    xXIRawEvent *out, *swapped;
1376747b715Smrg    int rc;
1386747b715Smrg
1396747b715Smrg    rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
1406747b715Smrg    g_assert(rc == Success);
1416747b715Smrg
1426747b715Smrg    test_values_XIRawEvent(in, out, FALSE);
1436747b715Smrg
1446747b715Smrg    swapped = calloc(1, sizeof(xEvent) + out->length * 4);
1456747b715Smrg    XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
1466747b715Smrg    test_values_XIRawEvent(in, swapped, TRUE);
1476747b715Smrg
1486747b715Smrg    free(out);
1496747b715Smrg    free(swapped);
1506747b715Smrg}
1516747b715Smrg
1526747b715Smrgstatic void test_convert_XIFocusEvent(void)
1536747b715Smrg{
1546747b715Smrg    xEvent *out;
1556747b715Smrg    DeviceEvent in;
1566747b715Smrg    int rc;
1576747b715Smrg
1586747b715Smrg    in.header = ET_Internal;
1596747b715Smrg    in.type = ET_Enter;
1606747b715Smrg    rc = EventToXI2((InternalEvent*)&in, &out);
1616747b715Smrg    g_assert(rc == Success);
1626747b715Smrg    g_assert(out == NULL);
1636747b715Smrg
1646747b715Smrg    in.header = ET_Internal;
1656747b715Smrg    in.type = ET_FocusIn;
1666747b715Smrg    rc = EventToXI2((InternalEvent*)&in, &out);
1676747b715Smrg    g_assert(rc == Success);
1686747b715Smrg    g_assert(out == NULL);
1696747b715Smrg
1706747b715Smrg    in.header = ET_Internal;
1716747b715Smrg    in.type = ET_FocusOut;
1726747b715Smrg    rc = EventToXI2((InternalEvent*)&in, &out);
1736747b715Smrg    g_assert(rc == BadImplementation);
1746747b715Smrg
1756747b715Smrg    in.header = ET_Internal;
1766747b715Smrg    in.type = ET_Leave;
1776747b715Smrg    rc = EventToXI2((InternalEvent*)&in, &out);
1786747b715Smrg    g_assert(rc == BadImplementation);
1796747b715Smrg}
1806747b715Smrg
1816747b715Smrg
1826747b715Smrgstatic void test_convert_XIRawEvent(void)
1836747b715Smrg{
1846747b715Smrg    RawDeviceEvent in;
1856747b715Smrg    int i;
1866747b715Smrg
1876747b715Smrg    memset(&in, 0, sizeof(in));
1886747b715Smrg
1896747b715Smrg    g_test_message("Testing all event types");
1906747b715Smrg    in.header = ET_Internal;
1916747b715Smrg    in.type = ET_RawMotion;
1926747b715Smrg    test_XIRawEvent(&in);
1936747b715Smrg
1946747b715Smrg    in.header = ET_Internal;
1956747b715Smrg    in.type = ET_RawKeyPress;
1966747b715Smrg    test_XIRawEvent(&in);
1976747b715Smrg
1986747b715Smrg    in.header = ET_Internal;
1996747b715Smrg    in.type = ET_RawKeyRelease;
2006747b715Smrg    test_XIRawEvent(&in);
2016747b715Smrg
2026747b715Smrg    in.header = ET_Internal;
2036747b715Smrg    in.type = ET_RawButtonPress;
2046747b715Smrg    test_XIRawEvent(&in);
2056747b715Smrg
2066747b715Smrg    in.header = ET_Internal;
2076747b715Smrg    in.type = ET_RawButtonRelease;
2086747b715Smrg    test_XIRawEvent(&in);
2096747b715Smrg
2106747b715Smrg    g_test_message("Testing details and other fields");
2116747b715Smrg    in.detail.button = 1L;
2126747b715Smrg    test_XIRawEvent(&in);
2136747b715Smrg    in.detail.button = 1L << 8;
2146747b715Smrg    test_XIRawEvent(&in);
2156747b715Smrg    in.detail.button = 1L << 16;
2166747b715Smrg    test_XIRawEvent(&in);
2176747b715Smrg    in.detail.button = 1L << 24;
2186747b715Smrg    test_XIRawEvent(&in);
2196747b715Smrg    in.detail.button = ~0L;
2206747b715Smrg    test_XIRawEvent(&in);
2216747b715Smrg
2226747b715Smrg    in.detail.button = 0;
2236747b715Smrg
2246747b715Smrg    in.time = 1L;
2256747b715Smrg    test_XIRawEvent(&in);
2266747b715Smrg    in.time = 1L << 8;
2276747b715Smrg    test_XIRawEvent(&in);
2286747b715Smrg    in.time = 1L << 16;
2296747b715Smrg    test_XIRawEvent(&in);
2306747b715Smrg    in.time = 1L << 24;
2316747b715Smrg    test_XIRawEvent(&in);
2326747b715Smrg    in.time = ~0L;
2336747b715Smrg    test_XIRawEvent(&in);
2346747b715Smrg
2356747b715Smrg    in.deviceid = 1;
2366747b715Smrg    test_XIRawEvent(&in);
2376747b715Smrg    in.deviceid = 1 << 8;
2386747b715Smrg    test_XIRawEvent(&in);
2396747b715Smrg    in.deviceid = ~0 & 0xFF;
2406747b715Smrg    test_XIRawEvent(&in);
2416747b715Smrg
2426747b715Smrg    g_test_message("Testing valuator masks");
2436747b715Smrg    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
2446747b715Smrg    {
2456747b715Smrg        XISetMask(in.valuators.mask, i);
2466747b715Smrg        test_XIRawEvent(&in);
2476747b715Smrg        XIClearMask(in.valuators.mask, i);
2486747b715Smrg    }
2496747b715Smrg
2506747b715Smrg    for (i = 0; i < MAX_VALUATORS; i++)
2516747b715Smrg    {
2526747b715Smrg        XISetMask(in.valuators.mask, i);
2536747b715Smrg
2546747b715Smrg        in.valuators.data[i] = i;
2556747b715Smrg        in.valuators.data_raw[i] = i + 10;
2566747b715Smrg        in.valuators.data_frac[i] = i + 20;
2576747b715Smrg        in.valuators.data_raw_frac[i] = i + 30;
2586747b715Smrg        test_XIRawEvent(&in);
2596747b715Smrg        XIClearMask(in.valuators.mask, i);
2606747b715Smrg    }
2616747b715Smrg
2626747b715Smrg    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
2636747b715Smrg    {
2646747b715Smrg        XISetMask(in.valuators.mask, i);
2656747b715Smrg        test_XIRawEvent(&in);
2666747b715Smrg    }
2676747b715Smrg}
2686747b715Smrg
2696747b715Smrgstatic void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
2706747b715Smrg                                      BOOL swap)
2716747b715Smrg{
2726747b715Smrg    int buttons, valuators;
2736747b715Smrg    int i;
2746747b715Smrg    unsigned char *ptr;
2756747b715Smrg    FP3232 *values;
2766747b715Smrg
2776747b715Smrg    if (swap) {
2786747b715Smrg        char n;
2796747b715Smrg
2806747b715Smrg        swaps(&out->sequenceNumber, n);
2816747b715Smrg        swapl(&out->length, n);
2826747b715Smrg        swaps(&out->evtype, n);
2836747b715Smrg        swaps(&out->deviceid, n);
2846747b715Smrg        swaps(&out->sourceid, n);
2856747b715Smrg        swapl(&out->time, n);
2866747b715Smrg        swapl(&out->detail, n);
2876747b715Smrg        swapl(&out->root, n);
2886747b715Smrg        swapl(&out->event, n);
2896747b715Smrg        swapl(&out->child, n);
2906747b715Smrg        swapl(&out->root_x, n);
2916747b715Smrg        swapl(&out->root_y, n);
2926747b715Smrg        swapl(&out->event_x, n);
2936747b715Smrg        swapl(&out->event_y, n);
2946747b715Smrg        swaps(&out->buttons_len, n);
2956747b715Smrg        swaps(&out->valuators_len, n);
2966747b715Smrg        swapl(&out->mods.base_mods, n);
2976747b715Smrg        swapl(&out->mods.latched_mods, n);
2986747b715Smrg        swapl(&out->mods.locked_mods, n);
2996747b715Smrg        swapl(&out->mods.effective_mods, n);
3006747b715Smrg    }
3016747b715Smrg
3026747b715Smrg    g_assert(out->extension == 0); /* IReqCode defaults to 0 */
3036747b715Smrg    g_assert(out->evtype == GetXI2Type((InternalEvent*)in));
3046747b715Smrg    g_assert(out->time == in->time);
3056747b715Smrg    g_assert(out->detail == in->detail.button);
3066747b715Smrg    g_assert(out->length >= 12);
3076747b715Smrg
3086747b715Smrg    g_assert(out->deviceid == in->deviceid);
3096747b715Smrg    g_assert(out->sourceid == in->sourceid);
3106747b715Smrg
3116747b715Smrg    g_assert(out->flags == 0); /* FIXME: we don't set the flags yet */
3126747b715Smrg
3136747b715Smrg    g_assert(out->root == in->root);
3146747b715Smrg    g_assert(out->event == None); /* set in FixUpEventFromWindow */
3156747b715Smrg    g_assert(out->child == None); /* set in FixUpEventFromWindow */
3166747b715Smrg
3176747b715Smrg    g_assert(out->mods.base_mods == in->mods.base);
3186747b715Smrg    g_assert(out->mods.latched_mods == in->mods.latched);
3196747b715Smrg    g_assert(out->mods.locked_mods == in->mods.locked);
3206747b715Smrg    g_assert(out->mods.effective_mods == in->mods.effective);
3216747b715Smrg
3226747b715Smrg    g_assert(out->group.base_group == in->group.base);
3236747b715Smrg    g_assert(out->group.latched_group == in->group.latched);
3246747b715Smrg    g_assert(out->group.locked_group == in->group.locked);
3256747b715Smrg    g_assert(out->group.effective_group == in->group.effective);
3266747b715Smrg
3276747b715Smrg    g_assert(out->event_x == 0); /* set in FixUpEventFromWindow */
3286747b715Smrg    g_assert(out->event_y == 0); /* set in FixUpEventFromWindow */
3296747b715Smrg
3306747b715Smrg    g_assert(out->root_x == FP1616(in->root_x, in->root_x_frac));
3316747b715Smrg    g_assert(out->root_y == FP1616(in->root_y, in->root_y_frac));
3326747b715Smrg
3336747b715Smrg    buttons = 0;
3346747b715Smrg    for (i = 0; i < bits_to_bytes(sizeof(in->buttons)); i++)
3356747b715Smrg    {
3366747b715Smrg        if (XIMaskIsSet(in->buttons, i))
3376747b715Smrg        {
3386747b715Smrg            g_assert(out->buttons_len >= bytes_to_int32(bits_to_bytes(i)));
3396747b715Smrg            buttons++;
3406747b715Smrg        }
3416747b715Smrg    }
3426747b715Smrg
3436747b715Smrg    ptr = (unsigned char*)&out[1];
3446747b715Smrg    for (i = 0; i < sizeof(in->buttons) * 8; i++)
3456747b715Smrg        g_assert(XIMaskIsSet(in->buttons, i) == XIMaskIsSet(ptr, i));
3466747b715Smrg
3476747b715Smrg
3486747b715Smrg    valuators = 0;
3496747b715Smrg    for (i = 0; i < sizeof(in->valuators.mask) * 8; i++)
3506747b715Smrg        if (XIMaskIsSet(in->valuators.mask, i))
3516747b715Smrg            valuators++;
3526747b715Smrg
3536747b715Smrg    g_assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(valuators)));
3546747b715Smrg
3556747b715Smrg    ptr += out->buttons_len * 4;
3566747b715Smrg    values = (FP3232*)(ptr + out->valuators_len * 4);
3576747b715Smrg    for (i = 0; i < sizeof(in->valuators.mask) * 8 ||
3586747b715Smrg                i < (out->valuators_len * 4) * 8; i++)
3596747b715Smrg    {
3606747b715Smrg        if (i > sizeof(in->valuators.mask) * 8)
3616747b715Smrg            g_assert(!XIMaskIsSet(ptr, i));
3626747b715Smrg        else if (i > out->valuators_len * 4 * 8)
3636747b715Smrg            g_assert(!XIMaskIsSet(in->valuators.mask, i));
3646747b715Smrg        else {
3656747b715Smrg            g_assert(XIMaskIsSet(in->valuators.mask, i) ==
3666747b715Smrg                     XIMaskIsSet(ptr, i));
3676747b715Smrg
3686747b715Smrg            if (XIMaskIsSet(ptr, i))
3696747b715Smrg            {
3706747b715Smrg                FP3232 vi, vo;
3716747b715Smrg
3726747b715Smrg                vi.integral = in->valuators.data[i];
3736747b715Smrg                vi.frac = in->valuators.data_frac[i];
3746747b715Smrg
3756747b715Smrg                vo = *values;
3766747b715Smrg
3776747b715Smrg                if (swap)
3786747b715Smrg                {
3796747b715Smrg                    char n;
3806747b715Smrg                    swapl(&vo.integral, n);
3816747b715Smrg                    swapl(&vo.frac, n);
3826747b715Smrg                }
3836747b715Smrg
3846747b715Smrg
3856747b715Smrg                g_assert(vi.integral == vo.integral);
3866747b715Smrg                g_assert(vi.frac == vo.frac);
3876747b715Smrg                values++;
3886747b715Smrg            }
3896747b715Smrg        }
3906747b715Smrg    }
3916747b715Smrg}
3926747b715Smrg
3936747b715Smrgstatic void test_XIDeviceEvent(DeviceEvent *in)
3946747b715Smrg{
3956747b715Smrg    xXIDeviceEvent *out, *swapped;
3966747b715Smrg    int rc;
3976747b715Smrg
3986747b715Smrg    rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
3996747b715Smrg    g_assert(rc == Success);
4006747b715Smrg
4016747b715Smrg    test_values_XIDeviceEvent(in, out, FALSE);
4026747b715Smrg
4036747b715Smrg    swapped = calloc(1, sizeof(xEvent) + out->length * 4);
4046747b715Smrg    XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
4056747b715Smrg    test_values_XIDeviceEvent(in, swapped, TRUE);
4066747b715Smrg
4076747b715Smrg    free(out);
4086747b715Smrg    free(swapped);
4096747b715Smrg}
4106747b715Smrg
4116747b715Smrgstatic void test_convert_XIDeviceEvent(void)
4126747b715Smrg{
4136747b715Smrg    DeviceEvent in;
4146747b715Smrg    int i;
4156747b715Smrg
4166747b715Smrg    memset(&in, 0, sizeof(in));
4176747b715Smrg
4186747b715Smrg    g_test_message("Testing simple field values");
4196747b715Smrg    in.header = ET_Internal;
4206747b715Smrg    in.type = ET_Motion;
4216747b715Smrg    in.length = sizeof(DeviceEvent);
4226747b715Smrg    in.time             = 0;
4236747b715Smrg    in.deviceid         = 1;
4246747b715Smrg    in.sourceid         = 2;
4256747b715Smrg    in.root             = 3;
4266747b715Smrg    in.root_x           = 4;
4276747b715Smrg    in.root_x_frac      = 5;
4286747b715Smrg    in.root_y           = 6;
4296747b715Smrg    in.root_y_frac      = 7;
4306747b715Smrg    in.detail.button    = 8;
4316747b715Smrg    in.mods.base        = 9;
4326747b715Smrg    in.mods.latched     = 10;
4336747b715Smrg    in.mods.locked      = 11;
4346747b715Smrg    in.mods.effective   = 11;
4356747b715Smrg    in.group.base       = 12;
4366747b715Smrg    in.group.latched    = 13;
4376747b715Smrg    in.group.locked     = 14;
4386747b715Smrg    in.group.effective  = 15;
4396747b715Smrg
4406747b715Smrg    test_XIDeviceEvent(&in);
4416747b715Smrg
4426747b715Smrg    g_test_message("Testing field ranges");
4436747b715Smrg    /* 32 bit */
4446747b715Smrg    in.detail.button = 1L;
4456747b715Smrg    test_XIDeviceEvent(&in);
4466747b715Smrg    in.detail.button = 1L << 8;
4476747b715Smrg    test_XIDeviceEvent(&in);
4486747b715Smrg    in.detail.button = 1L << 16;
4496747b715Smrg    test_XIDeviceEvent(&in);
4506747b715Smrg    in.detail.button = 1L << 24;
4516747b715Smrg    test_XIDeviceEvent(&in);
4526747b715Smrg    in.detail.button = ~0L;
4536747b715Smrg    test_XIDeviceEvent(&in);
4546747b715Smrg
4556747b715Smrg    /* 32 bit */
4566747b715Smrg    in.time = 1L;
4576747b715Smrg    test_XIDeviceEvent(&in);
4586747b715Smrg    in.time = 1L << 8;
4596747b715Smrg    test_XIDeviceEvent(&in);
4606747b715Smrg    in.time = 1L << 16;
4616747b715Smrg    test_XIDeviceEvent(&in);
4626747b715Smrg    in.time = 1L << 24;
4636747b715Smrg    test_XIDeviceEvent(&in);
4646747b715Smrg    in.time = ~0L;
4656747b715Smrg    test_XIDeviceEvent(&in);
4666747b715Smrg
4676747b715Smrg    /* 16 bit */
4686747b715Smrg    in.deviceid = 1;
4696747b715Smrg    test_XIDeviceEvent(&in);
4706747b715Smrg    in.deviceid = 1 << 8;
4716747b715Smrg    test_XIDeviceEvent(&in);
4726747b715Smrg    in.deviceid = ~0 & 0xFF;
4736747b715Smrg    test_XIDeviceEvent(&in);
4746747b715Smrg
4756747b715Smrg    /* 16 bit */
4766747b715Smrg    in.sourceid = 1;
4776747b715Smrg    test_XIDeviceEvent(&in);
4786747b715Smrg    in.deviceid = 1 << 8;
4796747b715Smrg    test_XIDeviceEvent(&in);
4806747b715Smrg    in.deviceid = ~0 & 0xFF;
4816747b715Smrg    test_XIDeviceEvent(&in);
4826747b715Smrg
4836747b715Smrg    /* 32 bit */
4846747b715Smrg    in.root = 1L;
4856747b715Smrg    test_XIDeviceEvent(&in);
4866747b715Smrg    in.root = 1L << 8;
4876747b715Smrg    test_XIDeviceEvent(&in);
4886747b715Smrg    in.root = 1L << 16;
4896747b715Smrg    test_XIDeviceEvent(&in);
4906747b715Smrg    in.root = 1L << 24;
4916747b715Smrg    test_XIDeviceEvent(&in);
4926747b715Smrg    in.root = ~0L;
4936747b715Smrg    test_XIDeviceEvent(&in);
4946747b715Smrg
4956747b715Smrg    /* 16 bit */
4966747b715Smrg    in.root_x = 1;
4976747b715Smrg    test_XIDeviceEvent(&in);
4986747b715Smrg    in.root_x = 1 << 8;
4996747b715Smrg    test_XIDeviceEvent(&in);
5006747b715Smrg    in.root_x = ~0 & 0xFF;
5016747b715Smrg    test_XIDeviceEvent(&in);
5026747b715Smrg
5036747b715Smrg    in.root_x_frac = 1;
5046747b715Smrg    test_XIDeviceEvent(&in);
5056747b715Smrg    in.root_x_frac = 1 << 8;
5066747b715Smrg    test_XIDeviceEvent(&in);
5076747b715Smrg    in.root_x_frac = ~0 & 0xFF;
5086747b715Smrg    test_XIDeviceEvent(&in);
5096747b715Smrg
5106747b715Smrg    in.root_y = 1;
5116747b715Smrg    test_XIDeviceEvent(&in);
5126747b715Smrg    in.root_y = 1 << 8;
5136747b715Smrg    test_XIDeviceEvent(&in);
5146747b715Smrg    in.root_y = ~0 & 0xFF;
5156747b715Smrg    test_XIDeviceEvent(&in);
5166747b715Smrg
5176747b715Smrg    in.root_y_frac = 1;
5186747b715Smrg    test_XIDeviceEvent(&in);
5196747b715Smrg    in.root_y_frac = 1 << 8;
5206747b715Smrg    test_XIDeviceEvent(&in);
5216747b715Smrg    in.root_y_frac = ~0 & 0xFF;
5226747b715Smrg    test_XIDeviceEvent(&in);
5236747b715Smrg
5246747b715Smrg    /* 32 bit */
5256747b715Smrg    in.mods.base = 1L;
5266747b715Smrg    test_XIDeviceEvent(&in);
5276747b715Smrg    in.mods.base = 1L << 8;
5286747b715Smrg    test_XIDeviceEvent(&in);
5296747b715Smrg    in.mods.base = 1L << 16;
5306747b715Smrg    test_XIDeviceEvent(&in);
5316747b715Smrg    in.mods.base = 1L << 24;
5326747b715Smrg    test_XIDeviceEvent(&in);
5336747b715Smrg    in.mods.base = ~0L;
5346747b715Smrg    test_XIDeviceEvent(&in);
5356747b715Smrg
5366747b715Smrg    in.mods.latched = 1L;
5376747b715Smrg    test_XIDeviceEvent(&in);
5386747b715Smrg    in.mods.latched = 1L << 8;
5396747b715Smrg    test_XIDeviceEvent(&in);
5406747b715Smrg    in.mods.latched = 1L << 16;
5416747b715Smrg    test_XIDeviceEvent(&in);
5426747b715Smrg    in.mods.latched = 1L << 24;
5436747b715Smrg    test_XIDeviceEvent(&in);
5446747b715Smrg    in.mods.latched = ~0L;
5456747b715Smrg    test_XIDeviceEvent(&in);
5466747b715Smrg
5476747b715Smrg    in.mods.locked = 1L;
5486747b715Smrg    test_XIDeviceEvent(&in);
5496747b715Smrg    in.mods.locked = 1L << 8;
5506747b715Smrg    test_XIDeviceEvent(&in);
5516747b715Smrg    in.mods.locked = 1L << 16;
5526747b715Smrg    test_XIDeviceEvent(&in);
5536747b715Smrg    in.mods.locked = 1L << 24;
5546747b715Smrg    test_XIDeviceEvent(&in);
5556747b715Smrg    in.mods.locked = ~0L;
5566747b715Smrg    test_XIDeviceEvent(&in);
5576747b715Smrg
5586747b715Smrg    in.mods.effective = 1L;
5596747b715Smrg    test_XIDeviceEvent(&in);
5606747b715Smrg    in.mods.effective = 1L << 8;
5616747b715Smrg    test_XIDeviceEvent(&in);
5626747b715Smrg    in.mods.effective = 1L << 16;
5636747b715Smrg    test_XIDeviceEvent(&in);
5646747b715Smrg    in.mods.effective = 1L << 24;
5656747b715Smrg    test_XIDeviceEvent(&in);
5666747b715Smrg    in.mods.effective = ~0L;
5676747b715Smrg    test_XIDeviceEvent(&in);
5686747b715Smrg
5696747b715Smrg    /* 8 bit */
5706747b715Smrg    in.group.base = 1;
5716747b715Smrg    test_XIDeviceEvent(&in);
5726747b715Smrg    in.group.base = ~0 & 0xFF;
5736747b715Smrg    test_XIDeviceEvent(&in);
5746747b715Smrg
5756747b715Smrg    in.group.latched = 1;
5766747b715Smrg    test_XIDeviceEvent(&in);
5776747b715Smrg    in.group.latched = ~0 & 0xFF;
5786747b715Smrg    test_XIDeviceEvent(&in);
5796747b715Smrg
5806747b715Smrg    in.group.locked = 1;
5816747b715Smrg    test_XIDeviceEvent(&in);
5826747b715Smrg    in.group.locked = ~0 & 0xFF;
5836747b715Smrg    test_XIDeviceEvent(&in);
5846747b715Smrg
5856747b715Smrg    in.mods.effective = 1;
5866747b715Smrg    test_XIDeviceEvent(&in);
5876747b715Smrg    in.mods.effective = ~0 & 0xFF;
5886747b715Smrg    test_XIDeviceEvent(&in);
5896747b715Smrg
5906747b715Smrg    g_test_message("Testing button masks");
5916747b715Smrg    for (i = 0; i < sizeof(in.buttons) * 8; i++)
5926747b715Smrg    {
5936747b715Smrg        XISetMask(in.buttons, i);
5946747b715Smrg        test_XIDeviceEvent(&in);
5956747b715Smrg        XIClearMask(in.buttons, i);
5966747b715Smrg    }
5976747b715Smrg
5986747b715Smrg    for (i = 0; i < sizeof(in.buttons) * 8; i++)
5996747b715Smrg    {
6006747b715Smrg        XISetMask(in.buttons, i);
6016747b715Smrg        test_XIDeviceEvent(&in);
6026747b715Smrg    }
6036747b715Smrg
6046747b715Smrg    g_test_message("Testing valuator masks");
6056747b715Smrg    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
6066747b715Smrg    {
6076747b715Smrg        XISetMask(in.valuators.mask, i);
6086747b715Smrg        test_XIDeviceEvent(&in);
6096747b715Smrg        XIClearMask(in.valuators.mask, i);
6106747b715Smrg    }
6116747b715Smrg
6126747b715Smrg    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
6136747b715Smrg    {
6146747b715Smrg        XISetMask(in.valuators.mask, i);
6156747b715Smrg
6166747b715Smrg        in.valuators.data[i] = i;
6176747b715Smrg        in.valuators.data_frac[i] = i + 20;
6186747b715Smrg        test_XIDeviceEvent(&in);
6196747b715Smrg        XIClearMask(in.valuators.mask, i);
6206747b715Smrg    }
6216747b715Smrg
6226747b715Smrg    for (i = 0; i < sizeof(in.valuators.mask) * 8; i++)
6236747b715Smrg    {
6246747b715Smrg        XISetMask(in.valuators.mask, i);
6256747b715Smrg        test_XIDeviceEvent(&in);
6266747b715Smrg    }
6276747b715Smrg}
6286747b715Smrg
6296747b715Smrgstatic void test_values_XIDeviceChangedEvent(DeviceChangedEvent *in,
6306747b715Smrg                                             xXIDeviceChangedEvent *out,
6316747b715Smrg                                             BOOL swap)
6326747b715Smrg{
6336747b715Smrg    int i, j;
6346747b715Smrg    unsigned char *ptr;
6356747b715Smrg
6366747b715Smrg    if (swap)
6376747b715Smrg    {
6386747b715Smrg        char n;
6396747b715Smrg
6406747b715Smrg        swaps(&out->sequenceNumber, n);
6416747b715Smrg        swapl(&out->length, n);
6426747b715Smrg        swaps(&out->evtype, n);
6436747b715Smrg        swaps(&out->deviceid, n);
6446747b715Smrg        swaps(&out->sourceid, n);
6456747b715Smrg        swapl(&out->time, n);
6466747b715Smrg        swaps(&out->num_classes, n);
6476747b715Smrg    }
6486747b715Smrg
6496747b715Smrg    g_assert(out->type == GenericEvent);
6506747b715Smrg    g_assert(out->extension == 0); /* IReqCode defaults to 0 */
6516747b715Smrg    g_assert(out->evtype == GetXI2Type((InternalEvent*)in));
6526747b715Smrg    g_assert(out->time == in->time);
6536747b715Smrg    g_assert(out->deviceid == in->deviceid);
6546747b715Smrg    g_assert(out->sourceid == in->sourceid);
6556747b715Smrg
6566747b715Smrg    ptr = (unsigned char*)&out[1];
6576747b715Smrg    for (i = 0; i < out->num_classes; i++)
6586747b715Smrg    {
6596747b715Smrg        xXIAnyInfo* any = (xXIAnyInfo*)ptr;
6606747b715Smrg
6616747b715Smrg        if (swap)
6626747b715Smrg        {
6636747b715Smrg            char n;
6646747b715Smrg            swaps(&any->length, n);
6656747b715Smrg            swaps(&any->type, n);
6666747b715Smrg            swaps(&any->sourceid, n);
6676747b715Smrg        }
6686747b715Smrg
6696747b715Smrg        switch(any->type)
6706747b715Smrg        {
6716747b715Smrg            case XIButtonClass:
6726747b715Smrg                {
6736747b715Smrg                    xXIButtonInfo *b = (xXIButtonInfo*)any;
6746747b715Smrg                    Atom *names;
6756747b715Smrg
6766747b715Smrg                    if (swap)
6776747b715Smrg                    {
6786747b715Smrg                        char n;
6796747b715Smrg                        swaps(&b->num_buttons, n);
6806747b715Smrg                    }
6816747b715Smrg
6826747b715Smrg                    g_assert(b->length ==
6836747b715Smrg                            bytes_to_int32(sizeof(xXIButtonInfo)) +
6846747b715Smrg                            bytes_to_int32(bits_to_bytes(b->num_buttons)) +
6856747b715Smrg                            b->num_buttons);
6866747b715Smrg                    g_assert(b->num_buttons == in->buttons.num_buttons);
6876747b715Smrg
6886747b715Smrg                    names = (Atom*)((char*)&b[1] +
6896747b715Smrg                            pad_to_int32(bits_to_bytes(b->num_buttons)));
6906747b715Smrg                    for (j = 0; j < b->num_buttons; j++)
6916747b715Smrg                    {
6926747b715Smrg                        if (swap)
6936747b715Smrg                        {
6946747b715Smrg                            char n;
6956747b715Smrg                            swapl(&names[j], n);
6966747b715Smrg                        }
6976747b715Smrg                        g_assert(names[j] == in->buttons.names[j]);
6986747b715Smrg                    }
6996747b715Smrg                }
7006747b715Smrg                break;
7016747b715Smrg            case XIKeyClass:
7026747b715Smrg                {
7036747b715Smrg                    xXIKeyInfo *k = (xXIKeyInfo*)any;
7046747b715Smrg                    uint32_t *kc;
7056747b715Smrg
7066747b715Smrg                    if (swap)
7076747b715Smrg                    {
7086747b715Smrg                        char n;
7096747b715Smrg                        swaps(&k->num_keycodes, n);
7106747b715Smrg                    }
7116747b715Smrg
7126747b715Smrg                    g_assert(k->length ==
7136747b715Smrg                            bytes_to_int32(sizeof(xXIKeyInfo)) +
7146747b715Smrg                            k->num_keycodes);
7156747b715Smrg                    g_assert(k->num_keycodes == in->keys.max_keycode -
7166747b715Smrg                            in->keys.min_keycode + 1);
7176747b715Smrg
7186747b715Smrg                    kc = (uint32_t*)&k[1];
7196747b715Smrg                    for (j = 0; j < k->num_keycodes; j++)
7206747b715Smrg                    {
7216747b715Smrg                        if (swap)
7226747b715Smrg                        {
7236747b715Smrg                            char n;
7246747b715Smrg                            swapl(&kc[j], n);
7256747b715Smrg                        }
7266747b715Smrg                        g_assert(kc[j] >= in->keys.min_keycode);
7276747b715Smrg                        g_assert(kc[j] <= in->keys.max_keycode);
7286747b715Smrg                    }
7296747b715Smrg                }
7306747b715Smrg                break;
7316747b715Smrg            case XIValuatorClass:
7326747b715Smrg                {
7336747b715Smrg                    xXIValuatorInfo *v = (xXIValuatorInfo*)any;
7346747b715Smrg                    g_assert(v->length ==
7356747b715Smrg                             bytes_to_int32(sizeof(xXIValuatorInfo)));
7366747b715Smrg
7376747b715Smrg                }
7386747b715Smrg                break;
7396747b715Smrg            default:
7406747b715Smrg                g_error("Invalid class type.\n");
7416747b715Smrg                break;
7426747b715Smrg        }
7436747b715Smrg
7446747b715Smrg        ptr += any->length * 4;
7456747b715Smrg    }
7466747b715Smrg
7476747b715Smrg}
7486747b715Smrg
7496747b715Smrgstatic void test_XIDeviceChangedEvent(DeviceChangedEvent *in)
7506747b715Smrg{
7516747b715Smrg    xXIDeviceChangedEvent *out, *swapped;
7526747b715Smrg    int rc;
7536747b715Smrg
7546747b715Smrg    rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
7556747b715Smrg    g_assert(rc == Success);
7566747b715Smrg
7576747b715Smrg    test_values_XIDeviceChangedEvent(in, out, FALSE);
7586747b715Smrg
7596747b715Smrg    swapped = calloc(1, sizeof(xEvent) + out->length * 4);
7606747b715Smrg    XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
7616747b715Smrg    test_values_XIDeviceChangedEvent(in, swapped, TRUE);
7626747b715Smrg
7636747b715Smrg    free(out);
7646747b715Smrg    free(swapped);
7656747b715Smrg}
7666747b715Smrg
7676747b715Smrgstatic void test_convert_XIDeviceChangedEvent(void)
7686747b715Smrg{
7696747b715Smrg    DeviceChangedEvent in;
7706747b715Smrg    int i;
7716747b715Smrg
7726747b715Smrg    g_test_message("Testing simple field values");
7736747b715Smrg    memset(&in, 0, sizeof(in));
7746747b715Smrg    in.header = ET_Internal;
7756747b715Smrg    in.type = ET_DeviceChanged;
7766747b715Smrg    in.length = sizeof(DeviceChangedEvent);
7776747b715Smrg    in.time             = 0;
7786747b715Smrg    in.deviceid         = 1;
7796747b715Smrg    in.sourceid         = 2;
7806747b715Smrg    in.masterid         = 3;
7816747b715Smrg    in.num_valuators    = 4;
7826747b715Smrg    in.flags = DEVCHANGE_SLAVE_SWITCH | DEVCHANGE_POINTER_EVENT | DEVCHANGE_KEYBOARD_EVENT;
7836747b715Smrg
7846747b715Smrg    for (i = 0; i < MAX_BUTTONS; i++)
7856747b715Smrg        in.buttons.names[i] = i + 10;
7866747b715Smrg
7876747b715Smrg    in.keys.min_keycode = 8;
7886747b715Smrg    in.keys.max_keycode = 255;
7896747b715Smrg
7906747b715Smrg    test_XIDeviceChangedEvent(&in);
7916747b715Smrg
7926747b715Smrg    in.time = 1L;
7936747b715Smrg    test_XIDeviceChangedEvent(&in);
7946747b715Smrg    in.time = 1L << 8;
7956747b715Smrg    test_XIDeviceChangedEvent(&in);
7966747b715Smrg    in.time = 1L << 16;
7976747b715Smrg    test_XIDeviceChangedEvent(&in);
7986747b715Smrg    in.time = 1L << 24;
7996747b715Smrg    test_XIDeviceChangedEvent(&in);
8006747b715Smrg    in.time = ~0L;
8016747b715Smrg    test_XIDeviceChangedEvent(&in);
8026747b715Smrg
8036747b715Smrg    in.deviceid = 1L;
8046747b715Smrg    test_XIDeviceChangedEvent(&in);
8056747b715Smrg    in.deviceid = 1L << 8;
8066747b715Smrg    test_XIDeviceChangedEvent(&in);
8076747b715Smrg    in.deviceid = ~0 & 0xFFFF;
8086747b715Smrg    test_XIDeviceChangedEvent(&in);
8096747b715Smrg
8106747b715Smrg    in.sourceid = 1L;
8116747b715Smrg    test_XIDeviceChangedEvent(&in);
8126747b715Smrg    in.sourceid = 1L << 8;
8136747b715Smrg    test_XIDeviceChangedEvent(&in);
8146747b715Smrg    in.sourceid = ~0 & 0xFFFF;
8156747b715Smrg    test_XIDeviceChangedEvent(&in);
8166747b715Smrg
8176747b715Smrg    in.masterid = 1L;
8186747b715Smrg    test_XIDeviceChangedEvent(&in);
8196747b715Smrg    in.masterid = 1L << 8;
8206747b715Smrg    test_XIDeviceChangedEvent(&in);
8216747b715Smrg    in.masterid = ~0 & 0xFFFF;
8226747b715Smrg    test_XIDeviceChangedEvent(&in);
8236747b715Smrg
8246747b715Smrg    in.buttons.num_buttons = 0;
8256747b715Smrg    test_XIDeviceChangedEvent(&in);
8266747b715Smrg
8276747b715Smrg    in.buttons.num_buttons = 1;
8286747b715Smrg    test_XIDeviceChangedEvent(&in);
8296747b715Smrg
8306747b715Smrg    in.buttons.num_buttons = MAX_BUTTONS;
8316747b715Smrg    test_XIDeviceChangedEvent(&in);
8326747b715Smrg
8336747b715Smrg    in.keys.min_keycode = 0;
8346747b715Smrg    in.keys.max_keycode = 0;
8356747b715Smrg    test_XIDeviceChangedEvent(&in);
8366747b715Smrg
8376747b715Smrg    in.keys.max_keycode = 1 << 8;
8386747b715Smrg    test_XIDeviceChangedEvent(&in);
8396747b715Smrg
8406747b715Smrg    in.keys.max_keycode = 0xFFFC; /* highest range, above that the length
8416747b715Smrg                                     field gives up */
8426747b715Smrg    test_XIDeviceChangedEvent(&in);
8436747b715Smrg
8446747b715Smrg    in.keys.min_keycode = 1 << 8;
8456747b715Smrg    in.keys.max_keycode = 1 << 8;
8466747b715Smrg    test_XIDeviceChangedEvent(&in);
8476747b715Smrg
8486747b715Smrg    in.keys.min_keycode = 1 << 8;
8496747b715Smrg    in.keys.max_keycode = 0;
8506747b715Smrg    test_XIDeviceChangedEvent(&in);
8516747b715Smrg
8526747b715Smrg    in.num_valuators = 0;
8536747b715Smrg    test_XIDeviceChangedEvent(&in);
8546747b715Smrg
8556747b715Smrg    in.num_valuators = 1;
8566747b715Smrg    test_XIDeviceChangedEvent(&in);
8576747b715Smrg
8586747b715Smrg    in.num_valuators = MAX_VALUATORS;
8596747b715Smrg    test_XIDeviceChangedEvent(&in);
8606747b715Smrg
8616747b715Smrg    for (i = 0; i < MAX_VALUATORS; i++)
8626747b715Smrg    {
8636747b715Smrg        in.valuators[i].min = 0;
8646747b715Smrg        in.valuators[i].max = 0;
8656747b715Smrg        test_XIDeviceChangedEvent(&in);
8666747b715Smrg
8676747b715Smrg        in.valuators[i].max = 1 << 8;
8686747b715Smrg        test_XIDeviceChangedEvent(&in);
8696747b715Smrg        in.valuators[i].max = 1 << 16;
8706747b715Smrg        test_XIDeviceChangedEvent(&in);
8716747b715Smrg        in.valuators[i].max = 1 << 24;
8726747b715Smrg        test_XIDeviceChangedEvent(&in);
8736747b715Smrg        in.valuators[i].max = abs(~0);
8746747b715Smrg        test_XIDeviceChangedEvent(&in);
8756747b715Smrg
8766747b715Smrg        in.valuators[i].resolution = 1 << 8;
8776747b715Smrg        test_XIDeviceChangedEvent(&in);
8786747b715Smrg        in.valuators[i].resolution = 1 << 16;
8796747b715Smrg        test_XIDeviceChangedEvent(&in);
8806747b715Smrg        in.valuators[i].resolution = 1 << 24;
8816747b715Smrg        test_XIDeviceChangedEvent(&in);
8826747b715Smrg        in.valuators[i].resolution = abs(~0);
8836747b715Smrg        test_XIDeviceChangedEvent(&in);
8846747b715Smrg
8856747b715Smrg        in.valuators[i].name = i;
8866747b715Smrg        test_XIDeviceChangedEvent(&in);
8876747b715Smrg
8886747b715Smrg        in.valuators[i].mode = Relative;
8896747b715Smrg        test_XIDeviceChangedEvent(&in);
8906747b715Smrg
8916747b715Smrg        in.valuators[i].mode = Absolute;
8926747b715Smrg        test_XIDeviceChangedEvent(&in);
8936747b715Smrg    }
8946747b715Smrg}
8956747b715Smrg
8966747b715Smrgint main(int argc, char** argv)
8976747b715Smrg{
8986747b715Smrg    g_test_init(&argc, &argv,NULL);
8996747b715Smrg    g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
9006747b715Smrg
9016747b715Smrg    g_test_add_func("/xi2/eventconvert/XIRawEvent", test_convert_XIRawEvent);
9026747b715Smrg    g_test_add_func("/xi2/eventconvert/XIFocusEvent", test_convert_XIFocusEvent);
9036747b715Smrg    g_test_add_func("/xi2/eventconvert/XIDeviceEvent", test_convert_XIDeviceEvent);
9046747b715Smrg    g_test_add_func("/xi2/eventconvert/XIDeviceChangedEvent", test_convert_XIDeviceChangedEvent);
9056747b715Smrg
9066747b715Smrg    return g_test_run();
9076747b715Smrg}
908