Package version up to 2.7.1
[platform/core/uifw/libtdm.git] / src / tdm_event_loop.c
index 32b7674..5117c27 100644 (file)
@@ -9,7 +9,7 @@
  *          Taeheon Kim <th908.kim@samsung.com>,
  *          YoungJun Cho <yj44.cho@samsung.com>,
  *          SooChan Lim <sc1.lim@samsung.com>,
- *          Boram Park <sc1.lim@samsung.com>
+ *          Boram Park <boram1288.park@samsung.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
 #include "tdm_private.h"
 
 typedef struct _tdm_event_loop_source_base {
+       struct list_head link;
+       tdm_private_display *private_display;
        struct wl_event_source *wl_source;
 } tdm_event_loop_source_base;
 
 typedef struct _tdm_event_loop_source_fd {
        tdm_event_loop_source_base base;
-       tdm_private_display *private_display;
        tdm_event_loop_fd_handler func;
        void *user_data;
 } tdm_event_loop_source_fd;
 
 typedef struct _tdm_event_loop_source_timer {
        tdm_event_loop_source_base base;
-       tdm_private_display *private_display;
        tdm_event_loop_timer_handler func;
        void *user_data;
 } tdm_event_loop_source_timer;
 
+static tdm_private_loop *keep_private_loop;
+
 static tdm_error
 _tdm_event_loop_main_fd_handler(int fd, tdm_event_loop_mask mask, void *user_data)
 {
        tdm_private_module *private_module = (tdm_private_module*)user_data;
+       tdm_private_display *private_display;
        tdm_func_display *func_display;
        tdm_error ret;
 
@@ -74,7 +77,10 @@ _tdm_event_loop_main_fd_handler(int fd, tdm_event_loop_mask mask, void *user_dat
        if (!func_display->display_handle_events)
                return TDM_ERROR_NONE;
 
+       private_display = private_module->private_display;
+       private_display->current_module = private_module;
        ret = func_display->display_handle_events(private_module->bdata);
+       private_display->current_module = NULL;
 
        return ret;
 }
@@ -112,6 +118,8 @@ tdm_event_loop_init(tdm_private_display *private_display)
                return TDM_ERROR_OPERATION_FAILED;
        }
 
+       LIST_INITHEAD(&private_loop->source_list);
+
        private_loop->dpy = private_display;
        private_display->private_loop = private_loop;
 
@@ -124,6 +132,8 @@ tdm_event_loop_init(tdm_private_display *private_display)
                return TDM_ERROR_OPERATION_FAILED;
        }
 
+       keep_private_loop = private_loop;
+
        TDM_INFO("event loop fd(%d)", wl_event_loop_get_fd(private_loop->wl_loop));
 
        return TDM_ERROR_NONE;
@@ -133,6 +143,7 @@ INTERN void
 tdm_event_loop_deinit(tdm_private_display *private_display)
 {
        tdm_private_module *private_module = NULL;
+       tdm_event_loop_source_base *source = NULL, *ss = NULL;
 
        TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
 
@@ -151,11 +162,21 @@ tdm_event_loop_deinit(tdm_private_display *private_display)
                private_module->fd = -1;
        }
 
-       if (private_display->private_loop->wl_display)
-               wl_display_destroy(private_display->private_loop->wl_display);
+       LIST_FOR_EACH_ENTRY_SAFE(source, ss, &private_display->private_loop->source_list, link) {
+               tdm_event_loop_source_remove(source);
+       }
+
+#if WAYLAND_VERSION_MAJOR >= 1 && WAYLAND_VERSION_MINOR >= 15
+       wl_display_destroy_clients(private_display->private_loop->wl_display);
+#endif
+
+       wl_display_destroy(private_display->private_loop->wl_display);
 
        free(private_display->private_loop);
        private_display->private_loop = NULL;
+       keep_private_loop = NULL;
+
+       TDM_INFO("event loop deinit done");
 }
 
 INTERN void
@@ -282,7 +303,7 @@ _tdm_event_loop_fd_func(int fd, uint32_t wl_mask, void *data)
        TDM_RETURN_VAL_IF_FAIL(fd_source, 1);
        TDM_RETURN_VAL_IF_FAIL(fd_source->func, 1);
 
-       private_display = fd_source->private_display;
+       private_display = fd_source->base.private_display;
 
        if (wl_mask & WL_EVENT_READABLE)
                mask |= TDM_EVENT_LOOP_READABLE;
@@ -329,10 +350,10 @@ tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask
        if (mask & TDM_EVENT_LOOP_WRITABLE)
                wl_mask |= WL_EVENT_WRITABLE;
 
-       fd_source->private_display = private_display;
        fd_source->func = func;
        fd_source->user_data = user_data;
 
+       fd_source->base.private_display = private_display;
        fd_source->base.wl_source =
                wl_event_loop_add_fd(private_loop->wl_loop,
                                                         fd, wl_mask, _tdm_event_loop_fd_func, fd_source);
@@ -343,6 +364,8 @@ tdm_event_loop_add_fd_handler(tdm_display *dpy, int fd, tdm_event_loop_mask mask
                return NULL;
        }
 
+       LIST_ADDTAIL(&fd_source->base.link, &private_loop->source_list);
+
        if (error)
                *error = TDM_ERROR_NONE;
 
@@ -382,7 +405,7 @@ _tdm_event_loop_timer_func(void *data)
        TDM_RETURN_VAL_IF_FAIL(timer_source, 1);
        TDM_RETURN_VAL_IF_FAIL(timer_source->func, 1);
 
-       private_display = timer_source->private_display;
+       private_display = timer_source->base.private_display;
 
        /* TDM event_loop function is actually for TDM backend module. When we call the
         * backend's functions, we have to lock the mutex. TDM backend shouldn't consider
@@ -416,10 +439,10 @@ tdm_event_loop_add_timer_handler(tdm_display *dpy, tdm_event_loop_timer_handler
        timer_source = calloc(1, sizeof(tdm_event_loop_source_timer));
        TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(timer_source, TDM_ERROR_OUT_OF_MEMORY, NULL);
 
-       timer_source->private_display = private_display;
        timer_source->func = func;
        timer_source->user_data = user_data;
 
+       timer_source->base.private_display = private_display;
        timer_source->base.wl_source =
                wl_event_loop_add_timer(private_loop->wl_loop,
                                                                _tdm_event_loop_timer_func, timer_source);
@@ -430,6 +453,8 @@ tdm_event_loop_add_timer_handler(tdm_display *dpy, tdm_event_loop_timer_handler
                return NULL;
        }
 
+       LIST_ADDTAIL(&timer_source->base.link, &private_loop->source_list);
+
        if (error)
                *error = TDM_ERROR_NONE;
 
@@ -459,9 +484,11 @@ tdm_event_loop_source_remove(tdm_event_loop_source *source)
 
        TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED());
 
-       if (!base)
+       if (!base || !keep_private_loop)
                return;
 
+       LIST_DEL(&base->link);
+
        wl_event_source_remove(base->wl_source);
 
        free(source);