Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Tested-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Dave Airlie <airlied@redhat.com>
937 lines
26 KiB
C
937 lines
26 KiB
C
/**
|
|
* Copyright © 2009 Red Hat, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
* * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#ifdef HAVE_DIX_CONFIG_H
|
|
#include <dix-config.h>
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "inputstr.h"
|
|
#include "eventstr.h"
|
|
#include "eventconvert.h"
|
|
#include "exevents.h"
|
|
#include "inpututils.h"
|
|
#include <X11/extensions/XI2proto.h>
|
|
|
|
static void test_values_XIRawEvent(RawDeviceEvent *in, xXIRawEvent *out,
|
|
BOOL swap)
|
|
{
|
|
int i;
|
|
unsigned char *ptr;
|
|
FP3232 *value, *raw_value;
|
|
int nvals = 0;
|
|
int bits_set;
|
|
int len;
|
|
uint32_t flagmask = 0;
|
|
|
|
if (swap)
|
|
{
|
|
swaps(&out->sequenceNumber);
|
|
swapl(&out->length);
|
|
swaps(&out->evtype);
|
|
swaps(&out->deviceid);
|
|
swapl(&out->time);
|
|
swapl(&out->detail);
|
|
swaps(&out->valuators_len);
|
|
swapl(&out->flags);
|
|
}
|
|
|
|
|
|
assert(out->type == GenericEvent);
|
|
assert(out->extension == 0); /* IReqCode defaults to 0 */
|
|
assert(out->evtype == GetXI2Type((InternalEvent*)in));
|
|
assert(out->time == in->time);
|
|
assert(out->detail == in->detail.button);
|
|
assert(out->deviceid == in->deviceid);
|
|
assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(sizeof(in->valuators.mask))));
|
|
|
|
switch (in->type) {
|
|
case ET_RawMotion:
|
|
case ET_RawButtonPress:
|
|
case ET_RawButtonRelease:
|
|
flagmask = XIPointerEmulated;
|
|
break;
|
|
default:
|
|
flagmask = 0;
|
|
}
|
|
assert((out->flags & ~flagmask) == 0);
|
|
|
|
ptr = (unsigned char*)&out[1];
|
|
bits_set = 0;
|
|
|
|
for (i = 0; out->valuators_len && i < sizeof(in->valuators.mask) * 8; i++)
|
|
{
|
|
if (i >= MAX_VALUATORS)
|
|
assert (!XIMaskIsSet(in->valuators.mask, i));
|
|
assert (XIMaskIsSet(in->valuators.mask, i) == XIMaskIsSet(ptr, i));
|
|
if (XIMaskIsSet(in->valuators.mask, i))
|
|
bits_set++;
|
|
}
|
|
|
|
/* length is len of valuator mask (in 4-byte units) + the number of bits
|
|
* set. Each bit set represents 2 8-byte values, hence the
|
|
* 'bits_set * 4' */
|
|
len = out->valuators_len + bits_set * 4;
|
|
assert(out->length == len);
|
|
|
|
nvals = 0;
|
|
|
|
for (i = 0; out->valuators_len && i < MAX_VALUATORS; i++)
|
|
{
|
|
assert (XIMaskIsSet(in->valuators.mask, i) == XIMaskIsSet(ptr, i));
|
|
if (XIMaskIsSet(in->valuators.mask, i))
|
|
{
|
|
FP3232 vi, vo;
|
|
value = (FP3232*)(((unsigned char*)&out[1]) + out->valuators_len * 4);
|
|
value += nvals;
|
|
|
|
vi = double_to_fp3232(in->valuators.data[i]);
|
|
|
|
vo.integral = value->integral;
|
|
vo.frac = value->frac;
|
|
if (swap)
|
|
{
|
|
swapl(&vo.integral);
|
|
swapl(&vo.frac);
|
|
}
|
|
|
|
assert(vi.integral == vo.integral);
|
|
assert(vi.frac == vo.frac);
|
|
|
|
raw_value = value + bits_set;
|
|
|
|
vi = double_to_fp3232(in->valuators.data_raw[i]);
|
|
|
|
vo.integral = raw_value->integral;
|
|
vo.frac = raw_value->frac;
|
|
if (swap)
|
|
{
|
|
swapl(&vo.integral);
|
|
swapl(&vo.frac);
|
|
}
|
|
|
|
assert(vi.integral == vo.integral);
|
|
assert(vi.frac == vo.frac);
|
|
|
|
nvals++;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void test_XIRawEvent(RawDeviceEvent *in)
|
|
{
|
|
xXIRawEvent *out, *swapped;
|
|
int rc;
|
|
|
|
rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
|
|
assert(rc == Success);
|
|
|
|
test_values_XIRawEvent(in, out, FALSE);
|
|
|
|
swapped = calloc(1, sizeof(xEvent) + out->length * 4);
|
|
XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
|
|
test_values_XIRawEvent(in, swapped, TRUE);
|
|
|
|
free(out);
|
|
free(swapped);
|
|
}
|
|
|
|
static void test_convert_XIFocusEvent(void)
|
|
{
|
|
xEvent *out;
|
|
DeviceEvent in;
|
|
int rc;
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_Enter;
|
|
rc = EventToXI2((InternalEvent*)&in, &out);
|
|
assert(rc == Success);
|
|
assert(out == NULL);
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_FocusIn;
|
|
rc = EventToXI2((InternalEvent*)&in, &out);
|
|
assert(rc == Success);
|
|
assert(out == NULL);
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_FocusOut;
|
|
rc = EventToXI2((InternalEvent*)&in, &out);
|
|
assert(rc == BadImplementation);
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_Leave;
|
|
rc = EventToXI2((InternalEvent*)&in, &out);
|
|
assert(rc == BadImplementation);
|
|
}
|
|
|
|
|
|
static void test_convert_XIRawEvent(void)
|
|
{
|
|
RawDeviceEvent in;
|
|
int i;
|
|
|
|
memset(&in, 0, sizeof(in));
|
|
|
|
printf("Testing all event types\n");
|
|
in.header = ET_Internal;
|
|
in.type = ET_RawMotion;
|
|
test_XIRawEvent(&in);
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_RawKeyPress;
|
|
test_XIRawEvent(&in);
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_RawKeyRelease;
|
|
test_XIRawEvent(&in);
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_RawButtonPress;
|
|
test_XIRawEvent(&in);
|
|
|
|
in.header = ET_Internal;
|
|
in.type = ET_RawButtonRelease;
|
|
test_XIRawEvent(&in);
|
|
|
|
printf("Testing details and other fields\n");
|
|
in.detail.button = 1L;
|
|
test_XIRawEvent(&in);
|
|
in.detail.button = 1L << 8;
|
|
test_XIRawEvent(&in);
|
|
in.detail.button = 1L << 16;
|
|
test_XIRawEvent(&in);
|
|
in.detail.button = 1L << 24;
|
|
test_XIRawEvent(&in);
|
|
in.detail.button = ~0L;
|
|
test_XIRawEvent(&in);
|
|
|
|
in.detail.button = 0;
|
|
|
|
in.time = 1L;
|
|
test_XIRawEvent(&in);
|
|
in.time = 1L << 8;
|
|
test_XIRawEvent(&in);
|
|
in.time = 1L << 16;
|
|
test_XIRawEvent(&in);
|
|
in.time = 1L << 24;
|
|
test_XIRawEvent(&in);
|
|
in.time = ~0L;
|
|
test_XIRawEvent(&in);
|
|
|
|
in.deviceid = 1;
|
|
test_XIRawEvent(&in);
|
|
in.deviceid = 1 << 8;
|
|
test_XIRawEvent(&in);
|
|
in.deviceid = ~0 & 0xFF;
|
|
test_XIRawEvent(&in);
|
|
|
|
printf("Testing valuator masks\n");
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
{
|
|
XISetMask(in.valuators.mask, i);
|
|
test_XIRawEvent(&in);
|
|
XIClearMask(in.valuators.mask, i);
|
|
}
|
|
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
{
|
|
XISetMask(in.valuators.mask, i);
|
|
|
|
in.valuators.data[i] = i + (i * 0.0010);
|
|
in.valuators.data_raw[i] = (i + 10) + (i * 0.0030);
|
|
test_XIRawEvent(&in);
|
|
XIClearMask(in.valuators.mask, i);
|
|
}
|
|
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
{
|
|
XISetMask(in.valuators.mask, i);
|
|
test_XIRawEvent(&in);
|
|
}
|
|
}
|
|
|
|
static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
|
|
BOOL swap)
|
|
{
|
|
int buttons, valuators;
|
|
int i;
|
|
unsigned char *ptr;
|
|
uint32_t flagmask = 0;
|
|
FP3232 *values;
|
|
|
|
if (swap) {
|
|
swaps(&out->sequenceNumber);
|
|
swapl(&out->length);
|
|
swaps(&out->evtype);
|
|
swaps(&out->deviceid);
|
|
swaps(&out->sourceid);
|
|
swapl(&out->time);
|
|
swapl(&out->detail);
|
|
swapl(&out->root);
|
|
swapl(&out->event);
|
|
swapl(&out->child);
|
|
swapl(&out->root_x);
|
|
swapl(&out->root_y);
|
|
swapl(&out->event_x);
|
|
swapl(&out->event_y);
|
|
swaps(&out->buttons_len);
|
|
swaps(&out->valuators_len);
|
|
swapl(&out->mods.base_mods);
|
|
swapl(&out->mods.latched_mods);
|
|
swapl(&out->mods.locked_mods);
|
|
swapl(&out->mods.effective_mods);
|
|
swapl(&out->flags);
|
|
}
|
|
|
|
assert(out->extension == 0); /* IReqCode defaults to 0 */
|
|
assert(out->evtype == GetXI2Type((InternalEvent*)in));
|
|
assert(out->time == in->time);
|
|
assert(out->detail == in->detail.button);
|
|
assert(out->length >= 12);
|
|
|
|
assert(out->deviceid == in->deviceid);
|
|
assert(out->sourceid == in->sourceid);
|
|
|
|
switch (in->type) {
|
|
case ET_ButtonPress:
|
|
case ET_Motion:
|
|
case ET_ButtonRelease:
|
|
flagmask = XIPointerEmulated;
|
|
break;
|
|
case ET_KeyPress:
|
|
flagmask = XIKeyRepeat;
|
|
break;
|
|
default:
|
|
flagmask = 0;
|
|
break;
|
|
}
|
|
assert((out->flags & ~flagmask) == 0);
|
|
|
|
assert(out->root == in->root);
|
|
assert(out->event == None); /* set in FixUpEventFromWindow */
|
|
assert(out->child == None); /* set in FixUpEventFromWindow */
|
|
|
|
assert(out->mods.base_mods == in->mods.base);
|
|
assert(out->mods.latched_mods == in->mods.latched);
|
|
assert(out->mods.locked_mods == in->mods.locked);
|
|
assert(out->mods.effective_mods == in->mods.effective);
|
|
|
|
assert(out->group.base_group == in->group.base);
|
|
assert(out->group.latched_group == in->group.latched);
|
|
assert(out->group.locked_group == in->group.locked);
|
|
assert(out->group.effective_group == in->group.effective);
|
|
|
|
assert(out->event_x == 0); /* set in FixUpEventFromWindow */
|
|
assert(out->event_y == 0); /* set in FixUpEventFromWindow */
|
|
|
|
assert(out->root_x == FP1616(in->root_x, in->root_x_frac));
|
|
assert(out->root_y == FP1616(in->root_y, in->root_y_frac));
|
|
|
|
buttons = 0;
|
|
for (i = 0; i < bits_to_bytes(sizeof(in->buttons)); i++)
|
|
{
|
|
if (XIMaskIsSet(in->buttons, i))
|
|
{
|
|
assert(out->buttons_len >= bytes_to_int32(bits_to_bytes(i)));
|
|
buttons++;
|
|
}
|
|
}
|
|
|
|
ptr = (unsigned char*)&out[1];
|
|
for (i = 0; i < sizeof(in->buttons) * 8; i++)
|
|
assert(XIMaskIsSet(in->buttons, i) == XIMaskIsSet(ptr, i));
|
|
|
|
|
|
valuators = 0;
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
if (XIMaskIsSet(in->valuators.mask, i))
|
|
valuators++;
|
|
|
|
assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(valuators)));
|
|
|
|
ptr += out->buttons_len * 4;
|
|
values = (FP3232*)(ptr + out->valuators_len * 4);
|
|
for (i = 0; i < sizeof(in->valuators.mask) * 8 ||
|
|
i < (out->valuators_len * 4) * 8; i++)
|
|
{
|
|
if (i >= MAX_VALUATORS)
|
|
assert(!XIMaskIsSet(in->valuators.mask, i) && !XIMaskIsSet(ptr, i));
|
|
else if (i > sizeof(in->valuators.mask) * 8)
|
|
assert(!XIMaskIsSet(ptr, i));
|
|
else if (i > out->valuators_len * 4 * 8)
|
|
assert(!XIMaskIsSet(in->valuators.mask, i));
|
|
else {
|
|
assert(XIMaskIsSet(in->valuators.mask, i) ==
|
|
XIMaskIsSet(ptr, i));
|
|
|
|
if (XIMaskIsSet(ptr, i))
|
|
{
|
|
FP3232 vi, vo;
|
|
|
|
vi.integral = trunc(in->valuators.data[i]);
|
|
vi.frac = (in->valuators.data[i] - vi.integral) * (1UL << 32);
|
|
|
|
vo = *values;
|
|
|
|
if (swap)
|
|
{
|
|
swapl(&vo.integral);
|
|
swapl(&vo.frac);
|
|
}
|
|
|
|
|
|
assert(vi.integral == vo.integral);
|
|
assert(vi.frac == vo.frac);
|
|
values++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void test_XIDeviceEvent(DeviceEvent *in)
|
|
{
|
|
xXIDeviceEvent *out, *swapped;
|
|
int rc;
|
|
|
|
rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
|
|
assert(rc == Success);
|
|
|
|
test_values_XIDeviceEvent(in, out, FALSE);
|
|
|
|
swapped = calloc(1, sizeof(xEvent) + out->length * 4);
|
|
XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
|
|
test_values_XIDeviceEvent(in, swapped, TRUE);
|
|
|
|
free(out);
|
|
free(swapped);
|
|
}
|
|
|
|
static void test_convert_XIDeviceEvent(void)
|
|
{
|
|
DeviceEvent in;
|
|
int i;
|
|
|
|
memset(&in, 0, sizeof(in));
|
|
|
|
printf("Testing simple field values\n");
|
|
in.header = ET_Internal;
|
|
in.type = ET_Motion;
|
|
in.length = sizeof(DeviceEvent);
|
|
in.time = 0;
|
|
in.deviceid = 1;
|
|
in.sourceid = 2;
|
|
in.root = 3;
|
|
in.root_x = 4;
|
|
in.root_x_frac = 5;
|
|
in.root_y = 6;
|
|
in.root_y_frac = 7;
|
|
in.detail.button = 8;
|
|
in.mods.base = 9;
|
|
in.mods.latched = 10;
|
|
in.mods.locked = 11;
|
|
in.mods.effective = 11;
|
|
in.group.base = 12;
|
|
in.group.latched = 13;
|
|
in.group.locked = 14;
|
|
in.group.effective = 15;
|
|
|
|
test_XIDeviceEvent(&in);
|
|
|
|
printf("Testing field ranges\n");
|
|
/* 32 bit */
|
|
in.detail.button = 1L;
|
|
test_XIDeviceEvent(&in);
|
|
in.detail.button = 1L << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.detail.button = 1L << 16;
|
|
test_XIDeviceEvent(&in);
|
|
in.detail.button = 1L << 24;
|
|
test_XIDeviceEvent(&in);
|
|
in.detail.button = ~0L;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
/* 32 bit */
|
|
in.time = 1L;
|
|
test_XIDeviceEvent(&in);
|
|
in.time = 1L << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.time = 1L << 16;
|
|
test_XIDeviceEvent(&in);
|
|
in.time = 1L << 24;
|
|
test_XIDeviceEvent(&in);
|
|
in.time = ~0L;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
/* 16 bit */
|
|
in.deviceid = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.deviceid = 1 << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.deviceid = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
/* 16 bit */
|
|
in.sourceid = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.deviceid = 1 << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.deviceid = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
/* 32 bit */
|
|
in.root = 1L;
|
|
test_XIDeviceEvent(&in);
|
|
in.root = 1L << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.root = 1L << 16;
|
|
test_XIDeviceEvent(&in);
|
|
in.root = 1L << 24;
|
|
test_XIDeviceEvent(&in);
|
|
in.root = ~0L;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
/* 16 bit */
|
|
in.root_x = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_x = 1 << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_x = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.root_x_frac = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_x_frac = 1 << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_x_frac = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.root_y = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_y = 1 << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_y = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.root_y_frac = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_y_frac = 1 << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.root_y_frac = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
/* 32 bit */
|
|
in.mods.base = 1L;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.base = 1L << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.base = 1L << 16;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.base = 1L << 24;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.base = ~0L;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.mods.latched = 1L;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.latched = 1L << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.latched = 1L << 16;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.latched = 1L << 24;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.latched = ~0L;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.mods.locked = 1L;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.locked = 1L << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.locked = 1L << 16;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.locked = 1L << 24;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.locked = ~0L;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.mods.effective = 1L;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.effective = 1L << 8;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.effective = 1L << 16;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.effective = 1L << 24;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.effective = ~0L;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
/* 8 bit */
|
|
in.group.base = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.group.base = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.group.latched = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.group.latched = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.group.locked = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.group.locked = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
in.mods.effective = 1;
|
|
test_XIDeviceEvent(&in);
|
|
in.mods.effective = ~0 & 0xFF;
|
|
test_XIDeviceEvent(&in);
|
|
|
|
printf("Testing button masks\n");
|
|
for (i = 0; i < sizeof(in.buttons) * 8; i++)
|
|
{
|
|
XISetMask(in.buttons, i);
|
|
test_XIDeviceEvent(&in);
|
|
XIClearMask(in.buttons, i);
|
|
}
|
|
|
|
for (i = 0; i < sizeof(in.buttons) * 8; i++)
|
|
{
|
|
XISetMask(in.buttons, i);
|
|
test_XIDeviceEvent(&in);
|
|
}
|
|
|
|
printf("Testing valuator masks\n");
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
{
|
|
XISetMask(in.valuators.mask, i);
|
|
test_XIDeviceEvent(&in);
|
|
XIClearMask(in.valuators.mask, i);
|
|
}
|
|
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
{
|
|
XISetMask(in.valuators.mask, i);
|
|
|
|
in.valuators.data[i] = i + (i * 0.0020);
|
|
test_XIDeviceEvent(&in);
|
|
XIClearMask(in.valuators.mask, i);
|
|
}
|
|
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
{
|
|
XISetMask(in.valuators.mask, i);
|
|
test_XIDeviceEvent(&in);
|
|
}
|
|
}
|
|
|
|
static void test_values_XIDeviceChangedEvent(DeviceChangedEvent *in,
|
|
xXIDeviceChangedEvent *out,
|
|
BOOL swap)
|
|
{
|
|
int i, j;
|
|
unsigned char *ptr;
|
|
|
|
if (swap)
|
|
{
|
|
swaps(&out->sequenceNumber);
|
|
swapl(&out->length);
|
|
swaps(&out->evtype);
|
|
swaps(&out->deviceid);
|
|
swaps(&out->sourceid);
|
|
swapl(&out->time);
|
|
swaps(&out->num_classes);
|
|
}
|
|
|
|
assert(out->type == GenericEvent);
|
|
assert(out->extension == 0); /* IReqCode defaults to 0 */
|
|
assert(out->evtype == GetXI2Type((InternalEvent*)in));
|
|
assert(out->time == in->time);
|
|
assert(out->deviceid == in->deviceid);
|
|
assert(out->sourceid == in->sourceid);
|
|
|
|
ptr = (unsigned char*)&out[1];
|
|
for (i = 0; i < out->num_classes; i++)
|
|
{
|
|
xXIAnyInfo* any = (xXIAnyInfo*)ptr;
|
|
|
|
if (swap)
|
|
{
|
|
swaps(&any->length);
|
|
swaps(&any->type);
|
|
swaps(&any->sourceid);
|
|
}
|
|
|
|
switch(any->type)
|
|
{
|
|
case XIButtonClass:
|
|
{
|
|
xXIButtonInfo *b = (xXIButtonInfo*)any;
|
|
Atom *names;
|
|
|
|
if (swap)
|
|
{
|
|
swaps(&b->num_buttons);
|
|
}
|
|
|
|
assert(b->length ==
|
|
bytes_to_int32(sizeof(xXIButtonInfo)) +
|
|
bytes_to_int32(bits_to_bytes(b->num_buttons)) +
|
|
b->num_buttons);
|
|
assert(b->num_buttons == in->buttons.num_buttons);
|
|
|
|
names = (Atom*)((char*)&b[1] +
|
|
pad_to_int32(bits_to_bytes(b->num_buttons)));
|
|
for (j = 0; j < b->num_buttons; j++)
|
|
{
|
|
if (swap)
|
|
{
|
|
swapl(&names[j]);
|
|
}
|
|
assert(names[j] == in->buttons.names[j]);
|
|
}
|
|
}
|
|
break;
|
|
case XIKeyClass:
|
|
{
|
|
xXIKeyInfo *k = (xXIKeyInfo*)any;
|
|
uint32_t *kc;
|
|
|
|
if (swap)
|
|
{
|
|
swaps(&k->num_keycodes);
|
|
}
|
|
|
|
assert(k->length ==
|
|
bytes_to_int32(sizeof(xXIKeyInfo)) +
|
|
k->num_keycodes);
|
|
assert(k->num_keycodes == in->keys.max_keycode -
|
|
in->keys.min_keycode + 1);
|
|
|
|
kc = (uint32_t*)&k[1];
|
|
for (j = 0; j < k->num_keycodes; j++)
|
|
{
|
|
if (swap)
|
|
{
|
|
swapl(&kc[j]);
|
|
}
|
|
assert(kc[j] >= in->keys.min_keycode);
|
|
assert(kc[j] <= in->keys.max_keycode);
|
|
}
|
|
}
|
|
break;
|
|
case XIValuatorClass:
|
|
{
|
|
xXIValuatorInfo *v = (xXIValuatorInfo*)any;
|
|
assert(v->length ==
|
|
bytes_to_int32(sizeof(xXIValuatorInfo)));
|
|
|
|
}
|
|
break;
|
|
case XIScrollClass:
|
|
{
|
|
xXIScrollInfo *s = (xXIScrollInfo*)any;
|
|
assert(s->length ==
|
|
bytes_to_int32(sizeof(xXIScrollInfo)));
|
|
|
|
assert(s->sourceid == in->sourceid);
|
|
assert(s->number < in->num_valuators);
|
|
switch(s->type)
|
|
{
|
|
case XIScrollTypeVertical:
|
|
assert(in->valuators[s->number].scroll.type == SCROLL_TYPE_VERTICAL);
|
|
break;
|
|
case XIScrollTypeHorizontal:
|
|
assert(in->valuators[s->number].scroll.type == SCROLL_TYPE_HORIZONTAL);
|
|
break;
|
|
}
|
|
if (s->flags & XIScrollFlagPreferred)
|
|
assert(in->valuators[s->number].scroll.flags & SCROLL_FLAG_PREFERRED);
|
|
}
|
|
default:
|
|
printf("Invalid class type.\n\n");
|
|
assert(1);
|
|
break;
|
|
}
|
|
|
|
ptr += any->length * 4;
|
|
}
|
|
|
|
}
|
|
|
|
static void test_XIDeviceChangedEvent(DeviceChangedEvent *in)
|
|
{
|
|
xXIDeviceChangedEvent *out, *swapped;
|
|
int rc;
|
|
|
|
rc = EventToXI2((InternalEvent*)in, (xEvent**)&out);
|
|
assert(rc == Success);
|
|
|
|
test_values_XIDeviceChangedEvent(in, out, FALSE);
|
|
|
|
swapped = calloc(1, sizeof(xEvent) + out->length * 4);
|
|
XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)swapped);
|
|
test_values_XIDeviceChangedEvent(in, swapped, TRUE);
|
|
|
|
free(out);
|
|
free(swapped);
|
|
}
|
|
|
|
static void test_convert_XIDeviceChangedEvent(void)
|
|
{
|
|
DeviceChangedEvent in;
|
|
int i;
|
|
|
|
printf("Testing simple field values\n");
|
|
memset(&in, 0, sizeof(in));
|
|
in.header = ET_Internal;
|
|
in.type = ET_DeviceChanged;
|
|
in.length = sizeof(DeviceChangedEvent);
|
|
in.time = 0;
|
|
in.deviceid = 1;
|
|
in.sourceid = 2;
|
|
in.masterid = 3;
|
|
in.num_valuators = 4;
|
|
in.flags = DEVCHANGE_SLAVE_SWITCH | DEVCHANGE_POINTER_EVENT | DEVCHANGE_KEYBOARD_EVENT;
|
|
|
|
for (i = 0; i < MAX_BUTTONS; i++)
|
|
in.buttons.names[i] = i + 10;
|
|
|
|
in.keys.min_keycode = 8;
|
|
in.keys.max_keycode = 255;
|
|
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.time = 1L;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.time = 1L << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.time = 1L << 16;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.time = 1L << 24;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.time = ~0L;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.deviceid = 1L;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.deviceid = 1L << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.deviceid = ~0 & 0xFFFF;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.sourceid = 1L;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.sourceid = 1L << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.sourceid = ~0 & 0xFFFF;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.masterid = 1L;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.masterid = 1L << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.masterid = ~0 & 0xFFFF;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.buttons.num_buttons = 0;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.buttons.num_buttons = 1;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.buttons.num_buttons = MAX_BUTTONS;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.keys.min_keycode = 0;
|
|
in.keys.max_keycode = 0;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.keys.max_keycode = 1 << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.keys.max_keycode = 0xFFFC; /* highest range, above that the length
|
|
field gives up */
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.keys.min_keycode = 1 << 8;
|
|
in.keys.max_keycode = 1 << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.keys.min_keycode = 1 << 8;
|
|
in.keys.max_keycode = 0;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.num_valuators = 0;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.num_valuators = 1;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.num_valuators = MAX_VALUATORS;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
for (i = 0; i < MAX_VALUATORS; i++)
|
|
{
|
|
in.valuators[i].min = 0;
|
|
in.valuators[i].max = 0;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.valuators[i].max = 1 << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.valuators[i].max = 1 << 16;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.valuators[i].max = 1 << 24;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.valuators[i].max = abs(~0);
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.valuators[i].resolution = 1 << 8;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.valuators[i].resolution = 1 << 16;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.valuators[i].resolution = 1 << 24;
|
|
test_XIDeviceChangedEvent(&in);
|
|
in.valuators[i].resolution = abs(~0);
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.valuators[i].name = i;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.valuators[i].mode = Relative;
|
|
test_XIDeviceChangedEvent(&in);
|
|
|
|
in.valuators[i].mode = Absolute;
|
|
test_XIDeviceChangedEvent(&in);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
test_convert_XIRawEvent();
|
|
test_convert_XIFocusEvent();
|
|
test_convert_XIDeviceEvent();
|
|
test_convert_XIDeviceChangedEvent();
|
|
|
|
return 0;
|
|
}
|