2a54e3d11dcd4fa4f6e5596d5c9b4824c2e92799
[platform/core/uifw/libds-tizen.git] / examples / tinyds-tdm.c
1 #include <assert.h>
2 #include <stdbool.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <signal.h>
6 #include <time.h>
7
8 #include <drm_fourcc.h>
9 #include <pixman.h>
10 #include <wayland-server.h>
11 #include <libds/log.h>
12 #include <libds/backend.h>
13 #include <libds/output.h>
14 #include <libds/compositor.h>
15 #include <libds/xdg_shell.h>
16 #include <libds-tizen/allocator/tbm.h>
17 #include <libds-tizen/backend/tdm.h>
18 #include <libds/backend/libinput.h>
19 #include <libds-tizen/tbm_server.h>
20 #include <libds-tizen/dpms.h>
21 #include <libds/input_device.h>
22 #include <libds/keyboard.h>
23 #include <libds/touch.h>
24 #include <libds/pointer.h>
25 #include <libds/seat.h>
26 #include <libds-tizen/input_devicemgr.h>
27 #include <xkbcommon/xkbcommon.h>
28 #include <libds/interfaces/keyboard.h>
29 #include <libds-tizen/launch.h>
30 #include <libds-tizen/backend/tdm_output_hwc.h>
31 #include <libds-tizen/input_method.h>
32 #include <libds-tizen/text_input.h>
33 #include <libds-tizen/policy.h>
34
35 #define USE_TDM_BUFFER_QUEUE
36 #define CURSOR_W 10
37 #define CURSOR_H 16
38
39 #ifdef USE_TDM_BUFFER_QUEUE
40 #include "pixman-tbm-helper.h"
41 #include "tinyds-tdm-renderer.h"
42 #else
43 #include <libds/swapchain.h>
44 #endif
45
46 #include "pixman-helper.h"
47 #include "protocol-trace.h"
48
49 #define TINYDS_UNUSED   __attribute__((unused))
50 struct tinyds_keyboard;
51 struct tinyds_pointer;
52
53 struct tinyds_output
54 {
55     struct tinyds_server *server;
56     struct ds_output *ds_output;
57     struct ds_allocator *allocator;
58 #ifdef USE_TDM_BUFFER_QUEUE
59     struct tinyds_renderer renderer;
60     struct ds_tdm_buffer_queue *buffer_queue;
61     struct wl_listener buffer_queue_acquirable;
62 #else
63     struct ds_swapchain *swapchain;
64 #endif
65     struct ds_buffer *front_buffer;
66
67     struct wl_listener output_destroy;
68     struct wl_listener output_frame;
69
70     int width, height;
71
72     struct wl_event_source *idle_commit;
73     bool committable;
74     bool damaged;
75     bool target_updated;
76
77     struct ds_tdm_output_hwc *hwc;
78     struct ds_tdm_output_hwc_window *bg_hwc_window;
79
80 #ifdef USE_CURSOR
81     bool cursor_enabled;
82     struct ds_tdm_output_hwc_window *cursor_hwc_window;
83 #endif
84 };
85
86 struct tinyds_dpms
87 {
88     struct ds_tizen_dpms *ds_dpms;
89     struct tinyds_server *server;
90
91     struct wl_listener destroy;
92     struct wl_listener set_dpms;
93     struct wl_listener get_dpms;
94 };
95
96 struct tinyds_policy
97 {
98     struct ds_tizen_policy *policy;
99
100     struct wl_listener destroy;
101     struct wl_listener new_surface;
102     struct wl_listener activate_below_by_univeral_id;
103     struct wl_listener lower_by_universal_id;
104     struct wl_listener set_transient_for;
105     struct wl_listener unset_transient_for;
106     struct wl_listener place_subsurface_below_parent;
107     struct wl_listener set_subsurface_stand_alone;
108     struct wl_listener set_background_state;
109     struct wl_listener unset_background_state;
110     struct wl_listener add_activate_above_by_universal_id;
111     struct wl_listener set_appid;
112     struct wl_listener set_transient_for_below;
113
114     struct wl_list policy_surfaces;
115 };
116
117 struct tinyds_policy_surface
118 {
119     struct ds_tizen_policy_surface *policy_surface;
120
121     struct wl_listener destroy;
122     struct wl_listener new_visibility;
123     struct wl_listener new_position;
124     struct wl_listener activate;
125     struct wl_listener raise;
126     struct wl_listener lower;
127     struct wl_listener set_focus_skip;
128     struct wl_listener unset_focus_skip;
129     struct wl_listener set_role;
130     struct wl_listener set_window_type;
131     struct wl_listener set_conformant;
132     struct wl_listener unset_conformant;
133     struct wl_listener get_conformant;
134     struct wl_listener set_notification_level;
135     struct wl_listener set_window_screen_mode;
136     struct wl_listener get_subsurface;
137     struct wl_listener iconify;
138     struct wl_listener uniconify;
139     struct wl_listener add_aux_hint;
140     struct wl_listener change_aux_hint;
141     struct wl_listener delete_aux_hint;
142     struct wl_listener get_supported_aux_hints;
143     struct wl_listener set_floating_mode;
144     struct wl_listener unset_floating_mode;
145     struct wl_listener set_stack_mode;
146     struct wl_listener new_subsurface_watcher;
147     struct wl_listener set_parent;
148     struct wl_listener ack_conformant_region;
149     struct wl_listener set_video;
150     struct wl_listener show;
151     struct wl_listener hide;
152     struct wl_listener set_parent_with_below;
153
154     struct wl_list visibilities;
155     struct wl_list positions;
156     struct wl_list subsurface_watchers;
157
158     struct wl_list link; //tinyds_policy::policy_surfaces
159 };
160
161 struct tinyds_policy_visibility
162 {
163     struct ds_tizen_policy_visibility *visibility;
164
165     struct wl_listener destroy;
166
167     struct wl_list link; //tinyds_policy::visibilities
168 };
169
170 struct tinyds_policy_position
171 {
172     struct ds_tizen_policy_position *position;
173
174     struct wl_listener destroy;
175     struct wl_listener set;
176
177     struct wl_list link; //tinyds_policy::positions
178 };
179
180 struct tinyds_policy_subsurface_watcher
181 {
182     struct ds_tizen_policy_subsurface_watcher *subsurface_watcher;
183
184     struct wl_listener destroy;
185
186     struct wl_list link; //tinyds_policy::subsurface_watchers
187 };
188
189 struct tinyds_server
190 {
191     struct ds_tbm_server *tbm_server;
192
193     struct wl_display *display;
194
195     struct ds_backend *backend;
196     struct ds_backend *input_backend;
197     struct ds_compositor *compositor;
198     struct ds_xdg_shell *xdg_shell;
199     struct ds_seat *seat;
200     uint32_t seat_caps;
201     double output_x, output_y;
202     struct ds_tizen_input_devicemgr *devicemgr;
203     struct ds_tizen_launch_effect *effect;
204     struct ds_tizen_launch_splash *splash;
205
206     struct tinyds_output *output;
207     struct tinyds_dpms *dpms;
208     struct tinyds_policy *policy;
209
210     struct wl_event_source *stdin_source;
211
212     struct wl_list views;
213
214     struct wl_listener new_output;
215     struct wl_listener new_input;
216     struct wl_listener new_xdg_surface;
217     struct wl_listener devicemgr_destroy;
218     struct wl_listener pointer_warp;
219     struct wl_listener effect_destroy;
220     struct wl_listener effect_type_set;
221     struct wl_listener effect_type_unset;
222     struct wl_listener new_splash;
223     struct wl_listener splash_owner;
224
225     struct wl_list keyboards;
226     struct wl_list pointers;
227
228     struct tinyds_text_input *text_input;
229     struct tinyds_input_method *input_method;
230 };
231
232 struct tinyds_view
233 {
234     struct tinyds_server *server;
235
236     struct tinyds_texture *texture;
237     struct ds_xdg_surface *xdg_surface;
238
239     struct wl_listener xdg_surface_map;
240     struct wl_listener xdg_surface_unmap;
241     struct wl_listener xdg_surface_destroy;
242     struct wl_listener surface_commit;
243     struct wl_list link; // tinyds_server::views
244
245     struct ds_tdm_output_hwc_window *hwc_window;
246
247     int x, y;
248     bool mapped;
249
250     pid_t pid;
251     int effect_type;
252 };
253
254 struct tinyds_pointer
255 {
256     struct ds_input_device *dev;
257     struct tinyds_server *server;
258
259     struct tinyds_view *focused_view;
260
261     struct wl_listener destroy;
262     struct wl_listener motion; //relative
263     struct wl_listener button;
264     struct wl_listener frame;
265     struct wl_list link; //tinyds_server::pointers
266 };
267
268 struct tinyds_keyboard
269 {
270     struct ds_input_device *dev;
271     struct tinyds_server *server;
272
273     struct wl_listener destroy;
274     struct wl_listener key;
275     struct wl_list link; //tinyds_server::keyboards
276 };
277
278 struct tinyds_touch
279 {
280     struct ds_input_device *dev;
281     struct tinyds_server *server;
282
283     struct wl_listener destroy;
284     struct wl_listener down;
285     struct wl_listener up;
286     struct wl_listener motion;
287 };
288
289 struct tinyds_text_input {
290     struct ds_tizen_text_input *input;
291     struct ds_tizen_text_input_manager *text_input_mgr;
292
293     struct tinyds_server *server;
294     struct ds_surface *surface;
295
296     struct wl_list input_methods;
297
298     struct wl_listener mgr_destroy;
299     struct wl_listener new_text_input;
300
301     struct wl_listener destroy;
302     struct wl_listener text_input_activate;
303     struct wl_listener text_input_deactivate;
304     struct wl_listener text_input_reset;
305     struct wl_listener text_input_set_content_type;
306     struct wl_listener text_input_invoke_action;
307     struct wl_listener text_input_commit_state;
308     struct wl_listener text_input_set_preferred_language;
309 };
310
311 struct tinyds_input_method {
312     struct ds_tizen_input_method *input_method;
313     struct ds_tizen_input_method_manager *input_method_mgr;
314
315     struct tinyds_server *server;
316     struct tinyds_text_input *input;
317     struct tinyds_input_method_context *context;
318
319     struct wl_list link;
320
321     struct wl_listener destroy;
322     struct wl_listener mgr_destroy;
323 };
324
325 struct tinyds_input_method_context {
326     struct ds_tizen_input_method_context *context;
327
328     struct tinyds_server *server;
329     struct tinyds_text_input *input;
330     struct tinyds_input_method *input_method;
331
332     struct wl_listener destroy;
333
334     struct wl_listener im_context_commit_string;
335     struct wl_listener im_context_preedit_string;
336     struct wl_listener im_context_preedit_styling;
337     struct wl_listener im_context_preedit_cursor;
338     struct wl_listener im_context_delete_surrounding_text;
339     struct wl_listener im_context_cursor_position;
340     struct wl_listener im_context_modifiers_map;
341     struct wl_listener im_context_keysym;
342     struct wl_listener im_context_grab_keyboard;
343     struct wl_listener im_context_key;
344     struct wl_listener im_context_modifiers;
345     struct wl_listener im_context_language;
346     struct wl_listener im_context_text_direction;
347 };
348
349 struct tinyds_server tinyds;
350
351 static bool init_server(struct tinyds_server *server, struct wl_display *display);
352 static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
353 static void output_handle_destroy(struct wl_listener *listener, void *data);
354 static void output_handle_frame(struct wl_listener *listener, void *data);
355 static void draw_server_with_damage(struct tinyds_server *server);
356 static void draw_output(struct tinyds_output *output);
357 static void output_swap_buffer(struct tinyds_output *output,
358         struct ds_buffer *buffer);
359 static void view_send_frame_done(struct tinyds_view *view);
360 static void output_hwc_init(struct tinyds_output *output);
361 static void output_schedule_commit(struct tinyds_output *output);
362 static void output_commit(struct tinyds_output *output);
363 #ifdef USE_TDM_BUFFER_QUEUE
364 static void output_buffer_queue_init(struct tinyds_output *output);
365 static void output_renderer_init(struct tinyds_output *output);
366 static void output_draw_with_renderer(struct tinyds_output *output);
367 #else
368 static void output_swapchain_init(struct tinyds_output *output,
369         int width, int height, uint32_t format);
370 static void output_draw_with_swapchain(struct tinyds_output *output);
371 static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
372 #endif
373 static void dpms_handle_destroy(struct wl_listener *listener, void *data);
374 static void dpms_handle_set_dpms(struct wl_listener *listener, void *data);
375 static void dpms_handle_get_dpms(struct wl_listener *listener, void *data);
376 static void server_add_keyboard(struct tinyds_server *server,
377         struct ds_input_device *dev);
378 static void server_add_pointer(struct tinyds_server *server,
379         struct ds_input_device *dev);
380 static void server_add_touch(struct tinyds_server *server,
381         struct ds_input_device *dev);
382 static bool new_policy(struct tinyds_server *server);
383 static struct tinyds_view *
384 server_view_at(struct tinyds_server *server, double lx, double ly,
385         double *sx, double *sy);
386
387 static bool add_new_text_input(struct tinyds_server *server);
388 static bool add_new_input_method(struct tinyds_server *server);
389 static bool add_new_input_method_context(
390         struct tinyds_input_method *input_method,
391         struct tinyds_text_input *text_input);
392
393 static void text_input_mgr_handle_destroy(struct wl_listener *listener,
394         void *data TINYDS_UNUSED);
395 static void text_input_mgr_handle_new_text_input(struct wl_listener *listener,
396         void *data TINYDS_UNUSED);
397
398 static void input_method_mgr_handle_destroy(struct wl_listener *listener,
399         void *data TINYDS_UNUSED);
400
401 static void input_method_handle_destroy(struct wl_listener *listener,
402         void *data TINYDS_UNUSED);
403
404 int
405 main(void)
406 {
407     struct tinyds_server *server = &tinyds;
408     struct wl_display *display;
409     struct wl_event_loop *loop;
410     const char *socket;
411     bool res;
412
413     ds_log_init(DS_INF, NULL);
414
415     display = wl_display_create();
416     assert(display);
417
418     res = init_server(server, display);
419     assert(res);
420
421     socket = wl_display_add_socket_auto(display);
422     assert(socket);
423
424     ds_backend_start(server->backend);
425     ds_backend_start(server->input_backend);
426
427     setenv("WAYLAND_DISPLAY", socket, true);
428
429     ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
430
431     loop = wl_display_get_event_loop(display);
432     server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
433             WL_EVENT_READABLE, server_dispatch_stdin, server);
434
435     wl_display_run(display);
436
437     protocol_trace_enable(false);
438     protocol_trace_fini();
439
440     wl_display_destroy_clients(display);
441     wl_display_destroy(display);
442
443     return 0;
444 }
445
446 static void
447 view_populate_pid(struct tinyds_view *view)
448 {
449     pid_t pid;
450     struct wl_client *client = NULL;
451     struct ds_surface *surface;
452
453     surface = ds_xdg_surface_get_surface(view->xdg_surface);
454     if (!surface)
455         return;
456
457     client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
458     if (!client)
459         return;
460
461     wl_client_get_credentials(client, &pid, NULL, NULL);
462
463     ds_inf("view pid(%u)", pid);
464     view->pid = pid;
465
466     view->effect_type = ds_tizen_launch_effect_get_effect_type(view->server->effect, pid);
467     ds_tizen_launch_effect_unset_effect_type(view->server->effect, pid);
468     ds_inf("view effect_type(%d)", view->effect_type);
469 }
470
471 static void
472 view_handle_xdg_surface_map(struct wl_listener *listener,
473         void *data TINYDS_UNUSED)
474 {
475     struct tinyds_view *view;
476     struct ds_keyboard *keyboard;
477     struct tinyds_keyboard *kbd;
478
479     view = wl_container_of(listener, view, xdg_surface_map);
480     view->mapped = true;
481
482     view_populate_pid(view);
483
484     wl_list_for_each(kbd, &view->server->keyboards, link) {
485         keyboard = ds_input_device_get_keyboard(kbd->dev);
486         if (keyboard != NULL) {
487             ds_seat_keyboard_notify_enter(view->server->seat,
488                     ds_xdg_surface_get_surface(view->xdg_surface),
489                     keyboard->keycodes, keyboard->num_keycodes,
490                     &keyboard->modifiers);
491             return;
492         }
493     }
494 }
495
496 static void
497 view_handle_xdg_surface_unmap(struct wl_listener *listener,
498         void *data TINYDS_UNUSED)
499 {
500     struct tinyds_view *view;
501
502     view = wl_container_of(listener, view, xdg_surface_unmap);
503     view->mapped = false;
504 }
505
506 static void
507 view_handle_xdg_surface_destroy(struct wl_listener *listener,
508         void *data TINYDS_UNUSED) 
509 {
510     struct tinyds_view *view;
511
512     view = wl_container_of(listener, view, xdg_surface_destroy);
513
514     draw_server_with_damage(view->server);
515
516     ds_tdm_output_hwc_window_destroy(view->hwc_window);
517
518     wl_list_remove(&view->xdg_surface_destroy.link);
519     wl_list_remove(&view->xdg_surface_map.link);
520     wl_list_remove(&view->xdg_surface_unmap.link);
521     wl_list_remove(&view->surface_commit.link);
522     wl_list_remove(&view->link);
523     free(view);
524 }
525
526 static void
527 view_handle_surface_commit(struct wl_listener *listener,
528         void *data TINYDS_UNUSED)
529 {
530     struct tinyds_view *view;
531
532     view = wl_container_of(listener, view, surface_commit);
533     draw_server_with_damage(view->server);
534 }
535
536 static void
537 server_new_xdg_surface(struct wl_listener *listener, void *data)
538 {
539     static unsigned int seedx = 1;
540     static unsigned int seedy = 43210;
541     struct tinyds_server *server;
542     struct tinyds_view *view;
543     struct ds_xdg_surface *xdg_surface;
544
545     server = wl_container_of(listener, server, new_xdg_surface);
546     xdg_surface = data;
547
548     ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
549
550     view = calloc(1, sizeof *view);
551     assert(view);
552
553     view->server = server;
554     view->xdg_surface = xdg_surface;
555
556     view->xdg_surface_map.notify = view_handle_xdg_surface_map;
557     ds_xdg_surface_add_map_listener(xdg_surface,
558             &view->xdg_surface_map);
559
560     view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
561     ds_xdg_surface_add_unmap_listener(xdg_surface,
562             &view->xdg_surface_unmap);
563
564     view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
565     ds_xdg_surface_add_destroy_listener(xdg_surface,
566             &view->xdg_surface_destroy);
567
568     view->surface_commit.notify = view_handle_surface_commit;
569     ds_surface_add_commit_listener(
570             ds_xdg_surface_get_surface(xdg_surface),
571             &view->surface_commit);
572
573     view->x = rand_r(&seedx) % 1000;
574     view->y = rand_r(&seedy) % 500;
575
576     view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
577     assert(view->hwc_window);
578
579     wl_list_insert(server->views.prev, &view->link);
580
581     view->pid = 0;
582     view->effect_type = -1;
583
584     ds_inf("view at (%d, %d)", view->x, view->y);
585 }
586
587 static void
588 backend_handle_new_output(struct wl_listener *listener, void *data)
589 {
590     struct tinyds_server *server;
591     struct tinyds_output *output;
592     struct ds_output *ds_output;
593     const struct ds_output_mode *mode;
594     struct ds_tdm_box src_box;
595
596     server = wl_container_of(listener, server, new_output);
597     ds_output = data;
598
599     ds_inf("New output(%p)", ds_output);
600
601     if (server->output)
602         return;
603
604     mode = ds_output_get_preferred_mode(ds_output);
605     ds_output_set_mode(ds_output, mode);
606
607     output = calloc(1, sizeof *output);
608     if (!output)
609         return;
610
611     output->server = server;
612     output->ds_output = ds_output;
613     output->width = mode->width;
614     output->height = mode->height;
615     output->damaged = true;
616     output->committable = true;
617
618     output_hwc_init(output);
619
620 #ifdef USE_TDM_BUFFER_QUEUE
621     output_buffer_queue_init(output);
622     output_renderer_init(output);
623 #else
624     output_swapchain_init(output, mode->width, mode->height,
625             DRM_FORMAT_XRGB8888);
626 #endif
627
628     output->bg_hwc_window = ds_tdm_output_hwc_window_create(output->hwc);
629     assert(output->bg_hwc_window);
630
631     src_box.x = 0;
632     src_box.y = 0;
633     src_box.width = output->width;
634     src_box.height = output->height;
635
636     ds_tdm_output_hwc_window_set_src_box(output->bg_hwc_window, &src_box);
637     ds_tdm_output_hwc_window_set_position(output->bg_hwc_window, 0, 0);
638     ds_tdm_output_hwc_window_set_dest_size(output->bg_hwc_window, output->width, output->height);
639     ds_tdm_output_hwc_window_set_transform(output->bg_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
640
641 #ifdef USE_CURSOR
642     output->cursor_enabled = false;
643 #endif
644
645     output->output_destroy.notify = output_handle_destroy;
646     ds_output_add_destroy_listener(ds_output, &output->output_destroy);
647
648     output->output_frame.notify = output_handle_frame;
649     ds_output_add_frame_listener(ds_output, &output->output_frame);
650
651     ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height);
652
653     server->output = output;
654     server->output_x = (double)(output->width) / 2;
655     server->output_y = (double)(output->height) / 2;
656
657     output_schedule_commit(output);
658 }
659
660 static bool
661 add_new_dpms(struct tinyds_server *server)
662 {
663     struct tinyds_dpms *dpms;
664
665     dpms = calloc(1, sizeof *dpms);
666     if (!dpms)
667         return false;
668
669     dpms->ds_dpms = ds_tizen_dpms_create(server->display);
670     if (!dpms->ds_dpms) {
671         free(dpms);
672         ds_err("Could not create ds_tizen_dpms");
673         return false;
674     }
675
676     dpms->destroy.notify = dpms_handle_destroy;
677     ds_tizen_dpms_add_destroy_listener(dpms->ds_dpms, &dpms->destroy);
678
679     dpms->set_dpms.notify = dpms_handle_set_dpms;
680     ds_tizen_dpms_add_set_dpms_listener(dpms->ds_dpms, &dpms->set_dpms);
681
682     dpms->get_dpms.notify = dpms_handle_get_dpms;
683     ds_tizen_dpms_add_get_dpms_listener(dpms->ds_dpms, &dpms->get_dpms);
684
685     server->dpms = dpms;
686
687     ds_inf("Dpms (%p) added", dpms);
688
689     return true;
690 }
691
692 static void
693 backend_handle_new_input(struct wl_listener *listener, void *data)
694 {
695     struct tinyds_server *server;
696     struct ds_input_device *dev = data;
697     enum ds_input_device_type dev_type;
698
699     server = wl_container_of(listener, server, new_input);
700
701     dev_type = ds_input_device_get_type(dev);
702
703     switch (dev_type) {
704         case DS_INPUT_DEVICE_KEYBOARD:
705             server_add_keyboard(server, dev);
706             server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD;
707             break;
708         case DS_INPUT_DEVICE_TOUCH:
709             server_add_touch(server, dev);
710             server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH;
711             break;
712         case DS_INPUT_DEVICE_POINTER:
713             server_add_pointer(server, dev);
714             server->seat_caps |= WL_SEAT_CAPABILITY_POINTER;
715             break;
716         default:
717             ds_err("Unknown type(%d) of ds_input_device", dev_type);
718             break;
719     }
720
721     ds_seat_set_capabilities(server->seat, server->seat_caps);
722 }
723
724 static void
725 devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode)
726 {
727     struct ds_tizen_input_devicemgr_keymap_data *data;
728
729     data = calloc(1, sizeof *data);
730     if (!data) {
731         ds_err("Failed to alloc memory");
732         return;
733     }
734
735     data->name = strdup(name);
736     data->keycode = keycode;
737
738     wl_list_insert(list, &data->link);
739 }
740
741 static void
742 devicemgr_cleanup_keymap_list(struct wl_list *list)
743 {
744     struct ds_tizen_input_devicemgr_keymap_data *data, *tmp;
745
746     wl_list_for_each_safe(data, tmp, list, link) {
747         wl_list_remove(&data->link);
748         free(data->name);
749         free(data);
750     }
751 }
752
753 static void
754 devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr)
755 {
756     struct wl_list keymap_list;
757     bool res;
758
759     wl_list_init(&keymap_list);
760
761     devicemgr_add_keymap_data(&keymap_list, "XF86VolumeRaise", 455);
762     devicemgr_add_keymap_data(&keymap_list, "XF86VolumeLower", 456);
763     devicemgr_add_keymap_data(&keymap_list, "XF86LightOn", 457);
764     devicemgr_add_keymap_data(&keymap_list, "XF86LightOff", 458);
765
766     res = ds_tizen_input_devicemgr_set_keymap_list(devicemgr, &keymap_list);
767     if (!res)
768         ds_inf("Failed to set keymap");
769
770     devicemgr_cleanup_keymap_list(&keymap_list);
771 }
772
773 static void
774 devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data)
775 {
776     struct tinyds_server *server;
777     struct tinyds_pointer *pointer;
778     struct ds_tizen_input_devicemgr_event_pointer_warp *event = data;
779     double sx = 0.f, sy = 0.f;
780     struct tinyds_view *view = NULL;
781
782     server = wl_container_of(listener, server, pointer_warp);
783
784     ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface,
785             event->x, event->y);
786
787     wl_list_for_each(pointer, &server->pointers, link){
788         if (!pointer->focused_view) continue;
789         view = pointer->focused_view;
790     }
791     if (!view) return;
792
793     if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) {
794         ds_inf("Pointer is not on the requested surface");
795         return;
796     }
797
798     server->output_x = view->x + (event->x * server->output->width);
799     server->output_y = view->y + (event->y * server->output->height);
800
801     server_view_at(server, server->output_x, server->output_y, &sx, &sy);
802
803     ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f",
804             sx, sy, server->output_x, server->output_y);
805
806     ds_seat_pointer_notify_motion(server->seat,
807             event->time_msec, sx, sy);
808 }
809
810 static void
811 devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
812 {
813     struct tinyds_server *server =
814         wl_container_of(listener, server, devicemgr_destroy);
815
816     wl_list_remove(&server->devicemgr_destroy.link);
817     wl_list_remove(&server->pointer_warp.link);
818
819     server->devicemgr = NULL;
820 }
821
822 static void
823 launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
824 {
825     struct tinyds_server *server =
826         wl_container_of(listener, server, effect_destroy);
827
828     wl_list_remove(&server->effect_destroy.link);
829     wl_list_remove(&server->effect_type_set.link);
830     wl_list_remove(&server->effect_type_unset.link);
831     wl_list_remove(&server->new_splash.link);
832
833     server->effect = NULL;
834 }
835
836 static void
837 launch_effect_handle_type_set(struct wl_listener *listener, void *data)
838 {
839     struct tinyds_server *server;
840     struct ds_tizen_launch_effect_event_type_set *event = data;
841     struct tinyds_view *view = NULL;
842     bool existing = false;
843
844     server = wl_container_of(listener, server, effect_type_set);
845
846     ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch");
847
848     wl_list_for_each(view, &server->views, link) {
849         if (view->pid == event->pid) {
850             view->effect_type = event->effect_type;
851             ds_inf("Launch effect. existing pid");
852             existing = true;
853         }
854     }
855     if (existing) {
856         ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid);
857     } else {
858         ds_tizen_launch_effect_set_effect_type(server->effect, event->pid, event->effect_type);
859     }
860 }
861
862 static void
863 launch_effect_handle_type_unset(struct wl_listener *listener, void *data)
864 {
865     struct tinyds_server *server;
866     struct ds_tizen_launch_effect_event_type_unset *event = data;
867     struct tinyds_view *view = NULL;
868
869     server = wl_container_of(listener, server, effect_type_unset);
870
871     ds_inf("Launch effect. type_unset: pid(%u)", event->pid);
872
873     wl_list_for_each(view, &server->views, link) {
874         if (view->pid == event->pid) {
875             view->effect_type = -1;
876             ds_inf("Launch effect. pid found");
877         }
878     }
879     ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid);
880 }
881
882 static void
883 launch_splash_handle_owner(struct wl_listener *listener, void *data)
884 {
885     struct tinyds_server *server;
886     struct ds_tizen_launch_splash_event_owner *event = data;
887     struct tinyds_view *view = NULL;
888
889     server = wl_container_of(listener, server, splash_owner);
890
891     ds_inf("Splash owner. pid(%u)", event->pid);
892
893     wl_list_for_each(view, &server->views, link) {
894         if (view->pid == event->pid) {
895             if (event->pid == ds_tizen_launch_splash_get_pid(server->splash))
896                 ;//
897             else {
898                 ds_tizen_launch_splash_set_pid(server->splash, event->pid);
899             }
900         }
901     }
902 }
903
904 static void
905 launch_effect_handle_new_splash(struct wl_listener *listener, void *data)
906 {
907     struct tinyds_server *server;
908     struct ds_tizen_launch_splash *splash = data;
909     struct tinyds_view *view = NULL;
910
911     server = wl_container_of(listener, server, new_splash);
912
913     ds_inf("Launch new splash. splash(%p)", splash);
914     if (!splash) return;
915
916     server->splash = splash;
917
918     // new view for "Launchscreen"
919     view = calloc(1, sizeof *view);
920     assert(view);
921     wl_list_insert(server->views.prev, &view->link);
922     view->pid = ds_tizen_launch_splash_get_pid(splash);
923
924     server->splash_owner.notify = launch_splash_handle_owner;
925     ds_tizen_launch_splash_add_owner_listener(server->splash,
926             &server->splash_owner);
927 }
928
929 static bool
930 init_server(struct tinyds_server *server, struct wl_display *display)
931 {
932     server->display = display;
933
934     wl_list_init(&server->views);
935
936     if (wl_display_init_shm(display) != 0)
937         return false;
938
939     server->backend = ds_tdm_backend_create(display);
940     if (!server->backend)
941         return false;
942
943     server->input_backend = ds_libinput_backend_create(display);
944     if (!server->input_backend) {
945         ds_backend_destroy(server->backend);
946         return false;
947     }
948
949     server->new_output.notify = backend_handle_new_output;
950     ds_backend_add_new_output_listener(server->backend,
951             &server->new_output);
952
953     wl_list_init(&server->keyboards);
954     wl_list_init(&server->pointers);
955     server->new_input.notify = backend_handle_new_input;
956     ds_backend_add_new_input_listener(server->input_backend, &server->new_input);
957
958     server->compositor = ds_compositor_create(display);
959     if (!server->compositor)
960         goto err;
961
962     server->tbm_server = ds_tbm_server_create(display);
963     if (!server->tbm_server)
964         goto err;
965
966     server->xdg_shell = ds_xdg_shell_create(display);
967     if (!server->xdg_shell)
968         goto err;
969
970     server->new_xdg_surface.notify = server_new_xdg_surface;
971     ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
972             &server->new_xdg_surface);
973
974     if (!add_new_dpms(server))
975         goto err;
976
977     if (!new_policy(server))
978         goto err;
979
980     server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
981     if (!server->seat)
982         goto err;
983     server->seat_caps = 0;
984
985     server->devicemgr = ds_tizen_input_devicemgr_create(
986             server->input_backend, server->seat);
987     if (!server->devicemgr) {
988         ds_err("Could not create ds_tizen_input_devicemgr");
989         goto err;
990     }
991
992     devicemgr_set_keymap(server->devicemgr);
993
994     server->devicemgr_destroy.notify = devicemgr_handle_destroy;
995     ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr,
996             &server->devicemgr_destroy);
997
998     server->pointer_warp.notify = devicemgr_handle_pointer_warp;
999     ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr,
1000             &server->pointer_warp);
1001
1002     server->effect = ds_tizen_launch_effect_create(display);
1003     if (!server->effect) {
1004         goto err;
1005     }
1006
1007     server->effect_destroy.notify = launch_effect_handle_destroy;
1008     ds_tizen_launch_effect_add_destroy_listener(server->effect,
1009             &server->effect_destroy);
1010
1011     server->effect_type_set.notify = launch_effect_handle_type_set;
1012     ds_tizen_launch_effect_add_type_set_listener(server->effect,
1013             &server->effect_type_set);
1014
1015     server->effect_type_unset.notify = launch_effect_handle_type_unset;
1016     ds_tizen_launch_effect_add_type_unset_listener(server->effect,
1017             &server->effect_type_unset);
1018
1019     server->new_splash.notify = launch_effect_handle_new_splash;
1020     ds_tizen_launch_effect_add_new_splash_listener(server->effect,
1021             &server->new_splash);
1022
1023     if (!add_new_text_input(server))
1024         goto err;
1025
1026     if (!add_new_input_method(server))
1027         goto err;
1028
1029     if (protocol_trace_init(display))
1030         protocol_trace_enable(true);
1031
1032     return true;
1033
1034 err:
1035     ds_backend_destroy(server->backend);
1036     ds_backend_destroy(server->input_backend);
1037
1038     return false;
1039 }
1040
1041 static void
1042 output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
1043 {
1044     struct tinyds_output *output =
1045         wl_container_of(listener, output, output_destroy);
1046
1047     if (output->bg_hwc_window)
1048         ds_tdm_output_hwc_window_destroy(output->bg_hwc_window);
1049
1050     wl_list_remove(&output->output_destroy.link);
1051     wl_list_remove(&output->output_frame.link);
1052
1053     if (output->front_buffer)
1054         ds_buffer_unlock(output->front_buffer);
1055
1056 #ifdef USE_TDM_BUFFER_QUEUE
1057     fini_renderer(&output->renderer);
1058 #else
1059     if (output->swapchain)
1060         ds_swapchain_destroy(output->swapchain);
1061
1062     if (output->allocator)
1063         ds_allocator_destroy(output->allocator);
1064 #endif
1065
1066     wl_display_terminate(output->server->display);
1067
1068     output->server->output = NULL;
1069
1070     free(output);
1071 }
1072
1073 static void
1074 output_commit(struct tinyds_output *output)
1075 {
1076     uint32_t num_changed = 0;
1077     uint32_t num_windows = 0, current_num_windows = 0;
1078     struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL;
1079     struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL;
1080     enum ds_tdm_output_hwc_window_composition composition;
1081     struct tinyds_view *view;
1082     int i;
1083     bool need_target = false;
1084     bool fully_obscured = false;
1085     struct ds_buffer *ds_buffer;
1086     struct ds_tdm_box src_box;
1087     int w = 0, h = 0;
1088
1089     if (!output->committable)
1090         return;
1091
1092     if (!output->damaged && !output->target_updated)
1093         return;
1094
1095     wl_list_for_each_reverse(view, &output->server->views, link) {
1096         if (!view->hwc_window)
1097             continue;
1098
1099         ds_buffer = ds_surface_get_buffer(
1100                 ds_xdg_surface_get_surface(view->xdg_surface));
1101         if (!ds_buffer)
1102             continue;
1103
1104         if (!view->mapped)
1105             continue;
1106
1107         num_windows++;
1108
1109         ds_buffer_get_size(ds_buffer, &w, &h);
1110
1111         if ((output->width <= w) && (output->height <= h))
1112             fully_obscured = true;
1113     }
1114
1115     if (fully_obscured) {
1116         ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
1117                 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
1118     } else {
1119         ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
1120                 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
1121         num_windows++;
1122         need_target = true;
1123     }
1124
1125 #ifdef USE_CURSOR
1126     if (output->cursor_hwc_window) {
1127         src_box.x = 0;
1128         src_box.y = 0;
1129         src_box.width = CURSOR_W;
1130         src_box.height = CURSOR_H;
1131
1132         ds_tdm_output_hwc_window_set_src_box(output->cursor_hwc_window, &src_box);
1133         ds_tdm_output_hwc_window_set_position(output->cursor_hwc_window, output->server->output_x, output->server->output_y);
1134         ds_tdm_output_hwc_window_set_dest_size(output->cursor_hwc_window, CURSOR_W, CURSOR_H);
1135         ds_tdm_output_hwc_window_set_transform(output->cursor_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
1136
1137         ds_tdm_output_hwc_window_set_composition(output->cursor_hwc_window,
1138                     DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
1139         num_windows++;
1140         need_target = true;
1141     }
1142 #endif
1143
1144     if (num_windows) {
1145         composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows);
1146         if (!composited_hwc_windows)
1147             return;
1148
1149         wl_list_for_each_reverse(view, &output->server->views, link) {
1150             if (!view->hwc_window)
1151                 continue;
1152
1153             ds_buffer = ds_surface_get_buffer(
1154                     ds_xdg_surface_get_surface(view->xdg_surface));
1155             if (!ds_buffer)
1156                 continue;
1157
1158             ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer);
1159
1160             ds_buffer_get_size(ds_buffer, &w, &h);
1161
1162             src_box.x = 0;
1163             src_box.y = 0;
1164             src_box.width = w;
1165             src_box.height = h;
1166
1167             ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box);
1168             ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y);
1169             ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h);
1170             ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
1171
1172             if (view->mapped) {
1173 #ifdef USE_CURSOR
1174                 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
1175                         DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
1176 #endif
1177                 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
1178                         DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE);
1179
1180                 composited_hwc_windows[current_num_windows] = view->hwc_window;
1181                 current_num_windows++;
1182             } else {
1183                 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
1184                         DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
1185             }
1186         }
1187
1188         if (!fully_obscured) {
1189             composited_hwc_windows[current_num_windows] = output->bg_hwc_window;
1190             current_num_windows++;
1191         }
1192
1193 #ifdef USE_CURSOR
1194         if (output->cursor_hwc_window) {
1195             composited_hwc_windows[current_num_windows] = output->cursor_hwc_window;
1196             current_num_windows++;
1197         }
1198 #endif
1199     }
1200
1201     if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows,
1202             num_windows, &num_changed)) {
1203         free(composited_hwc_windows);
1204         ds_err("Could not hwc validate");
1205         return;
1206     }
1207
1208     if (composited_hwc_windows)
1209         free(composited_hwc_windows);
1210
1211     if (num_changed > 0) {
1212         changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows);
1213         if (!changed_hwc_windows)
1214             return;
1215
1216         if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed,
1217                 changed_hwc_windows)) {
1218             free(changed_hwc_windows);
1219             ds_err("Could not get chaged composition");
1220             return;
1221         }
1222
1223         for (i = 0; i < num_changed; i++) {
1224             composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]);
1225             if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) {
1226                 need_target = true;
1227                 break;
1228             }
1229         }
1230     }
1231
1232     if (changed_hwc_windows)
1233         free(changed_hwc_windows);
1234
1235     if (need_target && output->damaged)
1236         draw_output(output);
1237
1238 #ifdef USE_TDM_BUFFER_QUEUE
1239     struct ds_buffer *buffer;
1240
1241     buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
1242     if (buffer) {
1243         if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, buffer)) {
1244             ds_err("Could not set hwc client target buffer");
1245             return;
1246         }
1247
1248         output_swap_buffer(output, buffer);
1249     }
1250 #endif
1251
1252     if (!ds_tdm_output_hwc_accept_validation(output->hwc)) {
1253         ds_err("Could not hwc accept validateion");
1254         return;
1255     }
1256
1257     ds_output_commit(output->ds_output);
1258
1259     output->committable = false;
1260     output->damaged = false;
1261     output->target_updated = false;
1262
1263     wl_list_for_each(view, &output->server->views, link) {
1264         enum ds_tdm_output_hwc_window_composition composition;
1265
1266         if (!view->mapped)
1267             continue;
1268
1269         composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
1270         if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
1271             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
1272             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
1273             view_send_frame_done(view);
1274     }
1275
1276     ds_dbg("output:%p commit", output);
1277 }
1278
1279 static void
1280 output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
1281 {
1282     struct tinyds_output *output =
1283         wl_container_of(listener, output, output_frame);
1284
1285     ds_dbg("output:%p handle frame", output);
1286
1287     output->committable = true;
1288
1289     output_commit(output);
1290 }
1291
1292 static void
1293 draw_server_with_damage(struct tinyds_server *server)
1294 {
1295     server->output->damaged = true;
1296     output_schedule_commit(server->output);
1297 }
1298
1299 static void
1300 output_hwc_init(struct tinyds_output *output)
1301 {
1302     struct ds_tdm_output *tdm_output;
1303
1304     tdm_output = ds_tdm_output_from_output(output->ds_output);
1305     assert(tdm_output);
1306
1307     output->hwc = ds_tdm_output_get_hwc(tdm_output);
1308     assert(output->hwc);
1309
1310     ds_tdm_output_hwc_set_enabled(output->hwc, true);
1311 }
1312
1313 #ifdef USE_TDM_BUFFER_QUEUE
1314 static void
1315 output_handle_buffer_queue_acquirable(struct wl_listener *listener,
1316         void *data TINYDS_UNUSED)
1317 {
1318     struct tinyds_output *output;
1319
1320     output = wl_container_of(listener, output, buffer_queue_acquirable);
1321
1322     output->target_updated = true;
1323     output_schedule_commit(output);
1324 }
1325
1326 static void
1327 output_buffer_queue_init(struct tinyds_output *output)
1328 {
1329     struct ds_tdm_output *tdm_output;
1330
1331     tdm_output = ds_tdm_output_from_output(output->ds_output);
1332     assert(tdm_output);
1333
1334     output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
1335     assert(output->buffer_queue);
1336
1337     output->buffer_queue_acquirable.notify =
1338         output_handle_buffer_queue_acquirable;
1339     ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
1340             &output->buffer_queue_acquirable);
1341 }
1342
1343 static void
1344 output_renderer_init(struct tinyds_output *output)
1345 {
1346     init_renderer(&output->renderer);
1347
1348     renderer_set_surface_queue(&output->renderer,
1349             ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
1350
1351     renderer_set_bg_color(&output->renderer, 80, 80, 80);
1352 }
1353
1354 static void
1355 output_draw_with_renderer(struct tinyds_output *output)
1356 {
1357     struct tinyds_view *view;
1358
1359     ds_dbg(">> BEGIN UPDATE TEXTURES");
1360
1361     wl_list_for_each(view, &output->server->views, link) {
1362         struct ds_buffer *ds_buffer;
1363         struct ds_tbm_client_buffer *tbm_buffer;
1364         tbm_surface_h surface;
1365         enum ds_tdm_output_hwc_window_composition composition;
1366
1367         if (!view->mapped)
1368             continue;
1369
1370         composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
1371         if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
1372             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
1373             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
1374             continue;
1375
1376         ds_buffer = ds_surface_get_buffer(
1377                 ds_xdg_surface_get_surface(view->xdg_surface));
1378         if (!ds_buffer)
1379             continue;
1380
1381         tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
1382         if (!tbm_buffer)
1383             continue;
1384
1385         surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
1386         if (!surface)
1387             continue;
1388
1389         renderer_add_texture(&output->renderer, surface, view->x, view->y);
1390
1391         view_send_frame_done(view);
1392     }
1393
1394     ds_dbg("<< END UPDATE TEXTURES");
1395
1396     renderer_draw(&output->renderer);
1397 }
1398 #else
1399 static void
1400 output_swapchain_init(struct tinyds_output *output,
1401         int width, int height, uint32_t format)
1402
1403 {
1404     output->allocator = ds_tbm_allocator_create();
1405     assert(output->allocator);
1406
1407     output->swapchain = ds_swapchain_create(output->allocator,
1408             width, height, format);
1409     assert(output->swapchain);
1410 }
1411
1412 static void
1413 output_draw_with_swapchain(struct tinyds_output *output)
1414 {
1415     struct tinyds_view *view;
1416     struct ds_buffer *output_buffer;
1417     pixman_image_t *output_image;
1418     enum ds_tdm_output_hwc_window_composition composition;
1419
1420     output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
1421     if (!output_buffer)
1422         return;
1423
1424     output_image = pixman_image_from_buffer(output_buffer,
1425             DS_BUFFER_DATA_PTR_ACCESS_WRITE);
1426     if (!output_image) {
1427         ds_buffer_unlock(output_buffer);
1428         return;
1429     }
1430
1431     pixman_image_fill_color(output_image, 80, 80, 80);
1432
1433     wl_list_for_each(view, &output->server->views, link) {
1434         if (!view->mapped)
1435             continue;
1436
1437         composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
1438         if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
1439             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
1440             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
1441             continue;
1442
1443         draw_view(view, output_image);
1444     }
1445     pixman_image_unref(output_image);
1446
1447     if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, output_buffer)) {
1448         ds_err("Could not set hwc client target buffer");
1449         ds_buffer_unlock(output_buffer);
1450         return;
1451     }
1452
1453     output_swap_buffer(output, output_buffer);
1454 }
1455
1456 static void
1457 draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
1458 {
1459     struct ds_buffer *buffer;
1460     pixman_image_t *src_image;
1461
1462     buffer = ds_surface_get_buffer(
1463             ds_xdg_surface_get_surface(view->xdg_surface));
1464     if (!buffer)
1465         return;
1466
1467     src_image = pixman_image_from_buffer(buffer,
1468             DS_BUFFER_DATA_PTR_ACCESS_READ);
1469     pixman_image_composite32(PIXMAN_OP_OVER,
1470             src_image,
1471             NULL,
1472             dst_image,
1473             0, 0, 0, 0,
1474             view->x, view->y,
1475             pixman_image_get_width(src_image),
1476             pixman_image_get_height(src_image));
1477     pixman_image_unref(src_image);
1478
1479     view_send_frame_done(view);
1480 }
1481 #endif
1482
1483 static void
1484 draw_output(struct tinyds_output *output)
1485 {
1486 #ifdef USE_TDM_BUFFER_QUEUE
1487     output_draw_with_renderer(output);
1488 #else
1489     output_draw_with_swapchain(output);
1490 #endif
1491
1492     ds_dbg("output:%p draw", output);
1493 }
1494
1495 static void
1496 output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
1497 {
1498     ds_output_attach_buffer(output->ds_output, buffer);
1499
1500     if (output->front_buffer)
1501         ds_buffer_unlock(output->front_buffer);
1502     output->front_buffer = buffer;
1503 }
1504
1505 static void
1506 view_send_frame_done(struct tinyds_view *view)
1507 {
1508     struct timespec now;
1509     clock_gettime(CLOCK_MONOTONIC, &now);
1510     ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
1511             &now);
1512 }
1513
1514 static int
1515 server_dispatch_stdin(int fd, uint32_t mask, void *data)
1516 {
1517     struct tinyds_server *server = data;
1518
1519     wl_display_terminate(server->display);
1520
1521     return 1;
1522 }
1523
1524 static void
1525 dpms_handle_destroy(struct wl_listener *listener, void *data)
1526 {
1527     struct tinyds_dpms *dpms;
1528
1529     dpms = wl_container_of(listener, dpms, destroy);
1530
1531     ds_inf("Dpms(%p) destroyed", dpms);
1532
1533     wl_list_remove(&dpms->destroy.link);
1534     wl_list_remove(&dpms->set_dpms.link);
1535     wl_list_remove(&dpms->get_dpms.link);
1536
1537     free(dpms);
1538 }
1539
1540 static void
1541 dpms_handle_set_dpms(struct wl_listener *listener, void *data)
1542 {
1543     struct tinyds_dpms *dpms;
1544     struct ds_tizen_dpms_event *event = data;
1545
1546     dpms = wl_container_of(listener, dpms, set_dpms);
1547
1548     ds_inf("Dpms(%p) set dpms : %d", dpms, event->mode);
1549
1550     //To do
1551     //set dpms mode to output
1552     ds_tizen_dpms_send_set_result(dpms->ds_dpms, event->mode,
1553         DS_TIZEN_DPMS_ERROR_NONE);
1554 }
1555
1556 static void
1557 dpms_handle_get_dpms(struct wl_listener *listener, void *data)
1558 {
1559     struct tinyds_dpms *dpms;
1560
1561     dpms = wl_container_of(listener, dpms, get_dpms);
1562
1563     ds_inf("Dpms(%p) get dpms", dpms);
1564
1565     //To do
1566     //get dpms mode from output
1567     ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON,
1568         DS_TIZEN_DPMS_ERROR_NONE);
1569 }
1570
1571 static void
1572 keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
1573 {
1574     struct tinyds_keyboard *kbd;
1575
1576     kbd = wl_container_of(listener, kbd, destroy);
1577
1578     ds_inf("Keyboard(%p) destroyed", kbd);
1579
1580     wl_list_remove(&kbd->destroy.link);
1581     wl_list_remove(&kbd->key.link);
1582     wl_list_remove(&kbd->link);
1583
1584     free(kbd);
1585 }
1586
1587 static bool
1588 server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
1589 {
1590     switch (sym) {
1591         case XKB_KEY_BackSpace:
1592             wl_display_terminate(server->display);
1593             break;
1594         default:
1595             return false;
1596     }
1597
1598     return true;
1599 }
1600
1601 static void
1602 keyboard_handle_key(struct wl_listener *listener, void *data)
1603 {
1604     struct tinyds_keyboard *kbd;
1605     struct ds_event_keyboard_key *event = data;
1606     struct ds_keyboard *ds_keyboard;
1607     struct xkb_state *xkb_state;
1608     const xkb_keysym_t *syms;
1609     int nsyms;
1610     bool handled = false;
1611
1612     kbd = wl_container_of(listener, kbd, key);
1613
1614     ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
1615             "update_state(%d)", kbd->dev,
1616             event->keycode, event->state, event->time_msec,
1617             event->update_state);
1618
1619     ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
1620
1621     if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1622         xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
1623         if (xkb_state) {
1624             nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
1625                     &syms);
1626             for (int i = 0; i < nsyms; i++) {
1627                 handled = server_handle_keybinding(kbd->server, syms[i]);
1628             }
1629         }
1630     }
1631
1632     if (!handled) {
1633         ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec,
1634                 event->keycode, event->state);
1635     }
1636 }
1637
1638 static void
1639 server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
1640 {
1641     struct tinyds_keyboard *kbd;
1642     struct xkb_context *context;
1643     struct xkb_keymap *keymap;
1644
1645     kbd = calloc(1, sizeof *kbd);
1646     assert(kbd);
1647
1648     kbd->dev = dev;
1649     kbd->server = server;
1650
1651     context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
1652     if (!context)
1653         goto err;
1654
1655     keymap = xkb_keymap_new_from_names(context, NULL,
1656             XKB_KEYMAP_COMPILE_NO_FLAGS);
1657
1658     if (!keymap) {
1659         ds_err("Failed to compile keymap");
1660         xkb_context_unref(context);
1661         goto err;
1662     }
1663
1664     ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap);
1665
1666     xkb_keymap_unref(keymap);
1667     xkb_context_unref(context);
1668
1669     kbd->destroy.notify = keyboard_handle_device_destroy;
1670     ds_input_device_add_destroy_listener(dev, &kbd->destroy);
1671
1672     kbd->key.notify = keyboard_handle_key;
1673     ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
1674
1675     wl_list_insert(&server->keyboards, &kbd->link);
1676
1677     ds_inf("Keyboard(%p) added", kbd);
1678
1679     return;
1680
1681 err:
1682     free(kbd);
1683 }
1684
1685 static struct tinyds_view *
1686 server_view_at(struct tinyds_server *server, double lx, double ly,
1687         double *sx, double *sy)
1688 {
1689     struct tinyds_view *view;
1690     struct ds_surface *surface;
1691     struct ds_buffer *buffer;
1692     int x, y, w = 0, h = 0;
1693
1694     wl_list_for_each(view, &server->views, link) {
1695         surface = ds_xdg_surface_get_surface(view->xdg_surface);
1696         buffer = ds_surface_get_buffer(surface);
1697         ds_buffer_get_size(buffer, &w, &h);
1698
1699         x = view->x;
1700         y = view->y;
1701
1702         if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) {
1703             *sx = lx - x;
1704             *sy = ly - y;
1705
1706             return view;
1707         }
1708     }
1709
1710     return NULL;
1711 }
1712
1713 static void
1714 touch_handle_device_destroy(struct wl_listener *listener, void *data)
1715 {
1716     struct tinyds_touch *touch;
1717
1718     touch = wl_container_of(listener, touch, destroy);
1719
1720     ds_inf("Touch(%p) destroyed", touch);
1721
1722     wl_list_remove(&touch->destroy.link);
1723     wl_list_remove(&touch->down.link);
1724     wl_list_remove(&touch->up.link);
1725     wl_list_remove(&touch->motion.link);
1726
1727     free(touch);
1728 }
1729
1730 static void
1731 touch_handle_down(struct wl_listener *listener, void *data)
1732 {
1733     struct ds_event_touch_down *event = data;
1734     struct tinyds_touch *touch;
1735     struct tinyds_view *view;
1736     struct tinyds_server *server;
1737     double sx = 0.f, sy = 0.f;
1738
1739     touch = wl_container_of(listener, touch, down);
1740
1741     server = touch->server;
1742     server->output_x = event->x * server->output->width;
1743     server->output_y = event->y * server->output->height;
1744
1745     ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1746             touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1747
1748     view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1749
1750     if (view) {
1751         ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface),
1752                 event->time_msec, event->id, sx, sy);
1753     }
1754
1755 #ifdef USE_CURSOR
1756     if (server->output && server->output->cursor_enabled) {
1757         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1758         draw_server_with_damage(server);
1759     }
1760 #endif
1761 }
1762
1763 static void
1764 touch_handle_up(struct wl_listener *listener, void *data)
1765 {
1766     struct ds_event_touch_up *event = data;
1767     struct tinyds_touch *touch;
1768
1769     touch = wl_container_of(listener, touch, up);
1770
1771     ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
1772             touch->dev, event->id, event->time_msec);
1773
1774     ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id);
1775 }
1776
1777 static void
1778 touch_handle_motion(struct wl_listener *listener, void *data)
1779 {
1780     struct ds_event_touch_motion *event = data;
1781     struct tinyds_touch *touch;
1782     struct tinyds_view *view;
1783     struct tinyds_server *server;
1784     double sx = 0.f, sy = 0.f;
1785
1786     touch = wl_container_of(listener, touch, motion);
1787
1788     server = touch->server;
1789     server->output_x = event->x * server->output->width;
1790     server->output_y = event->y * server->output->height;
1791
1792     ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1793             touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1794
1795     view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1796
1797     if (view) {
1798         ds_seat_touch_notify_motion(server->seat, event->time_msec,
1799                 event->id, sx, sy);
1800     }
1801
1802 #ifdef USE_CURSOR
1803     if (server->output && server->output->cursor_enabled) {
1804         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1805         draw_server_with_damage(server);
1806     }
1807 #endif
1808 }
1809
1810 static void
1811 server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
1812 {
1813     struct tinyds_touch *touch;
1814
1815     touch = calloc(1, sizeof *touch);
1816     assert(touch);
1817
1818     touch->dev = dev;
1819     touch->server = server;
1820
1821     touch->destroy.notify = touch_handle_device_destroy;
1822     ds_input_device_add_destroy_listener(dev, &touch->destroy);
1823
1824     touch->down.notify = touch_handle_down;
1825     ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
1826
1827     touch->up.notify = touch_handle_up;
1828     ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
1829
1830     touch->motion.notify = touch_handle_motion;
1831     ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
1832
1833     ds_inf("Touch(%p) added", touch);
1834 }
1835
1836 static void
1837 pointer_handle_device_destroy(struct wl_listener *listener, void *data)
1838 {
1839     struct tinyds_pointer *pointer;
1840     struct tinyds_server *server;
1841
1842     pointer = wl_container_of(listener, pointer, destroy);
1843
1844     ds_inf("Pointer(%p) destroyed", pointer);
1845
1846     wl_list_remove(&pointer->destroy.link);
1847     wl_list_remove(&pointer->motion.link);
1848     wl_list_remove(&pointer->button.link);
1849     wl_list_remove(&pointer->frame.link);
1850     wl_list_remove(&pointer->link);
1851
1852 #ifdef USE_CURSOR
1853     server = pointer->server;
1854     if (server->output && wl_list_empty(&server->pointers))
1855     {
1856         server->output->cursor_enabled = false;
1857         renderer_cursor_destroy(&server->output->renderer);
1858
1859         if (server->output->cursor_hwc_window)
1860         {
1861             ds_tdm_output_hwc_window_destroy(server->output->cursor_hwc_window);
1862             server->output->cursor_hwc_window = NULL;
1863         }
1864         draw_server_with_damage(server);
1865     }
1866 #endif
1867
1868     free(pointer);
1869 }
1870
1871 static void
1872 pointer_handle_motion(struct wl_listener *listener, void *data)
1873 {
1874     struct tinyds_pointer *pointer;
1875     struct ds_event_pointer_motion *event = data;
1876     struct tinyds_view *view;
1877     struct tinyds_server *server;
1878     int ow = 0, oh = 0;
1879     double sx, sy;
1880
1881     pointer = wl_container_of(listener, pointer, motion);
1882
1883     server = pointer->server;
1884     if (server->output) {
1885         ow = server->output->width;
1886         oh = server->output->height;
1887     }
1888
1889     if (server->output_x + event->delta_x >= ow)
1890         server->output_x = ow;
1891     else if(server->output_x + event->delta_x <= 0.f)
1892         server->output_x = 0.f;
1893     else
1894         server->output_x = server->output_x + event->delta_x ;
1895     if (server->output_y + event->delta_y >= oh)
1896         server->output_y = oh;
1897     else if(server->output_y + event->delta_y <= 0.f)
1898         server->output_y = 0.f;
1899     else
1900         server->output_y = server->output_y + event->delta_y ;
1901
1902     ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f",
1903             pointer, event->delta_x, event->delta_y, server->output_x, server->output_y);
1904
1905     view = server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy);
1906
1907     if (pointer->focused_view != view) {
1908         if (pointer->focused_view) {
1909             ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
1910             ds_seat_pointer_notify_clear_focus(pointer->server->seat);
1911             pointer->focused_view = NULL;
1912         }
1913
1914         if (view) {
1915             ds_inf("Set pointer focus to view(%p)", view);
1916             ds_seat_pointer_notify_enter(pointer->server->seat,
1917                     ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
1918             pointer->focused_view = view;
1919         }
1920     }
1921
1922     if (view) {
1923         ds_seat_pointer_notify_motion(pointer->server->seat,
1924                 event->time_msec, sx, sy);
1925     }
1926
1927 #ifdef USE_CURSOR
1928     if (server->output && server->output->cursor_enabled) {
1929         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1930         draw_server_with_damage(server);
1931     }
1932 #endif
1933 }
1934
1935 static void
1936 pointer_handle_button(struct wl_listener *listener, void *data)
1937 {
1938     struct tinyds_pointer *pointer;
1939     struct ds_event_pointer_button *event = data;
1940
1941     pointer = wl_container_of(listener, pointer, button);
1942
1943     ds_inf("Pointer(%p) button(%d): state(%s) time(%d)",
1944             pointer, event->button,
1945             (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released",
1946             event->time_msec);
1947
1948     ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state);
1949 }
1950
1951 static void
1952 pointer_handle_frame(struct wl_listener *listener, void *data)
1953 {
1954     struct tinyds_pointer *pointer;
1955
1956     pointer = wl_container_of(listener, pointer, frame);
1957
1958     ds_inf("Pointer(%p) frame", pointer);
1959     ds_seat_pointer_notify_frame(pointer->server->seat);
1960 }
1961
1962 static void
1963 server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev)
1964 {
1965     struct tinyds_pointer *pointer;
1966
1967     pointer = calloc(1, sizeof *pointer);
1968     assert(pointer);
1969
1970     pointer->dev = dev;
1971     pointer->server = server;
1972
1973     pointer->destroy.notify = pointer_handle_device_destroy;
1974     ds_input_device_add_destroy_listener(dev, &pointer->destroy);
1975
1976     pointer->motion.notify = pointer_handle_motion;
1977     ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev),
1978             &pointer->motion);
1979
1980     pointer->button.notify = pointer_handle_button;
1981     ds_pointer_add_button_listener(ds_input_device_get_pointer(dev),
1982             &pointer->button);
1983
1984     pointer->frame.notify = pointer_handle_frame;
1985     ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev),
1986             &pointer->frame);
1987
1988     pointer->focused_view = NULL;
1989
1990 #ifdef USE_CURSOR
1991     if (server->output && wl_list_empty(&server->pointers)) {
1992         server->output_x = (double)(server->output->width) / 2;
1993         server->output_y = (double)(server->output->height) / 2;
1994
1995         server->output->cursor_enabled = true;
1996         renderer_cursor_create(&server->output->renderer, 255, 0, 0, CURSOR_W, CURSOR_H);
1997         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1998
1999         server->output->cursor_hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
2000         assert(server->output->cursor_hwc_window);
2001         draw_server_with_damage(server);
2002     }
2003 #endif
2004
2005     wl_list_insert(&server->pointers, &pointer->link);
2006
2007     ds_inf("Pointer(%p) added", pointer);
2008 }
2009
2010 static void
2011 output_schedule_commit_handle_idle_timer(void *data)
2012 {
2013     struct tinyds_output *output = data;
2014     output->idle_commit = NULL;
2015
2016     output_commit(output);
2017 }
2018
2019 static void
2020 output_schedule_commit(struct tinyds_output *output)
2021 {
2022     if (output->idle_commit)
2023         return;
2024
2025     struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display);
2026     output->idle_commit =
2027         wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output);
2028 }
2029
2030 static void
2031 text_input_mgr_handle_destroy(struct wl_listener *listener, void *data)
2032 {
2033     struct tinyds_text_input *text_input;
2034     struct tinyds_server *server;
2035
2036     ds_inf("text_input_mgr_handle_destroy");
2037     text_input = wl_container_of(listener, text_input, mgr_destroy);
2038
2039     wl_list_remove(&text_input->mgr_destroy.link);
2040     wl_list_remove(&text_input->new_text_input.link);
2041
2042     server = text_input->server;
2043     server->text_input = NULL;
2044 }
2045
2046 static void
2047 text_input_handle_destroy(struct wl_listener *listener, void *data)
2048 {
2049     struct tinyds_text_input *text_input;
2050
2051     ds_inf("text_input_handle_destroy");
2052
2053     text_input = wl_container_of(listener, text_input, destroy);
2054
2055     wl_list_remove(&text_input->destroy.link);
2056     wl_list_remove(&text_input->text_input_activate.link);
2057     wl_list_remove(&text_input->text_input_deactivate.link);
2058     wl_list_remove(&text_input->text_input_reset.link);
2059     wl_list_remove(&text_input->text_input_set_content_type.link);
2060     wl_list_remove(&text_input->text_input_invoke_action.link);
2061     wl_list_remove(&text_input->text_input_commit_state.link);
2062     wl_list_remove(&text_input->text_input_set_preferred_language.link);
2063
2064     free(text_input);
2065 }
2066
2067 static void
2068 text_input_handle_activate(struct wl_listener *listener, void *data)
2069 {
2070     struct tinyds_text_input *text_input;
2071     struct tinyds_input_method *input_method;
2072     struct ds_tizen_text_input_event_activate *event = data;
2073
2074     text_input = wl_container_of(listener, text_input, text_input_activate);
2075
2076     input_method = text_input->server->input_method;
2077
2078     ds_inf("text_input_handle_activate. text_input(%p) seat(%p) surface(%p) text_input(%p)",
2079         text_input, event->seat, event->surface, event->text_input);
2080
2081     if (input_method->input == text_input)
2082         return;
2083     if (input_method->input)
2084         ;//deactivate_input_method(server->input_method);
2085     input_method->input = text_input;
2086     wl_list_insert(&text_input->input_methods, &input_method->link);
2087
2088     text_input->surface = event->surface;
2089
2090     if (!add_new_input_method_context(input_method, text_input))
2091         return;
2092
2093     // ds_tizen_input_method_send_set_text_input_id();
2094 }
2095
2096 static void
2097 text_input_handle_deactivate(struct wl_listener *listener, void *data)
2098 {
2099     struct tinyds_text_input *text_input;
2100     struct tinyds_input_method *input_method, *tmp;
2101     struct ds_tizen_text_input_event_deactivate *event = data;
2102
2103     text_input = wl_container_of(listener, text_input, text_input_deactivate);
2104     ds_inf("text_input_handle_deactivate. text_input(%p) seat(%p) text_input(%p)",
2105         text_input, event->seat, event->text_input);
2106
2107     wl_list_for_each_safe(input_method, tmp, &text_input->input_methods, link) {
2108         if (!input_method->input_method || !input_method->context->context) continue;
2109         ds_tizen_input_method_send_deactivate(input_method->input_method, input_method->context->context);
2110         input_method->input = NULL;
2111         input_method->context = NULL;
2112         wl_list_remove(&input_method->link);
2113     }
2114
2115     text_input->surface = NULL;
2116     // ds_tizen_input_method_send_close_connection();
2117 }
2118
2119 static void
2120 text_input_handle_reset(struct wl_listener *listener, void *data)
2121 {
2122     struct tinyds_text_input *text_input;
2123     struct tinyds_input_method *input_method;
2124
2125     text_input = wl_container_of(listener, text_input, text_input_reset);
2126
2127     ds_inf("text_input_handle_reset. text_input(%p)", text_input);
2128
2129     wl_list_for_each(input_method, &text_input->input_methods, link) {
2130         if (!input_method->context || !input_method->context->context) continue;
2131         ds_tizen_input_method_context_send_reset(input_method->context->context);
2132     }
2133 }
2134
2135 static void
2136 text_input_handle_set_content_type(struct wl_listener *listener, void *data)
2137 {
2138     struct tinyds_text_input *text_input;
2139     struct ds_tizen_text_input_event_set_content_type *event = data;
2140     struct tinyds_input_method *input_method;
2141
2142     text_input = wl_container_of(listener, text_input, text_input_set_content_type);
2143
2144     ds_inf("text_input_handle_content_type. text_input(%p) hint(%u) purpose(%u)",
2145         text_input, event->hint, event->purpose);
2146
2147     wl_list_for_each(input_method, &text_input->input_methods, link) {
2148         if (!input_method->context || !input_method->context->context) continue;
2149         ds_tizen_input_method_context_send_content_type(input_method->context->context,
2150             event->hint, event->purpose);
2151     }
2152 }
2153
2154 static void
2155 text_input_handle_invoke_action(struct wl_listener *listener, void *data)
2156 {
2157     struct tinyds_text_input *text_input;
2158     struct ds_tizen_text_input_event_invoke_action *event = data;
2159     struct tinyds_input_method *input_method;
2160
2161     text_input = wl_container_of(listener, text_input, text_input_invoke_action);
2162
2163     ds_inf("text_input_handle_invoke_action. text_input(%p) button(%u) index(%u)",
2164         text_input, event->button, event->index);
2165
2166     wl_list_for_each(input_method, &text_input->input_methods, link) {
2167         if (!input_method->context || !input_method->context->context) continue;
2168         ds_tizen_input_method_context_send_invoke_action(input_method->context->context,
2169             event->button, event->index);
2170     }
2171 }
2172
2173 static void
2174 text_input_handle_commit_state(struct wl_listener *listener, void *data)
2175 {
2176     struct tinyds_text_input *text_input;
2177     struct ds_tizen_text_input_event_commit_state *event = data;
2178     struct tinyds_input_method *input_method;
2179
2180     text_input = wl_container_of(listener, text_input, text_input_commit_state);
2181
2182     ds_inf("text_input_handle_commit_state. text_input(%p) serial(%u)",
2183         text_input, event->serial);
2184
2185     wl_list_for_each(input_method, &text_input->input_methods, link) {
2186         if (!input_method->context || !input_method->context->context) continue;
2187         ds_tizen_input_method_context_send_commit_state(input_method->context->context,
2188             event->serial);
2189     }
2190 }
2191
2192 static void
2193 text_input_handle_set_preferred_language(struct wl_listener *listener, void *data)
2194 {
2195     struct tinyds_text_input *text_input;
2196     struct ds_tizen_text_input_event_set_preferred_language *event = data;
2197     struct tinyds_input_method *input_method;
2198
2199     text_input = wl_container_of(listener, text_input, text_input_set_preferred_language);
2200
2201     ds_inf("text_input_handle_set_preferred_language. text_input(%p) language(%s)",
2202         text_input, event->language);
2203
2204     wl_list_for_each(input_method, &text_input->input_methods, link) {
2205         if (!input_method->context || !input_method->context->context) continue;
2206         ds_tizen_input_method_context_send_preferred_language(input_method->context->context,
2207             event->language);
2208     }
2209 }
2210
2211 static void
2212 text_input_mgr_handle_new_text_input(struct wl_listener *listener, void *data)
2213 {
2214     struct tinyds_text_input *text_input;
2215     struct ds_tizen_text_input *input = data;
2216
2217     text_input = wl_container_of(listener, text_input, new_text_input);
2218
2219     ds_inf("text_input_mgr_handle_new_text_input");
2220
2221     text_input->input = input;
2222
2223     text_input->destroy.notify = text_input_handle_destroy;
2224     ds_tizen_text_input_add_destroy_listener(text_input->input,
2225         &text_input->destroy);
2226
2227     text_input->text_input_activate.notify = text_input_handle_activate;
2228     ds_tizen_text_input_add_activate_listener(text_input->input,
2229         &text_input->text_input_activate);
2230
2231     text_input->text_input_deactivate.notify = text_input_handle_deactivate;
2232     ds_tizen_text_input_add_deactivate_listener(text_input->input,
2233         &text_input->text_input_deactivate);
2234
2235     text_input->text_input_reset.notify = text_input_handle_reset;
2236     ds_tizen_text_input_add_reset_listener(text_input->input,
2237         &text_input->text_input_reset);
2238
2239     text_input->text_input_set_content_type.notify = text_input_handle_set_content_type;
2240     ds_tizen_text_input_add_set_content_type_listener(text_input->input,
2241         &text_input->text_input_set_content_type);
2242
2243     text_input->text_input_invoke_action.notify = text_input_handle_invoke_action;
2244     ds_tizen_text_input_add_invoke_action_listener(text_input->input,
2245         &text_input->text_input_invoke_action);
2246
2247     text_input->text_input_commit_state.notify = text_input_handle_commit_state;
2248     ds_tizen_text_input_add_commit_state_listener(text_input->input,
2249         &text_input->text_input_commit_state);
2250
2251     text_input->text_input_set_preferred_language.notify = text_input_handle_set_preferred_language;
2252     ds_tizen_text_input_add_set_preferred_language_listener(text_input->input,
2253         &text_input->text_input_set_preferred_language);
2254 }
2255
2256 static void
2257 input_method_mgr_handle_destroy(struct wl_listener *listener, void *data)
2258 {
2259     struct tinyds_input_method *input_method;
2260
2261     ds_inf("input_method_mgr_handle_destroy");
2262
2263     input_method = wl_container_of(listener, input_method, mgr_destroy);
2264
2265     wl_list_remove(&input_method->mgr_destroy.link);
2266 }
2267
2268 static void
2269 input_method_handle_destroy(struct wl_listener *listener, void *data)
2270 {
2271     struct tinyds_input_method *input_method;
2272     struct tinyds_server *server;
2273
2274     ds_inf("input_method_handle_destroy");
2275
2276     input_method = wl_container_of(listener, input_method, destroy);
2277
2278     wl_list_remove(&input_method->destroy.link);
2279
2280     server = input_method->server;
2281     server->input_method = NULL;
2282
2283     free(input_method);
2284 }
2285
2286 static void
2287 context_handle_destroy(struct wl_listener *listener, void *data)
2288 {
2289     struct tinyds_input_method_context *context;
2290     struct tinyds_server *server;
2291
2292     ds_inf("context_handle_destroy");
2293
2294     context = wl_container_of(listener, context, destroy);
2295
2296     wl_list_remove(&context->destroy.link);
2297
2298     wl_list_remove(&context->im_context_commit_string.link);
2299     wl_list_remove(&context->im_context_preedit_string.link);
2300     wl_list_remove(&context->im_context_preedit_styling.link);
2301     wl_list_remove(&context->im_context_preedit_cursor.link);
2302     wl_list_remove(&context->im_context_delete_surrounding_text.link);
2303     wl_list_remove(&context->im_context_cursor_position.link);
2304     wl_list_remove(&context->im_context_modifiers_map.link);
2305     wl_list_remove(&context->im_context_keysym.link);
2306     wl_list_remove(&context->im_context_grab_keyboard.link);
2307     wl_list_remove(&context->im_context_key.link);
2308     wl_list_remove(&context->im_context_modifiers.link);
2309     wl_list_remove(&context->im_context_language.link);
2310     wl_list_remove(&context->im_context_text_direction.link);
2311
2312     server = context->server;
2313     server->input_method->context = NULL;
2314
2315     free(context);
2316 }
2317
2318 static void
2319 context_handle_commit_string(struct wl_listener *listener, void *data)
2320 {
2321     struct tinyds_text_input *text_input;
2322     struct tinyds_input_method_context *context;
2323     struct ds_tizen_input_method_context_event_commit_string *event = data;
2324
2325     context = wl_container_of(listener, context, im_context_commit_string);
2326     text_input = context->server->text_input;
2327
2328     ds_inf("context_handle_commit_string. text_input(%p) serial(%u) text(%s)",
2329         text_input, event->serial, event->text);
2330
2331     ds_tizen_text_input_send_commit_string(text_input->input, event->serial, event->text);
2332 }
2333
2334 static void
2335 context_handle_preedit_string(struct wl_listener *listener, void *data)
2336 {
2337     struct tinyds_input_method_context *context;
2338     struct tinyds_text_input *text_input;
2339     struct ds_tizen_input_method_context_event_preedit_string *event = data;
2340
2341     context = wl_container_of(listener, context, im_context_preedit_string);
2342     text_input = context->server->text_input;
2343
2344     ds_inf("context_handle_preedit_string. text_input(%p) serial(%u) text(%s) commit(%s)",
2345         text_input, event->serial, event->text, event->commit);
2346
2347     ds_tizen_text_input_send_preedit_string(text_input->input, event->serial, event->text, event->commit);
2348 }
2349
2350 static void
2351 context_handle_preedit_styling(struct wl_listener *listener, void *data)
2352 {
2353     struct tinyds_input_method_context *context;
2354     struct tinyds_text_input *text_input;
2355     struct ds_tizen_input_method_context_event_preedit_styling *event = data;
2356
2357     context = wl_container_of(listener, context, im_context_preedit_styling);
2358     text_input = context->server->text_input;
2359
2360     ds_inf("context_handle_preedit_styling. text_input(%p) index(%u) length(%u) style(%u)",
2361         text_input, event->index, event->length, event->style);
2362
2363     ds_tizen_text_input_send_preedit_styling(text_input->input, event->index, event->length, event->style);
2364 }
2365
2366 static void
2367 context_handle_preedit_cursor(struct wl_listener *listener, void *data)
2368 {
2369     struct tinyds_input_method_context *context;
2370     struct tinyds_text_input *text_input;
2371     struct ds_tizen_input_method_context_event_preedit_cursor *event = data;
2372
2373     context = wl_container_of(listener, context, im_context_preedit_cursor);
2374     text_input = context->server->text_input;
2375
2376     ds_inf("context_handle_preedit_cursor. text_input(%p) index(%u)",
2377         text_input, event->index);
2378
2379     ds_tizen_text_input_send_preedit_cursor(text_input->input, event->index);
2380 }
2381
2382 static void
2383 context_handle_delete_surrounding_text(struct wl_listener *listener, void *data)
2384 {
2385     struct tinyds_input_method_context *context;
2386     struct tinyds_text_input *text_input;
2387     struct ds_tizen_input_method_context_event_delete_surrounding_text *event = data;
2388
2389     context = wl_container_of(listener, context, im_context_delete_surrounding_text);
2390     text_input = context->server->text_input;
2391
2392     ds_inf("context_handle_delete_surrounding_text. text_input(%p) index(%d) length(%u)",
2393         text_input, event->index, event->length);
2394
2395     ds_tizen_text_input_send_delete_surrounding_text(text_input->input, event->index, event->length);
2396 }
2397
2398 static void
2399 context_handle_cursor_position(struct wl_listener *listener, void *data)
2400 {
2401     struct tinyds_input_method_context *context;
2402     struct tinyds_text_input *text_input;
2403     struct ds_tizen_input_method_context_event_cursor_position *event = data;
2404
2405     context = wl_container_of(listener, context, im_context_cursor_position);
2406     text_input = context->server->text_input;
2407
2408     ds_inf("context_handle_cursor_position. text_input(%p) index(%d) length(%d)",
2409         text_input, event->index, event->anchor);
2410
2411     ds_tizen_text_input_send_cursor_position(text_input->input, event->index, event->anchor);
2412 }
2413
2414 static void
2415 context_handle_modifiers_map(struct wl_listener *listener, void *data)
2416 {
2417     struct tinyds_input_method_context *context;
2418     struct tinyds_text_input *text_input;
2419     struct ds_tizen_input_method_context_event_modifiers_map *event = data;
2420
2421     context = wl_container_of(listener, context, im_context_modifiers_map);
2422     text_input = context->server->text_input;
2423
2424     ds_inf("context_handle_modifiers_map. text_input(%p) map(%p)",
2425         text_input, event->map);
2426
2427     ds_tizen_text_input_send_modifiers_map(text_input->input, event->map);
2428 }
2429
2430 static void
2431 context_handle_keysym(struct wl_listener *listener, void *data)
2432 {
2433     struct tinyds_input_method_context *context;
2434     struct tinyds_text_input *text_input;
2435     struct ds_tizen_input_method_context_event_keysym *event = data;
2436
2437     context = wl_container_of(listener, context, im_context_keysym);
2438     text_input = context->server->text_input;
2439
2440     ds_inf("context_handle_keysym. text_input(%p) serial(%u) time(%u) sysm(%u) state(%u) modifiers(%u)",
2441         text_input, event->serial, event->time, event->sym, event->state, event->modifiers);
2442
2443     ds_tizen_text_input_send_keysym(text_input->input, event->serial, event->time, event->sym, event->state, event->modifiers);
2444 }
2445
2446 static void
2447 context_handle_grab_keyboard(struct wl_listener *listener, void *data)
2448 {
2449     struct tinyds_input_method_context *context;
2450     struct tinyds_text_input *text_input;
2451
2452     context = wl_container_of(listener, context, im_context_grab_keyboard);
2453     text_input = context->server->text_input;
2454
2455     ds_inf("context_handle_grab_keyboard. text_input(%p)",
2456         text_input);
2457
2458     //TODO
2459 }
2460
2461 static void
2462 context_handle_key(struct wl_listener *listener, void *data)
2463 {
2464     struct tinyds_input_method_context *context;
2465     struct tinyds_text_input *text_input;
2466
2467     context = wl_container_of(listener, context, im_context_key);
2468     text_input = context->server->text_input;
2469
2470     ds_inf("context_handle_key. text_input(%p)",
2471         text_input);
2472
2473    //TODO
2474 }
2475
2476 static void
2477 context_handle_modifiers(struct wl_listener *listener, void *data)
2478 {
2479     struct tinyds_input_method_context *context;
2480     struct tinyds_text_input *text_input;
2481
2482     context = wl_container_of(listener, context, im_context_modifiers);
2483     text_input = context->server->text_input;
2484
2485     ds_inf("context_handle_modifiers. text_input(%p)",
2486         text_input);
2487
2488    //TODO
2489 }
2490
2491 static void
2492 context_handle_language(struct wl_listener *listener, void *data)
2493 {
2494     struct tinyds_input_method_context *context;
2495     struct tinyds_text_input *text_input;
2496     struct ds_tizen_input_method_context_event_language *event = data;
2497
2498     context = wl_container_of(listener, context, im_context_language);
2499     text_input = context->server->text_input;
2500
2501     ds_inf("context_handle_language. text_input(%p) serial(%u), language(%s)",
2502         text_input, event->serial, event->language);
2503
2504     ds_tizen_text_input_send_language(text_input->input, event->serial, event->language);
2505 }
2506
2507 static void
2508 context_handle_text_direction(struct wl_listener *listener, void *data)
2509 {
2510     struct tinyds_input_method_context *context;
2511     struct tinyds_text_input *text_input;
2512     struct ds_tizen_input_method_context_event_text_direction *event = data;
2513
2514     context = wl_container_of(listener, context, im_context_text_direction);
2515     text_input = context->server->text_input;
2516
2517     ds_inf("context_handle_text_direction. text_input(%p) serial(%u), direction(%u)",
2518         text_input, event->serial, event->direction);
2519
2520     ds_tizen_text_input_send_text_direction(text_input->input, event->serial, event->direction);
2521 }
2522
2523 static bool
2524 add_new_text_input(struct tinyds_server *server)
2525 {
2526     struct tinyds_text_input *text_input;
2527
2528     text_input = calloc(1, sizeof *text_input);
2529     if (!text_input)
2530         return false;
2531
2532     text_input->text_input_mgr = ds_tizen_text_input_manager_create(server->display);
2533     if (!text_input->text_input_mgr) {
2534         free(text_input);
2535         ds_err("Could not create ds_tizen_text_input_manager");
2536         return false;
2537     }
2538
2539     wl_list_init(&text_input->input_methods);
2540
2541     text_input->mgr_destroy.notify = text_input_mgr_handle_destroy;
2542     ds_tizen_text_input_manager_add_destroy_listener(text_input->text_input_mgr,
2543             &text_input->mgr_destroy);
2544
2545     text_input->new_text_input.notify = text_input_mgr_handle_new_text_input;
2546     ds_tizen_text_input_manager_add_new_text_input_listener(text_input->text_input_mgr,
2547             &text_input->new_text_input);
2548
2549     text_input->server = server;
2550     server->text_input = text_input;
2551
2552     ds_inf("Text_Input (%p) added", text_input);
2553
2554     return true;
2555 }
2556
2557 static bool
2558 add_new_input_method(struct tinyds_server *server)
2559 {
2560     struct tinyds_input_method *input_method;
2561
2562     input_method = calloc(1, sizeof *input_method);
2563     if (!input_method)
2564         return false;
2565
2566     input_method->input_method = ds_tizen_input_method_create(server->display);
2567     if (!input_method->input_method) {
2568         free(input_method);
2569         ds_err("Could not create ds_tizen_input_method");
2570         return false;
2571     }
2572     input_method->destroy.notify = input_method_handle_destroy;
2573     ds_tizen_input_method_add_destroy_listener(input_method->input_method,
2574             &input_method->destroy);
2575
2576     input_method->input_method_mgr = ds_tizen_input_method_manager_create(server->display);
2577     if (!input_method->input_method_mgr) {
2578         free(input_method);
2579         ds_err("Could not create ds_tizen_input_method_manager");
2580         return false;
2581     }
2582
2583     input_method->mgr_destroy.notify = input_method_mgr_handle_destroy;
2584     ds_tizen_input_method_manager_add_destroy_listener(input_method->input_method_mgr,
2585             &input_method->mgr_destroy);
2586
2587     input_method->server = server;
2588     server->input_method = input_method;
2589
2590     ds_inf("Input_Method (%p) added", input_method);
2591
2592     return true;
2593 }
2594
2595 static bool
2596 add_new_input_method_context(struct tinyds_input_method *input_method,
2597         struct tinyds_text_input *text_input)
2598 {
2599     struct tinyds_input_method_context *context;
2600
2601     context = calloc(1, sizeof *context);
2602     if (context == NULL)
2603     {
2604         ds_err("calloc is failed. tinyds_input_method_context");
2605         return false;
2606     }
2607     input_method->context = context;
2608     context->input_method = input_method;
2609     context->server = input_method->server;
2610     context->input = text_input;
2611
2612     context->context = ds_tizen_input_method_create_context(input_method->input_method);
2613     if (context->context == NULL) {
2614         ds_err("ds_tizen_input_method_create_context() failed.");
2615         return false;
2616     }
2617
2618     context->destroy.notify = context_handle_destroy;
2619     ds_tizen_input_method_context_add_destroy_listener(context->context,
2620         &context->destroy);
2621
2622     context->im_context_commit_string.notify = context_handle_commit_string;
2623     ds_tizen_input_method_context_add_commit_string_listener(context->context,
2624         &context->im_context_commit_string);
2625
2626     context->im_context_preedit_string.notify = context_handle_preedit_string;
2627     ds_tizen_input_method_context_add_preedit_string_listener(context->context,
2628         &context->im_context_preedit_string);
2629
2630     context->im_context_preedit_styling.notify = context_handle_preedit_styling;
2631     ds_tizen_input_method_context_add_preedit_styling_listener(context->context,
2632         &context->im_context_preedit_styling);
2633
2634     context->im_context_preedit_cursor.notify = context_handle_preedit_cursor;
2635     ds_tizen_input_method_context_add_preedit_cursor_listener(context->context,
2636         &context->im_context_preedit_cursor);
2637
2638     context->im_context_delete_surrounding_text.notify = context_handle_delete_surrounding_text;
2639     ds_tizen_input_method_context_add_delete_surrounding_text_listener(context->context,
2640         &context->im_context_delete_surrounding_text);
2641
2642     context->im_context_cursor_position.notify = context_handle_cursor_position;
2643     ds_tizen_input_method_context_add_cursor_position_listener(context->context,
2644         &context->im_context_cursor_position);
2645
2646     context->im_context_modifiers_map.notify = context_handle_modifiers_map;
2647     ds_tizen_input_method_context_add_modifiers_map_listener(context->context,
2648         &context->im_context_modifiers_map);
2649
2650     context->im_context_keysym.notify = context_handle_keysym;
2651     ds_tizen_input_method_context_add_keysym_listener(context->context,
2652         &context->im_context_keysym);
2653
2654     context->im_context_grab_keyboard.notify = context_handle_grab_keyboard;
2655     ds_tizen_input_method_context_add_grab_keyboard_listener(context->context,
2656         &context->im_context_grab_keyboard);
2657
2658     context->im_context_key.notify = context_handle_key;
2659     ds_tizen_input_method_context_add_key_listener(context->context,
2660         &context->im_context_key);
2661
2662     context->im_context_modifiers.notify = context_handle_modifiers;
2663     ds_tizen_input_method_context_add_modifiers_listener(context->context,
2664         &context->im_context_modifiers);
2665
2666     context->im_context_language.notify = context_handle_language;
2667     ds_tizen_input_method_context_add_language_listener(context->context,
2668         &context->im_context_language);
2669
2670     context->im_context_text_direction.notify = context_handle_text_direction;
2671     ds_tizen_input_method_context_add_text_direction_listener(context->context,
2672         &context->im_context_text_direction);
2673
2674     return true;
2675 }
2676
2677 static void
2678 visibility_handle_destroy(struct wl_listener *listener, void *data)
2679 {
2680     struct tinyds_policy_visibility *visibility;
2681
2682     visibility = wl_container_of(listener, visibility, destroy);
2683
2684     ds_inf("Policy Visibility(%p) destroy", visibility);
2685
2686     wl_list_remove(&visibility->destroy.link);
2687     wl_list_remove(&visibility->link);
2688     free(visibility);
2689 }
2690
2691 static void
2692 position_handle_destroy(struct wl_listener *listener, void *data)
2693 {
2694     struct tinyds_policy_position *position;
2695
2696     position = wl_container_of(listener, position, destroy);
2697
2698     ds_inf("Policy Position(%p) destroy", position);
2699
2700     wl_list_remove(&position->destroy.link);
2701     wl_list_remove(&position->set.link);
2702     wl_list_remove(&position->link);
2703     free(position);
2704 }
2705
2706 static void
2707 position_handle_set(struct wl_listener *listener, void *data)
2708 {
2709     struct tinyds_policy_position *position;
2710
2711     position = wl_container_of(listener, position, set);
2712
2713     ds_inf("Policy Position(%p) set", position);
2714
2715     // TODO:
2716 }
2717
2718 static void
2719 subsurface_watcher_handle_destroy(struct wl_listener *listener, void *data)
2720 {
2721     struct tinyds_policy_subsurface_watcher *subsurface_watcher;
2722
2723     subsurface_watcher = wl_container_of(listener, subsurface_watcher, destroy);
2724
2725     ds_inf("Policy Subsurface_Watcher(%p) destroy", subsurface_watcher);
2726
2727     wl_list_remove(&subsurface_watcher->destroy.link);
2728     wl_list_remove(&subsurface_watcher->link);
2729     free(subsurface_watcher);
2730 }
2731
2732 static void
2733 policy_surface_handle_destroy(struct wl_listener *listener, void *data)
2734 {
2735     struct tinyds_policy_surface *policy_surface;
2736
2737     policy_surface = wl_container_of(listener, policy_surface, destroy);
2738
2739     ds_inf("Policy Info(%p) destroy", policy_surface);
2740
2741     wl_list_remove(&policy_surface->destroy.link);
2742     wl_list_remove(&policy_surface->new_visibility.link);
2743     wl_list_remove(&policy_surface->new_position.link);
2744     wl_list_remove(&policy_surface->activate.link);
2745     wl_list_remove(&policy_surface->raise.link);
2746     wl_list_remove(&policy_surface->lower.link);
2747     wl_list_remove(&policy_surface->set_focus_skip.link);
2748     wl_list_remove(&policy_surface->unset_focus_skip.link);
2749     wl_list_remove(&policy_surface->set_role.link);
2750     wl_list_remove(&policy_surface->set_window_type.link);
2751     wl_list_remove(&policy_surface->set_conformant.link);
2752     wl_list_remove(&policy_surface->unset_conformant.link);
2753     wl_list_remove(&policy_surface->get_conformant.link);
2754     wl_list_remove(&policy_surface->set_notification_level.link);
2755     wl_list_remove(&policy_surface->set_window_screen_mode.link);
2756     wl_list_remove(&policy_surface->get_subsurface.link);
2757     wl_list_remove(&policy_surface->iconify.link);
2758     wl_list_remove(&policy_surface->uniconify.link);
2759     wl_list_remove(&policy_surface->add_aux_hint.link);
2760     wl_list_remove(&policy_surface->change_aux_hint.link);
2761     wl_list_remove(&policy_surface->delete_aux_hint.link);
2762     wl_list_remove(&policy_surface->get_supported_aux_hints.link);
2763     wl_list_remove(&policy_surface->set_floating_mode.link);
2764     wl_list_remove(&policy_surface->unset_floating_mode.link);
2765     wl_list_remove(&policy_surface->set_stack_mode.link);
2766     wl_list_remove(&policy_surface->new_subsurface_watcher.link);
2767     wl_list_remove(&policy_surface->set_parent.link);
2768     wl_list_remove(&policy_surface->ack_conformant_region.link);
2769     wl_list_remove(&policy_surface->set_video.link);
2770     wl_list_remove(&policy_surface->show.link);
2771     wl_list_remove(&policy_surface->hide.link);
2772     wl_list_remove(&policy_surface->set_parent_with_below.link);
2773     wl_list_remove(&policy_surface->link);
2774     free(policy_surface);
2775 }
2776
2777 static void
2778 policy_surface_handle_new_visibility(struct wl_listener *listener, void *data)
2779 {
2780     struct tinyds_policy_surface *policy_surface;
2781     struct tinyds_policy_visibility *visibility;
2782     struct ds_tizen_event_policy_surface_new_visibility *event;
2783
2784     policy_surface = wl_container_of(listener, policy_surface, new_visibility);
2785     event = (struct ds_tizen_event_policy_surface_new_visibility *)data;
2786
2787     ds_inf("Policy Info(%p) new_visibility", policy_surface);
2788
2789     visibility = calloc(1, sizeof *visibility);
2790     if (!visibility)
2791         return;
2792
2793     visibility->visibility = event->visibility;
2794
2795     visibility->destroy.notify = visibility_handle_destroy;
2796     ds_tizen_policy_visibility_add_destroy_listener(visibility->visibility,
2797         &visibility->destroy);
2798
2799     wl_list_insert(&policy_surface->visibilities, &visibility->link);
2800 }
2801
2802 static void
2803 policy_surface_handle_new_position(struct wl_listener *listener, void *data)
2804 {
2805     struct tinyds_policy_surface *policy_surface;
2806     struct tinyds_policy_position *position;
2807     struct ds_tizen_event_policy_surface_new_position *event;
2808
2809     policy_surface = wl_container_of(listener, policy_surface, new_position);
2810     event = (struct ds_tizen_event_policy_surface_new_position *)data;
2811
2812     ds_inf("Policy Info(%p) new_position", policy_surface);
2813
2814     position = calloc(1, sizeof *position);
2815     if (!position)
2816         return;
2817
2818     position->position = event->position;
2819
2820     position->destroy.notify = position_handle_destroy;
2821     ds_tizen_policy_position_add_destroy_listener(position->position,
2822         &position->destroy);
2823
2824     position->set.notify = position_handle_set;
2825     ds_tizen_policy_position_add_set_listener(position->position,
2826         &position->set);
2827
2828     wl_list_insert(&policy_surface->positions, &position->link);
2829 }
2830
2831 static void
2832 policy_surface_handle_activate(struct wl_listener *listener, void *data)
2833 {
2834     struct tinyds_policy_surface *policy_surface;
2835
2836     policy_surface = wl_container_of(listener, policy_surface, activate);
2837
2838     ds_inf("Policy Info(%p) activate", policy_surface);
2839
2840     // TODO:
2841 }
2842
2843 static void
2844 policy_surface_handle_raise(struct wl_listener *listener, void *data)
2845 {
2846     struct tinyds_policy_surface *policy_surface;
2847
2848     policy_surface = wl_container_of(listener, policy_surface, raise);
2849
2850     ds_inf("Policy Info(%p) raise", policy_surface);
2851
2852     // TODO:
2853 }
2854
2855 static void
2856 policy_surface_handle_lower(struct wl_listener *listener, void *data)
2857 {
2858     struct tinyds_policy_surface *policy_surface;
2859
2860     policy_surface = wl_container_of(listener, policy_surface, raise);
2861
2862     ds_inf("Policy Info(%p) lower", policy_surface);
2863
2864     // TODO:
2865 }
2866
2867 static void
2868 policy_surface_handle_set_focus_skip(struct wl_listener *listener, void *data)
2869 {
2870     struct tinyds_policy_surface *policy_surface;
2871
2872     policy_surface = wl_container_of(listener, policy_surface, set_focus_skip);
2873
2874     ds_inf("Policy Info(%p) set_focus_skip", policy_surface);
2875
2876     // TODO:
2877 }
2878
2879 static void
2880 policy_surface_handle_unset_focus_skip(struct wl_listener *listener, void *data)
2881 {
2882     struct tinyds_policy_surface *policy_surface;
2883
2884     policy_surface = wl_container_of(listener, policy_surface, unset_focus_skip);
2885
2886     ds_inf("Policy Info(%p) unset_focus_skip", policy_surface);
2887
2888     // TODO:
2889 }
2890
2891 static void
2892 policy_surface_handle_set_role(struct wl_listener *listener, void *data)
2893 {
2894     struct tinyds_policy_surface *policy_surface;
2895
2896     policy_surface = wl_container_of(listener, policy_surface, set_role);
2897
2898     ds_inf("Policy Info(%p) set_role", policy_surface);
2899
2900     // TODO:
2901 }
2902
2903 static void
2904 policy_surface_handle_set_window_type(struct wl_listener *listener, void *data)
2905 {
2906     struct tinyds_policy_surface *policy_surface;
2907
2908     policy_surface = wl_container_of(listener, policy_surface, set_window_type);
2909
2910     ds_inf("Policy Info(%p) set_window_type", policy_surface);
2911
2912     // TODO:
2913 }
2914
2915 static void
2916 policy_surface_handle_set_conformant(struct wl_listener *listener, void *data)
2917 {
2918     struct tinyds_policy_surface *policy_surface;
2919
2920     policy_surface = wl_container_of(listener, policy_surface, set_conformant);
2921
2922     ds_inf("Policy Info(%p) set_conformant", policy_surface);
2923
2924     // TODO:
2925 }
2926
2927 static void
2928 policy_surface_handle_unset_conformant(struct wl_listener *listener, void *data)
2929 {
2930     struct tinyds_policy_surface *policy_surface;
2931
2932     policy_surface = wl_container_of(listener, policy_surface, unset_conformant);
2933
2934     ds_inf("Policy Info(%p) unset_conformant", policy_surface);
2935
2936     // TODO:
2937 }
2938
2939 static void
2940 policy_surface_handle_get_conformant(struct wl_listener *listener, void *data)
2941 {
2942     struct tinyds_policy_surface *policy_surface;
2943
2944     policy_surface = wl_container_of(listener, policy_surface, get_conformant);
2945
2946     ds_inf("Policy Info(%p) get_conformant", policy_surface);
2947
2948     // TODO:
2949 }
2950
2951 static void
2952 policy_surface_handle_set_notification_level(struct wl_listener *listener, void *data)
2953 {
2954     struct tinyds_policy_surface *policy_surface;
2955
2956     policy_surface = wl_container_of(listener, policy_surface, set_notification_level);
2957
2958     ds_inf("Policy Info(%p) set_notification_level", policy_surface);
2959
2960     // TODO:
2961 }
2962
2963 static void
2964 policy_surface_handle_set_window_screen_mode(struct wl_listener *listener, void *data)
2965 {
2966     struct tinyds_policy_surface *policy_surface;
2967
2968     policy_surface = wl_container_of(listener, policy_surface, set_window_screen_mode);
2969
2970     ds_inf("Policy Info(%p) set_window_screen_mode", policy_surface);
2971
2972     // TODO:
2973 }
2974
2975 static void
2976 policy_surface_handle_get_subsurface(struct wl_listener *listener, void *data)
2977 {
2978     struct tinyds_policy_surface *policy_surface;
2979
2980     policy_surface = wl_container_of(listener, policy_surface, get_subsurface);
2981
2982     ds_inf("Policy Info(%p) get_subsurface", policy_surface);
2983
2984     // TODO:
2985 }
2986
2987 static void
2988 policy_surface_handle_iconify(struct wl_listener *listener, void *data)
2989 {
2990     struct tinyds_policy_surface *policy_surface;
2991
2992     policy_surface = wl_container_of(listener, policy_surface, iconify);
2993
2994     ds_inf("Policy Info(%p) iconify", policy_surface);
2995
2996     // TODO:
2997 }
2998
2999 static void
3000 policy_surface_handle_uniconify(struct wl_listener *listener, void *data)
3001 {
3002     struct tinyds_policy_surface *policy_surface;
3003
3004     policy_surface = wl_container_of(listener, policy_surface, uniconify);
3005
3006     ds_inf("Policy Info(%p) uniconify", policy_surface);
3007
3008     // TODO:
3009 }
3010
3011 static void
3012 policy_surface_handle_add_aux_hint(struct wl_listener *listener, void *data)
3013 {
3014     struct tinyds_policy_surface *policy_surface;
3015
3016     policy_surface = wl_container_of(listener, policy_surface, add_aux_hint);
3017
3018     ds_inf("Policy Info(%p) add_aux_hint", policy_surface);
3019
3020     // TODO:
3021 }
3022
3023 static void
3024 policy_surface_handle_change_aux_hint(struct wl_listener *listener, void *data)
3025 {
3026     struct tinyds_policy_surface *policy_surface;
3027
3028     policy_surface = wl_container_of(listener, policy_surface, change_aux_hint);
3029
3030     ds_inf("Policy Info(%p) change_aux_hint", policy_surface);
3031
3032     // TODO:
3033 }
3034
3035 static void
3036 policy_surface_handle_delete_aux_hint(struct wl_listener *listener, void *data)
3037 {
3038     struct tinyds_policy_surface *policy_surface;
3039
3040     policy_surface = wl_container_of(listener, policy_surface, delete_aux_hint);
3041
3042     ds_inf("Policy Info(%p) delete_aux_hint", policy_surface);
3043
3044     // TODO:
3045 }
3046
3047 static void
3048 policy_surface_handle_get_supported_aux_hints(struct wl_listener *listener, void *data)
3049 {
3050     struct tinyds_policy_surface *policy_surface;
3051
3052     policy_surface = wl_container_of(listener, policy_surface, get_supported_aux_hints);
3053
3054     ds_inf("Policy Info(%p) get_supported_aux_hints", policy_surface);
3055
3056     // TODO:
3057 }
3058
3059 static void
3060 policy_surface_handle_set_floating_mode(struct wl_listener *listener, void *data)
3061 {
3062     struct tinyds_policy_surface *policy_surface;
3063
3064     policy_surface = wl_container_of(listener, policy_surface, set_floating_mode);
3065
3066     ds_inf("Policy Info(%p) set_floating_mode", policy_surface);
3067
3068     // TODO:
3069 }
3070
3071 static void
3072 policy_surface_handle_unset_floating_mode(struct wl_listener *listener, void *data)
3073 {
3074     struct tinyds_policy_surface *policy_surface;
3075
3076     policy_surface = wl_container_of(listener, policy_surface, unset_floating_mode);
3077
3078     ds_inf("Policy Info(%p) unset_floating_mode", policy_surface);
3079
3080     // TODO:
3081 }
3082
3083 static void
3084 policy_surface_handle_set_stack_mode(struct wl_listener *listener, void *data)
3085 {
3086     struct tinyds_policy_surface *policy_surface;
3087
3088     policy_surface = wl_container_of(listener, policy_surface, set_stack_mode);
3089
3090     ds_inf("Policy Info(%p) set_stack_mode", policy_surface);
3091
3092     // TODO:
3093 }
3094
3095 static void
3096 policy_surface_handle_new_subsurface_watcher(struct wl_listener *listener, void *data)
3097 {
3098     struct tinyds_policy_surface *policy_surface;
3099     struct tinyds_policy_subsurface_watcher*subsurface_watcher;
3100     struct ds_tizen_event_policy_surface_new_subsurface_watcher *event;
3101
3102     policy_surface = wl_container_of(listener, policy_surface, new_subsurface_watcher);
3103     event = (struct ds_tizen_event_policy_surface_new_subsurface_watcher *)data;
3104
3105     ds_inf("Policy Info(%p) new_subsurface_watcher", policy_surface);
3106
3107     subsurface_watcher = calloc(1, sizeof *subsurface_watcher);
3108     if (!subsurface_watcher)
3109         return;
3110
3111     subsurface_watcher->subsurface_watcher = event->subsurface_watcher;
3112
3113     subsurface_watcher->destroy.notify = subsurface_watcher_handle_destroy;
3114     ds_tizen_policy_subsurface_watcher_add_destroy_listener(subsurface_watcher->subsurface_watcher,
3115         &subsurface_watcher->destroy);
3116
3117     wl_list_insert(&policy_surface->subsurface_watchers, &subsurface_watcher->link);
3118 }
3119
3120 static void
3121 policy_surface_handle_set_parent(struct wl_listener *listener, void *data)
3122 {
3123     struct tinyds_policy_surface *policy_surface;
3124
3125     policy_surface = wl_container_of(listener, policy_surface, set_parent);
3126
3127     ds_inf("Policy Info(%p) set_parent", policy_surface);
3128
3129     // TODO:
3130 }
3131
3132 static void
3133 policy_surface_handle_ack_conformant_region(struct wl_listener *listener, void *data)
3134 {
3135     struct tinyds_policy_surface *policy_surface;
3136
3137     policy_surface = wl_container_of(listener, policy_surface, ack_conformant_region);
3138
3139     ds_inf("Policy Info(%p) ack_conformant_region", policy_surface);
3140
3141     // TODO:
3142 }
3143
3144 static void
3145 policy_surface_handle_set_video(struct wl_listener *listener, void *data)
3146 {
3147     struct tinyds_policy_surface *policy_surface;
3148
3149     policy_surface = wl_container_of(listener, policy_surface, set_video);
3150
3151     ds_inf("Policy Info(%p) set_video", policy_surface);
3152
3153     // TODO:
3154 }
3155
3156 static void
3157 policy_surface_handle_show(struct wl_listener *listener, void *data)
3158 {
3159     struct tinyds_policy_surface *policy_surface;
3160
3161     policy_surface = wl_container_of(listener, policy_surface, show);
3162
3163     ds_inf("Policy Info(%p) show", policy_surface);
3164
3165     // TODO:
3166 }
3167
3168 static void
3169 policy_surface_handle_hide(struct wl_listener *listener, void *data)
3170 {
3171     struct tinyds_policy_surface *policy_surface;
3172
3173     policy_surface = wl_container_of(listener, policy_surface, hide);
3174
3175     ds_inf("Policy Info(%p) hide", policy_surface);
3176
3177     // TODO:
3178 }
3179
3180 static void
3181 policy_surface_handle_set_parent_with_below(struct wl_listener *listener, void *data)
3182 {
3183     struct tinyds_policy_surface *policy_surface;
3184
3185     policy_surface = wl_container_of(listener, policy_surface, set_parent_with_below);
3186
3187     ds_inf("Policy Info(%p) set_parent_with_below", policy_surface);
3188
3189     // TODO:
3190 }
3191
3192 static void
3193 policy_handle_destroy(struct wl_listener *listener, void *data)
3194 {
3195     struct tinyds_policy *policy;
3196
3197     policy = wl_container_of(listener, policy, destroy);
3198
3199     ds_inf("Policy(%p) destroy", policy);
3200
3201     wl_list_remove(&policy->destroy.link);
3202     wl_list_remove(&policy->new_surface.link);
3203     wl_list_remove(&policy->activate_below_by_univeral_id.link);
3204     wl_list_remove(&policy->lower_by_universal_id.link);
3205     wl_list_remove(&policy->set_transient_for.link);
3206     wl_list_remove(&policy->unset_transient_for.link);
3207     wl_list_remove(&policy->place_subsurface_below_parent.link);
3208     wl_list_remove(&policy->set_subsurface_stand_alone.link);
3209     wl_list_remove(&policy->set_background_state.link);
3210     wl_list_remove(&policy->unset_background_state.link);
3211     wl_list_remove(&policy->add_activate_above_by_universal_id.link);
3212     wl_list_remove(&policy->set_appid.link);
3213     wl_list_remove(&policy->set_transient_for_below.link);
3214
3215     free(policy);
3216 }
3217
3218 static void
3219 policy_handle_new_surface(struct wl_listener *listener, void *data)
3220 {
3221     struct tinyds_policy *policy;
3222     struct tinyds_policy_surface *policy_surface;
3223     struct ds_tizen_event_policy_new_surface *event;
3224
3225     policy = wl_container_of(listener, policy, new_surface);
3226     event = (struct ds_tizen_event_policy_new_surface *)data;
3227
3228     ds_inf("Policy(%p) new_surface", policy);
3229
3230     policy_surface = calloc(1, sizeof *policy_surface);
3231     if (!policy_surface)
3232         return;
3233
3234     policy_surface->policy_surface = event->policy_surface;
3235
3236     policy_surface->destroy.notify = policy_surface_handle_destroy;
3237     ds_tizen_policy_surface_add_destroy_listener(policy_surface->policy_surface,
3238         &policy_surface->destroy);
3239
3240     policy_surface->new_visibility.notify = policy_surface_handle_new_visibility;
3241     ds_tizen_policy_surface_add_new_visibility_listener(policy_surface->policy_surface,
3242         &policy_surface->new_visibility);
3243
3244     policy_surface->new_position.notify = policy_surface_handle_new_position;
3245     ds_tizen_policy_surface_add_new_position_listener(policy_surface->policy_surface,
3246         &policy_surface->new_position);
3247
3248     policy_surface->activate.notify = policy_surface_handle_activate;
3249     ds_tizen_policy_surface_add_activate_listener(policy_surface->policy_surface,
3250         &policy_surface->activate);
3251
3252     policy_surface->raise.notify = policy_surface_handle_raise;
3253     ds_tizen_policy_surface_add_raise_listener(policy_surface->policy_surface,
3254         &policy_surface->raise);
3255
3256     policy_surface->lower.notify = policy_surface_handle_lower;
3257     ds_tizen_policy_surface_add_lower_listener(policy_surface->policy_surface,
3258         &policy_surface->lower);
3259
3260     policy_surface->set_focus_skip.notify = policy_surface_handle_set_focus_skip;
3261     ds_tizen_policy_surface_add_set_focus_skip_listener(policy_surface->policy_surface,
3262         &policy_surface->set_focus_skip);
3263
3264     policy_surface->unset_focus_skip.notify = policy_surface_handle_unset_focus_skip;
3265     ds_tizen_policy_surface_add_unset_focus_skip_listener(policy_surface->policy_surface,
3266         &policy_surface->unset_focus_skip);
3267
3268     policy_surface->set_role.notify = policy_surface_handle_set_role;
3269     ds_tizen_policy_surface_add_set_role_listener(policy_surface->policy_surface,
3270         &policy_surface->set_role);
3271
3272     policy_surface->set_window_type.notify = policy_surface_handle_set_window_type;
3273     ds_tizen_policy_surface_add_set_window_type_listener(policy_surface->policy_surface,
3274         &policy_surface->set_window_type);
3275
3276     policy_surface->set_conformant.notify = policy_surface_handle_set_conformant;
3277     ds_tizen_policy_surface_add_set_conformant_listener(policy_surface->policy_surface,
3278         &policy_surface->set_conformant);
3279
3280     policy_surface->unset_conformant.notify = policy_surface_handle_unset_conformant;
3281     ds_tizen_policy_surface_add_unset_conformant_listener(policy_surface->policy_surface,
3282         &policy_surface->unset_conformant);
3283
3284     policy_surface->get_conformant.notify = policy_surface_handle_get_conformant;
3285     ds_tizen_policy_surface_add_get_conformant_listener(policy_surface->policy_surface,
3286         &policy_surface->get_conformant);
3287
3288     policy_surface->set_notification_level.notify =
3289         policy_surface_handle_set_notification_level;
3290     ds_tizen_policy_surface_add_set_notification_level_listener(
3291             policy_surface->policy_surface, &policy_surface->set_notification_level);
3292
3293     policy_surface->set_window_screen_mode.notify =
3294         policy_surface_handle_set_window_screen_mode;
3295     ds_tizen_policy_surface_add_set_window_screen_mode_listener(
3296         policy_surface->policy_surface, &policy_surface->set_window_screen_mode);
3297
3298     policy_surface->get_subsurface.notify = policy_surface_handle_get_subsurface;
3299     ds_tizen_policy_surface_add_get_subsurface_listener(policy_surface->policy_surface,
3300         &policy_surface->get_subsurface);
3301
3302     policy_surface->iconify.notify = policy_surface_handle_iconify;
3303     ds_tizen_policy_surface_add_iconify_listener(policy_surface->policy_surface,
3304         &policy_surface->iconify);
3305
3306     policy_surface->uniconify.notify = policy_surface_handle_uniconify;
3307     ds_tizen_policy_surface_add_uniconify_listener(policy_surface->policy_surface,
3308         &policy_surface->uniconify);
3309
3310     policy_surface->add_aux_hint.notify = policy_surface_handle_add_aux_hint;
3311     ds_tizen_policy_surface_add_add_aux_hint_listener(policy_surface->policy_surface,
3312         &policy_surface->add_aux_hint);
3313
3314     policy_surface->change_aux_hint.notify = policy_surface_handle_change_aux_hint;
3315     ds_tizen_policy_surface_add_change_aux_hint_listener(policy_surface->policy_surface,
3316         &policy_surface->change_aux_hint);
3317
3318     policy_surface->delete_aux_hint.notify = policy_surface_handle_delete_aux_hint;
3319     ds_tizen_policy_surface_add_delete_aux_hint_listener(policy_surface->policy_surface,
3320         &policy_surface->delete_aux_hint);
3321
3322     policy_surface->get_supported_aux_hints.notify =
3323         policy_surface_handle_get_supported_aux_hints;
3324     ds_tizen_policy_surface_add_get_supported_aux_hints_listener(
3325         policy_surface->policy_surface, &policy_surface->get_supported_aux_hints);
3326
3327     policy_surface->set_floating_mode.notify =
3328         policy_surface_handle_set_floating_mode;
3329     ds_tizen_policy_surface_add_set_floating_mode_listener(
3330         policy_surface->policy_surface, &policy_surface->set_floating_mode);
3331
3332     policy_surface->unset_floating_mode.notify =
3333         policy_surface_handle_unset_floating_mode;
3334     ds_tizen_policy_surface_add_unset_floating_mode_listener(
3335         policy_surface->policy_surface, &policy_surface->unset_floating_mode);
3336
3337     policy_surface->set_stack_mode.notify = policy_surface_handle_set_stack_mode;
3338     ds_tizen_policy_surface_add_set_stack_mode_listener(policy_surface->policy_surface,
3339         &policy_surface->set_stack_mode);
3340
3341     policy_surface->new_subsurface_watcher.notify =
3342         policy_surface_handle_new_subsurface_watcher;
3343     ds_tizen_policy_surface_add_new_subsurface_watcher_listener(
3344         policy_surface->policy_surface, &policy_surface->new_subsurface_watcher);
3345
3346     policy_surface->set_parent.notify = policy_surface_handle_set_parent;
3347     ds_tizen_policy_surface_add_set_parent_listener(policy_surface->policy_surface,
3348         &policy_surface->set_parent);
3349
3350     policy_surface->ack_conformant_region.notify =
3351         policy_surface_handle_ack_conformant_region;
3352     ds_tizen_policy_surface_add_ack_conformant_region_listener(
3353         policy_surface->policy_surface, &policy_surface->ack_conformant_region);
3354
3355     policy_surface->set_video.notify = policy_surface_handle_set_video;
3356     ds_tizen_policy_surface_add_set_video_listener(policy_surface->policy_surface,
3357         &policy_surface->set_video);
3358
3359     policy_surface->show.notify = policy_surface_handle_show;
3360     ds_tizen_policy_surface_add_show_listener(policy_surface->policy_surface,
3361         &policy_surface->show);
3362
3363     policy_surface->hide.notify = policy_surface_handle_hide;
3364     ds_tizen_policy_surface_add_hide_listener(policy_surface->policy_surface,
3365         &policy_surface->hide);
3366
3367     policy_surface->set_parent_with_below.notify =
3368         policy_surface_handle_set_parent_with_below;
3369     ds_tizen_policy_surface_add_set_parent_with_below_listener(
3370             policy_surface->policy_surface, &policy_surface->set_parent_with_below);
3371
3372
3373     wl_list_init(&policy_surface->visibilities);
3374     wl_list_init(&policy_surface->positions);
3375     wl_list_init(&policy_surface->subsurface_watchers);
3376
3377     wl_list_insert(&policy->policy_surfaces, &policy_surface->link);
3378 }
3379
3380 static void
3381 policy_handle_activate_below_by_univeral_id(struct wl_listener *listener, void *data)
3382 {
3383     struct tinyds_policy *policy;
3384
3385     policy = wl_container_of(listener, policy, activate_below_by_univeral_id);
3386
3387     ds_inf("Policy(%p) activate_below_by_univeral_id", policy);
3388
3389     // TODO:
3390 }
3391
3392 static void
3393 policy_handle_lower_by_universal_id(struct wl_listener *listener, void *data)
3394 {
3395     struct tinyds_policy *policy;
3396
3397     policy = wl_container_of(listener, policy, lower_by_universal_id);
3398
3399     ds_inf("Policy(%p) lower_by_universal_id", policy);
3400
3401     // TODO:
3402 }
3403
3404 static void
3405 policy_handle_set_transient_for(struct wl_listener *listener, void *data)
3406 {
3407     struct tinyds_policy *policy;
3408
3409     policy = wl_container_of(listener, policy, set_transient_for);
3410
3411     ds_inf("Policy(%p) set_transient_for", policy);
3412
3413     // TODO:
3414 }
3415
3416 static void
3417 policy_handle_unset_transient_for(struct wl_listener *listener, void *data)
3418 {
3419     struct tinyds_policy *policy;
3420
3421     policy = wl_container_of(listener, policy, unset_transient_for);
3422
3423     ds_inf("Policy(%p) unset_transient_for", policy);
3424
3425     // TODO:
3426 }
3427
3428 static void
3429 policy_handle_place_subsurface_below_parent(struct wl_listener *listener, void *data)
3430 {
3431     struct tinyds_policy *policy;
3432
3433     policy = wl_container_of(listener, policy, place_subsurface_below_parent);
3434
3435     ds_inf("Policy(%p) place_subsurface_below_parent", policy);
3436
3437     // TODO:
3438 }
3439
3440 static void
3441 policy_handle_set_subsurface_stand_alone(struct wl_listener *listener, void *data)
3442 {
3443     struct tinyds_policy *policy;
3444
3445     policy = wl_container_of(listener, policy, set_subsurface_stand_alone);
3446
3447     ds_inf("Policy(%p) set_subsurface_stand_alone", policy);
3448
3449     // TODO:
3450 }
3451
3452 static void
3453 policy_handle_set_background_state(struct wl_listener *listener, void *data)
3454 {
3455     struct tinyds_policy *policy;
3456
3457     policy = wl_container_of(listener, policy, set_background_state);
3458
3459     ds_inf("Policy(%p) set_background_state", policy);
3460
3461     // TODO:
3462 }
3463
3464 static void
3465 policy_handle_unset_background_state(struct wl_listener *listener, void *data)
3466 {
3467     struct tinyds_policy *policy;
3468
3469     policy = wl_container_of(listener, policy, unset_background_state);
3470
3471     ds_inf("Policy(%p) unset_background_state", policy);
3472
3473     // TODO:
3474 }
3475
3476 static void
3477 policy_handle_add_activate_above_by_universal_id(struct wl_listener *listener, void *data)
3478 {
3479     struct tinyds_policy *policy;
3480
3481     policy = wl_container_of(listener, policy, add_activate_above_by_universal_id);
3482
3483     ds_inf("Policy(%p) add_activate_above_by_universal_id", policy);
3484
3485     // TODO:
3486 }
3487
3488 static void
3489 policy_handle_set_appid(struct wl_listener *listener, void *data)
3490 {
3491     struct tinyds_policy *policy;
3492
3493     policy = wl_container_of(listener, policy, set_appid);
3494
3495     ds_inf("Policy(%p) set_appid", policy);
3496
3497     // TODO:
3498 }
3499
3500 static void
3501 policy_handle_set_transient_for_below(struct wl_listener *listener, void *data)
3502 {
3503     struct tinyds_policy *policy;
3504
3505     policy = wl_container_of(listener, policy, set_transient_for_below);
3506
3507     ds_inf("Policy(%p) set_transient_for_below", policy);
3508
3509     // TODO:
3510 }
3511
3512 static bool
3513 new_policy(struct tinyds_server *server)
3514 {
3515     struct tinyds_policy *policy;
3516
3517     policy = calloc(1, sizeof *policy);
3518     if (!policy)
3519         return false;
3520
3521     policy->policy = ds_tizen_policy_create(server->display);
3522     if (!policy->policy) {
3523         free(policy);
3524         ds_err("Could not create ds_tizen_policy");
3525         return false;
3526     }
3527
3528     policy->destroy.notify = policy_handle_destroy;
3529     ds_tizen_policy_add_destroy_listener(policy->policy, &policy->destroy);
3530
3531     policy->new_surface.notify = policy_handle_new_surface;
3532     ds_tizen_policy_add_new_surface_listener(policy->policy, &policy->new_surface);
3533
3534     policy->activate_below_by_univeral_id.notify =
3535         policy_handle_activate_below_by_univeral_id;
3536     ds_tizen_policy_add_activate_below_by_univeral_id_listener(policy->policy,
3537         &policy->activate_below_by_univeral_id);
3538
3539     policy->lower_by_universal_id.notify = policy_handle_lower_by_universal_id;
3540     ds_tizen_policy_add_lower_by_universal_id_listener(policy->policy,
3541         &policy->lower_by_universal_id);
3542
3543     policy->set_transient_for.notify = policy_handle_set_transient_for;
3544     ds_tizen_policy_add_set_transient_for_listener(policy->policy,
3545         &policy->set_transient_for);
3546
3547     policy->unset_transient_for.notify = policy_handle_unset_transient_for;
3548     ds_tizen_policy_add_unset_transient_for_listener(policy->policy,
3549         &policy->unset_transient_for);
3550
3551     policy->place_subsurface_below_parent.notify =
3552         policy_handle_place_subsurface_below_parent;
3553     ds_tizen_policy_add_place_subsurface_below_parent_listener(policy->policy,
3554         &policy->place_subsurface_below_parent);
3555
3556     policy->set_subsurface_stand_alone.notify =
3557         policy_handle_set_subsurface_stand_alone;
3558     ds_tizen_policy_add_set_subsurface_stand_alone_listener(policy->policy,
3559         &policy->set_subsurface_stand_alone);
3560
3561     policy->set_background_state.notify = policy_handle_set_background_state;
3562     ds_tizen_policy_add_set_background_state_listener(policy->policy,
3563         &policy->set_background_state);
3564
3565     policy->unset_background_state.notify = policy_handle_unset_background_state;
3566     ds_tizen_policy_add_unset_background_state_listener(policy->policy,
3567         &policy->unset_background_state);
3568
3569     policy->add_activate_above_by_universal_id.notify =
3570         policy_handle_add_activate_above_by_universal_id;
3571     ds_tizen_policy_add_activate_above_by_universal_id_listener(policy->policy,
3572         &policy->add_activate_above_by_universal_id);
3573
3574     policy->set_appid.notify = policy_handle_set_appid;
3575     ds_tizen_policy_add_set_appid_listener(policy->policy, &policy->set_appid);
3576
3577     policy->set_transient_for_below.notify =
3578         policy_handle_set_transient_for_below;
3579     ds_tizen_policy_add_set_transient_for_below_listener(policy->policy,
3580         &policy->set_transient_for_below);
3581
3582     wl_list_init(&policy->policy_surfaces);
3583
3584     server->policy = policy;
3585
3586     ds_inf("Policy (%p) created", policy);
3587
3588     return true;
3589 }