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