lib_LTLIBRARIES = libwfits-core.la
-libwfits_core_la_SOURCES = \
- harness.cpp \
- test_bind_interface.cpp \
- test_cursor.cpp \
+libwfits_core_la_SOURCES = \
+ display.cpp \
+ compositor.cpp \
+ shell.cpp \
+ seat.cpp \
+ pointer.cpp \
+ surface.cpp \
+ harness.cpp \
+ test_bind_interface.cpp \
+ test_cursor.cpp \
test_data.cpp
libwfits_core_la_LIBADD = \
--- /dev/null
+#include "compositor.h"
+
+Compositor::Compositor(const Display& display)
+ : display_(display)
+ , wl_compositor_(
+ display.bind<wl_compositor>(
+ "wl_compositor", &wl_compositor_interface))
+{
+ ASSERT(wl_compositor_ != NULL);
+
+ wl_compositor_set_user_data(*this, this);
+}
+
+/*virtual*/ Compositor::~Compositor()
+{
+ wl_compositor_destroy(*this);
+}
--- /dev/null
+#ifndef __WFITS_CORE_COMPOSITOR_H__
+#define __WFITS_CORE_COMPOSITOR_H__
+
+#include "display.h"
+
+class Compositor
+{
+public:
+ Compositor(const Display&);
+
+ virtual ~Compositor();
+
+ operator wl_compositor*() const { return wl_compositor_; }
+ const Display& display() const { return display_; }
+
+private:
+ const Display& display_;
+ wl_compositor *wl_compositor_;
+};
+
+#endif
--- /dev/null
+#include "display.h"
+
+Display::Display()
+ : wl_display_(wl_display_connect(0))
+ , wl_registry_(NULL)
+ , globals_()
+{
+ ASSERT(wl_display_ != NULL);
+
+ wl_registry_ = wl_display_get_registry(*this);
+
+ wl_display_set_user_data(*this, this);
+
+ ASSERT(wl_registry_ != NULL);
+
+ static const struct wl_registry_listener listener = {global};
+
+ wl_registry_add_listener(wl_registry_, &listener, this);
+
+ dispatch();
+}
+
+/*virtual*/ Display::~Display()
+{
+ wl_registry_destroy(wl_registry_);
+ wl_display_disconnect(*this);
+}
+
+void Display::roundtrip() const
+{
+ ASSERT(wl_display_roundtrip(*this) >= 0);
+}
+
+void Display::dispatch() const
+{
+ ASSERT(wl_display_dispatch(*this) >= 0);
+}
+
+/*static*/ void Display::global(
+ void *data, struct wl_registry *wl_registry, uint32_t id,
+ const char* interface, uint32_t version)
+{
+ Display* display = static_cast<Display*>(data);
+
+ ASSERT(display->wl_registry_ == wl_registry);
+
+ display->globals_[std::string(interface)] = GlobalInfo(id, version);
+}
#ifndef __WFITS_CORE_DISPLAY_H__
#define __WFITS_CORE_DISPLAY_H__
+#include <map>
#include <wayland-client.h>
#include "common/test.h"
class Display
{
+ typedef std::pair<uint32_t, uint32_t> GlobalInfo;
+ typedef std::map<std::string, GlobalInfo> Globals;
public:
- Display()
- : display_(wl_display_connect(0))
- {
- FAIL_IF(display_ == NULL);
- }
+ Display();
- virtual ~Display()
+ virtual ~Display();
+
+ template <typename T>
+ T* bind(
+ const std::string& interface,
+ const struct wl_interface *wl_interface) const
{
- wl_display_disconnect(*this);
+ const Globals::const_iterator match(globals_.find(interface));
+
+ ASSERT(match != globals_.end());
+
+ return static_cast<T*>(
+ wl_registry_bind(
+ wl_registry_, match->second.first, wl_interface,
+ match->second.second));
}
- operator wl_display*() { return display_; }
+ void roundtrip() const;
+ void dispatch() const;
+
+ operator wl_display*() const { return wl_display_; }
private:
- wl_display* display_;
+ static void global(
+ void*, struct wl_registry*, uint32_t, const char*, uint32_t);
+
+ wl_display *wl_display_;
+ wl_registry *wl_registry_;
+ Globals globals_;
};
#endif
#include "harness.h"
CoreTestHarness::CoreTestHarness()
- : Display::Display()
- , registry_(0)
+ : display_()
+ , tests_()
{
- registry_ = wl_display_get_registry(*this);
-
- static const struct wl_registry_listener listener = {
- &CoreTestHarness::globalListener
- };
-
- wl_registry_add_listener(registry_, &listener, this);
- FAIL_IF_EQUAL(registry_, NULL);
+ return;
}
CoreTestHarness::~CoreTestHarness()
{
- wl_registry_destroy(*this);
+ return;
}
void CoreTestHarness::queueTest(Test test)
void CoreTestHarness::run()
{
- // trigger client global announcements
- wl_display_dispatch(*this);
-
setup();
while (not tests_.empty())
{
tests_.front()(); // call test
tests_.pop_front(); // remove test
+ display().roundtrip();
}
teardown();
}
-/*static*/
-void CoreTestHarness::globalListener(
- void *data, struct wl_registry *registry, uint32_t id, const char* iface, uint32_t version)
-{
- CoreTestHarness* harness = static_cast<CoreTestHarness*>(data);
- FAIL_UNLESS_EQUAL(registry, *harness);
- harness->handleGlobal(id, std::string(iface), version);
-}
-
class SimpleTest : public CoreTestHarness
{
public:
return;
}
- void handleGlobal(uint32_t, const std::string&, uint32_t)
- {
- return;
- }
-
void setup()
{
queueTest(boost::bind(&SimpleTest::test, boost::ref(*this)));
}
-
+
void test()
{
if (++tested < 10)
queueTest(boost::bind(&SimpleTest::test, boost::ref(*this)));
}
}
-
+
void teardown()
{
FAIL_UNLESS_EQUAL(tested, 10);
}
-
+
unsigned tested;
};
#include <boost/bind.hpp>
#include <deque>
#include <string>
+
#include "display.h"
-class CoreTestHarness : public Display
+class CoreTestHarness
{
public:
typedef boost::function<void()> Test;
/**
* Optionally override this to do any special
- * interface binding and/or setup.
- **/
- virtual void handleGlobal(uint32_t, const std::string&, uint32_t) { };
-
- /**
- * Optionally override this to do any special
* setup before processing Tests.
* i.e. you can queue all your tests from here.
**/
**/
virtual void teardown() { };
- operator wl_registry*() { return registry_; }
+ const Display& display() const { return display_; }
private:
- static void globalListener(void*, struct wl_registry*, uint32_t, const char*, uint32_t);
-
- wl_registry* registry_;
- Tests tests_;
+ Display display_;
+ Tests tests_;
};
#define WFITS_CORE_HARNESS_TEST_CASE(HarnessClass, suite) \
--- /dev/null
+#include "surface.h"
+#include "pointer.h"
+
+Pointer::Pointer(const Seat& seat)
+ : seat_(seat)
+ , focus_(NULL)
+ , x_(-1)
+ , y_(-1)
+ , button_(0)
+ , buttonState_(0)
+ , axis_(0)
+ , axisValue_(0.f)
+ , wl_pointer_(NULL)
+{
+ ASSERT(seat.capabilities() & WL_SEAT_CAPABILITY_POINTER);
+
+ wl_pointer_ = wl_seat_get_pointer(seat);
+
+ ASSERT(wl_pointer_ != NULL);
+
+ wl_pointer_set_user_data(*this, this);
+
+ static const wl_pointer_listener listener = {
+ enter, leave, motion, button, axis};
+
+ wl_pointer_add_listener(*this, &listener, this);
+}
+
+/*virtual*/ Pointer::~Pointer()
+{
+ wl_pointer_destroy(*this);
+}
+
+bool Pointer::hasFocus(const Surface* surface)
+{
+ return focus_ == surface;
+}
+
+/*static*/ void Pointer::enter(
+ void *data, wl_pointer *wl_pointer, uint32_t serial,
+ wl_surface *wl_surface, wl_fixed_t x, wl_fixed_t y)
+{
+ Pointer* pointer = static_cast<Pointer*>(data);
+ ASSERT(wl_pointer == *pointer);
+
+ std::cout << "Pointer::enter(): " << wl_fixed_to_int(x) << " "
+ << wl_fixed_to_int(y) << std::endl;
+
+ pointer->focus_ = static_cast<Surface*>(
+ wl_surface_get_user_data(wl_surface));
+ pointer->x_ = wl_fixed_to_int(x);
+ pointer->y_ = wl_fixed_to_int(y);
+}
+
+/*static*/ void Pointer::leave(
+ void *data, wl_pointer *wl_pointer, uint32_t serial,
+ wl_surface *wl_surface)
+{
+ Pointer* pointer = static_cast<Pointer*>(data);
+ ASSERT(wl_pointer == *pointer);
+
+ std::cout << "Pointer::leave(): " << std::endl;
+
+ pointer->focus_ = NULL;
+ pointer->x_ = -1;
+ pointer->y_ = -1;
+}
+
+/*static*/ void Pointer::motion(
+ void *data, wl_pointer *wl_pointer, uint32_t time,
+ wl_fixed_t x, wl_fixed_t y)
+{
+ Pointer* pointer = static_cast<Pointer*>(data);
+ ASSERT(wl_pointer == *pointer);
+
+ std::cout << "Pointer::motion(): " << wl_fixed_to_int(x) << " "
+ << wl_fixed_to_int(y) << std::endl;
+
+ pointer->x_ = wl_fixed_to_int(x);
+ pointer->y_ = wl_fixed_to_int(y);
+}
+
+/*static*/ void Pointer::button(
+ void *data, wl_pointer *wl_pointer, uint32_t serial,
+ uint32_t time, uint32_t button, uint32_t state)
+{
+ Pointer* pointer = static_cast<Pointer*>(data);
+ ASSERT(wl_pointer == *pointer);
+
+ pointer->button_ = button;
+ pointer->buttonState_ = state;
+}
+
+/*static*/ void Pointer::axis(
+ void *data, wl_pointer *wl_pointer, uint32_t time,
+ uint32_t axis, wl_fixed_t value)
+{
+ Pointer* pointer = static_cast<Pointer*>(data);
+ ASSERT(wl_pointer == *pointer);
+
+ pointer->axis_ = axis;
+ pointer->axisValue_ = wl_fixed_to_double(value);
+}
--- /dev/null
+#ifndef __WFITS_CORE_POINTER_H__
+#define __WFITS_CORE_POINTER_H__
+
+#include "seat.h"
+
+class Surface;
+
+class Pointer
+{
+public:
+ Pointer(const Seat&);
+
+ virtual ~Pointer();
+
+ operator wl_pointer*() const { return wl_pointer_; }
+ const Seat& seat() const { return seat_; }
+
+ bool hasFocus(const Surface*);
+
+private:
+ static void enter(
+ void*, wl_pointer*, uint32_t, wl_surface*, wl_fixed_t, wl_fixed_t);
+ static void leave(
+ void*, wl_pointer*, uint32_t, wl_surface*);
+ static void motion(
+ void*, wl_pointer*, uint32_t, wl_fixed_t, wl_fixed_t);
+ static void button(
+ void*, wl_pointer*, uint32_t, uint32_t, uint32_t, uint32_t);
+ static void axis(
+ void*, wl_pointer*, uint32_t, uint32_t, wl_fixed_t);
+
+ const Seat& seat_;
+ Surface* focus_;
+ int32_t x_;
+ int32_t y_;
+ uint32_t button_;
+ uint32_t buttonState_;
+ uint32_t axis_;
+ uint32_t axisValue_;
+ wl_pointer* wl_pointer_;
+};
+
+#endif
--- /dev/null
+#include "seat.h"
+
+Seat::Seat(const Display& display)
+ : display_(display)
+ , wl_seat_(display.bind<wl_seat>("wl_seat", &wl_seat_interface))
+ , capabilities_(0)
+{
+ ASSERT(wl_seat_ != NULL);
+
+ wl_seat_set_user_data(*this, this);
+
+ static const wl_seat_listener listener = {capabilities};
+ wl_seat_add_listener(*this, &listener, this);
+
+ display.roundtrip();
+}
+
+/*virtual*/ Seat::~Seat()
+{
+ wl_seat_destroy(*this);
+}
+
+/*static*/ void Seat::capabilities(void *data, wl_seat *wl_seat, uint32_t caps)
+{
+ Seat* seat = static_cast<Seat*>(data);
+
+ ASSERT(wl_seat == *seat);
+
+ seat->capabilities_ = caps;
+}
--- /dev/null
+#ifndef __WFITS_CORE_SEAT_H__
+#define __WFITS_CORE_SEAT_H__
+
+#include "display.h"
+
+class Seat
+{
+public:
+ Seat(const Display&);
+
+ virtual ~Seat();
+
+ operator wl_seat*() const { return wl_seat_; }
+ const Display& display() const { return display_; }
+ uint32_t capabilities() const { return capabilities_; }
+
+private:
+ static void capabilities(void*, wl_seat*, uint32_t);
+
+ const Display& display_;
+ wl_seat* wl_seat_;
+ uint32_t capabilities_;
+};
+
+#endif
--- /dev/null
+#include "shell.h"
+
+Shell::Shell(const Display& display)
+ : display_(display)
+ , wl_shell_(
+ display.bind<wl_shell>(
+ "wl_shell", &wl_shell_interface))
+{
+ ASSERT(wl_shell_ != NULL);
+
+ wl_shell_set_user_data(*this, this);
+
+ ASSERT(wl_shell_get_user_data(*this) == this);
+}
+
+/*virtual*/ Shell::~Shell()
+{
+ wl_shell_destroy(*this);
+}
--- /dev/null
+#ifndef __WFITS_CORE_SHELL_H__
+#define __WFITS_CORE_SHELL_H__
+
+#include "display.h"
+
+class Shell
+{
+public:
+ Shell(const Display&);
+
+ virtual ~Shell();
+
+ operator wl_shell*() const { return wl_shell_; }
+ const Display& display() const { return display_; }
+
+private:
+ const Display& display_;
+ wl_shell *wl_shell_;
+};
+
+#endif
--- /dev/null
+#include "surface.h"
+
+Surface::Surface(const Compositor& compositor)
+ : compositor_(compositor)
+ , wl_surface_(
+ wl_compositor_create_surface(compositor))
+{
+ ASSERT(wl_surface_ != NULL);
+
+ wl_surface_set_user_data(*this, this);
+
+ static const wl_surface_listener listener = {enter, leave};
+
+ wl_surface_add_listener(*this, &listener, this);
+
+ compositor.display().roundtrip();
+}
+
+/*virtual*/ Surface::~Surface()
+{
+ wl_surface_destroy(*this);
+}
+
+static void handleDone(void *data, wl_callback *callback, uint32_t time)
+{
+ bool *done = static_cast<bool*>(data);
+ *done = true;
+ wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener doneListener = {handleDone};
+
+void Surface::commit() const
+{
+ bool done(false);
+ wl_callback* callback(wl_surface_frame(*this));
+
+ wl_callback_add_listener(callback, &doneListener, &done);
+ wl_surface_commit(*this);
+
+ while (not done) {
+ compositor().display().dispatch();
+ }
+}
+
+/*static*/ void Surface::enter(
+ void *data, wl_surface *wl_surface, wl_output *wl_output)
+{
+ Surface* surface = static_cast<Surface*>(data);
+ ASSERT(wl_surface == *surface);
+}
+
+/*static*/ void Surface::leave(
+ void *data, wl_surface *wl_surface, wl_output *wl_output)
+{
+ Surface* surface = static_cast<Surface*>(data);
+ ASSERT(wl_surface == *surface);
+}
--- /dev/null
+#ifndef __WFITS_CORE_SURFACE_H__
+#define __WFITS_CORE_SURFACE_H__
+
+#include "compositor.h"
+
+class Surface
+{
+public:
+ Surface(const Compositor&);
+
+ virtual ~Surface();
+
+ operator wl_surface*() const { return wl_surface_; }
+ const Compositor& compositor() const { return compositor_; }
+
+ void commit() const;
+
+private:
+ static void enter(void*, wl_surface*, wl_output*);
+ static void leave(void*, wl_surface*, wl_output*);
+
+ const Compositor& compositor_;
+ wl_surface *wl_surface_;
+};
+
+#endif
-
#include "harness.h"
template <typename O, const wl_interface& interface, const std::string& str_interface>
return;
}
- void handleGlobal(uint32_t id, const std::string& iface, uint32_t)
+ void setup()
{
- if (iface == str_interface)
- {
- object_ = static_cast<O*>(
- wl_registry_bind(
- *this, id, &interface, 1
- )
- );
- }
+ object_ = display().template bind<O>(str_interface, &interface);
}
void teardown()
BIND_TEST(wl_seat)
BIND_TEST(wl_shell)
BIND_TEST(wl_data_device_manager)
+// BIND_TEST(wfits_input)
+// BIND_TEST(wfits_query)
+
public:
ThemeLoadTest()
: CoreTestHarness::CoreTestHarness()
- , shm_(0)
+ , shm_(display().bind<wl_shm>("wl_shm", &wl_shm_interface))
{
- return;
- }
-
- void handleGlobal(uint32_t id, const std::string& iface, uint32_t version)
- {
- if (iface == "wl_shm")
- {
- shm_ = static_cast<wl_shm*>(wl_registry_bind(*this, id, &wl_shm_interface, 1));
- FAIL_IF_EQUAL(shm_, NULL);
- }
+ ASSERT(shm_ != NULL);
}
void setup()
class data_ ## name : public DataTest<name> \
{ \
public: \
- DATA_SETTER_GETTER(name) \
- void handleGlobal(uint32_t id, const std::string& iface, uint32_t version) \
+ data_ ## name() \
+ : DataTest<name>::DataTest() \
{ \
- if (iface == #name) \
- { \
- obj_ = static_cast<name*>(wl_registry_bind(*this, id, & name ## _interface, 1)); \
- } \
+ obj_ = display().bind<name>(#name, & name ## _interface); \
} \
+ DATA_SETTER_GETTER(name) \
}; \
WFITS_CORE_HARNESS_TEST_CASE(data_ ## name, "DataInterface")