--- /dev/null
+#include "gtest/gtest.h"
+#include "ut_common.h"
+#include "stdint.h"
+#include "fcntl.h"
+
+extern "C" {
+#include "tdm.h"
+#include "tdm_backend.h"
+#include "tbm_bufmgr.h"
+#include "tbm_surface.h"
+#include "tbm_surface_internal.h"
+#include "tbm_drm_helper.h"
+}
+
+class TDMEventLoop: public ::testing::Test
+{
+protected:
+ static tdm_display *dpy;
+ tdm_error error;
+ tdm_event_loop_source *loop_src;
+ int fd;
+
+ static void SetEnv(void)
+ {
+ setenv("TDM_DEBUG_MODULE", "all", 1);
+ setenv("TDM_DEBUG", "1", 1);
+ setenv("TDM_THREAD", "0", 1);
+ setenv("XDG_RUNTIME_DIR", "/run", 1);
+ setenv("TBM_DISPLAY_SERVER", "1", 1);
+ }
+
+ static void UnsetEnv(void)
+ {
+ unsetenv("TDM_DEBUG_MODULE");
+ unsetenv("TDM_DEBUG");
+ unsetenv("TDM_THREAD");
+ unsetenv("XDG_RUNTIME_DIR");
+ unsetenv("TBM_DISPLAY_SERVER");
+ }
+
+ static void SetUpTestCase()
+ {
+ tdm_error error;
+ SetEnv();
+ dpy = tdm_display_init(&error);
+ ASSERT_NE(NULL, dpy);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ }
+
+ static void TearDownTestCase()
+ {
+ tdm_display_deinit(dpy);
+ UnsetEnv();
+ }
+
+ int GetFd()
+ {
+ if (fd == -1)
+ fd = tbm_drm_helper_get_master_fd();
+ return fd;
+ }
+
+ void SetUp()
+ {
+ loop_src = NULL;
+ fd = -1;
+ }
+
+ void TearDown()
+ {
+ if (loop_src)
+ tdm_event_loop_source_remove(loop_src);
+ if (fd >= 0)
+ close(fd);
+ }
+};
+
+tdm_display *TDMEventLoop::dpy = NULL;
+
+static int handler_is_called = 0;
+static tdm_error timer_handler(void *user_data)
+{
+ if (user_data == &handler_is_called)
+ handler_is_called = 1;
+ return TDM_ERROR_NONE;
+}
+
+static tdm_error fd_handler(int fd, tdm_event_loop_mask mask, void *user_data)
+{
+ if (user_data == &handler_is_called)
+ handler_is_called = 1;
+ return TDM_ERROR_NONE;
+}
+
+/*void tdm_event_loop_source_remove(tdm_event_loop_source *source); */
+TEST_F(TDMEventLoop, SourceRemoveFailNULL)
+{
+ tdm_event_loop_source_remove(NULL);
+}
+
+/* tdm_event_loop_source* tdm_event_loop_add_timer_handler(tdm_display *dpy,
+ tdm_event_loop_timer_handler func,
+ void *user_data, tdm_error *error); */
+TEST_F(TDMEventLoop, AddTimerHandlerFailNULL)
+{
+ loop_src = tdm_event_loop_add_timer_handler(NULL, timer_handler, &handler_is_called, &error);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ ASSERT_EQ(NULL, loop_src);
+
+ loop_src = tdm_event_loop_add_timer_handler(dpy, NULL, &handler_is_called, &error);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ ASSERT_EQ(NULL, loop_src);
+
+ loop_src = tdm_event_loop_add_timer_handler(dpy, NULL, &handler_is_called, NULL);
+ ASSERT_EQ(NULL, loop_src);
+}
+
+TEST_F(TDMEventLoop, AddTimerHandlerSuccessful)
+{
+ loop_src = tdm_event_loop_add_timer_handler(dpy, timer_handler, &handler_is_called, &error);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ ASSERT_NE(NULL, loop_src);
+}
+
+/* tdm_error tdm_event_loop_source_timer_update(tdm_event_loop_source *source, unsigned int ms_delay); */
+TEST_F(TDMEventLoop, SourceTimerUpdateFailNULL)
+{
+ error = tdm_event_loop_source_timer_update(NULL, 0);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+}
+TEST_F(TDMEventLoop, SourceTimerUpdateSuccessful)
+{
+ loop_src = tdm_event_loop_add_timer_handler(dpy, timer_handler, &handler_is_called, &error);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ ASSERT_NE(NULL, loop_src);
+
+ error = tdm_event_loop_source_timer_update(loop_src, 10);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+}
+
+/* tdm_event_loop_source* tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask,
+ tdm_event_loop_fd_handler func, void *user_data,
+ tdm_error *error); */
+TEST_F(TDMEventLoop, AddFdHandlerFailNULL)
+{
+ loop_src = tdm_event_loop_add_fd_handler(NULL, 0, TDM_EVENT_LOOP_READABLE,
+ fd_handler, &handler_is_called, &error);
+ ASSERT_EQ(NULL, loop_src);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+
+ loop_src = tdm_event_loop_add_fd_handler(dpy, 0, TDM_EVENT_LOOP_READABLE,
+ NULL, &handler_is_called, &error);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ ASSERT_EQ(NULL, loop_src);
+}
+
+TEST_F(TDMEventLoop, AddFdHandlerFailInvalidFd)
+{
+ loop_src = tdm_event_loop_add_fd_handler(dpy, -1, TDM_EVENT_LOOP_READABLE,
+ fd_handler, &handler_is_called, &error);
+ ASSERT_NE(TDM_ERROR_NONE, error);
+ ASSERT_EQ(NULL, loop_src);
+}
+
+TEST_F(TDMEventLoop, AddFdHandlerSuccessful)
+{
+ int fd = GetFd();
+ ASSERT_NE(-1, fd);
+
+ loop_src = tdm_event_loop_add_fd_handler(dpy, fd, TDM_EVENT_LOOP_READABLE,
+ fd_handler, &handler_is_called, &error);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ ASSERT_NE(NULL, loop_src);
+}
+
+/* tdm_error tdm_event_loop_source_fd_update(tdm_event_loop_source *source, tdm_event_loop_mask mask); */
+TEST_F(TDMEventLoop, SourceFdUpdateFailNULL)
+{
+ error = tdm_event_loop_source_fd_update(NULL, TDM_EVENT_LOOP_READABLE);
+}
+
+TEST_F(TDMEventLoop, SourceFdUpdateSuccessful)
+{
+ int fd;
+ tdm_event_loop_mask flag = TDM_EVENT_LOOP_WRITABLE;
+
+ fd = GetFd();
+ ASSERT_NE(-1, fd);
+
+ loop_src = tdm_event_loop_add_fd_handler(dpy, fd, flag,
+ fd_handler, &handler_is_called, &error);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+ ASSERT_NE(NULL, loop_src);
+
+ error = tdm_event_loop_source_fd_update(loop_src, TDM_EVENT_LOOP_READABLE);
+ ASSERT_EQ(TDM_ERROR_NONE, error);
+}
+