[PATCH 8/8] Test: Input: Add touch tests
Daniel Stone
daniel at fooishbar.org
Wed Jan 19 15:11:50 PST 2011
Add tests for:
* checking basic functionality of BeginTouchPoint,
FindTouchPoint*, and EndTouchPoint
* ensuring all touch event types match each other in
GrabMatchesSecond
* ensuring all touch events are selected together, or not at all, in
XISelectEvents (this test authored by Chase Douglas)
* ensuring EventToXI2 is predictable between runs
* validating TouchBegin, TouchMotion, TouchMotionUnowned, TouchEnd,
and TouchOwnership protocol conversion
Signed-off-by: Daniel Stone <daniel at fooishbar.org>
Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
---
v5: Added tests for TouchMotionUnowned and TouchOwnership as well.
Make BeginTouchPoint/FindTouchPoint*/EndTouchPoint tests slightly more
comprehensive.
test/input.c | 169 +++++++++++++++++++++++++++++++++++-
test/xi2/protocol-eventconvert.c | 114 ++++++++++++++++++++++++-
test/xi2/protocol-xiselectevents.c | 64 ++++++++++++++
3 files changed, 345 insertions(+), 2 deletions(-)
diff --git a/test/input.c b/test/input.c
index 879e14f..21b4c8d 100644
--- a/test/input.c
+++ b/test/input.c
@@ -277,6 +277,11 @@ static void dix_event_to_core_conversion(void)
dix_event_to_core_fail(ET_ProximityOut + 1, BadImplementation);
dix_event_to_core_fail(ET_ProximityIn, BadMatch);
dix_event_to_core_fail(ET_ProximityOut, BadMatch);
+ dix_event_to_core_fail(ET_TouchBegin, BadMatch);
+ dix_event_to_core_fail(ET_TouchMotion, BadMatch);
+ dix_event_to_core_fail(ET_TouchMotionUnowned, BadMatch);
+ dix_event_to_core_fail(ET_TouchOwnership, BadMatch);
+ dix_event_to_core_fail(ET_TouchEnd, BadMatch);
dix_event_to_core(ET_KeyPress);
dix_event_to_core(ET_KeyRelease);
@@ -285,6 +290,34 @@ static void dix_event_to_core_conversion(void)
dix_event_to_core(ET_Motion);
}
+static void dix_event_to_xi2_conversion(void)
+{
+ DeviceEvent ev;
+ xXIDeviceEvent *xi2, *xi2_flags;
+ int rc;
+
+ memset(&ev, 0, sizeof(ev));
+
+ ev.header = 0xFF;
+ ev.length = sizeof(DeviceEvent);
+ ev.type = ET_TouchBegin;
+
+ rc = EventToXI2((InternalEvent*)&ev, (xEvent**)&xi2);
+ g_assert(rc == Success);
+ g_assert(xi2->type == GenericEvent);
+ g_assert(xi2->evtype == XI_TouchBegin);
+ g_assert(xi2->flags == 0);
+
+ ev.flags = XITouchOwner;
+ rc = EventToXI2((InternalEvent*)&ev, (xEvent**)&xi2_flags);
+ g_assert(rc == Success);
+ g_assert(xi2_flags->type == GenericEvent);
+ g_assert(xi2_flags->evtype == XI_TouchBegin);
+ g_assert(xi2_flags->flags == XITouchOwner);
+ xi2_flags->flags = 0;
+ g_assert(memcmp(xi2, xi2_flags, sizeof(*xi2)) == 0);
+}
+
static void xi2_struct_sizes(void)
{
#define compare(req) \
@@ -674,6 +707,38 @@ static void dix_grab_matching(void)
g_assert(rc == TRUE);
rc = GrabMatchesSecond(&b, &a, FALSE);
g_assert(rc == TRUE);
+
+ /* All touch grabs must match a TouchBegin grab. */
+ a.grabtype = GRABTYPE_XI2;
+ b.grabtype = GRABTYPE_XI2;
+ a.type = XI_TouchBegin;
+ b.type = XI_TouchMotion;
+ a.detail.exact = 0;
+ b.detail.exact = 0;
+ a.modifiersDetail.exact = 0;
+ b.modifiersDetail.exact = 0;
+ rc = GrabMatchesSecond(&a, &b, FALSE);
+ g_assert(rc == TRUE);
+ rc = GrabMatchesSecond(&b, &a, FALSE);
+ g_assert(rc == TRUE);
+
+ b.type = XI_TouchMotionUnowned;
+ rc = GrabMatchesSecond(&a, &b, FALSE);
+ g_assert(rc == TRUE);
+ rc = GrabMatchesSecond(&b, &a, FALSE);
+ g_assert(rc == TRUE);
+
+ b.type = XI_TouchOwnership;
+ rc = GrabMatchesSecond(&a, &b, FALSE);
+ g_assert(rc == TRUE);
+ rc = GrabMatchesSecond(&b, &a, FALSE);
+ g_assert(rc == TRUE);
+
+ b.type = XI_TouchEnd;
+ rc = GrabMatchesSecond(&a, &b, FALSE);
+ g_assert(rc == TRUE);
+ rc = GrabMatchesSecond(&b, &a, FALSE);
+ g_assert(rc == TRUE);
}
static void test_bits_to_byte(int i)
@@ -1061,6 +1126,105 @@ static void include_bit_test_macros(void)
}
}
+static void touch_create(void)
+{
+ DeviceIntRec dev;
+ TouchClassRec touch;
+ TouchPointInfoRec touches[2];
+ TouchPointInfoPtr ti;
+
+ memset(&dev, 0, sizeof(dev));
+ memset(&touch, 0, sizeof(touch));
+ memset(touches, 0, sizeof(*touches) * 2);
+ touch.touches = touches;
+ touch.num_touches = 2;
+ touch.num_axes = 2;
+ touch.next_client_id = 1;
+ dev.touch = &touch;
+
+ /* Make sure we get a valid touchpoint back. */
+ ti = BeginTouchPoint(&dev, 0xdeadbeef);
+ g_assert(ti);
+ g_assert(ti->active == TRUE);
+ g_assert(ti->ddx_id == 0xdeadbeef);
+ g_assert(ti->client_id != 0);
+ g_assert(ti->pending_finish == 0);
+ g_assert(ti->num_listeners == 0);
+ g_assert(ti->num_grabs == 0);
+ g_assert(ti->sprite.spriteTraceGood == 0);
+}
+
+static void touch_find_point(void)
+{
+ DeviceIntRec dev;
+ TouchClassRec touch;
+ TouchPointInfoRec touches[2];
+ TouchPointInfoPtr create_ret, find_ret;
+
+ memset(&dev, 0, sizeof(dev));
+ memset(&touch, 0, sizeof(touch));
+ memset(touches, 0, sizeof(*touches) * 2);
+ touch.touches = touches;
+ touch.num_touches = 2;
+ touch.num_axes = 2;
+ touch.next_client_id = 1;
+ dev.touch = &touch;
+
+ create_ret = BeginTouchPoint(&dev, 0xdeadbeef);
+ g_assert(create_ret);
+
+ /* Make sure we can find the touch by both DDX and client ID. */
+ find_ret = FindTouchPointByDDXID(&dev, 0xdeadbeef);
+ g_assert(create_ret == find_ret);
+ find_ret = FindTouchPointByClientID(&dev, create_ret->client_id);
+ g_assert(find_ret->active == TRUE);
+ g_assert(find_ret->ddx_id == 0xdeadbeef);
+
+ /* Touches which are pending finish must be findable by their client ID,
+ * but not by their DDX ID, as only the DIX can inject ownership change
+ * events. */
+ find_ret->pending_finish = 1;
+ find_ret = FindTouchPointByClientID(&dev, create_ret->client_id);
+ g_assert(find_ret == create_ret);
+ find_ret = FindTouchPointByDDXID(&dev, 0xdeadbeef);
+ g_assert(!find_ret);
+}
+
+static void touch_finish(void)
+{
+ DeviceIntRec dev;
+ TouchClassRec touch;
+ TouchPointInfoRec touches[2];
+ TouchPointInfoPtr ti;
+ uint32_t client_id;
+
+ memset(&dev, 0, sizeof(dev));
+ memset(&touch, 0, sizeof(touch));
+ memset(touches, 0, sizeof(*touches) * 2);
+ touch.touches = touches;
+ touch.num_touches = 2;
+ touch.num_axes = 2;
+ touch.next_client_id = 1;
+ dev.touch = &touch;
+
+ /* Make sure the touch is in a sane state once we kill it, and that we
+ * can't find it once it's gone. */
+ ti = BeginTouchPoint(&dev, 0xdeadbeef);
+ g_assert(ti);
+ client_id = ti->client_id;
+ EndTouchPoint(&dev, ti);
+ g_assert(ti->active == FALSE);
+ g_assert(ti->pending_finish == 0);
+ g_assert(ti->num_listeners == 0);
+ g_assert(ti->num_grabs == 0);
+ g_assert(ti->sprite.spriteTraceGood == 0);
+ g_assert(ti->client_id == 0);
+ g_assert(ti->ddx_id == 0);
+
+ g_assert(FindTouchPointByDDXID(&dev, 0xdeadbeef) == NULL);
+ g_assert(FindTouchPointByClientID(&dev, client_id) == NULL);
+}
+
int main(int argc, char** argv)
{
g_test_init(&argc, &argv,NULL);
@@ -1070,6 +1234,7 @@ int main(int argc, char** argv)
g_test_add_func("/dix/input/attributes", dix_input_attributes);
g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
+ g_test_add_func("/dix/input/event-xi2-conversion", dix_event_to_xi2_conversion);
g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
@@ -1077,7 +1242,9 @@ int main(int argc, char** argv)
g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
g_test_add_func("/include/bit_test_macros", include_bit_test_macros);
g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
-
+ g_test_add_func("/dix/input/touch-create", touch_create);
+ g_test_add_func("/dix/input/touch-find-point", touch_find_point);
+ g_test_add_func("/dix/input/touch-finish", touch_finish);
return g_test_run();
}
diff --git a/test/xi2/protocol-eventconvert.c b/test/xi2/protocol-eventconvert.c
index 0478c33..f8de46b 100644
--- a/test/xi2/protocol-eventconvert.c
+++ b/test/xi2/protocol-eventconvert.c
@@ -149,6 +149,61 @@ static void test_XIRawEvent(RawDeviceEvent *in)
free(swapped);
}
+static void test_values_XITouchOwnershipEvent(TouchOwnershipEvent *in,
+ xXITouchOwnershipEvent *out,
+ BOOL swap)
+{
+ char n;
+
+ if (swap)
+ {
+ swaps(&out->sequenceNumber, n);
+ swapl(&out->length, n);
+ swaps(&out->evtype, n);
+ swaps(&out->deviceid, n);
+ swapl(&out->time, n);
+ swaps(&out->sourceid, n);
+ swapl(&out->touchid, n);
+ swapl(&out->flags, n);
+ }
+
+ g_assert(out->type == GenericEvent);
+ g_assert(out->extension == 0);
+ g_assert(out->length == bytes_to_int32(sizeof(*out) - sizeof(xEvent)));
+ g_assert(out->evtype == XI_TouchOwnership);
+ g_assert(out->deviceid == in->deviceid);
+ g_assert(out->time == in->time);
+ g_assert(out->sourceid == in->sourceid);
+ g_assert(out->reason == in->reason);
+ g_assert(out->touchid == in->touchid);
+ g_assert(out->flags == in->flags);
+}
+
+static void test_convert_XITouchOwnershipEvent(void)
+{
+ TouchOwnershipEvent in;
+ xXITouchOwnershipEvent *out, swapped;
+ int rc;
+
+ in.header = ET_Internal;
+ in.type = ET_TouchOwnership;
+ in.touchid = 0xdeadbeef;
+ in.time = 234;
+ in.deviceid = 12;
+ in.sourceid = 14;
+ in.reason = XITouchOwnerAccept;
+ in.resource = 0xcafebabe;
+ in.flags = 0;
+ rc = EventToXI2((InternalEvent *) &in, (xEvent **) &out);
+ g_assert(rc == Success);
+
+ test_values_XITouchOwnershipEvent(&in, out, FALSE);
+ XI2EventSwap((xGenericEvent*)out, (xGenericEvent*)&swapped);
+ test_values_XITouchOwnershipEvent(&in, &swapped, TRUE);
+
+ free(out);
+}
+
static void test_convert_XIFocusEvent(void)
{
xEvent *out;
@@ -272,7 +327,7 @@ static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
int buttons, valuators;
int i;
unsigned char *ptr;
- uint32_t flagmask = 0;
+ uint32_t flagmask;
FP3232 *values;
if (swap) {
@@ -311,9 +366,20 @@ static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
g_assert(out->sourceid == in->sourceid);
switch (in->type) {
+ case ET_TouchBegin:
+ case ET_TouchEnd:
+ flagmask = XITouchOwner;
+ break;
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_Motion:
+ flagmask = XITouchPointer;
+ break;
case ET_KeyPress:
flagmask = XIKeyRepeat;
break;
+ case ET_TouchMotion:
+ case ET_TouchMotionUnowned:
default:
flagmask = 0;
break;
@@ -636,6 +702,50 @@ static void test_convert_XIDeviceEvent(void)
}
}
+static void test_convert_XITouch(void)
+{
+ DeviceEvent in;
+
+ memset(&in, 0, sizeof(in));
+
+ g_test_message("Testing TouchBegin");
+ in.header = ET_Internal;
+ in.type = ET_TouchBegin;
+ 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;
+ in.flags = XITouchOwner;
+ test_XIDeviceEvent(&in);
+
+ in.flags = 0;
+ g_test_message("Testing TouchMotion");
+ in.type = ET_TouchMotion;
+ test_XIDeviceEvent(&in);
+
+ g_test_message("Testing TouchMotionUnowned");
+ in.type = ET_TouchMotionUnowned;
+ test_XIDeviceEvent(&in);
+
+ g_test_message("Testing TouchEnd");
+ in.type = ET_TouchEnd;
+ test_XIDeviceEvent(&in);
+}
+
static void test_values_XIDeviceChangedEvent(DeviceChangedEvent *in,
xXIDeviceChangedEvent *out,
BOOL swap)
@@ -912,6 +1022,8 @@ int main(int argc, char** argv)
g_test_add_func("/xi2/eventconvert/XIFocusEvent", test_convert_XIFocusEvent);
g_test_add_func("/xi2/eventconvert/XIDeviceEvent", test_convert_XIDeviceEvent);
g_test_add_func("/xi2/eventconvert/XIDeviceChangedEvent", test_convert_XIDeviceChangedEvent);
+ g_test_add_func("/xi2/eventconvert/XITouch", test_convert_XITouch);
+ g_test_add_func("/xi2/eventconvert/XITouchOwnership", test_convert_XITouchOwnershipEvent);
return g_test_run();
}
diff --git a/test/xi2/protocol-xiselectevents.c b/test/xi2/protocol-xiselectevents.c
index f951a14..4564840 100644
--- a/test/xi2/protocol-xiselectevents.c
+++ b/test/xi2/protocol-xiselectevents.c
@@ -159,7 +159,23 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req)
memset(bits, 0, mask->mask_len * 4);
for (j = 0; j <= XI2LASTEVENT; j++)
{
+ /* Can't select for these events alone */
+ if (j == XI_TouchBegin || j == XI_TouchOwnership ||
+ j == XI_TouchEnd)
+ continue;
+
SetBit(bits, j);
+
+ /* Must select for TouchBegin + TouchOwnership + TouchEnd together,
+ * plus TouchMotion and optionally also TouchMotionUnowned */
+ if (j == XI_TouchMotion || j == XI_TouchMotionUnowned) {
+ SetBit(bits, XI_TouchBegin);
+ SetBit(bits, XI_TouchOwnership);
+ SetBit(bits, XI_TouchEnd);
+ if (j == XI_TouchMotionUnowned)
+ SetBit(bits, XI_TouchMotion);
+ }
+
request_XISelectEvent(req, Success);
ClearBit(bits, j);
}
@@ -175,7 +191,23 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req)
for (j = 0; j <= XI2LASTEVENT; j++)
{
+ /* Can't select for these events alone */
+ if (j == XI_TouchBegin || j == XI_TouchOwnership ||
+ j == XI_TouchEnd)
+ continue;
+
SetBit(bits, j);
+
+ /* Must select for TouchBegin + TouchOwnership + TouchEnd together,
+ * plus TouchMotion and optionally also TouchMotionUnowned */
+ if (j == XI_TouchMotion || j == XI_TouchMotionUnowned) {
+ SetBit(bits, XI_TouchBegin);
+ SetBit(bits, XI_TouchOwnership);
+ SetBit(bits, XI_TouchEnd);
+ if (j == XI_TouchMotionUnowned)
+ SetBit(bits, XI_TouchMotion);
+ }
+
request_XISelectEvent(req, Success);
}
@@ -189,7 +221,23 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req)
for (j = XI2LASTEVENT + 1; j < mask->mask_len * 4; j++)
{
+ /* Can't select for these events alone */
+ if (j == XI_TouchBegin || j == XI_TouchOwnership ||
+ j == XI_TouchEnd)
+ continue;
+
SetBit(bits, j);
+
+ /* Must select for TouchBegin + TouchOwnership + TouchEnd together,
+ * plus TouchMotion and optionally also TouchMotionUnowned */
+ if (j == XI_TouchMotion || j == XI_TouchMotionUnowned) {
+ SetBit(bits, XI_TouchBegin);
+ SetBit(bits, XI_TouchOwnership);
+ SetBit(bits, XI_TouchEnd);
+ if (j == XI_TouchMotionUnowned)
+ SetBit(bits, XI_TouchMotion);
+ }
+
request_XISelectEvent(req, BadValue);
ClearBit(bits, j);
}
@@ -202,7 +250,23 @@ static void request_XISelectEvents_masks(xXISelectEventsReq *req)
memset(bits, 0, mask->mask_len * 4);
for (j = 0; j <= XI2LASTEVENT; j++)
{
+ /* Can't select for these events alone */
+ if (j == XI_TouchBegin || j == XI_TouchOwnership ||
+ j == XI_TouchEnd)
+ continue;
+
SetBit(bits, j);
+
+ /* Must select for TouchBegin + TouchOwnership + TouchEnd together,
+ * plus TouchMotion and optionally also TouchMotionUnowned */
+ if (j == XI_TouchMotion || j == XI_TouchMotionUnowned) {
+ SetBit(bits, XI_TouchBegin);
+ SetBit(bits, XI_TouchOwnership);
+ SetBit(bits, XI_TouchEnd);
+ if (j == XI_TouchMotionUnowned)
+ SetBit(bits, XI_TouchMotion);
+ }
+
request_XISelectEvent(req, Success);
}
--
1.7.2.3
More information about the xorg-devel
mailing list