Series applied. The client keyboard stuff is something I've been wanting to add for a while. Thanks Neil! I like more tests :-)
---- U. Artie Eoff > -----Original Message----- > From: wayland-devel-bounces+ullysses.a.eoff=intel....@lists.freedesktop.org > [mailto:wayland-devel- > bounces+ullysses.a.eoff=intel....@lists.freedesktop.org] On Behalf Of Neil > Roberts > Sent: Wednesday, September 25, 2013 11:07 AM > To: wayland-devel@lists.freedesktop.org > Subject: [PATCH 3/3 wayland-fits] core: Add a test for multiple pointer and > keyboard resources > > This adds a test which creates multiple pointer and keyboard resources > for the same client and verifies that they all receive events. It also > tests various combiniations of pointer and keyboard focus and ensures > that for example a keyboard created while the surface already has > focus will correctly get updated about the state. > --- > src/test/core/Makefile.am | 1 + > src/test/core/test_multi_resource.cpp | 259 > ++++++++++++++++++++++++++++++++++ > 2 files changed, 260 insertions(+) > create mode 100644 src/test/core/test_multi_resource.cpp > > diff --git a/src/test/core/Makefile.am b/src/test/core/Makefile.am > index 3a93a67..ec7901b 100644 > --- a/src/test/core/Makefile.am > +++ b/src/test/core/Makefile.am > @@ -19,6 +19,7 @@ libwfits_core_la_SOURCES = \ > test_bind_interface.cpp \ > test_cursor.cpp \ > test_data.cpp \ > + test_multi_resource.cpp \ > test_surface.cpp \ > test_dnd.cpp > > diff --git a/src/test/core/test_multi_resource.cpp > b/src/test/core/test_multi_resource.cpp > new file mode 100644 > index 0000000..d3fb003 > --- /dev/null > +++ b/src/test/core/test_multi_resource.cpp > @@ -0,0 +1,259 @@ > +/* > + * Copyright © 2013 Intel Corporation > + * > + * Permission to use, copy, modify, distribute, and sell this software and > + * its documentation for any purpose is hereby granted without fee, provided > + * that the above copyright notice appear in all copies and that both that > + * copyright notice and this permission notice appear in supporting > + * documentation, and that the name of the copyright holders not be used in > + * advertising or publicity pertaining to distribution of the software > + * without specific, written prior permission. The copyright holders make > + * no representations about the suitability of this software for any > + * purpose. It is provided "as is" without express or implied warranty. > + * > + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS > + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND > + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY > + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER > + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF > + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN > + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include "harness.h" > +#include "compositor.h" > +#include "pointer.h" > +#include "keyboard.h" > +#include "seat.h" > +#include "surface.h" > +#include "shell.h" > +#include "shell_surface.h" > +#include "shm.h" > + > +namespace wfits { > +namespace test { > +namespace core { > +namespace input { > + > +class DummyClient > +{ > +public: > + DummyClient() > + : display_() > + , compositor_(display_) > + , shell_(display_) > + , seat_(display_) > + , surface_(compositor_) > + , shellSurface_(shell_, surface_) > + , shm_(display_) > + , buffer_(shm_, 128, 128) > + { > + wl_surface_attach(surface_, buffer_, 0, 0); > + wl_surface_damage(surface_, 0, 0, > + buffer_.width(), buffer_.height()); > + surface_.commit(); > + } > + > +private: > + Display display_; > + Compositor compositor_; > + Shell shell_; > + Seat seat_; > + Surface surface_; > + ShellSurface shellSurface_; > + SharedMemory shm_; > + SharedMemoryBuffer buffer_; > +}; > + > +class MultiResourceTest : public Harness > +{ > +public: > + MultiResourceTest() > + : Harness::Harness() > + , compositor_(display()) > + , shell_(display()) > + , seat_(display()) > + , surface_(compositor_) > + , shellSurface_(shell_, surface_) > + , shm_(display()) > + , buffer_(shm_, 128, 128) > + { > + } > + > + void setup(); > + void testPointer(); > + void testKeyboard(); > + > + void movePointer(const int32_t x, const int32_t y) > + { > + Geometry geometry(getSurfaceGeometry(surface_)); > + setGlobalPointerPosition(geometry.x + x, geometry.y + y); > + } > + > + void checkPointer(Pointer *pointer, const int32_t x, const int32_t y) > + { > + YIELD_UNTIL(pointer->x() == x and pointer->y() == y); > + } > + > +private: > + Compositor compositor_; > + Shell shell_; > + Seat seat_; > + Surface surface_; > + ShellSurface shellSurface_; > + SharedMemory shm_; > + SharedMemoryBuffer buffer_; > +}; > + > +void MultiResourceTest::setup() > +{ > + wl_surface_attach(surface_, buffer_, 0, 0); > + wl_surface_damage(surface_, 0, 0, buffer_.width(), buffer_.height()); > + surface_.commit(); > + > + queueStep(boost::bind(&MultiResourceTest::testPointer, > boost::ref(*this))); > + queueStep(boost::bind(&MultiResourceTest::testKeyboard, > boost::ref(*this))); > +} > + > +void MultiResourceTest::testPointer() > +{ > + Pointer *pointer_a = new Pointer(seat_); > + Pointer *pointer_b = new Pointer(seat_); > + > + movePointer(42, 120); > + > + /* Verify that both pointers received the new position */ > + YIELD_UNTIL(pointer_a->hasFocus(surface_)); > + YIELD_UNTIL(pointer_b->hasFocus(surface_)); > + checkPointer(pointer_a, 42, 120); > + checkPointer(pointer_b, 42, 120); > + > + /* Move the pointer outside of the surface */ > + movePointer(130, 130); > + YIELD_UNTIL(!pointer_a->hasFocus(surface_)); > + YIELD_UNTIL(!pointer_b->hasFocus(surface_)); > + > + /* Move the pointer back inside the surface while we only have > + * one pointer */ > + delete pointer_b; > + yield(); > + movePointer(42, 120); > + YIELD_UNTIL(pointer_a->hasFocus(surface_)); > + checkPointer(pointer_a, 42, 120); > + > + /* Verify that the second pointer gets the updated position > + * even if it is created later */ > + pointer_b = new Pointer(seat_); > + YIELD_UNTIL(pointer_b->hasFocus(surface_)); > + checkPointer(pointer_b, 42, 120); > + > + /* Both pointers should have the same focus serial or one of > + * them would fail to set the cursor */ > + ASSERT(pointer_a->focusSerial() == pointer_b->focusSerial()); > + > + delete pointer_a; > + delete pointer_b; > +} > + > +void MultiResourceTest::testKeyboard() > +{ > + Keyboard *keyboard_a = new Keyboard(seat_); > + Keyboard *keyboard_b = new Keyboard(seat_); > + > + /* Both keyboards should initially have focus */ > + YIELD_UNTIL(keyboard_a->hasFocus(surface_)); > + YIELD_UNTIL(keyboard_b->hasFocus(surface_)); > + > + xkb_mod_index_t shiftMod = > + xkb_keymap_mod_get_index(keyboard_a->keymap(), > + XKB_MOD_NAME_SHIFT); > + ASSERT(shiftMod != XKB_MOD_INVALID); > + > + inputKeySend(KEY_LEFTSHIFT, 1); > + inputKeySend(KEY_A, 1); > + > + /* Both keyboards should get key events */ > + YIELD_UNTIL(keyboard_a->keyPressed(KEY_LEFTSHIFT) and > + keyboard_b->keyPressed(KEY_LEFTSHIFT) and > + keyboard_a->keyPressed(KEY_A) and > + keyboard_b->keyPressed(KEY_A) and > + (keyboard_a->modsDepressed() & (1 << shiftMod)) != 0 and > + (keyboard_b->modsDepressed() & (1 << shiftMod)) != 0); > + > + inputKeySend(KEY_LEFTSHIFT, 0); > + inputKeySend(KEY_A, 0); > + > + YIELD_UNTIL(!keyboard_a->keyPressed(KEY_LEFTSHIFT) and > + !keyboard_b->keyPressed(KEY_LEFTSHIFT) and > + !keyboard_a->keyPressed(KEY_A) and > + !keyboard_b->keyPressed(KEY_A) and > + (keyboard_a->modsDepressed() & (1 << shiftMod)) == 0 and > + (keyboard_b->modsDepressed() & (1 << shiftMod)) == 0); > + > + /* Create another surface with a dummy display so that we can > + * be sure this client doesn't have focus */ > + DummyClient dummyClient; > + > + /* Give the old surface pointer focus but not keyboard focus */ > + movePointer(5, 5); > + { > + Pointer pointer(seat_); > + YIELD_UNTIL(!keyboard_a->hasFocus(surface_) and > + pointer.hasFocus(surface_)); > + } > + > + /* We should still be able to see the modifiers even though we > + * don't have a pointer resource and the surface doesn't have > + * keyboard focus */ > + inputKeySend(KEY_LEFTSHIFT, 1); > + YIELD_UNTIL((keyboard_a->modsDepressed() & (1 << shiftMod)) and > + (keyboard_b->modsDepressed() & (1 << shiftMod))); > + inputKeySend(KEY_LEFTSHIFT, 0); > + YIELD_UNTIL((keyboard_a->modsDepressed() & (1 << shiftMod)) == 0 and > + (keyboard_b->modsDepressed() & (1 << shiftMod)) == 0); > + > + delete keyboard_b; > + > + inputKeySend(KEY_A, 1); > + yield(); > + > + /* This client doesn't have focus so we shouldn't be able to > + * see the key press */ > + YIELD_UNTIL(!keyboard_a->keyPressed(KEY_A)); > + > + /* Give the surface focus by clicking on it */ > + inputKeySend(BTN_LEFT, 1); > + yield(); > + inputKeySend(BTN_LEFT, 0); > + yield(); > + > + /* The surface should now be told about the keypresses in the > + * enter event */ > + YIELD_UNTIL(keyboard_a->hasFocus(surface_) and > + keyboard_a->keyPressed(KEY_A)); > + > + inputKeySend(KEY_LEFTSHIFT, 1); > + YIELD_UNTIL(keyboard_a->keyPressed(KEY_LEFTSHIFT) and > + (keyboard_a->modsDepressed() & (1 << shiftMod))); > + > + /* If we later create another keyboard resource it should be > + * told about the modifiers and key presses on creation */ > + keyboard_b = new Keyboard(seat_); > + YIELD_UNTIL(keyboard_b->hasFocus(surface_) and > + keyboard_b->keyPressed(KEY_A) and > + keyboard_b->keyPressed(KEY_LEFTSHIFT) and > + (keyboard_b->modsDepressed() & (1 << shiftMod))); > + > + inputKeySend(KEY_A, 0); > + inputKeySend(KEY_LEFTSHIFT, 0); > + > + delete keyboard_a; > + delete keyboard_b; > +} > + > +WFITS_CORE_HARNESS_TEST_CASE(MultiResourceTest); > + > +} // namespace input > +} // namespace core > +} // namespace test > +} // namespace wfits > -- > 1.8.3.1 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel