example: check if a input_method_context is null.
[platform/core/uifw/libds-tizen.git] / examples / tinyds-tdm.c
index 23ff48e..a797ca2 100644 (file)
@@ -1,5 +1,3 @@
-#include "tinyds-helper.h"
-
 #include <assert.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <libds/log.h>
 #include <libds/backend.h>
 #include <libds/output.h>
-#include <libds/allocator/tbm.h>
-#include <libds/backend/tdm.h>
-#include <libds/swapchain.h>
 #include <libds/compositor.h>
 #include <libds/xdg_shell.h>
+#include <libds-tizen/allocator/tbm.h>
+#include <libds-tizen/backend/tdm.h>
+#include <libds/backend/libinput.h>
+#include <libds-tizen/tbm_server.h>
+#include <libds-tizen/dpms.h>
+#include <libds/input_device.h>
+#include <libds/keyboard.h>
+#include <libds/touch.h>
+#include <libds/pointer.h>
+#include <libds/seat.h>
+#include <libds-tizen/input_devicemgr.h>
+#include <xkbcommon/xkbcommon.h>
+#include <libds/interfaces/keyboard.h>
+#include <libds-tizen/launch.h>
+#include <libds-tizen/backend/tdm_output_hwc.h>
+#include <libds-tizen/input_method.h>
+#include <libds-tizen/text_input.h>
+#include <libds-tizen/policy.h>
+
+#define USE_TDM_BUFFER_QUEUE
+
+#ifdef USE_TDM_BUFFER_QUEUE
+#include "pixman-tbm-helper.h"
+#include "tinyds-tdm-renderer.h"
+#else
+#include <libds/swapchain.h>
+#endif
 
-#define TINYDS_UNUSED   __attribute__((unused))
+#include "pixman-helper.h"
 
-#define OUTPUT_WIDTH   1280
-#define OUTPUT_HEIGHT  720
+#define TINYDS_UNUSED   __attribute__((unused))
+struct tinyds_keyboard;
+struct tinyds_pointer;
 
 struct tinyds_output
 {
     struct tinyds_server *server;
     struct ds_output *ds_output;
     struct ds_allocator *allocator;
+#ifdef USE_TDM_BUFFER_QUEUE
+    struct tinyds_renderer renderer;
+    struct ds_tdm_buffer_queue *buffer_queue;
+    struct wl_listener buffer_queue_acquirable;
+#else
     struct ds_swapchain *swapchain;
+#endif
     struct ds_buffer *front_buffer;
 
     struct wl_listener output_destroy;
@@ -37,31 +66,166 @@ struct tinyds_output
 
     int width, height;
 
-    bool drawable;
+    struct wl_event_source *idle_commit;
+    bool committable;
     bool damaged;
+    bool target_updated;
+
+    struct ds_tdm_output_hwc *hwc;
+    struct ds_tdm_output_hwc_window *bg_hwc_window;
+};
+
+struct tinyds_dpms
+{
+    struct ds_tizen_dpms *ds_dpms;
+    struct tinyds_server *server;
+
+    struct wl_listener destroy;
+    struct wl_listener set_dpms;
+    struct wl_listener get_dpms;
+};
+
+struct tinyds_policy
+{
+    struct ds_tizen_policy *policy;
+
+    struct wl_listener destroy;
+    struct wl_listener new_surface;
+    struct wl_listener activate_below_by_univeral_id;
+    struct wl_listener lower_by_universal_id;
+    struct wl_listener set_transient_for;
+    struct wl_listener unset_transient_for;
+    struct wl_listener place_subsurface_below_parent;
+    struct wl_listener set_subsurface_stand_alone;
+    struct wl_listener set_background_state;
+    struct wl_listener unset_background_state;
+    struct wl_listener add_activate_above_by_universal_id;
+    struct wl_listener set_appid;
+    struct wl_listener set_transient_for_below;
+
+    struct wl_list policy_surfaces;
+};
+
+struct tinyds_policy_surface
+{
+    struct ds_tizen_policy_surface *policy_surface;
+
+    struct wl_listener destroy;
+    struct wl_listener new_visibility;
+    struct wl_listener new_position;
+    struct wl_listener activate;
+    struct wl_listener raise;
+    struct wl_listener lower;
+    struct wl_listener set_focus_skip;
+    struct wl_listener unset_focus_skip;
+    struct wl_listener set_role;
+    struct wl_listener set_window_type;
+    struct wl_listener set_conformant;
+    struct wl_listener unset_conformant;
+    struct wl_listener get_conformant;
+    struct wl_listener set_notification_level;
+    struct wl_listener set_window_screen_mode;
+    struct wl_listener get_subsurface;
+    struct wl_listener iconify;
+    struct wl_listener uniconify;
+    struct wl_listener add_aux_hint;
+    struct wl_listener change_aux_hint;
+    struct wl_listener delete_aux_hint;
+    struct wl_listener get_supported_aux_hints;
+    struct wl_listener set_floating_mode;
+    struct wl_listener unset_floating_mode;
+    struct wl_listener set_stack_mode;
+    struct wl_listener new_subsurface_watcher;
+    struct wl_listener set_parent;
+    struct wl_listener ack_conformant_region;
+    struct wl_listener set_video;
+    struct wl_listener show;
+    struct wl_listener hide;
+    struct wl_listener set_parent_with_below;
+
+    struct wl_list visibilities;
+    struct wl_list positions;
+    struct wl_list subsurface_watchers;
+
+    struct wl_list link; //tinyds_policy::policy_surfaces
+};
+
+struct tinyds_policy_visibility
+{
+    struct ds_tizen_policy_visibility *visibility;
+
+    struct wl_listener destroy;
+
+    struct wl_list link; //tinyds_policy::visibilities
+};
+
+struct tinyds_policy_position
+{
+    struct ds_tizen_policy_position *position;
+
+    struct wl_listener destroy;
+    struct wl_listener set;
+
+    struct wl_list link; //tinyds_policy::positions
+};
+
+struct tinyds_policy_subsurface_watcher
+{
+    struct ds_tizen_policy_subsurface_watcher *subsurface_watcher;
+
+    struct wl_listener destroy;
+
+    struct wl_list link; //tinyds_policy::subsurface_watchers
 };
 
 struct tinyds_server
 {
+    struct ds_tbm_server *tbm_server;
+
     struct wl_display *display;
 
     struct ds_backend *backend;
+    struct ds_backend *input_backend;
     struct ds_compositor *compositor;
     struct ds_xdg_shell *xdg_shell;
+    struct ds_seat *seat;
+    uint32_t seat_caps;
+    double output_x, output_y;
+    struct ds_tizen_input_devicemgr *devicemgr;
+    struct ds_tizen_launch_effect *effect;
+    struct ds_tizen_launch_splash *splash;
 
     struct tinyds_output *output;
-    struct tinyds_renderer renderer;
+    struct tinyds_dpms *dpms;
+    struct tinyds_policy *policy;
+
+    struct wl_event_source *stdin_source;
 
     struct wl_list views;
 
     struct wl_listener new_output;
+    struct wl_listener new_input;
     struct wl_listener new_xdg_surface;
+    struct wl_listener devicemgr_destroy;
+    struct wl_listener pointer_warp;
+    struct wl_listener effect_destroy;
+    struct wl_listener effect_type_set;
+    struct wl_listener effect_type_unset;
+    struct wl_listener new_splash;
+    struct wl_listener splash_owner;
+
+    struct wl_list keyboards;
+    struct wl_list pointers;
+
+    struct tinyds_text_input *text_input;
+    struct tinyds_input_method *input_method;
 };
 
 struct tinyds_view
 {
     struct tinyds_server *server;
 
+    struct tinyds_texture *texture;
     struct ds_xdg_surface *xdg_surface;
 
     struct wl_listener xdg_surface_map;
@@ -70,58 +234,253 @@ struct tinyds_view
     struct wl_listener surface_commit;
     struct wl_list link; // tinyds_server::views
 
+    struct ds_tdm_output_hwc_window *hwc_window;
+
     int x, y;
     bool mapped;
+
+    pid_t pid;
+    int effect_type;
+};
+
+struct tinyds_pointer
+{
+    struct ds_input_device *dev;
+    struct tinyds_server *server;
+
+    struct tinyds_view *focused_view;
+
+    struct wl_listener destroy;
+    struct wl_listener motion; //relative
+    struct wl_listener button;
+    struct wl_listener frame;
+    struct wl_list link; //tinyds_server::pointers
+};
+
+struct tinyds_keyboard
+{
+    struct ds_input_device *dev;
+    struct tinyds_server *server;
+
+    struct wl_listener destroy;
+    struct wl_listener key;
+    struct wl_list link; //tinyds_server::keyboards
+};
+
+struct tinyds_touch
+{
+    struct ds_input_device *dev;
+    struct tinyds_server *server;
+
+    struct wl_listener destroy;
+    struct wl_listener down;
+    struct wl_listener up;
+    struct wl_listener motion;
+};
+
+struct tinyds_text_input {
+    struct ds_tizen_text_input *input;
+    struct ds_tizen_text_input_manager *text_input_mgr;
+
+    struct tinyds_server *server;
+    struct ds_surface *surface;
+
+    struct wl_list input_methods;
+
+    struct wl_listener destroy;
+    struct wl_listener mgr_destroy;
+
+    struct wl_listener new_text_input;
+
+    struct wl_listener text_input_activate;
+    struct wl_listener text_input_deactivate;
+    struct wl_listener text_input_reset;
+    struct wl_listener text_input_set_content_type;
+    struct wl_listener text_input_invoke_action;
+    struct wl_listener text_input_commit_state;
+    struct wl_listener text_input_set_preferred_language;
+};
+
+struct tinyds_input_method {
+    struct ds_tizen_input_method *input_method;
+    struct ds_tizen_input_method_manager *input_method_mgr;
+
+    struct tinyds_server *server;
+    struct tinyds_text_input *input;
+    struct tinyds_input_method_context *context;
+
+    struct wl_list link;
+
+    struct wl_listener destroy;
+    struct wl_listener mgr_destroy;
+};
+
+struct tinyds_input_method_context {
+    struct ds_tizen_input_method_context *context;
+
+    struct tinyds_server *server;
+    struct tinyds_text_input *input;
+    struct tinyds_input_method *input_method;
+
+    struct wl_listener destroy;
+
+    struct wl_listener im_context_commit_string;
+    struct wl_listener im_context_preedit_string;
+    struct wl_listener im_context_preedit_styling;
+    struct wl_listener im_context_preedit_cursor;
+    struct wl_listener im_context_delete_surrounding_text;
+    struct wl_listener im_context_cursor_position;
+    struct wl_listener im_context_modifiers_map;
+    struct wl_listener im_context_keysym;
+    struct wl_listener im_context_grab_keyboard;
+    struct wl_listener im_context_key;
+    struct wl_listener im_context_modifiers;
+    struct wl_listener im_context_language;
+    struct wl_listener im_context_text_direction;
 };
 
-struct tinyds_server _tinyds;
+struct tinyds_server tinyds;
 
 static bool init_server(struct tinyds_server *server, struct wl_display *display);
+static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
 static void output_handle_destroy(struct wl_listener *listener, void *data);
 static void output_handle_frame(struct wl_listener *listener, void *data);
-static void draw_server(struct tinyds_server *server);
 static void draw_server_with_damage(struct tinyds_server *server);
 static void draw_output(struct tinyds_output *output);
+static void output_swap_buffer(struct tinyds_output *output,
+        struct ds_buffer *buffer);
+static void view_send_frame_done(struct tinyds_view *view);
+static void output_hwc_init(struct tinyds_output *output);
+static void output_schedule_commit(struct tinyds_output *output);
+static void output_commit(struct tinyds_output *output);
+#ifdef USE_TDM_BUFFER_QUEUE
+static void output_buffer_queue_init(struct tinyds_output *output);
+static void output_renderer_init(struct tinyds_output *output);
+static void output_draw_with_renderer(struct tinyds_output *output);
+#else
+static void output_swapchain_init(struct tinyds_output *output,
+        int width, int height, uint32_t format);
+static void output_draw_with_swapchain(struct tinyds_output *output);
 static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
+#endif
+static void dpms_handle_destroy(struct wl_listener *listener, void *data);
+static void dpms_handle_set_dpms(struct wl_listener *listener, void *data);
+static void dpms_handle_get_dpms(struct wl_listener *listener, void *data);
+static void server_add_keyboard(struct tinyds_server *server,
+        struct ds_input_device *dev);
+static void server_add_pointer(struct tinyds_server *server,
+        struct ds_input_device *dev);
+static void server_add_touch(struct tinyds_server *server,
+        struct ds_input_device *dev);
+static bool new_policy(struct tinyds_server *server);
+static struct tinyds_view *
+server_view_at(struct tinyds_server *server, double lx, double ly,
+        double *sx, double *sy);
+
+static bool add_new_text_input(struct tinyds_server *server);
+static bool add_new_input_method(struct tinyds_server *server);
+static bool add_new_input_method_context(
+        struct tinyds_input_method *input_method,
+        struct tinyds_text_input *text_input);
+
+static void text_input_mgr_handle_destroy(struct wl_listener *listener,
+        void *data TINYDS_UNUSED);
+static void text_input_mgr_handle_new_text_input(struct wl_listener *listener,
+        void *data TINYDS_UNUSED);
+
+static void input_method_mgr_handle_destroy(struct wl_listener *listener,
+        void *data TINYDS_UNUSED);
+
+static void input_method_handle_destroy(struct wl_listener *listener,
+        void *data TINYDS_UNUSED);
 
 int
 main(void)
 {
-    struct tinyds_server *server = &_tinyds;
+    struct tinyds_server *server = &tinyds;
     struct wl_display *display;
+    struct wl_event_loop *loop;
     const char *socket;
+    bool res;
 
-    ds_log_init(DS_DBG, NULL);
+    ds_log_init(DS_INF, NULL);
 
     display = wl_display_create();
     assert(display);
 
-    assert(init_server(server, display) == true);
-
-    assert(tinyds_renderer_init_display(&server->renderer, display));
+    res = init_server(server, display);
+    assert(res);
 
     socket = wl_display_add_socket_auto(display);
     assert(socket);
 
     ds_backend_start(server->backend);
+    ds_backend_start(server->input_backend);
 
     setenv("WAYLAND_DISPLAY", socket, true);
 
     ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
 
+    loop = wl_display_get_event_loop(display);
+    server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
+            WL_EVENT_READABLE, server_dispatch_stdin, server);
+
+    wl_display_run(display);
+
+    wl_display_destroy_clients(display);
     wl_display_destroy(display);
 
     return 0;
 }
 
 static void
+view_populate_pid(struct tinyds_view *view)
+{
+    pid_t pid;
+    struct wl_client *client = NULL;
+    struct ds_surface *surface;
+
+    surface = ds_xdg_surface_get_surface(view->xdg_surface);
+    if (!surface)
+        return;
+
+    client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
+    if (!client)
+        return;
+
+    wl_client_get_credentials(client, &pid, NULL, NULL);
+
+    ds_inf("view pid(%u)", pid);
+    view->pid = pid;
+
+    view->effect_type = ds_tizen_launch_effect_get_effect_type(view->server->effect, pid);
+    ds_tizen_launch_effect_unset_effect_type(view->server->effect, pid);
+    ds_inf("view effect_type(%d)", view->effect_type);
+}
+
+static void
 view_handle_xdg_surface_map(struct wl_listener *listener,
         void *data TINYDS_UNUSED)
 {
     struct tinyds_view *view;
+    struct ds_keyboard *keyboard;
+    struct tinyds_keyboard *kbd;
 
     view = wl_container_of(listener, view, xdg_surface_map);
     view->mapped = true;
+
+    view_populate_pid(view);
+
+    wl_list_for_each(kbd, &view->server->keyboards, link) {
+        keyboard = ds_input_device_get_keyboard(kbd->dev);
+        if (keyboard != NULL) {
+            ds_seat_keyboard_notify_enter(view->server->seat,
+                    ds_xdg_surface_get_surface(view->xdg_surface),
+                    keyboard->keycodes, keyboard->num_keycodes,
+                    &keyboard->modifiers);
+            return;
+        }
+    }
 }
 
 static void
@@ -144,6 +503,8 @@ view_handle_xdg_surface_destroy(struct wl_listener *listener,
 
     draw_server_with_damage(view->server);
 
+    ds_tdm_output_hwc_window_destroy(view->hwc_window);
+
     wl_list_remove(&view->xdg_surface_destroy.link);
     wl_list_remove(&view->xdg_surface_map.link);
     wl_list_remove(&view->xdg_surface_unmap.link);
@@ -165,6 +526,8 @@ view_handle_surface_commit(struct wl_listener *listener,
 static void
 server_new_xdg_surface(struct wl_listener *listener, void *data)
 {
+    static unsigned int seedx = 1;
+    static unsigned int seedy = 43210;
     struct tinyds_server *server;
     struct tinyds_view *view;
     struct ds_xdg_surface *xdg_surface;
@@ -175,6 +538,8 @@ server_new_xdg_surface(struct wl_listener *listener, void *data)
     ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
 
     view = calloc(1, sizeof *view);
+    assert(view);
+
     view->server = server;
     view->xdg_surface = xdg_surface;
 
@@ -195,7 +560,18 @@ server_new_xdg_surface(struct wl_listener *listener, void *data)
             ds_xdg_surface_get_surface(xdg_surface),
             &view->surface_commit);
 
+    view->x = rand_r(&seedx) % 1000;
+    view->y = rand_r(&seedy) % 500;
+
+    view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
+    assert(view->hwc_window);
+
     wl_list_insert(server->views.prev, &view->link);
+
+    view->pid = 0;
+    view->effect_type = -1;
+
+    ds_inf("view at (%d, %d)", view->x, view->y);
 }
 
 static void
@@ -204,6 +580,8 @@ backend_handle_new_output(struct wl_listener *listener, void *data)
     struct tinyds_server *server;
     struct tinyds_output *output;
     struct ds_output *ds_output;
+    const struct ds_output_mode *mode;
+    struct ds_tdm_box src_box;
 
     server = wl_container_of(listener, server, new_output);
     ds_output = data;
@@ -213,263 +591,2852 @@ backend_handle_new_output(struct wl_listener *listener, void *data)
     if (server->output)
         return;
 
+    mode = ds_output_get_preferred_mode(ds_output);
+    ds_output_set_mode(ds_output, mode);
+
     output = calloc(1, sizeof *output);
     if (!output)
         return;
 
     output->server = server;
     output->ds_output = ds_output;
+    output->width = mode->width;
+    output->height = mode->height;
+    output->damaged = true;
+    output->committable = true;
+
+    output_hwc_init(output);
+
+#ifdef USE_TDM_BUFFER_QUEUE
+    output_buffer_queue_init(output);
+    output_renderer_init(output);
+#else
+    output_swapchain_init(output, mode->width, mode->height,
+            DRM_FORMAT_XRGB8888);
+#endif
+
+    output->bg_hwc_window = ds_tdm_output_hwc_window_create(output->hwc);
+    assert(output->bg_hwc_window);
+
+    src_box.x = 0;
+    src_box.y = 0;
+    src_box.width = output->width;
+    src_box.height = output->height;
+
+    ds_tdm_output_hwc_window_set_src_box(output->bg_hwc_window, &src_box);
+    ds_tdm_output_hwc_window_set_position(output->bg_hwc_window, 0, 0);
+    ds_tdm_output_hwc_window_set_dest_size(output->bg_hwc_window, output->width, output->height);
+    ds_tdm_output_hwc_window_set_transform(output->bg_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
 
     output->output_destroy.notify = output_handle_destroy;
-    ds_output_add_destroy_listener(ds_output,
-            &output->output_destroy);
+    ds_output_add_destroy_listener(ds_output, &output->output_destroy);
 
     output->output_frame.notify = output_handle_frame;
-    ds_output_add_frame_listener(ds_output,
-            &output->output_frame);
+    ds_output_add_frame_listener(ds_output, &output->output_frame);
+
+    ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height);
 
     server->output = output;
+
+    output_schedule_commit(output);
 }
 
 static bool
-init_server(struct tinyds_server *server, struct wl_display *display)
+add_new_dpms(struct tinyds_server *server)
 {
-    server->display = display;
+    struct tinyds_dpms *dpms;
 
-    wl_list_init(&server->views);
-
-    if (wl_display_init_shm(display) != 0)
+    dpms = calloc(1, sizeof *dpms);
+    if (!dpms)
         return false;
 
-    server->backend = ds_tdm_backend_create(display);
-    if (!server->backend)
+    dpms->ds_dpms = ds_tizen_dpms_create(server->display);
+    if (!dpms->ds_dpms) {
+        free(dpms);
+        ds_err("Could not create ds_tizen_dpms");
         return false;
+    }
 
-    server->new_output.notify = backend_handle_new_output;
-    ds_backend_add_new_output_listener(server->backend,
-            &server->new_output);
+    dpms->destroy.notify = dpms_handle_destroy;
+    ds_tizen_dpms_add_destroy_listener(dpms->ds_dpms, &dpms->destroy);
 
-    server->compositor = ds_compositor_create(display);
-    if (!server->compositor) {
-        ds_backend_destroy(server->backend);
-        return false;
-    }
+    dpms->set_dpms.notify = dpms_handle_set_dpms;
+    ds_tizen_dpms_add_set_dpms_listener(dpms->ds_dpms, &dpms->set_dpms);
 
-    server->xdg_shell = ds_xdg_shell_create(display);
-    if (!server->xdg_shell) {
-        ds_backend_destroy(server->backend);
-        return false;
-    }
+    dpms->get_dpms.notify = dpms_handle_get_dpms;
+    ds_tizen_dpms_add_get_dpms_listener(dpms->ds_dpms, &dpms->get_dpms);
 
-    server->new_xdg_surface.notify = server_new_xdg_surface;
-    ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
-            &server->new_xdg_surface);
+    server->dpms = dpms;
+
+    ds_inf("Dpms (%p) added", dpms);
 
     return true;
 }
 
 static void
-output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
+backend_handle_new_input(struct wl_listener *listener, void *data)
 {
-    struct tinyds_output *output =
-        wl_container_of(listener, output, output_destroy);
-
-    wl_list_remove(&output->output_destroy.link);
-    wl_list_remove(&output->output_frame.link);
-
-    if (output->front_buffer)
-        ds_buffer_unlock(output->front_buffer);
+    struct tinyds_server *server;
+    struct ds_input_device *dev = data;
+    enum ds_input_device_type dev_type;
+
+    server = wl_container_of(listener, server, new_input);
+
+    dev_type = ds_input_device_get_type(dev);
+
+    switch (dev_type) {
+        case DS_INPUT_DEVICE_KEYBOARD:
+            server_add_keyboard(server, dev);
+            server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+            break;
+        case DS_INPUT_DEVICE_TOUCH:
+            server_add_touch(server, dev);
+            server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH;
+            break;
+        case DS_INPUT_DEVICE_POINTER:
+            server_add_pointer(server, dev);
+            server->seat_caps |= WL_SEAT_CAPABILITY_POINTER;
+            break;
+        default:
+            ds_err("Unknown type(%d) of ds_input_device", dev_type);
+            break;
+    }
 
-    if (output->swapchain)
-        ds_swapchain_destroy(output->swapchain);
+    ds_seat_set_capabilities(server->seat, server->seat_caps);
+}
 
-    if (output->allocator)
-        ds_allocator_destroy(output->allocator);
+static void
+devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode)
+{
+    struct ds_tizen_input_devicemgr_keymap_data *data;
 
-    wl_display_terminate(output->server->display);
+    data = calloc(1, sizeof *data);
+    if (!data) {
+        ds_err("Failed to alloc memory");
+        return;
+    }
 
-    output->server->output = NULL;
+    data->name = strdup(name);
+    data->keycode = keycode;
 
-    free(output);
+    wl_list_insert(list, &data->link);
 }
 
 static void
-output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
+devicemgr_cleanup_keymap_list(struct wl_list *list)
 {
-    struct tinyds_output *output =
-        wl_container_of(listener, output, output_frame);
+    struct ds_tizen_input_devicemgr_keymap_data *data, *tmp;
 
+    wl_list_for_each_safe(data, tmp, list, link) {
+        wl_list_remove(&data->link);
+        free(data->name);
+        free(data);
+    }
 }
 
 static void
-draw_server(struct tinyds_server *server)
+devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr)
 {
-    draw_output(server->output);
-}
+    struct wl_list keymap_list;
+    bool res;
 
-static void
-draw_server_with_damage(struct tinyds_server *server)
-{
-    server->output->damaged = true;
-    draw_output(server->output);
-}
+    wl_list_init(&keymap_list);
 
-static void image_fill_color(pixman_image_t *image,
-        uint8_t r, uint8_t g, uint8_t b);
-static pixman_image_t *image_from_buffer(struct ds_buffer *buffer,
-        enum ds_buffer_data_ptr_access_flag access_flag);
-static void view_send_frame_done(struct tinyds_view *view);
+    devicemgr_add_keymap_data(&keymap_list, "XF86VolumeRaise", 455);
+    devicemgr_add_keymap_data(&keymap_list, "XF86VolumeLower", 456);
+    devicemgr_add_keymap_data(&keymap_list, "XF86LightOn", 457);
+    devicemgr_add_keymap_data(&keymap_list, "XF86LightOff", 458);
+
+    res = ds_tizen_input_devicemgr_set_keymap_list(devicemgr, &keymap_list);
+    if (!res)
+        ds_inf("Failed to set keymap");
+
+    devicemgr_cleanup_keymap_list(&keymap_list);
+}
 
 static void
-draw_output(struct tinyds_output *output)
+devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data)
 {
-    struct ds_buffer *output_buffer;
-    pixman_image_t *output_image;
-    struct tinyds_view *view;
+    struct tinyds_server *server;
+    struct tinyds_pointer *pointer;
+    struct ds_tizen_input_devicemgr_event_pointer_warp *event = data;
+    double sx = 0.f, sy = 0.f;
+    struct tinyds_view *view = NULL;
 
-    if (!output->drawable || !output->damaged)
-        return;
+    server = wl_container_of(listener, server, pointer_warp);
 
-    output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
-    if (!output_buffer)
-        return;
+    ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface,
+            event->x, event->y);
 
-    output_image = image_from_buffer(output_buffer,
-            DS_BUFFER_DATA_PTR_ACCESS_WRITE);
-    if (!output_image) {
-        ds_buffer_unlock(output_buffer);
-        return;
+    wl_list_for_each(pointer, &server->pointers, link){
+        if (!pointer->focused_view) continue;
+        view = pointer->focused_view;
     }
+    if (!view) return;
 
-    image_fill_color(output_image, 80, 80, 80);
-
-    wl_list_for_each(view, &output->server->views, link) {
-        if (!view->mapped)
-            continue;
-        draw_view(view, output_image);
+    if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) {
+        ds_inf("Pointer is not on the requested surface");
+        return;
     }
-    pixman_image_unref(output_image);
 
-    ds_output_attach_buffer(output->ds_output, output_buffer);
-    ds_output_commit(output->ds_output);
+    server->output_x = view->x + (event->x * server->output->width);
+    server->output_y = view->y + (event->y * server->output->height);
 
-    if (output->front_buffer)
-        ds_buffer_unlock(output->front_buffer);
-    output->front_buffer = output_buffer;
+    server_view_at(server, server->output_x, server->output_y, &sx, &sy);
 
-    output->drawable = false;
-    output->damaged = false;
+    ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f",
+            sx, sy, server->output_x, server->output_y);
+
+    ds_seat_pointer_notify_motion(server->seat,
+            event->time_msec, sx, sy);
 }
 
 static void
-draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
+devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
 {
-    struct ds_buffer *buffer;
-    pixman_image_t *src_image;
-
-    buffer = ds_surface_get_buffer(
-            ds_xdg_surface_get_surface(view->xdg_surface));
-    if (!buffer)
-        return;
+    struct tinyds_server *server =
+        wl_container_of(listener, server, devicemgr_destroy);
 
-    src_image = image_from_buffer(buffer,
-            DS_BUFFER_DATA_PTR_ACCESS_READ);
-    pixman_image_composite32(PIXMAN_OP_OVER,
-            src_image,
-            NULL,
-            dst_image,
-            0, 0, 0, 0, 0, 0,
-            pixman_image_get_width(src_image),
-            pixman_image_get_height(src_image));
-    pixman_image_unref(src_image);
+    wl_list_remove(&server->devicemgr_destroy.link);
+    wl_list_remove(&server->pointer_warp.link);
 
-    view_send_frame_done(view);
+    server->devicemgr = NULL;
 }
 
-static pixman_color_t *
-color_rgb888(pixman_color_t *tmp, uint8_t r, uint8_t g, uint8_t b)
+static void
+launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
 {
-    tmp->alpha = 65535;
-    tmp->red = (r << 8) + r;
-    tmp->green = (g << 8) + g;
-    tmp->blue = (b << 8) +b;
+    struct tinyds_server *server =
+        wl_container_of(listener, server, effect_destroy);
 
-    return tmp;
+    wl_list_remove(&server->effect_destroy.link);
+    wl_list_remove(&server->effect_type_set.link);
+    wl_list_remove(&server->effect_type_unset.link);
+    wl_list_remove(&server->new_splash.link);
+
+    server->effect = NULL;
 }
 
 static void
-image_fill_color(pixman_image_t *image, uint8_t r, uint8_t g, uint8_t b)
+launch_effect_handle_type_set(struct wl_listener *listener, void *data)
 {
-    pixman_image_t *color_image;
-    pixman_color_t color;
+    struct tinyds_server *server;
+    struct ds_tizen_launch_effect_event_type_set *event = data;
+    struct tinyds_view *view = NULL;
+    bool existing = false;
 
-    color_rgb888(&color, r, g, b);
-    color_image = pixman_image_create_solid_fill(&color);
-    pixman_image_composite32(PIXMAN_OP_SRC,
-            color_image,
-            NULL,
-            image,
-            0, 0, 0, 0, 0, 0,
-            pixman_image_get_width(image),
-            pixman_image_get_height(image));
-    pixman_image_unref(color_image);
+    server = wl_container_of(listener, server, effect_type_set);
+
+    ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch");
+
+    wl_list_for_each(view, &server->views, link) {
+        if (view->pid == event->pid) {
+            view->effect_type = event->effect_type;
+            ds_inf("Launch effect. existing pid");
+            existing = true;
+        }
+    }
+    if (existing) {
+        ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid);
+    } else {
+        ds_tizen_launch_effect_set_effect_type(server->effect, event->pid, event->effect_type);
+    }
 }
 
-static void                                             
-destroy_pixman_image(pixman_image_t *image TINYDS_UNUSED, void *data)
+static void
+launch_effect_handle_type_unset(struct wl_listener *listener, void *data)
 {
-    struct ds_buffer *buffer = data;
-    ds_buffer_end_data_ptr_access(buffer);
-    ds_buffer_unlock(buffer);
+    struct tinyds_server *server;
+    struct ds_tizen_launch_effect_event_type_unset *event = data;
+    struct tinyds_view *view = NULL;
+
+    server = wl_container_of(listener, server, effect_type_unset);
+
+    ds_inf("Launch effect. type_unset: pid(%u)", event->pid);
+
+    wl_list_for_each(view, &server->views, link) {
+        if (view->pid == event->pid) {
+            view->effect_type = -1;
+            ds_inf("Launch effect. pid found");
+        }
+    }
+    ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid);
 }
 
-static uint32_t
-convert_drm_format_to_pixman(uint32_t fmt)
+static void
+launch_splash_handle_owner(struct wl_listener *listener, void *data)
 {
-    switch (fmt) {
-        case DRM_FORMAT_XRGB8888:
-            return PIXMAN_x8r8g8b8;
-        case DRM_FORMAT_ARGB8888:
-            return PIXMAN_a8r8g8b8;
-        default:
-            assert(0 && "not reached");
+    struct tinyds_server *server;
+    struct ds_tizen_launch_splash_event_owner *event = data;
+    struct tinyds_view *view = NULL;
+
+    server = wl_container_of(listener, server, splash_owner);
+
+    ds_inf("Splash owner. pid(%u)", event->pid);
+
+    wl_list_for_each(view, &server->views, link) {
+        if (view->pid == event->pid) {
+            if (event->pid == ds_tizen_launch_splash_get_pid(server->splash))
+                ;//
+            else {
+                ds_tizen_launch_splash_set_pid(server->splash, event->pid);
+            }
+        }
     }
 }
 
-static pixman_image_t *
-image_from_buffer(struct ds_buffer *buffer,
-        enum ds_buffer_data_ptr_access_flag access_flag)
+static void
+launch_effect_handle_new_splash(struct wl_listener *listener, void *data)
 {
-    pixman_image_t *image;
-    void *data;
-    uint32_t format;
-    size_t stride;
-    int width, height;
+    struct tinyds_server *server;
+    struct ds_tizen_launch_splash *splash = data;
+    struct tinyds_view *view = NULL;
 
-    ds_buffer_get_size(buffer, &width, &height);
+    server = wl_container_of(listener, server, new_splash);
 
-    if (!ds_buffer_begin_data_ptr_access(buffer,
-                access_flag, &data, &format, &stride))
-        return NULL;
+    ds_inf("Launch new splash. splash(%p)", splash);
+    if (!splash) return;
 
-    format = convert_drm_format_to_pixman(format);
-    image = pixman_image_create_bits(format, width, height, data, stride);
-    if (!image) {
-        ds_buffer_end_data_ptr_access(buffer);
-        return NULL;
-    }
+    server->splash = splash;
 
-    pixman_image_set_destroy_function(image,
-            destroy_pixman_image, ds_buffer_lock(buffer));
+    // new view for "Launchscreen"
+    view = calloc(1, sizeof *view);
+    assert(view);
+    wl_list_insert(server->views.prev, &view->link);
+    view->pid = ds_tizen_launch_splash_get_pid(splash);
 
-    return image;
+    server->splash_owner.notify = launch_splash_handle_owner;
+    ds_tizen_launch_splash_add_owner_listener(server->splash,
+            &server->splash_owner);
 }
 
-static void
-view_send_frame_done(struct tinyds_view *view)
+static bool
+init_server(struct tinyds_server *server, struct wl_display *display)
 {
-    struct timespec now;
-    clock_gettime(CLOCK_MONOTONIC, &now);
-    ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
-            &now);
+    server->display = display;
+
+    wl_list_init(&server->views);
+
+    if (wl_display_init_shm(display) != 0)
+        return false;
+
+    server->backend = ds_tdm_backend_create(display);
+    if (!server->backend)
+        return false;
+
+    server->input_backend = ds_libinput_backend_create(display);
+    if (!server->input_backend) {
+        ds_backend_destroy(server->backend);
+        return false;
+    }
+
+    server->new_output.notify = backend_handle_new_output;
+    ds_backend_add_new_output_listener(server->backend,
+            &server->new_output);
+
+    wl_list_init(&server->keyboards);
+    wl_list_init(&server->pointers);
+    server->new_input.notify = backend_handle_new_input;
+    ds_backend_add_new_input_listener(server->input_backend, &server->new_input);
+
+    server->compositor = ds_compositor_create(display);
+    if (!server->compositor)
+        goto err;
+
+    server->tbm_server = ds_tbm_server_create(display);
+    if (!server->tbm_server)
+        goto err;
+
+    server->xdg_shell = ds_xdg_shell_create(display);
+    if (!server->xdg_shell)
+        goto err;
+
+    server->new_xdg_surface.notify = server_new_xdg_surface;
+    ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
+            &server->new_xdg_surface);
+
+    if (!add_new_dpms(server))
+        goto err;
+
+    if (!new_policy(server))
+        goto err;
+
+    server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
+    if (!server->seat)
+        goto err;
+    server->seat_caps = 0;
+
+    server->devicemgr = ds_tizen_input_devicemgr_create(
+            server->input_backend, server->seat);
+    if (!server->devicemgr) {
+        ds_err("Could not create ds_tizen_input_devicemgr");
+        goto err;
+    }
+
+    devicemgr_set_keymap(server->devicemgr);
+
+    server->devicemgr_destroy.notify = devicemgr_handle_destroy;
+    ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr,
+            &server->devicemgr_destroy);
+
+    server->pointer_warp.notify = devicemgr_handle_pointer_warp;
+    ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr,
+            &server->pointer_warp);
+
+    server->effect = ds_tizen_launch_effect_create(display);
+    if (!server->effect) {
+        goto err;
+    }
+
+    server->effect_destroy.notify = launch_effect_handle_destroy;
+    ds_tizen_launch_effect_add_destroy_listener(server->effect,
+            &server->effect_destroy);
+
+    server->effect_type_set.notify = launch_effect_handle_type_set;
+    ds_tizen_launch_effect_add_type_set_listener(server->effect,
+            &server->effect_type_set);
+
+    server->effect_type_unset.notify = launch_effect_handle_type_unset;
+    ds_tizen_launch_effect_add_type_unset_listener(server->effect,
+            &server->effect_type_unset);
+
+    server->new_splash.notify = launch_effect_handle_new_splash;
+    ds_tizen_launch_effect_add_new_splash_listener(server->effect,
+            &server->new_splash);
+
+    if (!add_new_text_input(server))
+        goto err;
+
+    if (!add_new_input_method(server))
+        goto err;
+
+    return true;
+
+err:
+    ds_backend_destroy(server->backend);
+    ds_backend_destroy(server->input_backend);
+
+    return false;
+}
+
+static void
+output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
+{
+    struct tinyds_output *output =
+        wl_container_of(listener, output, output_destroy);
+
+    if (output->bg_hwc_window)
+        ds_tdm_output_hwc_window_destroy(output->bg_hwc_window);
+
+    wl_list_remove(&output->output_destroy.link);
+    wl_list_remove(&output->output_frame.link);
+
+    if (output->front_buffer)
+        ds_buffer_unlock(output->front_buffer);
+
+#ifdef USE_TDM_BUFFER_QUEUE
+    fini_renderer(&output->renderer);
+#else
+    if (output->swapchain)
+        ds_swapchain_destroy(output->swapchain);
+
+    if (output->allocator)
+        ds_allocator_destroy(output->allocator);
+#endif
+
+    wl_display_terminate(output->server->display);
+
+    output->server->output = NULL;
+
+    free(output);
+}
+
+static void
+output_commit(struct tinyds_output *output)
+{
+    uint32_t num_changed = 0;
+    uint32_t num_windows = 0, current_num_windows = 0;
+    struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL;
+    struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL;
+    enum ds_tdm_output_hwc_window_composition composition;
+    struct tinyds_view *view;
+    int i;
+    bool need_target = false;
+    bool fully_obscured = false;
+    struct ds_buffer *ds_buffer;
+    struct ds_tdm_box src_box;
+    int w = 0, h = 0;
+
+    if (!output->committable)
+        return;
+
+    if (!output->damaged && !output->target_updated)
+        return;
+
+    wl_list_for_each_reverse(view, &output->server->views, link) {
+        if (!view->hwc_window)
+            continue;
+
+        ds_buffer = ds_surface_get_buffer(
+                ds_xdg_surface_get_surface(view->xdg_surface));
+        if (!ds_buffer)
+            continue;
+
+        if (!view->mapped)
+            continue;
+
+        num_windows++;
+
+        ds_buffer_get_size(ds_buffer, &w, &h);
+
+        if ((output->width <= w) && (output->height <= h))
+            fully_obscured = true;
+    }
+
+    if (fully_obscured) {
+        ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
+                DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
+    } else {
+        ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
+                DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
+        num_windows++;
+        need_target = true;
+    }
+
+    if (num_windows) {
+        composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows);
+        if (!composited_hwc_windows)
+            return;
+
+        wl_list_for_each_reverse(view, &output->server->views, link) {
+            if (!view->hwc_window)
+                continue;
+
+            ds_buffer = ds_surface_get_buffer(
+                    ds_xdg_surface_get_surface(view->xdg_surface));
+            if (!ds_buffer)
+                continue;
+
+            ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer);
+
+            ds_buffer_get_size(ds_buffer, &w, &h);
+
+            src_box.x = 0;
+            src_box.y = 0;
+            src_box.width = w;
+            src_box.height = h;
+
+            ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box);
+            ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y);
+            ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h);
+            ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
+
+            if (view->mapped) {
+                ds_tdm_output_hwc_window_set_composition(view->hwc_window,
+                        DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE);
+
+                composited_hwc_windows[current_num_windows] = view->hwc_window;
+                current_num_windows++;
+            } else {
+                ds_tdm_output_hwc_window_set_composition(view->hwc_window,
+                        DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
+            }
+        }
+
+        if (!fully_obscured) {
+            composited_hwc_windows[current_num_windows] = output->bg_hwc_window;
+            current_num_windows++;
+        }
+    }
+
+    if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows,
+            num_windows, &num_changed)) {
+        free(composited_hwc_windows);
+        ds_err("Could not hwc validate");
+        return;
+    }
+
+    if (composited_hwc_windows)
+        free(composited_hwc_windows);
+
+    if (num_changed > 0) {
+        changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows);
+        if (!changed_hwc_windows)
+            return;
+
+        if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed,
+                changed_hwc_windows)) {
+            free(changed_hwc_windows);
+            ds_err("Could not get chaged composition");
+            return;
+        }
+
+        for (i = 0; i < num_changed; i++) {
+            composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]);
+            if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) {
+                need_target = true;
+                break;
+            }
+        }
+    }
+
+    if (changed_hwc_windows)
+        free(changed_hwc_windows);
+
+    if (need_target && output->damaged)
+        draw_output(output);
+
+#ifdef USE_TDM_BUFFER_QUEUE
+    struct ds_buffer *buffer;
+
+    buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
+    if (buffer) {
+        if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, buffer)) {
+            ds_err("Could not set hwc client target buffer");
+            return;
+        }
+
+        output_swap_buffer(output, buffer);
+    }
+#endif
+
+    if (!ds_tdm_output_hwc_accept_validation(output->hwc)) {
+        ds_err("Could not hwc accept validateion");
+        return;
+    }
+
+    ds_output_commit(output->ds_output);
+
+    output->committable = false;
+    output->damaged = false;
+    output->target_updated = false;
+
+    wl_list_for_each(view, &output->server->views, link) {
+        enum ds_tdm_output_hwc_window_composition composition;
+
+        if (!view->mapped)
+            continue;
+
+        composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
+        if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
+            (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
+            (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
+            view_send_frame_done(view);
+    }
+
+    ds_dbg("output:%p commit", output);
+}
+
+static void
+output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
+{
+    struct tinyds_output *output =
+        wl_container_of(listener, output, output_frame);
+
+    ds_dbg("output:%p handle frame", output);
+
+    output->committable = true;
+
+    output_commit(output);
+}
+
+static void
+draw_server_with_damage(struct tinyds_server *server)
+{
+    server->output->damaged = true;
+    output_schedule_commit(server->output);
+}
+
+static void
+output_hwc_init(struct tinyds_output *output)
+{
+    struct ds_tdm_output *tdm_output;
+
+    tdm_output = ds_tdm_output_from_output(output->ds_output);
+    assert(tdm_output);
+
+    output->hwc = ds_tdm_output_get_hwc(tdm_output);
+    assert(output->hwc);
+
+    ds_tdm_output_hwc_set_enabled(output->hwc, true);
+}
+
+#ifdef USE_TDM_BUFFER_QUEUE
+static void
+output_handle_buffer_queue_acquirable(struct wl_listener *listener,
+        void *data TINYDS_UNUSED)
+{
+    struct tinyds_output *output;
+
+    output = wl_container_of(listener, output, buffer_queue_acquirable);
+
+    output->target_updated = true;
+    output_schedule_commit(output);
+}
+
+static void
+output_buffer_queue_init(struct tinyds_output *output)
+{
+    struct ds_tdm_output *tdm_output;
+
+    tdm_output = ds_tdm_output_from_output(output->ds_output);
+    assert(tdm_output);
+
+    output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
+    assert(output->buffer_queue);
+
+    output->buffer_queue_acquirable.notify =
+        output_handle_buffer_queue_acquirable;
+    ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
+            &output->buffer_queue_acquirable);
+}
+
+static void
+output_renderer_init(struct tinyds_output *output)
+{
+    init_renderer(&output->renderer);
+
+    renderer_set_surface_queue(&output->renderer,
+            ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
+
+    renderer_set_bg_color(&output->renderer, 80, 80, 80);
+}
+
+static void
+output_draw_with_renderer(struct tinyds_output *output)
+{
+    struct tinyds_view *view;
+
+    ds_dbg(">> BEGIN UPDATE TEXTURES");
+
+    wl_list_for_each(view, &output->server->views, link) {
+        struct ds_buffer *ds_buffer;
+        struct ds_tbm_client_buffer *tbm_buffer;
+        tbm_surface_h surface;
+        enum ds_tdm_output_hwc_window_composition composition;
+
+        if (!view->mapped)
+            continue;
+
+        composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
+        if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
+            (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
+            (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
+            continue;
+
+        ds_buffer = ds_surface_get_buffer(
+                ds_xdg_surface_get_surface(view->xdg_surface));
+        if (!ds_buffer)
+            continue;
+
+        tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
+        if (!tbm_buffer)
+            continue;
+
+        surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
+        if (!surface)
+            continue;
+
+        renderer_add_texture(&output->renderer, surface, view->x, view->y);
+
+        view_send_frame_done(view);
+    }
+
+    ds_dbg("<< END UPDATE TEXTURES");
+
+    renderer_draw(&output->renderer);
+}
+#else
+static void
+output_swapchain_init(struct tinyds_output *output,
+        int width, int height, uint32_t format)
+
+{
+    output->allocator = ds_tbm_allocator_create();
+    assert(output->allocator);
+
+    output->swapchain = ds_swapchain_create(output->allocator,
+            width, height, format);
+    assert(output->swapchain);
+}
+
+static void
+output_draw_with_swapchain(struct tinyds_output *output)
+{
+    struct tinyds_view *view;
+    struct ds_buffer *output_buffer;
+    pixman_image_t *output_image;
+    enum ds_tdm_output_hwc_window_composition composition;
+
+    output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
+    if (!output_buffer)
+        return;
+
+    output_image = pixman_image_from_buffer(output_buffer,
+            DS_BUFFER_DATA_PTR_ACCESS_WRITE);
+    if (!output_image) {
+        ds_buffer_unlock(output_buffer);
+        return;
+    }
+
+    pixman_image_fill_color(output_image, 80, 80, 80);
+
+    wl_list_for_each(view, &output->server->views, link) {
+        if (!view->mapped)
+            continue;
+
+        composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
+        if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
+            (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
+            (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
+            continue;
+
+        draw_view(view, output_image);
+    }
+    pixman_image_unref(output_image);
+
+    if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, output_buffer)) {
+        ds_err("Could not set hwc client target buffer");
+        ds_buffer_unlock(output_buffer);
+        return;
+    }
+
+    output_swap_buffer(output, output_buffer);
+}
+
+static void
+draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
+{
+    struct ds_buffer *buffer;
+    pixman_image_t *src_image;
+
+    buffer = ds_surface_get_buffer(
+            ds_xdg_surface_get_surface(view->xdg_surface));
+    if (!buffer)
+        return;
+
+    src_image = pixman_image_from_buffer(buffer,
+            DS_BUFFER_DATA_PTR_ACCESS_READ);
+    pixman_image_composite32(PIXMAN_OP_OVER,
+            src_image,
+            NULL,
+            dst_image,
+            0, 0, 0, 0,
+            view->x, view->y,
+            pixman_image_get_width(src_image),
+            pixman_image_get_height(src_image));
+    pixman_image_unref(src_image);
+
+    view_send_frame_done(view);
+}
+#endif
+
+static void
+draw_output(struct tinyds_output *output)
+{
+#ifdef USE_TDM_BUFFER_QUEUE
+    output_draw_with_renderer(output);
+#else
+    output_draw_with_swapchain(output);
+#endif
+
+    ds_dbg("output:%p draw", output);
+}
+
+static void
+output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
+{
+    ds_output_attach_buffer(output->ds_output, buffer);
+
+    if (output->front_buffer)
+        ds_buffer_unlock(output->front_buffer);
+    output->front_buffer = buffer;
+}
+
+static void
+view_send_frame_done(struct tinyds_view *view)
+{
+    struct timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
+            &now);
+}
+
+static int
+server_dispatch_stdin(int fd, uint32_t mask, void *data)
+{
+    struct tinyds_server *server = data;
+
+    wl_display_terminate(server->display);
+
+    return 1;
+}
+
+static void
+dpms_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_dpms *dpms;
+
+    dpms = wl_container_of(listener, dpms, destroy);
+
+    ds_inf("Dpms(%p) destroyed", dpms);
+
+    wl_list_remove(&dpms->destroy.link);
+    wl_list_remove(&dpms->set_dpms.link);
+    wl_list_remove(&dpms->get_dpms.link);
+
+    free(dpms);
+}
+
+static void
+dpms_handle_set_dpms(struct wl_listener *listener, void *data)
+{
+    struct tinyds_dpms *dpms;
+    struct ds_tizen_dpms_event *event = data;
+
+    dpms = wl_container_of(listener, dpms, set_dpms);
+
+    ds_inf("Dpms(%p) set dpms : %d", dpms, event->mode);
+
+    //To do
+    //set dpms mode to output
+    ds_tizen_dpms_send_set_result(dpms->ds_dpms, event->mode,
+        DS_TIZEN_DPMS_ERROR_NONE);
+}
+
+static void
+dpms_handle_get_dpms(struct wl_listener *listener, void *data)
+{
+    struct tinyds_dpms *dpms;
+
+    dpms = wl_container_of(listener, dpms, get_dpms);
+
+    ds_inf("Dpms(%p) get dpms", dpms);
+
+    //To do
+    //get dpms mode from output
+    ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON,
+        DS_TIZEN_DPMS_ERROR_NONE);
+}
+
+static void
+keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_keyboard *kbd;
+
+    kbd = wl_container_of(listener, kbd, destroy);
+
+    ds_inf("Keyboard(%p) destroyed", kbd);
+
+    wl_list_remove(&kbd->destroy.link);
+    wl_list_remove(&kbd->key.link);
+    wl_list_remove(&kbd->link);
+
+    free(kbd);
+}
+
+static bool
+server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
+{
+    switch (sym) {
+        case XKB_KEY_BackSpace:
+            wl_display_terminate(server->display);
+            break;
+        default:
+            return false;
+    }
+
+    return true;
+}
+
+static void
+keyboard_handle_key(struct wl_listener *listener, void *data)
+{
+    struct tinyds_keyboard *kbd;
+    struct ds_event_keyboard_key *event = data;
+    struct ds_keyboard *ds_keyboard;
+    struct xkb_state *xkb_state;
+    const xkb_keysym_t *syms;
+    int nsyms;
+    bool handled = false;
+
+    kbd = wl_container_of(listener, kbd, key);
+
+    ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
+            "update_state(%d)", kbd->dev,
+            event->keycode, event->state, event->time_msec,
+            event->update_state);
+
+    ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
+
+    if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
+        xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
+        if (xkb_state) {
+            nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
+                    &syms);
+            for (int i = 0; i < nsyms; i++) {
+                handled = server_handle_keybinding(kbd->server, syms[i]);
+            }
+        }
+    }
+
+    if (!handled) {
+        ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec,
+                event->keycode, event->state);
+    }
+}
+
+static void
+server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
+{
+    struct tinyds_keyboard *kbd;
+    struct xkb_context *context;
+    struct xkb_keymap *keymap;
+
+    kbd = calloc(1, sizeof *kbd);
+    assert(kbd);
+
+    kbd->dev = dev;
+    kbd->server = server;
+
+    context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+    if (!context)
+        goto err;
+
+    keymap = xkb_keymap_new_from_names(context, NULL,
+            XKB_KEYMAP_COMPILE_NO_FLAGS);
+
+    if (!keymap) {
+        ds_err("Failed to compile keymap");
+        xkb_context_unref(context);
+        goto err;
+    }
+
+    ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap);
+
+    xkb_keymap_unref(keymap);
+    xkb_context_unref(context);
+
+    kbd->destroy.notify = keyboard_handle_device_destroy;
+    ds_input_device_add_destroy_listener(dev, &kbd->destroy);
+
+    kbd->key.notify = keyboard_handle_key;
+    ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
+
+    wl_list_insert(&server->keyboards, &kbd->link);
+
+    ds_inf("Keyboard(%p) added", kbd);
+
+    return;
+
+err:
+    free(kbd);
+}
+
+static struct tinyds_view *
+server_view_at(struct tinyds_server *server, double lx, double ly,
+        double *sx, double *sy)
+{
+    struct tinyds_view *view;
+    struct ds_surface *surface;
+    struct ds_buffer *buffer;
+    int x, y, w = 0, h = 0;
+
+    wl_list_for_each(view, &server->views, link) {
+        surface = ds_xdg_surface_get_surface(view->xdg_surface);
+        buffer = ds_surface_get_buffer(surface);
+        ds_buffer_get_size(buffer, &w, &h);
+
+        x = view->x;
+        y = view->y;
+
+        if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) {
+            *sx = lx - x;
+            *sy = ly - y;
+
+            return view;
+        }
+    }
+
+    return NULL;
+}
+
+static void
+touch_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_touch *touch;
+
+    touch = wl_container_of(listener, touch, destroy);
+
+    ds_inf("Touch(%p) destroyed", touch);
+
+    wl_list_remove(&touch->destroy.link);
+    wl_list_remove(&touch->down.link);
+    wl_list_remove(&touch->up.link);
+    wl_list_remove(&touch->motion.link);
+
+    free(touch);
+}
+
+static void
+touch_handle_down(struct wl_listener *listener, void *data)
+{
+    struct ds_event_touch_down *event = data;
+    struct tinyds_touch *touch;
+    struct tinyds_view *view;
+    struct tinyds_server *server;
+    double sx = 0.f, sy = 0.f;
+
+    touch = wl_container_of(listener, touch, down);
+
+    server = touch->server;
+    server->output_x = event->x * server->output->width;
+    server->output_y = event->y * server->output->height;
+
+    ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
+            touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
+
+    view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
+
+    if (view) {
+        ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface),
+                event->time_msec, event->id, sx, sy);
+    }
+}
+
+static void
+touch_handle_up(struct wl_listener *listener, void *data)
+{
+    struct ds_event_touch_up *event = data;
+    struct tinyds_touch *touch;
+
+    touch = wl_container_of(listener, touch, up);
+
+    ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
+            touch->dev, event->id, event->time_msec);
+
+    ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id);
+}
+
+static void
+touch_handle_motion(struct wl_listener *listener, void *data)
+{
+    struct ds_event_touch_motion *event = data;
+    struct tinyds_touch *touch;
+    struct tinyds_view *view;
+    struct tinyds_server *server;
+    double sx = 0.f, sy = 0.f;
+
+    touch = wl_container_of(listener, touch, motion);
+
+    server = touch->server;
+    server->output_x = event->x * server->output->width;
+    server->output_y = event->y * server->output->height;
+
+    ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
+            touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
+
+    view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
+
+    if (view) {
+        ds_seat_touch_notify_motion(server->seat, event->time_msec,
+                event->id, sx, sy);
+    }
+}
+
+static void
+server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
+{
+    struct tinyds_touch *touch;
+
+    touch = calloc(1, sizeof *touch);
+    assert(touch);
+
+    touch->dev = dev;
+    touch->server = server;
+
+    touch->destroy.notify = touch_handle_device_destroy;
+    ds_input_device_add_destroy_listener(dev, &touch->destroy);
+
+    touch->down.notify = touch_handle_down;
+    ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
+
+    touch->up.notify = touch_handle_up;
+    ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
+
+    touch->motion.notify = touch_handle_motion;
+    ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
+
+    ds_inf("Touch(%p) added", touch);
+}
+
+static void
+pointer_handle_device_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_pointer *pointer;
+
+    pointer = wl_container_of(listener, pointer, destroy);
+
+    ds_inf("Pointer(%p) destroyed", pointer);
+
+    wl_list_remove(&pointer->destroy.link);
+    wl_list_remove(&pointer->motion.link);
+    wl_list_remove(&pointer->button.link);
+    wl_list_remove(&pointer->frame.link);
+    wl_list_remove(&pointer->link);
+
+    free(pointer);
+}
+
+static void
+pointer_handle_motion(struct wl_listener *listener, void *data)
+{
+    struct tinyds_pointer *pointer;
+    struct ds_event_pointer_motion *event = data;
+    struct tinyds_view *view;
+    struct tinyds_server *server;
+    int ow = 0, oh = 0;
+    double sx, sy;
+
+    pointer = wl_container_of(listener, pointer, motion);
+
+    server = pointer->server;
+    if (server->output) {
+        ow = server->output->width;
+        oh = server->output->height;
+    }
+
+    if (server->output_x + event->delta_x >= ow)
+        server->output_x = ow;
+    else if(server->output_x + event->delta_x <= 0.f)
+        server->output_x = 0.f;
+    else
+        server->output_x = server->output_x + event->delta_x ;
+    if (server->output_y + event->delta_y >= oh)
+        server->output_y = oh;
+    else if(server->output_y + event->delta_y <= 0.f)
+        server->output_y = 0.f;
+    else
+        server->output_y = server->output_y + event->delta_y ;
+
+    ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f",
+            pointer, event->delta_x, event->delta_y, server->output_x, server->output_y);
+
+    view = server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy);
+
+    if (pointer->focused_view != view) {
+        if (pointer->focused_view) {
+            ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
+            ds_seat_pointer_notify_clear_focus(pointer->server->seat);
+            pointer->focused_view = NULL;
+        }
+
+        if (view) {
+            ds_inf("Set pointer focus to view(%p)", view);
+            ds_seat_pointer_notify_enter(pointer->server->seat,
+                    ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
+            pointer->focused_view = view;
+        }
+    }
+
+    if (view) {
+        ds_seat_pointer_notify_motion(pointer->server->seat,
+                event->time_msec, sx, sy);
+    }
+}
+
+static void
+pointer_handle_button(struct wl_listener *listener, void *data)
+{
+    struct tinyds_pointer *pointer;
+    struct ds_event_pointer_button *event = data;
+
+    pointer = wl_container_of(listener, pointer, button);
+
+    ds_inf("Pointer(%p) button(%d): state(%s) time(%d)",
+            pointer, event->button,
+            (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released",
+            event->time_msec);
+
+    ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state);
+}
+
+static void
+pointer_handle_frame(struct wl_listener *listener, void *data)
+{
+    struct tinyds_pointer *pointer;
+
+    pointer = wl_container_of(listener, pointer, frame);
+
+    ds_inf("Pointer(%p) frame", pointer);
+    ds_seat_pointer_notify_frame(pointer->server->seat);
+}
+
+static void
+server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev)
+{
+    struct tinyds_pointer *pointer;
+
+    pointer = calloc(1, sizeof *pointer);
+    assert(pointer);
+
+    pointer->dev = dev;
+    pointer->server = server;
+    server->output_x = 200;
+    server->output_y = 200;
+
+    pointer->destroy.notify = pointer_handle_device_destroy;
+    ds_input_device_add_destroy_listener(dev, &pointer->destroy);
+
+    pointer->motion.notify = pointer_handle_motion;
+    ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev),
+            &pointer->motion);
+
+    pointer->button.notify = pointer_handle_button;
+    ds_pointer_add_button_listener(ds_input_device_get_pointer(dev),
+            &pointer->button);
+
+    pointer->frame.notify = pointer_handle_frame;
+    ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev),
+            &pointer->frame);
+
+    pointer->focused_view = NULL;
+
+    wl_list_insert(&server->pointers, &pointer->link);
+
+    ds_inf("Pointer(%p) added", pointer);
+}
+
+static void
+output_schedule_commit_handle_idle_timer(void *data)
+{
+    struct tinyds_output *output = data;
+    output->idle_commit = NULL;
+
+    output_commit(output);
+}
+
+static void
+output_schedule_commit(struct tinyds_output *output)
+{
+    if (output->idle_commit)
+        return;
+
+    struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display);
+    output->idle_commit =
+        wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output);
+}
+
+static void
+text_input_mgr_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct tinyds_server *server;
+
+    ds_inf("text_input_mgr_handle_destroy");
+    text_input = wl_container_of(listener, text_input, mgr_destroy);
+
+    wl_list_remove(&text_input->mgr_destroy.link);
+    wl_list_remove(&text_input->destroy.link);
+
+    wl_list_remove(&text_input->new_text_input.link);
+
+    wl_list_remove(&text_input->text_input_activate.link);
+    wl_list_remove(&text_input->text_input_deactivate.link);
+    wl_list_remove(&text_input->text_input_reset.link);
+    wl_list_remove(&text_input->text_input_set_content_type.link);
+    wl_list_remove(&text_input->text_input_invoke_action.link);
+    wl_list_remove(&text_input->text_input_commit_state.link);
+    wl_list_remove(&text_input->text_input_set_preferred_language.link);
+
+    server = text_input->server;
+    server->text_input = NULL;
+
+    free(text_input);
+}
+
+static void
+text_input_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+
+    ds_inf("text_input_handle_destroy");
+
+    text_input = wl_container_of(listener, text_input, destroy);
+
+    wl_list_remove(&text_input->destroy.link);
+}
+
+static void
+text_input_handle_activate(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct tinyds_input_method *input_method;
+    struct ds_tizen_text_input_event_activate *event = data;
+
+    text_input = wl_container_of(listener, text_input, text_input_activate);
+
+    input_method = text_input->server->input_method;
+
+    ds_inf("text_input_handle_activate. text_input(%p) seat(%p) surface(%p) text_input(%p)",
+        text_input, event->seat, event->surface, event->text_input);
+
+    if (input_method->input == text_input)
+        return;
+    if (input_method->input)
+        ;//deactivate_input_method(server->input_method);
+    input_method->input = text_input;
+    wl_list_insert(&text_input->input_methods, &input_method->link);
+
+    text_input->surface = event->surface;
+
+    if (!add_new_input_method_context(input_method, text_input))
+        return;
+
+    // ds_tizen_input_method_send_set_text_input_id();
+}
+
+static void
+text_input_handle_deactivate(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct tinyds_input_method *input_method, *tmp;
+    struct ds_tizen_text_input_event_deactivate *event = data;
+
+    text_input = wl_container_of(listener, text_input, text_input_deactivate);
+    ds_inf("text_input_handle_deactivate. text_input(%p) seat(%p) text_input(%p)",
+        text_input, event->seat, event->text_input);
+
+    wl_list_for_each_safe(input_method, tmp, &text_input->input_methods, link) {
+        if (!input_method->input_method || !input_method->context->context) continue;
+        ds_tizen_input_method_send_deactivate(input_method->input_method, input_method->context->context);
+        input_method->input = NULL;
+        input_method->context = NULL;
+        wl_list_remove(&input_method->link);
+    }
+
+    text_input->surface = NULL;
+    // ds_tizen_input_method_send_close_connection();
+}
+
+static void
+text_input_handle_reset(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct tinyds_input_method *input_method;
+
+    text_input = wl_container_of(listener, text_input, text_input_reset);
+
+    ds_inf("text_input_handle_reset. text_input(%p)", text_input);
+
+    wl_list_for_each(input_method, &text_input->input_methods, link) {
+        if (!input_method->context || !input_method->context->context) continue;
+        ds_tizen_input_method_context_send_reset(input_method->context->context);
+    }
+}
+
+static void
+text_input_handle_set_content_type(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_text_input_event_set_content_type *event = data;
+    struct tinyds_input_method *input_method;
+
+    text_input = wl_container_of(listener, text_input, text_input_set_content_type);
+
+    ds_inf("text_input_handle_content_type. text_input(%p) hint(%u) purpose(%u)",
+        text_input, event->hint, event->purpose);
+
+    wl_list_for_each(input_method, &text_input->input_methods, link) {
+        if (!input_method->context || !input_method->context->context) continue;
+        ds_tizen_input_method_context_send_content_type(input_method->context->context,
+            event->hint, event->purpose);
+    }
+}
+
+static void
+text_input_handle_invoke_action(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_text_input_event_invoke_action *event = data;
+    struct tinyds_input_method *input_method;
+
+    text_input = wl_container_of(listener, text_input, text_input_invoke_action);
+
+    ds_inf("text_input_handle_invoke_action. text_input(%p) button(%u) index(%u)",
+        text_input, event->button, event->index);
+
+    wl_list_for_each(input_method, &text_input->input_methods, link) {
+        if (!input_method->context || !input_method->context->context) continue;
+        ds_tizen_input_method_context_send_invoke_action(input_method->context->context,
+            event->button, event->index);
+    }
+}
+
+static void
+text_input_handle_commit_state(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_text_input_event_commit_state *event = data;
+    struct tinyds_input_method *input_method;
+
+    text_input = wl_container_of(listener, text_input, text_input_commit_state);
+
+    ds_inf("text_input_handle_commit_state. text_input(%p) serial(%u)",
+        text_input, event->serial);
+
+    wl_list_for_each(input_method, &text_input->input_methods, link) {
+        if (!input_method->context || !input_method->context->context) continue;
+        ds_tizen_input_method_context_send_commit_state(input_method->context->context,
+            event->serial);
+    }
+}
+
+static void
+text_input_handle_set_preferred_language(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_text_input_event_set_preferred_language *event = data;
+    struct tinyds_input_method *input_method;
+
+    text_input = wl_container_of(listener, text_input, text_input_set_preferred_language);
+
+    ds_inf("text_input_handle_set_preferred_language. text_input(%p) language(%s)",
+        text_input, event->language);
+
+    wl_list_for_each(input_method, &text_input->input_methods, link) {
+        if (!input_method->context || !input_method->context->context) continue;
+        ds_tizen_input_method_context_send_preferred_language(input_method->context->context,
+            event->language);
+    }
+}
+
+static void
+text_input_mgr_handle_new_text_input(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_text_input *input = data;
+
+    text_input = wl_container_of(listener, text_input, new_text_input);
+
+    ds_inf("text_input_mgr_handle_new_text_input");
+
+    text_input->input = input;
+
+    text_input->destroy.notify = text_input_handle_destroy;
+    ds_tizen_text_input_add_destroy_listener(text_input->input,
+        &text_input->destroy);
+
+    text_input->text_input_activate.notify = text_input_handle_activate;
+    ds_tizen_text_input_add_activate_listener(text_input->input,
+        &text_input->text_input_activate);
+
+    text_input->text_input_deactivate.notify = text_input_handle_deactivate;
+    ds_tizen_text_input_add_deactivate_listener(text_input->input,
+        &text_input->text_input_deactivate);
+
+    text_input->text_input_reset.notify = text_input_handle_reset;
+    ds_tizen_text_input_add_reset_listener(text_input->input,
+        &text_input->text_input_reset);
+
+    text_input->text_input_set_content_type.notify = text_input_handle_set_content_type;
+    ds_tizen_text_input_add_set_content_type_listener(text_input->input,
+        &text_input->text_input_set_content_type);
+
+    text_input->text_input_invoke_action.notify = text_input_handle_invoke_action;
+    ds_tizen_text_input_add_invoke_action_listener(text_input->input,
+        &text_input->text_input_invoke_action);
+
+    text_input->text_input_commit_state.notify = text_input_handle_commit_state;
+    ds_tizen_text_input_add_commit_state_listener(text_input->input,
+        &text_input->text_input_commit_state);
+
+    text_input->text_input_set_preferred_language.notify = text_input_handle_set_preferred_language;
+    ds_tizen_text_input_add_set_preferred_language_listener(text_input->input,
+        &text_input->text_input_set_preferred_language);
+}
+
+static void
+input_method_mgr_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method *input_method;
+
+    ds_inf("input_method_mgr_handle_destroy");
+
+    input_method = wl_container_of(listener, input_method, mgr_destroy);
+
+    wl_list_remove(&input_method->mgr_destroy.link);
+}
+
+static void
+input_method_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method *input_method;
+    struct tinyds_server *server;
+
+    ds_inf("input_method_handle_destroy");
+
+    input_method = wl_container_of(listener, input_method, destroy);
+
+    wl_list_remove(&input_method->destroy.link);
+
+    server = input_method->server;
+    server->input_method = NULL;
+
+    free(input_method);
+}
+
+static void
+context_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_server *server;
+
+    ds_inf("context_handle_destroy");
+
+    context = wl_container_of(listener, context, destroy);
+
+    wl_list_remove(&context->destroy.link);
+
+    wl_list_remove(&context->im_context_commit_string.link);
+    wl_list_remove(&context->im_context_preedit_string.link);
+    wl_list_remove(&context->im_context_preedit_styling.link);
+    wl_list_remove(&context->im_context_preedit_cursor.link);
+    wl_list_remove(&context->im_context_delete_surrounding_text.link);
+    wl_list_remove(&context->im_context_cursor_position.link);
+    wl_list_remove(&context->im_context_modifiers_map.link);
+    wl_list_remove(&context->im_context_keysym.link);
+    wl_list_remove(&context->im_context_grab_keyboard.link);
+    wl_list_remove(&context->im_context_key.link);
+    wl_list_remove(&context->im_context_modifiers.link);
+    wl_list_remove(&context->im_context_language.link);
+    wl_list_remove(&context->im_context_text_direction.link);
+
+    server = context->server;
+    server->input_method->context = NULL;
+
+    free(context);
+}
+
+static void
+context_handle_commit_string(struct wl_listener *listener, void *data)
+{
+    struct tinyds_text_input *text_input;
+    struct tinyds_input_method_context *context;
+    struct ds_tizen_input_method_context_event_commit_string *event = data;
+
+    context = wl_container_of(listener, context, im_context_commit_string);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_commit_string. text_input(%p) serial(%u) text(%s)",
+        text_input, event->serial, event->text);
+
+    ds_tizen_text_input_send_commit_string(text_input->input, event->serial, event->text);
+}
+
+static void
+context_handle_preedit_string(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_preedit_string *event = data;
+
+    context = wl_container_of(listener, context, im_context_preedit_string);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_preedit_string. text_input(%p) serial(%u) text(%s) commit(%s)",
+        text_input, event->serial, event->text, event->commit);
+
+    ds_tizen_text_input_send_preedit_string(text_input->input, event->serial, event->text, event->commit);
+}
+
+static void
+context_handle_preedit_styling(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_preedit_styling *event = data;
+
+    context = wl_container_of(listener, context, im_context_preedit_styling);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_preedit_styling. text_input(%p) index(%u) length(%u) style(%u)",
+        text_input, event->index, event->length, event->style);
+
+    ds_tizen_text_input_send_preedit_styling(text_input->input, event->index, event->length, event->style);
+}
+
+static void
+context_handle_preedit_cursor(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_preedit_cursor *event = data;
+
+    context = wl_container_of(listener, context, im_context_preedit_cursor);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_preedit_cursor. text_input(%p) index(%u)",
+        text_input, event->index);
+
+    ds_tizen_text_input_send_preedit_cursor(text_input->input, event->index);
+}
+
+static void
+context_handle_delete_surrounding_text(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_delete_surrounding_text *event = data;
+
+    context = wl_container_of(listener, context, im_context_delete_surrounding_text);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_delete_surrounding_text. text_input(%p) index(%d) length(%u)",
+        text_input, event->index, event->length);
+
+    ds_tizen_text_input_send_delete_surrounding_text(text_input->input, event->index, event->length);
+}
+
+static void
+context_handle_cursor_position(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_cursor_position *event = data;
+
+    context = wl_container_of(listener, context, im_context_cursor_position);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_cursor_position. text_input(%p) index(%d) length(%d)",
+        text_input, event->index, event->anchor);
+
+    ds_tizen_text_input_send_cursor_position(text_input->input, event->index, event->anchor);
+}
+
+static void
+context_handle_modifiers_map(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_modifiers_map *event = data;
+
+    context = wl_container_of(listener, context, im_context_modifiers_map);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_modifiers_map. text_input(%p) map(%p)",
+        text_input, event->map);
+
+    ds_tizen_text_input_send_modifiers_map(text_input->input, event->map);
+}
+
+static void
+context_handle_keysym(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_keysym *event = data;
+
+    context = wl_container_of(listener, context, im_context_keysym);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_keysym. text_input(%p) serial(%u) time(%u) sysm(%u) state(%u) modifiers(%u)",
+        text_input, event->serial, event->time, event->sym, event->state, event->modifiers);
+
+    ds_tizen_text_input_send_keysym(text_input->input, event->serial, event->time, event->sym, event->state, event->modifiers);
+}
+
+static void
+context_handle_grab_keyboard(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+
+    context = wl_container_of(listener, context, im_context_grab_keyboard);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_grab_keyboard. text_input(%p)",
+        text_input);
+
+    //TODO
+}
+
+static void
+context_handle_key(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+
+    context = wl_container_of(listener, context, im_context_key);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_key. text_input(%p)",
+        text_input);
+
+   //TODO
+}
+
+static void
+context_handle_modifiers(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+
+    context = wl_container_of(listener, context, im_context_modifiers);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_modifiers. text_input(%p)",
+        text_input);
+
+   //TODO
+}
+
+static void
+context_handle_language(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_language *event = data;
+
+    context = wl_container_of(listener, context, im_context_language);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_language. text_input(%p) serial(%u), language(%s)",
+        text_input, event->serial, event->language);
+
+    ds_tizen_text_input_send_language(text_input->input, event->serial, event->language);
+}
+
+static void
+context_handle_text_direction(struct wl_listener *listener, void *data)
+{
+    struct tinyds_input_method_context *context;
+    struct tinyds_text_input *text_input;
+    struct ds_tizen_input_method_context_event_text_direction *event = data;
+
+    context = wl_container_of(listener, context, im_context_text_direction);
+    text_input = context->server->text_input;
+
+    ds_inf("context_handle_text_direction. text_input(%p) serial(%u), direction(%u)",
+        text_input, event->serial, event->direction);
+
+    ds_tizen_text_input_send_text_direction(text_input->input, event->serial, event->direction);
+}
+
+static bool
+add_new_text_input(struct tinyds_server *server)
+{
+    struct tinyds_text_input *text_input;
+
+    text_input = calloc(1, sizeof *text_input);
+    if (!text_input)
+        return false;
+
+    text_input->text_input_mgr = ds_tizen_text_input_manager_create(server->display);
+    if (!text_input->text_input_mgr) {
+        free(text_input);
+        ds_err("Could not create ds_tizen_text_input_manager");
+        return false;
+    }
+
+    wl_list_init(&text_input->input_methods);
+
+    text_input->destroy.notify = text_input_mgr_handle_destroy;
+    ds_tizen_text_input_manager_add_destroy_listener(text_input->text_input_mgr,
+            &text_input->destroy);
+
+    text_input->new_text_input.notify = text_input_mgr_handle_new_text_input;
+    ds_tizen_text_input_manager_add_new_text_input_listener(text_input->text_input_mgr,
+            &text_input->new_text_input);
+
+    text_input->server = server;
+    server->text_input = text_input;
+
+    ds_inf("Text_Input (%p) added", text_input);
+
+    return true;
+}
+
+static bool
+add_new_input_method(struct tinyds_server *server)
+{
+    struct tinyds_input_method *input_method;
+
+    input_method = calloc(1, sizeof *input_method);
+    if (!input_method)
+        return false;
+
+    input_method->input_method = ds_tizen_input_method_create(server->display);
+    if (!input_method->input_method) {
+        free(input_method);
+        ds_err("Could not create ds_tizen_input_method");
+        return false;
+    }
+    input_method->destroy.notify = input_method_handle_destroy;
+    ds_tizen_input_method_add_destroy_listener(input_method->input_method,
+            &input_method->destroy);
+
+    input_method->input_method_mgr = ds_tizen_input_method_manager_create(server->display);
+    if (!input_method->input_method_mgr) {
+        free(input_method);
+        ds_err("Could not create ds_tizen_input_method_manager");
+        return false;
+    }
+
+    input_method->mgr_destroy.notify = input_method_mgr_handle_destroy;
+    ds_tizen_input_method_manager_add_destroy_listener(input_method->input_method_mgr,
+            &input_method->mgr_destroy);
+
+    input_method->server = server;
+    server->input_method = input_method;
+
+    ds_inf("Input_Method (%p) added", input_method);
+
+    return true;
+}
+
+static bool
+add_new_input_method_context(struct tinyds_input_method *input_method,
+        struct tinyds_text_input *text_input)
+{
+    struct tinyds_input_method_context *context;
+
+    context = calloc(1, sizeof *context);
+    if (context == NULL)
+    {
+        ds_err("calloc is failed. tinyds_input_method_context");
+        return false;
+    }
+    input_method->context = context;
+    context->input_method = input_method;
+    context->server = input_method->server;
+    context->input = text_input;
+
+    context->context = ds_tizen_input_method_create_context(input_method->input_method);
+    if (context->context == NULL) {
+        ds_err("ds_tizen_input_method_create_context() failed.");
+        return false;
+    }
+
+    context->destroy.notify = context_handle_destroy;
+    ds_tizen_input_method_context_add_destroy_listener(context->context,
+        &context->destroy);
+
+    context->im_context_commit_string.notify = context_handle_commit_string;
+    ds_tizen_input_method_context_add_commit_string_listener(context->context,
+        &context->im_context_commit_string);
+
+    context->im_context_preedit_string.notify = context_handle_preedit_string;
+    ds_tizen_input_method_context_add_preedit_string_listener(context->context,
+        &context->im_context_preedit_string);
+
+    context->im_context_preedit_styling.notify = context_handle_preedit_styling;
+    ds_tizen_input_method_context_add_preedit_styling_listener(context->context,
+        &context->im_context_preedit_styling);
+
+    context->im_context_preedit_cursor.notify = context_handle_preedit_cursor;
+    ds_tizen_input_method_context_add_preedit_cursor_listener(context->context,
+        &context->im_context_preedit_cursor);
+
+    context->im_context_delete_surrounding_text.notify = context_handle_delete_surrounding_text;
+    ds_tizen_input_method_context_add_delete_surrounding_text_listener(context->context,
+        &context->im_context_delete_surrounding_text);
+
+    context->im_context_cursor_position.notify = context_handle_cursor_position;
+    ds_tizen_input_method_context_add_cursor_position_listener(context->context,
+        &context->im_context_cursor_position);
+
+    context->im_context_modifiers_map.notify = context_handle_modifiers_map;
+    ds_tizen_input_method_context_add_modifiers_map_listener(context->context,
+        &context->im_context_modifiers_map);
+
+    context->im_context_keysym.notify = context_handle_keysym;
+    ds_tizen_input_method_context_add_keysym_listener(context->context,
+        &context->im_context_keysym);
+
+    context->im_context_grab_keyboard.notify = context_handle_grab_keyboard;
+    ds_tizen_input_method_context_add_grab_keyboard_listener(context->context,
+        &context->im_context_grab_keyboard);
+
+    context->im_context_key.notify = context_handle_key;
+    ds_tizen_input_method_context_add_key_listener(context->context,
+        &context->im_context_key);
+
+    context->im_context_modifiers.notify = context_handle_modifiers;
+    ds_tizen_input_method_context_add_modifiers_listener(context->context,
+        &context->im_context_modifiers);
+
+    context->im_context_language.notify = context_handle_language;
+    ds_tizen_input_method_context_add_language_listener(context->context,
+        &context->im_context_language);
+
+    context->im_context_text_direction.notify = context_handle_text_direction;
+    ds_tizen_input_method_context_add_text_direction_listener(context->context,
+        &context->im_context_text_direction);
+
+    return true;
+}
+
+static void
+visibility_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_visibility *visibility;
+
+    visibility = wl_container_of(listener, visibility, destroy);
+
+    ds_inf("Policy Visibility(%p) destroy", visibility);
+
+    wl_list_remove(&visibility->link);
+    free(visibility);
+}
+
+static void
+position_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_position *position;
+
+    position = wl_container_of(listener, position, destroy);
+
+    ds_inf("Policy Position(%p) destroy", position);
+
+    wl_list_remove(&position->link);
+    free(position);
+}
+
+static void
+position_handle_set(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_position *position;
+
+    position = wl_container_of(listener, position, set);
+
+    ds_inf("Policy Position(%p) set", position);
+
+    // TODO:
+}
+
+static void
+subsurface_watcher_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_subsurface_watcher *subsurface_watcher;
+
+    subsurface_watcher = wl_container_of(listener, subsurface_watcher, destroy);
+
+    ds_inf("Policy Subsurface_Watcher(%p) destroy", subsurface_watcher);
+
+    wl_list_remove(&subsurface_watcher->link);
+    free(subsurface_watcher);
+}
+
+static void
+policy_surface_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, destroy);
+
+    ds_inf("Policy Info(%p) destroy", policy_surface);
+
+    wl_list_remove(&policy_surface->link);
+    free(policy_surface);
+}
+
+static void
+policy_surface_handle_new_visibility(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+    struct tinyds_policy_visibility *visibility;
+    struct ds_tizen_event_policy_surface_new_visibility *event;
+
+    policy_surface = wl_container_of(listener, policy_surface, new_visibility);
+    event = (struct ds_tizen_event_policy_surface_new_visibility *)data;
+
+    ds_inf("Policy Info(%p) new_visibility", policy_surface);
+
+    visibility = calloc(1, sizeof *visibility);
+    if (!visibility)
+        return;
+
+    visibility->visibility = event->visibility;
+
+    visibility->destroy.notify = visibility_handle_destroy;
+    ds_tizen_policy_visibility_add_destroy_listener(visibility->visibility,
+        &visibility->destroy);
+
+    wl_list_insert(&policy_surface->visibilities, &visibility->link);
+}
+
+static void
+policy_surface_handle_new_position(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+    struct tinyds_policy_position *position;
+    struct ds_tizen_event_policy_surface_new_position *event;
+
+    policy_surface = wl_container_of(listener, policy_surface, new_position);
+    event = (struct ds_tizen_event_policy_surface_new_position *)data;
+
+    ds_inf("Policy Info(%p) new_position", policy_surface);
+
+    position = calloc(1, sizeof *position);
+    if (!position)
+        return;
+
+    position->position = event->position;
+
+    position->destroy.notify = position_handle_destroy;
+    ds_tizen_policy_position_add_destroy_listener(position->position,
+        &position->destroy);
+
+    position->set.notify = position_handle_set;
+    ds_tizen_policy_position_add_set_listener(position->position,
+        &position->set);
+
+    wl_list_insert(&policy_surface->positions, &position->link);
+}
+
+static void
+policy_surface_handle_activate(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, activate);
+
+    ds_inf("Policy Info(%p) activate", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_raise(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, raise);
+
+    ds_inf("Policy Info(%p) raise", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_lower(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, raise);
+
+    ds_inf("Policy Info(%p) lower", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_focus_skip(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_focus_skip);
+
+    ds_inf("Policy Info(%p) set_focus_skip", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_unset_focus_skip(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, unset_focus_skip);
+
+    ds_inf("Policy Info(%p) unset_focus_skip", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_role(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_role);
+
+    ds_inf("Policy Info(%p) set_role", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_window_type(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_window_type);
+
+    ds_inf("Policy Info(%p) set_window_type", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_conformant(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_conformant);
+
+    ds_inf("Policy Info(%p) set_conformant", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_unset_conformant(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, unset_conformant);
+
+    ds_inf("Policy Info(%p) unset_conformant", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_get_conformant(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, get_conformant);
+
+    ds_inf("Policy Info(%p) get_conformant", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_notification_level(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_notification_level);
+
+    ds_inf("Policy Info(%p) set_notification_level", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_window_screen_mode(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_window_screen_mode);
+
+    ds_inf("Policy Info(%p) set_window_screen_mode", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_get_subsurface(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, get_subsurface);
+
+    ds_inf("Policy Info(%p) get_subsurface", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_iconify(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, iconify);
+
+    ds_inf("Policy Info(%p) iconify", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_uniconify(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, uniconify);
+
+    ds_inf("Policy Info(%p) uniconify", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_add_aux_hint(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, add_aux_hint);
+
+    ds_inf("Policy Info(%p) add_aux_hint", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_change_aux_hint(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, change_aux_hint);
+
+    ds_inf("Policy Info(%p) change_aux_hint", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_delete_aux_hint(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, delete_aux_hint);
+
+    ds_inf("Policy Info(%p) delete_aux_hint", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_get_supported_aux_hints(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, get_supported_aux_hints);
+
+    ds_inf("Policy Info(%p) get_supported_aux_hints", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_floating_mode(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_floating_mode);
+
+    ds_inf("Policy Info(%p) set_floating_mode", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_unset_floating_mode(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, unset_floating_mode);
+
+    ds_inf("Policy Info(%p) unset_floating_mode", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_stack_mode(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_stack_mode);
+
+    ds_inf("Policy Info(%p) set_stack_mode", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_new_subsurface_watcher(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+    struct tinyds_policy_subsurface_watcher*subsurface_watcher;
+    struct ds_tizen_event_policy_surface_new_subsurface_watcher *event;
+
+    policy_surface = wl_container_of(listener, policy_surface, new_subsurface_watcher);
+    event = (struct ds_tizen_event_policy_surface_new_subsurface_watcher *)data;
+
+    ds_inf("Policy Info(%p) new_subsurface_watcher", policy_surface);
+
+    subsurface_watcher = calloc(1, sizeof *subsurface_watcher);
+    if (!subsurface_watcher)
+        return;
+
+    subsurface_watcher->subsurface_watcher = event->subsurface_watcher;
+
+    subsurface_watcher->destroy.notify = subsurface_watcher_handle_destroy;
+    ds_tizen_policy_subsurface_watcher_add_destroy_listener(subsurface_watcher->subsurface_watcher,
+        &subsurface_watcher->destroy);
+
+    wl_list_insert(&policy_surface->subsurface_watchers, &subsurface_watcher->link);
+}
+
+static void
+policy_surface_handle_set_parent(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_parent);
+
+    ds_inf("Policy Info(%p) set_parent", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_ack_conformant_region(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, ack_conformant_region);
+
+    ds_inf("Policy Info(%p) ack_conformant_region", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_video(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_video);
+
+    ds_inf("Policy Info(%p) set_video", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_show(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, show);
+
+    ds_inf("Policy Info(%p) show", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_hide(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, hide);
+
+    ds_inf("Policy Info(%p) hide", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_surface_handle_set_parent_with_below(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy_surface *policy_surface;
+
+    policy_surface = wl_container_of(listener, policy_surface, set_parent_with_below);
+
+    ds_inf("Policy Info(%p) set_parent_with_below", policy_surface);
+
+    // TODO:
+}
+
+static void
+policy_handle_destroy(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, destroy);
+
+    ds_inf("Policy(%p) destroy", policy);
+
+    free(policy);
+}
+
+static void
+policy_handle_new_surface(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+    struct tinyds_policy_surface *policy_surface;
+    struct ds_tizen_event_policy_new_surface *event;
+
+    policy = wl_container_of(listener, policy, new_surface);
+    event = (struct ds_tizen_event_policy_new_surface *)data;
+
+    ds_inf("Policy(%p) new_surface", policy);
+
+    policy_surface = calloc(1, sizeof *policy_surface);
+    if (!policy_surface)
+        return;
+
+    policy_surface->policy_surface = event->policy_surface;
+
+    policy_surface->destroy.notify = policy_surface_handle_destroy;
+    ds_tizen_policy_surface_add_destroy_listener(policy_surface->policy_surface,
+        &policy_surface->destroy);
+
+    policy_surface->new_visibility.notify = policy_surface_handle_new_visibility;
+    ds_tizen_policy_surface_add_new_visibility_listener(policy_surface->policy_surface,
+        &policy_surface->new_visibility);
+
+    policy_surface->new_position.notify = policy_surface_handle_new_position;
+    ds_tizen_policy_surface_add_new_position_listener(policy_surface->policy_surface,
+        &policy_surface->new_position);
+
+    policy_surface->activate.notify = policy_surface_handle_activate;
+    ds_tizen_policy_surface_add_activate_listener(policy_surface->policy_surface,
+        &policy_surface->activate);
+
+    policy_surface->raise.notify = policy_surface_handle_raise;
+    ds_tizen_policy_surface_add_raise_listener(policy_surface->policy_surface,
+        &policy_surface->raise);
+
+    policy_surface->lower.notify = policy_surface_handle_lower;
+    ds_tizen_policy_surface_add_lower_listener(policy_surface->policy_surface,
+        &policy_surface->lower);
+
+    policy_surface->set_focus_skip.notify = policy_surface_handle_set_focus_skip;
+    ds_tizen_policy_surface_add_set_focus_skip_listener(policy_surface->policy_surface,
+        &policy_surface->set_focus_skip);
+
+    policy_surface->unset_focus_skip.notify = policy_surface_handle_unset_focus_skip;
+    ds_tizen_policy_surface_add_unset_focus_skip_listener(policy_surface->policy_surface,
+        &policy_surface->unset_focus_skip);
+
+    policy_surface->set_role.notify = policy_surface_handle_set_role;
+    ds_tizen_policy_surface_add_set_role_listener(policy_surface->policy_surface,
+        &policy_surface->set_role);
+
+    policy_surface->set_window_type.notify = policy_surface_handle_set_window_type;
+    ds_tizen_policy_surface_add_set_window_type_listener(policy_surface->policy_surface,
+        &policy_surface->set_window_type);
+
+    policy_surface->set_conformant.notify = policy_surface_handle_set_conformant;
+    ds_tizen_policy_surface_add_set_conformant_listener(policy_surface->policy_surface,
+        &policy_surface->set_conformant);
+
+    policy_surface->unset_conformant.notify = policy_surface_handle_unset_conformant;
+    ds_tizen_policy_surface_add_unset_conformant_listener(policy_surface->policy_surface,
+        &policy_surface->unset_conformant);
+
+    policy_surface->get_conformant.notify = policy_surface_handle_get_conformant;
+    ds_tizen_policy_surface_add_get_conformant_listener(policy_surface->policy_surface,
+        &policy_surface->get_conformant);
+
+    policy_surface->set_notification_level.notify =
+        policy_surface_handle_set_notification_level;
+    ds_tizen_policy_surface_add_set_notification_level_listener(
+            policy_surface->policy_surface, &policy_surface->set_notification_level);
+
+    policy_surface->set_window_screen_mode.notify =
+        policy_surface_handle_set_window_screen_mode;
+    ds_tizen_policy_surface_add_set_window_screen_mode_listener(
+        policy_surface->policy_surface, &policy_surface->set_window_screen_mode);
+
+    policy_surface->get_subsurface.notify = policy_surface_handle_get_subsurface;
+    ds_tizen_policy_surface_add_get_subsurface_listener(policy_surface->policy_surface,
+        &policy_surface->get_subsurface);
+
+    policy_surface->iconify.notify = policy_surface_handle_iconify;
+    ds_tizen_policy_surface_add_iconify_listener(policy_surface->policy_surface,
+        &policy_surface->iconify);
+
+    policy_surface->uniconify.notify = policy_surface_handle_uniconify;
+    ds_tizen_policy_surface_add_uniconify_listener(policy_surface->policy_surface,
+        &policy_surface->uniconify);
+
+    policy_surface->add_aux_hint.notify = policy_surface_handle_add_aux_hint;
+    ds_tizen_policy_surface_add_add_aux_hint_listener(policy_surface->policy_surface,
+        &policy_surface->add_aux_hint);
+
+    policy_surface->change_aux_hint.notify = policy_surface_handle_change_aux_hint;
+    ds_tizen_policy_surface_add_change_aux_hint_listener(policy_surface->policy_surface,
+        &policy_surface->change_aux_hint);
+
+    policy_surface->delete_aux_hint.notify = policy_surface_handle_delete_aux_hint;
+    ds_tizen_policy_surface_add_delete_aux_hint_listener(policy_surface->policy_surface,
+        &policy_surface->delete_aux_hint);
+
+    policy_surface->get_supported_aux_hints.notify =
+        policy_surface_handle_get_supported_aux_hints;
+    ds_tizen_policy_surface_add_get_supported_aux_hints_listener(
+        policy_surface->policy_surface, &policy_surface->get_supported_aux_hints);
+
+    policy_surface->set_floating_mode.notify =
+        policy_surface_handle_set_floating_mode;
+    ds_tizen_policy_surface_add_set_floating_mode_listener(
+        policy_surface->policy_surface, &policy_surface->set_floating_mode);
+
+    policy_surface->unset_floating_mode.notify =
+        policy_surface_handle_unset_floating_mode;
+    ds_tizen_policy_surface_add_unset_floating_mode_listener(
+        policy_surface->policy_surface, &policy_surface->unset_floating_mode);
+
+    policy_surface->set_stack_mode.notify = policy_surface_handle_set_stack_mode;
+    ds_tizen_policy_surface_add_set_stack_mode_listener(policy_surface->policy_surface,
+        &policy_surface->set_stack_mode);
+
+    policy_surface->new_subsurface_watcher.notify =
+        policy_surface_handle_new_subsurface_watcher;
+    ds_tizen_policy_surface_add_new_subsurface_watcher_listener(
+        policy_surface->policy_surface, &policy_surface->new_subsurface_watcher);
+
+    policy_surface->set_parent.notify = policy_surface_handle_set_parent;
+    ds_tizen_policy_surface_add_set_parent_listener(policy_surface->policy_surface,
+        &policy_surface->set_parent);
+
+    policy_surface->ack_conformant_region.notify =
+        policy_surface_handle_ack_conformant_region;
+    ds_tizen_policy_surface_add_ack_conformant_region_listener(
+        policy_surface->policy_surface, &policy_surface->ack_conformant_region);
+
+    policy_surface->set_video.notify = policy_surface_handle_set_video;
+    ds_tizen_policy_surface_add_set_video_listener(policy_surface->policy_surface,
+        &policy_surface->set_video);
+
+    policy_surface->show.notify = policy_surface_handle_show;
+    ds_tizen_policy_surface_add_show_listener(policy_surface->policy_surface,
+        &policy_surface->show);
+
+    policy_surface->hide.notify = policy_surface_handle_hide;
+    ds_tizen_policy_surface_add_hide_listener(policy_surface->policy_surface,
+        &policy_surface->hide);
+
+    policy_surface->set_parent_with_below.notify =
+        policy_surface_handle_set_parent_with_below;
+    ds_tizen_policy_surface_add_set_parent_with_below_listener(
+            policy_surface->policy_surface, &policy_surface->set_parent_with_below);
+
+
+    wl_list_init(&policy_surface->visibilities);
+    wl_list_init(&policy_surface->positions);
+    wl_list_init(&policy_surface->subsurface_watchers);
+
+    wl_list_insert(&policy->policy_surfaces, &policy_surface->link);
+}
+
+static void
+policy_handle_activate_below_by_univeral_id(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, activate_below_by_univeral_id);
+
+    ds_inf("Policy(%p) activate_below_by_univeral_id", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_lower_by_universal_id(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, lower_by_universal_id);
+
+    ds_inf("Policy(%p) lower_by_universal_id", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_set_transient_for(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, set_transient_for);
+
+    ds_inf("Policy(%p) set_transient_for", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_unset_transient_for(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, unset_transient_for);
+
+    ds_inf("Policy(%p) unset_transient_for", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_place_subsurface_below_parent(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, place_subsurface_below_parent);
+
+    ds_inf("Policy(%p) place_subsurface_below_parent", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_set_subsurface_stand_alone(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, set_subsurface_stand_alone);
+
+    ds_inf("Policy(%p) set_subsurface_stand_alone", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_set_background_state(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, set_background_state);
+
+    ds_inf("Policy(%p) set_background_state", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_unset_background_state(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, unset_background_state);
+
+    ds_inf("Policy(%p) unset_background_state", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_add_activate_above_by_universal_id(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, add_activate_above_by_universal_id);
+
+    ds_inf("Policy(%p) add_activate_above_by_universal_id", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_set_appid(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, set_appid);
+
+    ds_inf("Policy(%p) set_appid", policy);
+
+    // TODO:
+}
+
+static void
+policy_handle_set_transient_for_below(struct wl_listener *listener, void *data)
+{
+    struct tinyds_policy *policy;
+
+    policy = wl_container_of(listener, policy, set_transient_for_below);
+
+    ds_inf("Policy(%p) set_transient_for_below", policy);
+
+    // TODO:
+}
+
+static bool
+new_policy(struct tinyds_server *server)
+{
+    struct tinyds_policy *policy;
+
+    policy = calloc(1, sizeof *policy);
+    if (!policy)
+        return false;
+
+    policy->policy = ds_tizen_policy_create(server->display);
+    if (!policy->policy) {
+        free(policy);
+        ds_err("Could not create ds_tizen_policy");
+        return false;
+    }
+
+    policy->destroy.notify = policy_handle_destroy;
+    ds_tizen_policy_add_destroy_listener(policy->policy, &policy->destroy);
+
+    policy->new_surface.notify = policy_handle_new_surface;
+    ds_tizen_policy_add_new_surface_listener(policy->policy, &policy->new_surface);
+
+    policy->activate_below_by_univeral_id.notify =
+        policy_handle_activate_below_by_univeral_id;
+    ds_tizen_policy_add_activate_below_by_univeral_id_listener(policy->policy,
+        &policy->activate_below_by_univeral_id);
+
+    policy->lower_by_universal_id.notify = policy_handle_lower_by_universal_id;
+    ds_tizen_policy_add_lower_by_universal_id_listener(policy->policy,
+        &policy->lower_by_universal_id);
+
+    policy->set_transient_for.notify = policy_handle_set_transient_for;
+    ds_tizen_policy_add_set_transient_for_listener(policy->policy,
+        &policy->set_transient_for);
+
+    policy->unset_transient_for.notify = policy_handle_unset_transient_for;
+    ds_tizen_policy_add_unset_transient_for_listener(policy->policy,
+        &policy->unset_transient_for);
+
+    policy->place_subsurface_below_parent.notify =
+        policy_handle_place_subsurface_below_parent;
+    ds_tizen_policy_add_place_subsurface_below_parent_listener(policy->policy,
+        &policy->place_subsurface_below_parent);
+
+    policy->set_subsurface_stand_alone.notify =
+        policy_handle_set_subsurface_stand_alone;
+    ds_tizen_policy_add_set_subsurface_stand_alone_listener(policy->policy,
+        &policy->set_subsurface_stand_alone);
+
+    policy->set_background_state.notify = policy_handle_set_background_state;
+    ds_tizen_policy_add_set_background_state_listener(policy->policy,
+        &policy->destroy);
+
+    policy->unset_background_state.notify = policy_handle_unset_background_state;
+    ds_tizen_policy_add_unset_background_state_listener(policy->policy,
+        &policy->unset_background_state);
+
+    policy->add_activate_above_by_universal_id.notify =
+        policy_handle_add_activate_above_by_universal_id;
+    ds_tizen_policy_add_activate_above_by_universal_id_listener(policy->policy,
+        &policy->add_activate_above_by_universal_id);
+
+    policy->set_appid.notify = policy_handle_set_appid;
+    ds_tizen_policy_add_set_appid_listener(policy->policy, &policy->set_appid);
+
+    policy->set_transient_for_below.notify =
+        policy_handle_set_transient_for_below;
+    ds_tizen_policy_add_set_transient_for_below_listener(policy->policy,
+        &policy->set_transient_for_below);
+
+    wl_list_init(&policy->policy_surfaces);
+
+    server->policy = policy;
+
+    ds_inf("Policy (%p) created", policy);
+
+    return true;
 }