Re: [PATCH 2/2] Add test for XIQueryPointer button mask when physical touch is active

2012-05-15 Thread Chase Douglas
On 05/01/2012 10:21 PM, Peter Hutterer wrote:
 On Wed, Apr 25, 2012 at 06:15:51PM -0700, Chase Douglas wrote:
 Signed-off-by: Chase Douglas chase.doug...@canonical.com
 ---
 The functions to wait for specific events should probably be moved to
 xorg-gtest eventually, but I want to make sure they are generic enough for
 all use cases before doing that.
 
 I don't think I'm really qualified to review that properly, I'm not too
 familiar with the xorg-gtest.
 
 one comment: this patch should probably be split into the actual
 XIQueryPointer part and the misc helper functions beeing added.

Done.

[snip]

 +/**
 + * Wait for an event of a specific type on the X connection.
 + *
 + * param [in] display   The X display connection
 + * param [in] type  The X core protocol event type
 + * param [in] extension The X extension opcode of a generic event, or -1 
 for any
 + *  generic event
 + * param [in] evtypeThe X extension event type of a generic event, or 
 -1 for
 + *  any event of the given extension
 + * param [in] timeout   The timeout in milliseconds
 + *
 + * @return Whether an event is available
 + */
 +bool wait_for_event_of_type(::Display *display, int type, int extension,
 +int evtype, time_t timeout = 1000)
 +{
 +while (wait_for_event(display)) {
 +XEvent event;
 +if (!XPeekEvent(display, event))
 +throw std::runtime_error(Failed to peek X event);
 +
 +if (event.type != type) {
 +if (XNextEvent(display, event) != Success)
 +throw std::runtime_error(Failed to remove X event);
 +continue;
 +}
 +if (event.type != GenericEvent || extension == -1)
 +return true;
 +
 
 this could be simplified with XCheckTypedEvent

I looked into this, but it would cause differences in behavior depending
on whether you are looking for a generic event of a specific evtype vs a
normal event type. For example, you have the following event queue:

Exposure
Generic: XI_ButtonPress
Generic: XI_TouchBegin
EnterWindow

If you use XCheckTypedEvent, which removes the returned event from the
queue, the result of the following is different:

get_event_of_type(display, EnterWindow, -1, -1, event);
Queue is now:
Exposure
Generic: XI_ButtonPress
Generic: XI_TouchBegin

get_event_of_type(display, GenericEvent, xi2_opcode, XI_TouchBegin, event);
Queue is now:
Exposure
EnterWindow

Notice how we lost the Generic: XI_ButtonPress event. This is because
we call XCheckTypedEvent to get the next GenericEvent, but then we need
to discard it because the first event is the XI_ButtonPress. The result
is that sometimes, depending on the event type you request, other event
types are not discarded, but other times some events are discarded.

The current approach always discards events until the first match. It's
more consistent. If the user really needs functionality like
XCheckTypedEvent, they can use it manually.

I will update the comment for this function to make it clear that all
events up to the matched event are discarded.

[snip]

 +/**
 + * XIQueryPointer for XInput 2.1 and earlier should report the first button
 + * pressed if a touch is physically active. For XInput 2.2 and later 
 clients,
 + * the first button should not be reported.
 + */
 +TEST_P(XInput2Test, XIQueryPointerTouchscreen)
 +{
 +XIEventMask mask;
 +mask.deviceid = XIAllDevices;
 +mask.mask_len = XIMaskLen(XI_HierarchyChanged);
 +mask.mask = reinterpret_castunsigned char*(
 +calloc(XIMaskLen(XI_HierarchyChanged), 1));
 +XISetMask(mask.mask, XI_HierarchyChanged);
 +
 +ASSERT_EQ(Success,
 +  XISelectEvents(Display(), DefaultRootWindow(Display()), mask,
 +  1));
 +
 
 odd choice of line breaking. makes the code harder to read, IMO.
 
 +mask.deviceid = XIAllMasterDevices;
 +XIClearMask(mask.mask, XI_HierarchyChanged);
 +XISetMask(mask.mask, XI_ButtonPress);
 +
 +ASSERT_EQ(Success,
 +  XISelectEvents(Display(), DefaultRootWindow(Display()), mask,
 +  1));
 
 as above

Thanks for catching these. The 1 should be indented to align inside the
XISelectEvents call.

 rest looks ok (only skimmed it).

Ok. I'll resend with these changes.

-- Chase
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel


Re: [PATCH 2/2] Add test for XIQueryPointer button mask when physical touch is active

2012-05-15 Thread Peter Hutterer
On Tue, May 15, 2012 at 10:44:51AM -0700, Chase Douglas wrote:
 On 05/01/2012 10:21 PM, Peter Hutterer wrote:
  On Wed, Apr 25, 2012 at 06:15:51PM -0700, Chase Douglas wrote:
  Signed-off-by: Chase Douglas chase.doug...@canonical.com
  ---
  The functions to wait for specific events should probably be moved to
  xorg-gtest eventually, but I want to make sure they are generic enough for
  all use cases before doing that.
  
  I don't think I'm really qualified to review that properly, I'm not too
  familiar with the xorg-gtest.
  
  one comment: this patch should probably be split into the actual
  XIQueryPointer part and the misc helper functions beeing added.
 
 Done.
 
 [snip]
 
  +/**
  + * Wait for an event of a specific type on the X connection.
  + *
  + * param [in] display   The X display connection
  + * param [in] type  The X core protocol event type
  + * param [in] extension The X extension opcode of a generic event, or -1 
  for any
  + *  generic event
  + * param [in] evtypeThe X extension event type of a generic event, or 
  -1 for
  + *  any event of the given extension
  + * param [in] timeout   The timeout in milliseconds
  + *
  + * @return Whether an event is available
  + */
  +bool wait_for_event_of_type(::Display *display, int type, int extension,
  +int evtype, time_t timeout = 1000)
  +{
  +while (wait_for_event(display)) {
  +XEvent event;
  +if (!XPeekEvent(display, event))
  +throw std::runtime_error(Failed to peek X event);
  +
  +if (event.type != type) {
  +if (XNextEvent(display, event) != Success)
  +throw std::runtime_error(Failed to remove X event);
  +continue;
  +}
  +if (event.type != GenericEvent || extension == -1)
  +return true;
  +
  
  this could be simplified with XCheckTypedEvent
 
 I looked into this, but it would cause differences in behavior depending
 on whether you are looking for a generic event of a specific evtype vs a
 normal event type. For example, you have the following event queue:
 
 Exposure
 Generic: XI_ButtonPress
 Generic: XI_TouchBegin
 EnterWindow
 
 If you use XCheckTypedEvent, which removes the returned event from the
 queue, the result of the following is different:
 
 get_event_of_type(display, EnterWindow, -1, -1, event);
 Queue is now:
 Exposure
 Generic: XI_ButtonPress
 Generic: XI_TouchBegin
 
 get_event_of_type(display, GenericEvent, xi2_opcode, XI_TouchBegin, event);
 Queue is now:
 Exposure
 EnterWindow
 
 Notice how we lost the Generic: XI_ButtonPress event. This is because
 we call XCheckTypedEvent to get the next GenericEvent, but then we need
 to discard it because the first event is the XI_ButtonPress. The result
 is that sometimes, depending on the event type you request, other event
 types are not discarded, but other times some events are discarded.

right, looks like what we really need is a generic event-capable version for
XCheckTypedEvent so that we can have this sort of code with predictable
effects.

with the updated comment this code makes more sense now. thanks.

Cheers,
  Peter

 The current approach always discards events until the first match. It's
 more consistent. If the user really needs functionality like
 XCheckTypedEvent, they can use it manually.
 
 I will update the comment for this function to make it clear that all
 events up to the matched event are discarded.
 
 [snip]
 
  +/**
  + * XIQueryPointer for XInput 2.1 and earlier should report the first 
  button
  + * pressed if a touch is physically active. For XInput 2.2 and later 
  clients,
  + * the first button should not be reported.
  + */
  +TEST_P(XInput2Test, XIQueryPointerTouchscreen)
  +{
  +XIEventMask mask;
  +mask.deviceid = XIAllDevices;
  +mask.mask_len = XIMaskLen(XI_HierarchyChanged);
  +mask.mask = reinterpret_castunsigned char*(
  +calloc(XIMaskLen(XI_HierarchyChanged), 1));
  +XISetMask(mask.mask, XI_HierarchyChanged);
  +
  +ASSERT_EQ(Success,
  +  XISelectEvents(Display(), DefaultRootWindow(Display()), 
  mask,
  +  1));
  +
  
  odd choice of line breaking. makes the code harder to read, IMO.
  
  +mask.deviceid = XIAllMasterDevices;
  +XIClearMask(mask.mask, XI_HierarchyChanged);
  +XISetMask(mask.mask, XI_ButtonPress);
  +
  +ASSERT_EQ(Success,
  +  XISelectEvents(Display(), DefaultRootWindow(Display()), 
  mask,
  +  1));
  
  as above
 
 Thanks for catching these. The 1 should be indented to align inside the
 XISelectEvents call.
 
  rest looks ok (only skimmed it).
 
 Ok. I'll resend with these changes.
 
 -- Chase
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel


Re: [PATCH 2/2] Add test for XIQueryPointer button mask when physical touch is active

2012-05-01 Thread Peter Hutterer
On Wed, Apr 25, 2012 at 06:15:51PM -0700, Chase Douglas wrote:
 Signed-off-by: Chase Douglas chase.doug...@canonical.com
 ---
 The functions to wait for specific events should probably be moved to
 xorg-gtest eventually, but I want to make sure they are generic enough for
 all use cases before doing that.

I don't think I'm really qualified to review that properly, I'm not too
familiar with the xorg-gtest.

one comment: this patch should probably be split into the actual
XIQueryPointer part and the misc helper functions beeing added.

  configure.ac   |   14 +
  test/integration/.gitignore|1 +
  test/integration/Makefile.am   |   24 ++
  .../recordings/ntrig_dell_xt2/1_begin.record   |   11 +
  .../recordings/ntrig_dell_xt2/1_end.record |3 +
  .../recordings/ntrig_dell_xt2/device.prop  |   32 +++
  test/integration/xi2.cpp   |  267 
 
  7 files changed, 352 insertions(+), 0 deletions(-)
  create mode 100644 test/integration/.gitignore
  create mode 100644 test/integration/recordings/ntrig_dell_xt2/1_begin.record
  create mode 100644 test/integration/recordings/ntrig_dell_xt2/1_end.record
  create mode 100644 test/integration/recordings/ntrig_dell_xt2/device.prop
  create mode 100644 test/integration/xi2.cpp
 
 diff --git a/configure.ac b/configure.ac
 index fe350c9..bc9f46f 100644
 --- a/configure.ac
 +++ b/configure.ac
 @@ -2141,6 +2141,20 @@ if [test x$XORG = xyes  test 
 x$enable_integration_tests != xno]; then
  fi
  fi
  
 +PKG_CHECK_MODULES(TEST_X11, x11, have_test_x11=yes, have_test_x11=no)
 +PKG_CHECK_MODULES(TEST_XINPUT, [xi = 1.6], have_test_xinput=yes, 
 have_test_xinput=no)
 +
 +if [test x$have_test_x11 != xyes]; then
 +AC_MSG_NOTICE([libX11 not available, skipping input tests])
 +elif [test x$have_test_xinput != xyes]; then
 +AC_MSG_NOTICE([libXi 1.6 not available, skipping input tests])
 +elif [test x$have_xorg_gtest_evemu != xyes]; then
 +AC_MSG_NOTICE([uTouch-Evemu not available, skipping input tests])
 +else
 +enable_input_tests=yes
 +fi
 +AM_CONDITIONAL(ENABLE_XORG_GTEST_INPUT_TESTS, [test x$enable_input_tests = 
 xyes])
 +
  dnl and the rest of these are generic, so they're in config.h
  dnl 
  dnl though, thanks to the passing of some significant amount of time, the
 diff --git a/test/integration/.gitignore b/test/integration/.gitignore
 new file mode 100644
 index 000..ab86ebf
 --- /dev/null
 +++ b/test/integration/.gitignore
 @@ -0,0 +1 @@
 +gtest-tests
 diff --git a/test/integration/Makefile.am b/test/integration/Makefile.am
 index e70d642..3b7c858 100644
 --- a/test/integration/Makefile.am
 +++ b/test/integration/Makefile.am
 @@ -1,4 +1,28 @@
 +TESTS =
 +
  if ENABLE_XORG_GTEST_TESTS
  include $(top_srcdir)/test/integration/Makefile-xorg-gtest.am
  check_LIBRARIES = $(XORG_GTEST_BUILD_LIBS)
 +
 +if ENABLE_XORG_GTEST_INPUT_TESTS
 +TESTS += gtest-tests
  endif
 +endif
 +
 +check_PROGRAMS = $(TESTS)
 +
 +AM_CPPFLAGS = \
 + -DDEFAULT_XORG_SERVER=\$(abs_top_builddir)/hw/xfree86/Xorg\ \
 + -DTEST_ROOT_DIR=\$(abs_top_srcdir)/test/integration/\ \
 + $(GTEST_CPPFLAGS) \
 + $(XORG_GTEST_CPPFLAGS)
 +
 +AM_CXXFLAGS = $(GTEST_CXXFLAGS) $(XORG_GTEST_CXXFLAGS)
 +
 +gtest_tests_SOURCES = xi2.cpp
 +gtest_tests_LDADD = \
 + $(TEST_XINPUT_LIBS) \
 + $(TEST_X11_LIBS) \
 + $(XORG_GTEST_LIBS) \
 + $(EVEMU_LIBS) \
 + $(XORG_GTEST_MAIN_LIBS)
 diff --git a/test/integration/recordings/ntrig_dell_xt2/1_begin.record 
 b/test/integration/recordings/ntrig_dell_xt2/1_begin.record
 new file mode 100644
 index 000..28a849b
 --- /dev/null
 +++ b/test/integration/recordings/ntrig_dell_xt2/1_begin.record
 @@ -0,0 +1,11 @@
 +E: 1327542640.244087 0003  2745
 +E: 1327542640.244089 0003 0001 1639
 +E: 1327542640.244090 0003 0035 2745
 +E: 1327542640.244091 0003 0036 1639
 +E: 1327542640.244092 0003 0034 0
 +E: 1327542640.244093 0003 0030 468
 +E: 1327542640.244094 0003 0031 306
 +E: 1327542640.244095  0002 0
 +E: 1327542640.244251 0001 014d 1
 +E: 1327542640.244251 0001 014a 1
 +E: 1327542640.244253   0
 diff --git a/test/integration/recordings/ntrig_dell_xt2/1_end.record 
 b/test/integration/recordings/ntrig_dell_xt2/1_end.record
 new file mode 100644
 index 000..cd6a9d9
 --- /dev/null
 +++ b/test/integration/recordings/ntrig_dell_xt2/1_end.record
 @@ -0,0 +1,3 @@
 +E: 1327542642.244253 0001 014d 0
 +E: 1327542642.244253 0001 014a 0
 +E: 1327542642.244253   0

I really recommend renaming these as touch_1_begin and touch_1_end. 1 could
otherwise refer to buttons as well.

 diff --git a/test/integration/recordings/ntrig_dell_xt2/device.prop 
 b/test/integration/recordings/ntrig_dell_xt2/device.prop
 new file mode 100644
 index 000..2738c04
 --- /dev/null
 +++ b/test/integration/recordings/ntrig_dell_xt2/device.prop
 @@ -0,0 +1,32 @@
 +N: N-Trig MultiTouch (Virtual Test Device)
 

[PATCH 2/2] Add test for XIQueryPointer button mask when physical touch is active

2012-04-25 Thread Chase Douglas
Signed-off-by: Chase Douglas chase.doug...@canonical.com
---
The functions to wait for specific events should probably be moved to
xorg-gtest eventually, but I want to make sure they are generic enough for
all use cases before doing that.

 configure.ac   |   14 +
 test/integration/.gitignore|1 +
 test/integration/Makefile.am   |   24 ++
 .../recordings/ntrig_dell_xt2/1_begin.record   |   11 +
 .../recordings/ntrig_dell_xt2/1_end.record |3 +
 .../recordings/ntrig_dell_xt2/device.prop  |   32 +++
 test/integration/xi2.cpp   |  267 
 7 files changed, 352 insertions(+), 0 deletions(-)
 create mode 100644 test/integration/.gitignore
 create mode 100644 test/integration/recordings/ntrig_dell_xt2/1_begin.record
 create mode 100644 test/integration/recordings/ntrig_dell_xt2/1_end.record
 create mode 100644 test/integration/recordings/ntrig_dell_xt2/device.prop
 create mode 100644 test/integration/xi2.cpp

diff --git a/configure.ac b/configure.ac
index fe350c9..bc9f46f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2141,6 +2141,20 @@ if [test x$XORG = xyes  test 
x$enable_integration_tests != xno]; then
 fi
 fi
 
+PKG_CHECK_MODULES(TEST_X11, x11, have_test_x11=yes, have_test_x11=no)
+PKG_CHECK_MODULES(TEST_XINPUT, [xi = 1.6], have_test_xinput=yes, 
have_test_xinput=no)
+
+if [test x$have_test_x11 != xyes]; then
+AC_MSG_NOTICE([libX11 not available, skipping input tests])
+elif [test x$have_test_xinput != xyes]; then
+AC_MSG_NOTICE([libXi 1.6 not available, skipping input tests])
+elif [test x$have_xorg_gtest_evemu != xyes]; then
+AC_MSG_NOTICE([uTouch-Evemu not available, skipping input tests])
+else
+enable_input_tests=yes
+fi
+AM_CONDITIONAL(ENABLE_XORG_GTEST_INPUT_TESTS, [test x$enable_input_tests = 
xyes])
+
 dnl and the rest of these are generic, so they're in config.h
 dnl 
 dnl though, thanks to the passing of some significant amount of time, the
diff --git a/test/integration/.gitignore b/test/integration/.gitignore
new file mode 100644
index 000..ab86ebf
--- /dev/null
+++ b/test/integration/.gitignore
@@ -0,0 +1 @@
+gtest-tests
diff --git a/test/integration/Makefile.am b/test/integration/Makefile.am
index e70d642..3b7c858 100644
--- a/test/integration/Makefile.am
+++ b/test/integration/Makefile.am
@@ -1,4 +1,28 @@
+TESTS =
+
 if ENABLE_XORG_GTEST_TESTS
 include $(top_srcdir)/test/integration/Makefile-xorg-gtest.am
 check_LIBRARIES = $(XORG_GTEST_BUILD_LIBS)
+
+if ENABLE_XORG_GTEST_INPUT_TESTS
+TESTS += gtest-tests
 endif
+endif
+
+check_PROGRAMS = $(TESTS)
+
+AM_CPPFLAGS = \
+   -DDEFAULT_XORG_SERVER=\$(abs_top_builddir)/hw/xfree86/Xorg\ \
+   -DTEST_ROOT_DIR=\$(abs_top_srcdir)/test/integration/\ \
+   $(GTEST_CPPFLAGS) \
+   $(XORG_GTEST_CPPFLAGS)
+
+AM_CXXFLAGS = $(GTEST_CXXFLAGS) $(XORG_GTEST_CXXFLAGS)
+
+gtest_tests_SOURCES = xi2.cpp
+gtest_tests_LDADD = \
+   $(TEST_XINPUT_LIBS) \
+   $(TEST_X11_LIBS) \
+   $(XORG_GTEST_LIBS) \
+   $(EVEMU_LIBS) \
+   $(XORG_GTEST_MAIN_LIBS)
diff --git a/test/integration/recordings/ntrig_dell_xt2/1_begin.record 
b/test/integration/recordings/ntrig_dell_xt2/1_begin.record
new file mode 100644
index 000..28a849b
--- /dev/null
+++ b/test/integration/recordings/ntrig_dell_xt2/1_begin.record
@@ -0,0 +1,11 @@
+E: 1327542640.244087 0003  2745
+E: 1327542640.244089 0003 0001 1639
+E: 1327542640.244090 0003 0035 2745
+E: 1327542640.244091 0003 0036 1639
+E: 1327542640.244092 0003 0034 0
+E: 1327542640.244093 0003 0030 468
+E: 1327542640.244094 0003 0031 306
+E: 1327542640.244095  0002 0
+E: 1327542640.244251 0001 014d 1
+E: 1327542640.244251 0001 014a 1
+E: 1327542640.244253   0
diff --git a/test/integration/recordings/ntrig_dell_xt2/1_end.record 
b/test/integration/recordings/ntrig_dell_xt2/1_end.record
new file mode 100644
index 000..cd6a9d9
--- /dev/null
+++ b/test/integration/recordings/ntrig_dell_xt2/1_end.record
@@ -0,0 +1,3 @@
+E: 1327542642.244253 0001 014d 0
+E: 1327542642.244253 0001 014a 0
+E: 1327542642.244253   0
diff --git a/test/integration/recordings/ntrig_dell_xt2/device.prop 
b/test/integration/recordings/ntrig_dell_xt2/device.prop
new file mode 100644
index 000..2738c04
--- /dev/null
+++ b/test/integration/recordings/ntrig_dell_xt2/device.prop
@@ -0,0 +1,32 @@
+N: N-Trig MultiTouch (Virtual Test Device)
+I: 0003 1b96 0001 0110
+P: 00 00 00 00 00 00 00 00
+B: 00 0b 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 04 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 01 00 00 00 00 00 00 00 00
+B: 02 00 00 00 00 00 00 00 00
+B: 03 03 00 00 00 00 01 73 00