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