+#include <sys/eventfd.h>
+#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <wayland-client.h>
#include "tpl_wayland_egl_thread.h"
typedef struct _twe_wl_disp_source twe_wl_disp_source;
+typedef struct _twe_wl_surf_source twe_wl_surf_source;
struct _twe_thread_context {
int ref_cnt;
struct _twe_wl_surf_source {
GSource gsource;
- GPollFD gfd;
+ gpointer tag;
+ int event_fd;
struct wl_surface *surf;
- tbm_surface_queue_h tbm_queue;
+ tbm_surface_queue_h tbm_surface_queue;
};
static twe_thread_context *_twe_ctx;
{
twe_wl_disp_source *source;
- source = (twe_wl_disp_source *)g_main_context_find_source_by_user_data(g_main_loop_get_context(thread->ctx->twe_loop), display);
+ source = (twe_wl_disp_source *)g_main_context_find_source_by_user_data(
+ g_main_loop_get_context(thread->ctx->twe_loop), display);
if (!source) {
- printf("ERR: Cannot find wl_display:%d\n", display);
+ TPL_ERROR("Failed to get source from context.");
return;
}
g_source_unref(&source->gsource);
}
-void
+static gboolean
+_twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date)
+{
+ twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source;
+ GIOCondition cond;
+
+ cond = g_source_query_unix_fd(source, wl_surf_source->tag);
+
+ if (cond & G_IO_IN) {
+ ssize_t s;
+ uint64_t u;
+
+ s = read(wl_surf_source->event_fd, &u, sizeof(uint64_t));
+ if (s != sizeof(uint64_t))
+ TPL_ERROR("Failed to read from event_fd(%d)\n",
+ wl_surf_source->event_fd);
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+_twe_thread_wl_surface_finalize(GSource *source)
+{
+ twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source;
+
+ g_source_remove_unix_fd(source, wl_surf_source->tag);
+
+ close(wl_surf_source->event_fd);
+
+ return;
+}
+
+
+static GSourceFuncs _twe_wl_surface_funcs = {
+ .prepare = NULL,
+ .check = NULL,
+ .dispatch = _twe_thread_wl_surface_dispatch,
+ .finalize = _twe_thread_wl_surface_finalize,
+};
+
+int
twe_thread_add_wl_surface(twe_thread* thread,
struct wl_surface *surface,
tbm_surface_queue_h surface_queue)
{
- /* TODO */
- return;
+ twe_thread_context *ctx = thread->ctx;
+ twe_wl_surf_source *source = NULL;
+ GIOChannel *event_channel = NULL;
+
+ source = (twe_wl_surf_source *)g_source_new(&_twe_wl_surface_funcs,
+ sizeof(twe_wl_surf_source));
+ if (!source) {
+ TPL_ERROR("[THREAD] Failed to create GSource from event_channel(%p)",
+ event_channel);
+ return -1;
+ }
+
+ source->event_fd = eventfd(0, EFD_CLOEXEC);
+ if (source->event_fd < 0) {
+ TPL_ERROR("[THREAD] Failed to create eventfd. errno(%d)", errno);
+ g_source_unref(&source->gsource);
+ return -1;
+ }
+
+ source->tag = g_source_add_unix_fd(&source->gsource,
+ source->event_fd,
+ G_IO_IN);
+ source->surf = surface;
+ source->tbm_surface_queue = surface_queue;
+
+ g_source_set_callback(&source->gsource, NULL, surface, NULL);
+ g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop));
+ g_source_unref(&source->gsource);
+
+ return source->event_fd;
}
+void
+twe_thread_del_wl_surface(twe_thread* thread, struct wl_surface *surface)
+{
+ twe_thread_context *ctx = thread->ctx;
+ twe_wl_surf_source *source = NULL;
+
+ source = (twe_wl_surf_source *) g_main_context_find_source_by_user_data(
+ g_main_loop_get_context(ctx->twe_loop), surface);
+ if (!source) {
+ TPL_ERROR("[THREAD] Failed to get source from context.");
+ return;
+ }
+
+ g_source_destroy(&source->gsource);
+ g_source_unref(&source->gsource);
+}