tinyds: fix the SVACE issue
[platform/core/uifw/libds-tizen.git] / examples / tinyds-tdm.c
1 #include "tinyds-tdm.h"
2
3 struct tinyds_output
4 {
5     struct tinyds_server *server;
6     struct ds_output *ds_output;
7     struct ds_allocator *allocator;
8 #ifdef USE_TDM_BUFFER_QUEUE
9     struct tinyds_renderer renderer;
10     struct ds_tdm_buffer_queue *buffer_queue;
11     struct wl_listener buffer_queue_acquirable;
12 #else
13     struct ds_swapchain *swapchain;
14 #endif
15     struct ds_buffer *front_buffer;
16
17     struct wl_listener output_destroy;
18     struct wl_listener output_frame;
19
20     int width, height;
21
22     struct wl_event_source *idle_commit;
23     bool committable;
24     bool damaged;
25     bool target_updated;
26
27     struct ds_tdm_output_hwc *hwc;
28     struct ds_tdm_output_hwc_window *bg_hwc_window;
29
30 #ifdef USE_CURSOR
31     bool cursor_enabled;
32     struct ds_tdm_output_hwc_window *cursor_hwc_window;
33 #endif
34 };
35
36 struct tinyds_pointer
37 {
38     struct ds_input_device *dev;
39     struct tinyds_server *server;
40
41     struct tinyds_view *focused_view;
42
43     struct wl_listener destroy;
44     struct wl_listener motion; //relative
45     struct wl_listener button;
46     struct wl_listener frame;
47     struct wl_list link; //tinyds_server::pointers
48 };
49
50 struct tinyds_keyboard
51 {
52     struct ds_input_device *dev;
53     struct tinyds_server *server;
54
55     struct wl_listener destroy;
56     struct wl_listener key;
57     struct wl_list link; //tinyds_server::keyboards
58 };
59
60 struct tinyds_touch
61 {
62     struct ds_input_device *dev;
63     struct tinyds_server *server;
64
65     struct wl_listener destroy;
66     struct wl_listener down;
67     struct wl_listener up;
68     struct wl_listener motion;
69 };
70
71 struct tinyds_text_input {
72     struct ds_tizen_text_input *input;
73     struct ds_tizen_text_input_manager *text_input_mgr;
74
75     struct tinyds_server *server;
76     struct ds_surface *surface;
77
78     struct wl_list input_methods;
79
80     struct wl_listener mgr_destroy;
81     struct wl_listener new_text_input;
82
83     struct wl_listener destroy;
84     struct wl_listener text_input_activate;
85     struct wl_listener text_input_deactivate;
86     struct wl_listener text_input_reset;
87     struct wl_listener text_input_set_content_type;
88     struct wl_listener text_input_invoke_action;
89     struct wl_listener text_input_commit_state;
90     struct wl_listener text_input_set_preferred_language;
91 };
92
93 struct tinyds_input_method {
94     struct ds_tizen_input_method *input_method;
95     struct ds_tizen_input_method_manager *input_method_mgr;
96
97     struct tinyds_server *server;
98     struct tinyds_text_input *input;
99     struct tinyds_input_method_context *context;
100
101     struct wl_list link;
102
103     struct wl_listener destroy;
104     struct wl_listener mgr_destroy;
105 };
106
107 struct tinyds_input_method_context {
108     struct ds_tizen_input_method_context *context;
109
110     struct tinyds_server *server;
111     struct tinyds_text_input *input;
112     struct tinyds_input_method *input_method;
113
114     struct wl_listener destroy;
115
116     struct wl_listener im_context_commit_string;
117     struct wl_listener im_context_preedit_string;
118     struct wl_listener im_context_preedit_styling;
119     struct wl_listener im_context_preedit_cursor;
120     struct wl_listener im_context_delete_surrounding_text;
121     struct wl_listener im_context_cursor_position;
122     struct wl_listener im_context_modifiers_map;
123     struct wl_listener im_context_keysym;
124     struct wl_listener im_context_grab_keyboard;
125     struct wl_listener im_context_key;
126     struct wl_listener im_context_modifiers;
127     struct wl_listener im_context_language;
128     struct wl_listener im_context_text_direction;
129 };
130
131 struct tinyds_server tinyds;
132
133 static bool init_server(struct tinyds_server *server, struct wl_display *display);
134 static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
135 static void output_handle_destroy(struct wl_listener *listener, void *data);
136 static void output_handle_frame(struct wl_listener *listener, void *data);
137 static void draw_server_with_damage(struct tinyds_server *server);
138 static void draw_output(struct tinyds_output *output);
139 static void output_swap_buffer(struct tinyds_output *output,
140         struct ds_buffer *buffer);
141 static void view_send_frame_done(struct tinyds_view *view);
142 static void output_hwc_init(struct tinyds_output *output);
143 static void output_schedule_commit(struct tinyds_output *output);
144 static void output_commit(struct tinyds_output *output);
145 #ifdef USE_TDM_BUFFER_QUEUE
146 static void output_buffer_queue_init(struct tinyds_output *output);
147 static void output_renderer_init(struct tinyds_output *output);
148 static void output_draw_with_renderer(struct tinyds_output *output);
149 #else
150 static void output_swapchain_init(struct tinyds_output *output,
151         int width, int height, uint32_t format);
152 static void output_draw_with_swapchain(struct tinyds_output *output);
153 static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
154 #endif
155 static void server_add_keyboard(struct tinyds_server *server,
156         struct ds_input_device *dev);
157 static void server_add_pointer(struct tinyds_server *server,
158         struct ds_input_device *dev);
159 static void server_add_touch(struct tinyds_server *server,
160         struct ds_input_device *dev);
161 static bool add_new_text_input(struct tinyds_server *server);
162 static bool add_new_input_method(struct tinyds_server *server);
163 static bool add_new_input_method_context(
164         struct tinyds_input_method *input_method,
165         struct tinyds_text_input *text_input);
166
167 static void text_input_mgr_handle_destroy(struct wl_listener *listener,
168         void *data TINYDS_UNUSED);
169 static void text_input_mgr_handle_new_text_input(struct wl_listener *listener,
170         void *data TINYDS_UNUSED);
171
172 static void input_method_mgr_handle_destroy(struct wl_listener *listener,
173         void *data TINYDS_UNUSED);
174
175 static void input_method_handle_destroy(struct wl_listener *listener,
176         void *data TINYDS_UNUSED);
177
178 int
179 main(void)
180 {
181     struct tinyds_server *server = &tinyds;
182     struct wl_display *display;
183     struct wl_event_loop *loop;
184     const char *socket;
185     bool res;
186
187     ds_log_init(DS_INF, NULL);
188
189     display = wl_display_create();
190     assert(display);
191
192     res = init_server(server, display);
193     assert(res);
194
195     socket = wl_display_add_socket_auto(display);
196     assert(socket);
197
198     ds_backend_start(server->backend);
199     ds_backend_start(server->input_backend);
200
201     setenv("WAYLAND_DISPLAY", socket, true);
202
203     ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
204
205     loop = wl_display_get_event_loop(display);
206     server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
207             WL_EVENT_READABLE, server_dispatch_stdin, server);
208
209     wl_display_run(display);
210
211     protocol_trace_enable(false);
212     protocol_trace_fini();
213
214     wl_display_destroy_clients(display);
215     wl_display_destroy(display);
216
217     return 0;
218 }
219
220 static void
221 view_populate_pid(struct tinyds_view *view)
222 {
223     struct ds_surface *surface;
224     struct wl_client *client = NULL;
225     pid_t pid;
226
227     surface = ds_xdg_surface_get_surface(view->xdg_surface);
228     if (!surface)
229         return;
230
231     client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
232     if (!client)
233         return;
234
235     wl_client_get_credentials(client, &pid, NULL, NULL);
236     view->pid = pid;
237
238     ds_inf("view pid(%u)", pid);
239
240     view->effect_type = tinyds_launch_get_effect_type(
241             view->server->launch, pid);
242     tinyds_launch_unset_effect_type(view->server->launch, pid);
243
244     ds_inf("view effect_type(%d)", view->effect_type);
245 }
246
247 static void
248 view_handle_xdg_surface_map(struct wl_listener *listener,
249         void *data TINYDS_UNUSED)
250 {
251     struct tinyds_view *view;
252     struct ds_keyboard *keyboard;
253     struct tinyds_keyboard *kbd;
254
255     view = wl_container_of(listener, view, xdg_surface_map);
256     view->mapped = true;
257
258     view_populate_pid(view);
259
260     wl_list_for_each(kbd, &view->server->keyboards, link) {
261         keyboard = ds_input_device_get_keyboard(kbd->dev);
262         if (keyboard != NULL) {
263             ds_seat_keyboard_notify_enter(view->server->seat,
264                     ds_xdg_surface_get_surface(view->xdg_surface),
265                     keyboard->keycodes, keyboard->num_keycodes,
266                     &keyboard->modifiers);
267             return;
268         }
269     }
270 }
271
272 static void
273 view_handle_xdg_surface_unmap(struct wl_listener *listener,
274         void *data TINYDS_UNUSED)
275 {
276     struct tinyds_view *view;
277
278     view = wl_container_of(listener, view, xdg_surface_unmap);
279     view->mapped = false;
280 }
281
282 static void
283 view_handle_xdg_surface_destroy(struct wl_listener *listener,
284         void *data TINYDS_UNUSED) 
285 {
286     struct tinyds_view *view;
287
288     view = wl_container_of(listener, view, xdg_surface_destroy);
289
290     draw_server_with_damage(view->server);
291
292     ds_tdm_output_hwc_window_destroy(view->hwc_window);
293
294     wl_list_remove(&view->xdg_surface_destroy.link);
295     wl_list_remove(&view->xdg_surface_map.link);
296     wl_list_remove(&view->xdg_surface_unmap.link);
297     wl_list_remove(&view->surface_commit.link);
298     wl_list_remove(&view->link);
299     free(view);
300 }
301
302 static void
303 view_handle_surface_commit(struct wl_listener *listener,
304         void *data TINYDS_UNUSED)
305 {
306     struct tinyds_view *view;
307
308     view = wl_container_of(listener, view, surface_commit);
309     draw_server_with_damage(view->server);
310 }
311
312 static void
313 server_new_xdg_surface(struct wl_listener *listener, void *data)
314 {
315     static unsigned int seedx = 1;
316     static unsigned int seedy = 43210;
317     struct tinyds_server *server;
318     struct tinyds_view *view;
319     struct ds_xdg_surface *xdg_surface;
320
321     server = wl_container_of(listener, server, new_xdg_surface);
322     xdg_surface = data;
323
324     ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
325
326     view = calloc(1, sizeof *view);
327     assert(view);
328
329     view->server = server;
330     view->xdg_surface = xdg_surface;
331
332     view->xdg_surface_map.notify = view_handle_xdg_surface_map;
333     ds_xdg_surface_add_map_listener(xdg_surface,
334             &view->xdg_surface_map);
335
336     view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
337     ds_xdg_surface_add_unmap_listener(xdg_surface,
338             &view->xdg_surface_unmap);
339
340     view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
341     ds_xdg_surface_add_destroy_listener(xdg_surface,
342             &view->xdg_surface_destroy);
343
344     view->surface_commit.notify = view_handle_surface_commit;
345     ds_surface_add_commit_listener(
346             ds_xdg_surface_get_surface(xdg_surface),
347             &view->surface_commit);
348
349     view->x = rand_r(&seedx) % 1000;
350     view->y = rand_r(&seedy) % 500;
351
352     view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
353     assert(view->hwc_window);
354
355     wl_list_insert(server->views.prev, &view->link);
356
357     view->pid = 0;
358     view->effect_type = -1;
359
360     ds_inf("view at (%d, %d)", view->x, view->y);
361 }
362
363 static void
364 backend_handle_new_output(struct wl_listener *listener, void *data)
365 {
366     struct tinyds_server *server;
367     struct tinyds_output *output;
368     struct ds_output *ds_output;
369     const struct ds_output_mode *mode;
370     struct ds_tdm_box src_box;
371
372     server = wl_container_of(listener, server, new_output);
373     ds_output = data;
374
375     ds_inf("New output(%p)", ds_output);
376
377     if (server->output)
378         return;
379
380     mode = ds_output_get_preferred_mode(ds_output);
381     ds_output_set_mode(ds_output, mode);
382
383     output = calloc(1, sizeof *output);
384     if (!output)
385         return;
386
387     output->server = server;
388     output->ds_output = ds_output;
389     output->width = mode->width;
390     output->height = mode->height;
391     output->damaged = true;
392     output->committable = true;
393
394     output_hwc_init(output);
395
396 #ifdef USE_TDM_BUFFER_QUEUE
397     output_buffer_queue_init(output);
398     output_renderer_init(output);
399 #else
400     output_swapchain_init(output, mode->width, mode->height,
401             DRM_FORMAT_XRGB8888);
402 #endif
403
404     output->bg_hwc_window = ds_tdm_output_hwc_window_create(output->hwc);
405     assert(output->bg_hwc_window);
406
407     src_box.x = 0;
408     src_box.y = 0;
409     src_box.width = output->width;
410     src_box.height = output->height;
411
412     ds_tdm_output_hwc_window_set_src_box(output->bg_hwc_window, &src_box);
413     ds_tdm_output_hwc_window_set_position(output->bg_hwc_window, 0, 0);
414     ds_tdm_output_hwc_window_set_dest_size(output->bg_hwc_window, output->width, output->height);
415     ds_tdm_output_hwc_window_set_transform(output->bg_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
416
417 #ifdef USE_CURSOR
418     output->cursor_enabled = false;
419 #endif
420
421     output->output_destroy.notify = output_handle_destroy;
422     ds_output_add_destroy_listener(ds_output, &output->output_destroy);
423
424     output->output_frame.notify = output_handle_frame;
425     ds_output_add_frame_listener(ds_output, &output->output_frame);
426
427     tinyds_input_devicemgr_set_output_size(server->input_devicemgr, (uint32_t)output->width, (uint32_t)output->height);
428
429     server->output = output;
430     server->output_x = (double)(output->width) / 2;
431     server->output_y = (double)(output->height) / 2;
432
433     output_schedule_commit(output);
434 }
435
436 static void
437 backend_handle_new_input(struct wl_listener *listener, void *data)
438 {
439     struct tinyds_server *server;
440     struct ds_input_device *dev = data;
441     enum ds_input_device_type dev_type;
442
443     server = wl_container_of(listener, server, new_input);
444
445     dev_type = ds_input_device_get_type(dev);
446
447     switch (dev_type) {
448         case DS_INPUT_DEVICE_KEYBOARD:
449             server_add_keyboard(server, dev);
450             server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD;
451             break;
452         case DS_INPUT_DEVICE_TOUCH:
453             server_add_touch(server, dev);
454             server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH;
455             break;
456         case DS_INPUT_DEVICE_POINTER:
457             server_add_pointer(server, dev);
458             server->seat_caps |= WL_SEAT_CAPABILITY_POINTER;
459             break;
460         default:
461             ds_err("Unknown type(%d) of ds_input_device", dev_type);
462             break;
463     }
464
465     ds_seat_set_capabilities(server->seat, server->seat_caps);
466 }
467
468 static void
469 dpms_free_func(void *data)
470 {
471     struct tinyds_server *server = (struct tinyds_server *)data;
472
473     server->dpms = NULL;
474 }
475
476 static void
477 policy_free_func(void *data)
478 {
479     struct tinyds_server *server = (struct tinyds_server *)data;
480
481     server->policy = NULL;
482 }
483
484 static void
485 launch_free_func(void *data)
486 {
487     struct tinyds_server *server = (struct tinyds_server *)data;
488
489     server->launch = NULL;
490 }
491
492 static void
493 input_devicemgr_free_func(void *data)
494 {
495     struct tinyds_server *server = (struct tinyds_server *)data;
496
497     server->input_devicemgr = NULL;
498 }
499
500 static bool
501 init_server(struct tinyds_server *server, struct wl_display *display)
502 {
503     server->display = display;
504
505     wl_list_init(&server->views);
506
507     if (wl_display_init_shm(display) != 0)
508         return false;
509
510     server->backend = ds_tdm_backend_create(display);
511     if (!server->backend)
512         return false;
513
514     server->input_backend = ds_libinput_backend_create(display);
515     if (!server->input_backend) {
516         ds_backend_destroy(server->backend);
517         return false;
518     }
519
520     server->new_output.notify = backend_handle_new_output;
521     ds_backend_add_new_output_listener(server->backend,
522             &server->new_output);
523
524     wl_list_init(&server->keyboards);
525     wl_list_init(&server->pointers);
526     server->new_input.notify = backend_handle_new_input;
527     ds_backend_add_new_input_listener(server->input_backend, &server->new_input);
528
529     server->compositor = ds_compositor_create(display);
530     if (!server->compositor)
531         goto err;
532
533     server->tbm_server = ds_tbm_server_create(display);
534     if (!server->tbm_server)
535         goto err;
536
537     server->xdg_shell = ds_xdg_shell_create(display);
538     if (!server->xdg_shell)
539         goto err;
540
541     server->new_xdg_surface.notify = server_new_xdg_surface;
542     ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
543             &server->new_xdg_surface);
544
545     server->dpms = tinyds_dpms_init(server->display, dpms_free_func, (void *)server);
546     if (!server->dpms)
547         goto err;
548
549     server->policy = tinyds_policy_init(server->display, policy_free_func, (void *)server);
550     if (!server->policy)
551         goto err;
552
553     server->launch = tinyds_launch_init(server->display, launch_free_func, (void *)server);
554     if (!server->launch)
555         goto err;
556
557     server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
558     if (!server->seat)
559         goto err;
560     server->seat_caps = 0;
561
562     server->input_devicemgr = tinyds_input_devicemgr_init(server->input_backend,
563              server->seat, input_devicemgr_free_func, (void *)server);
564     if (!server->input_devicemgr)
565         goto err;
566
567     if (!add_new_text_input(server))
568         goto err;
569
570     if (!add_new_input_method(server))
571         goto err;
572
573     if (protocol_trace_init(display))
574         protocol_trace_enable(true);
575
576     return true;
577
578 err:
579     ds_backend_destroy(server->backend);
580     ds_backend_destroy(server->input_backend);
581
582     return false;
583 }
584
585 static void
586 output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
587 {
588     struct tinyds_output *output =
589         wl_container_of(listener, output, output_destroy);
590
591     if (output->bg_hwc_window)
592         ds_tdm_output_hwc_window_destroy(output->bg_hwc_window);
593
594     wl_list_remove(&output->output_destroy.link);
595     wl_list_remove(&output->output_frame.link);
596
597     if (output->front_buffer)
598         ds_buffer_unlock(output->front_buffer);
599
600 #ifdef USE_TDM_BUFFER_QUEUE
601     fini_renderer(&output->renderer);
602 #else
603     if (output->swapchain)
604         ds_swapchain_destroy(output->swapchain);
605
606     if (output->allocator)
607         ds_allocator_destroy(output->allocator);
608 #endif
609
610     wl_display_terminate(output->server->display);
611
612     output->server->output = NULL;
613
614     free(output);
615 }
616
617 static void
618 output_commit(struct tinyds_output *output)
619 {
620     uint32_t num_changed = 0;
621     uint32_t num_windows = 0, current_num_windows = 0;
622     struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL;
623     struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL;
624     enum ds_tdm_output_hwc_window_composition composition;
625     struct tinyds_view *view;
626     int i;
627     bool need_target = false;
628     bool fully_obscured = false;
629     struct ds_buffer *ds_buffer;
630     struct ds_tdm_box src_box;
631     int w = 0, h = 0;
632
633     if (!output->committable)
634         return;
635
636     if (!output->damaged && !output->target_updated)
637         return;
638
639     wl_list_for_each_reverse(view, &output->server->views, link) {
640         if (!view->hwc_window)
641             continue;
642
643         ds_buffer = ds_surface_get_buffer(
644                 ds_xdg_surface_get_surface(view->xdg_surface));
645         if (!ds_buffer)
646             continue;
647
648         if (!view->mapped)
649             continue;
650
651         num_windows++;
652
653         ds_buffer_get_size(ds_buffer, &w, &h);
654
655         if ((output->width <= w) && (output->height <= h))
656             fully_obscured = true;
657     }
658
659     if (fully_obscured) {
660         ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
661                 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
662     } else {
663         ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
664                 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
665         num_windows++;
666         need_target = true;
667     }
668
669 #ifdef USE_CURSOR
670     if (output->cursor_hwc_window) {
671         src_box.x = 0;
672         src_box.y = 0;
673         src_box.width = CURSOR_W;
674         src_box.height = CURSOR_H;
675
676         ds_tdm_output_hwc_window_set_src_box(output->cursor_hwc_window, &src_box);
677         ds_tdm_output_hwc_window_set_position(output->cursor_hwc_window, output->server->output_x, output->server->output_y);
678         ds_tdm_output_hwc_window_set_dest_size(output->cursor_hwc_window, CURSOR_W, CURSOR_H);
679         ds_tdm_output_hwc_window_set_transform(output->cursor_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
680
681         ds_tdm_output_hwc_window_set_composition(output->cursor_hwc_window,
682                     DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
683         num_windows++;
684         need_target = true;
685     }
686 #endif
687
688     if (num_windows) {
689         composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows);
690         if (!composited_hwc_windows)
691             return;
692
693         wl_list_for_each_reverse(view, &output->server->views, link) {
694             if (!view->hwc_window)
695                 continue;
696
697             ds_buffer = ds_surface_get_buffer(
698                     ds_xdg_surface_get_surface(view->xdg_surface));
699             if (!ds_buffer)
700                 continue;
701
702             ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer);
703
704             ds_buffer_get_size(ds_buffer, &w, &h);
705
706             src_box.x = 0;
707             src_box.y = 0;
708             src_box.width = w;
709             src_box.height = h;
710
711             ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box);
712             ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y);
713             ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h);
714             ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
715
716             if (view->mapped) {
717 #ifdef USE_CURSOR
718                 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
719                         DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
720 #endif
721                 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
722                         DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE);
723
724                 composited_hwc_windows[current_num_windows] = view->hwc_window;
725                 current_num_windows++;
726             } else {
727                 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
728                         DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
729             }
730         }
731
732         if (!fully_obscured) {
733             composited_hwc_windows[current_num_windows] = output->bg_hwc_window;
734             current_num_windows++;
735         }
736
737 #ifdef USE_CURSOR
738         if (output->cursor_hwc_window) {
739             composited_hwc_windows[current_num_windows] = output->cursor_hwc_window;
740             current_num_windows++;
741         }
742 #endif
743     }
744
745     if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows,
746             num_windows, &num_changed)) {
747         free(composited_hwc_windows);
748         ds_err("Could not hwc validate");
749         return;
750     }
751
752     if (composited_hwc_windows)
753         free(composited_hwc_windows);
754
755     if (num_changed > 0) {
756         changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows);
757         if (!changed_hwc_windows)
758             return;
759
760         if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed,
761                 changed_hwc_windows)) {
762             free(changed_hwc_windows);
763             ds_err("Could not get chaged composition");
764             return;
765         }
766
767         for (i = 0; i < num_changed; i++) {
768             composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]);
769             if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) {
770                 need_target = true;
771                 break;
772             }
773         }
774     }
775
776     if (changed_hwc_windows)
777         free(changed_hwc_windows);
778
779     if (need_target && output->damaged)
780         draw_output(output);
781
782 #ifdef USE_TDM_BUFFER_QUEUE
783     struct ds_buffer *buffer;
784
785     buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
786     if (buffer) {
787         if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, buffer)) {
788             ds_err("Could not set hwc client target buffer");
789             return;
790         }
791
792         output_swap_buffer(output, buffer);
793     }
794 #endif
795
796     if (!ds_tdm_output_hwc_accept_validation(output->hwc)) {
797         ds_err("Could not hwc accept validateion");
798         return;
799     }
800
801     ds_output_commit(output->ds_output);
802
803     output->committable = false;
804     output->damaged = false;
805     output->target_updated = false;
806
807     wl_list_for_each(view, &output->server->views, link) {
808         enum ds_tdm_output_hwc_window_composition composition;
809
810         if (!view->mapped)
811             continue;
812
813         composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
814         if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
815             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
816             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
817             view_send_frame_done(view);
818     }
819
820     ds_dbg("output:%p commit", output);
821 }
822
823 static void
824 output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
825 {
826     struct tinyds_output *output =
827         wl_container_of(listener, output, output_frame);
828
829     ds_dbg("output:%p handle frame", output);
830
831     output->committable = true;
832
833     output_commit(output);
834 }
835
836 static void
837 draw_server_with_damage(struct tinyds_server *server)
838 {
839     server->output->damaged = true;
840     output_schedule_commit(server->output);
841 }
842
843 static void
844 output_hwc_init(struct tinyds_output *output)
845 {
846     struct ds_tdm_output *tdm_output;
847
848     tdm_output = ds_tdm_output_from_output(output->ds_output);
849     assert(tdm_output);
850
851     output->hwc = ds_tdm_output_get_hwc(tdm_output);
852     assert(output->hwc);
853
854     ds_tdm_output_hwc_set_enabled(output->hwc, true);
855 }
856
857 #ifdef USE_TDM_BUFFER_QUEUE
858 static void
859 output_handle_buffer_queue_acquirable(struct wl_listener *listener,
860         void *data TINYDS_UNUSED)
861 {
862     struct tinyds_output *output;
863
864     output = wl_container_of(listener, output, buffer_queue_acquirable);
865
866     output->target_updated = true;
867     output_schedule_commit(output);
868 }
869
870 static void
871 output_buffer_queue_init(struct tinyds_output *output)
872 {
873     struct ds_tdm_output *tdm_output;
874
875     tdm_output = ds_tdm_output_from_output(output->ds_output);
876     assert(tdm_output);
877
878     output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
879     assert(output->buffer_queue);
880
881     output->buffer_queue_acquirable.notify =
882         output_handle_buffer_queue_acquirable;
883     ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
884             &output->buffer_queue_acquirable);
885 }
886
887 static void
888 output_renderer_init(struct tinyds_output *output)
889 {
890     init_renderer(&output->renderer);
891
892     renderer_set_surface_queue(&output->renderer,
893             ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
894
895     renderer_set_bg_color(&output->renderer, 80, 80, 80);
896 }
897
898 static void
899 output_draw_with_renderer(struct tinyds_output *output)
900 {
901     struct tinyds_view *view;
902
903     ds_dbg(">> BEGIN UPDATE TEXTURES");
904
905     wl_list_for_each(view, &output->server->views, link) {
906         struct ds_buffer *ds_buffer;
907         struct ds_tbm_client_buffer *tbm_buffer;
908         tbm_surface_h surface;
909         enum ds_tdm_output_hwc_window_composition composition;
910
911         if (!view->mapped)
912             continue;
913
914         composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
915         if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
916             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
917             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
918             continue;
919
920         ds_buffer = ds_surface_get_buffer(
921                 ds_xdg_surface_get_surface(view->xdg_surface));
922         if (!ds_buffer)
923             continue;
924
925         tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
926         if (!tbm_buffer)
927             continue;
928
929         surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
930         if (!surface)
931             continue;
932
933         renderer_add_texture(&output->renderer, surface, view->x, view->y);
934
935         view_send_frame_done(view);
936     }
937
938     ds_dbg("<< END UPDATE TEXTURES");
939
940     renderer_draw(&output->renderer);
941 }
942 #else
943 static void
944 output_swapchain_init(struct tinyds_output *output,
945         int width, int height, uint32_t format)
946
947 {
948     output->allocator = ds_tbm_allocator_create();
949     assert(output->allocator);
950
951     output->swapchain = ds_swapchain_create(output->allocator,
952             width, height, format);
953     assert(output->swapchain);
954 }
955
956 static void
957 output_draw_with_swapchain(struct tinyds_output *output)
958 {
959     struct tinyds_view *view;
960     struct ds_buffer *output_buffer;
961     pixman_image_t *output_image;
962     enum ds_tdm_output_hwc_window_composition composition;
963
964     output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
965     if (!output_buffer)
966         return;
967
968     output_image = pixman_image_from_buffer(output_buffer,
969             DS_BUFFER_DATA_PTR_ACCESS_WRITE);
970     if (!output_image) {
971         ds_buffer_unlock(output_buffer);
972         return;
973     }
974
975     pixman_image_fill_color(output_image, 80, 80, 80);
976
977     wl_list_for_each(view, &output->server->views, link) {
978         if (!view->mapped)
979             continue;
980
981         composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
982         if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
983             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
984             (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
985             continue;
986
987         draw_view(view, output_image);
988     }
989     pixman_image_unref(output_image);
990
991     if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, output_buffer)) {
992         ds_err("Could not set hwc client target buffer");
993         ds_buffer_unlock(output_buffer);
994         return;
995     }
996
997     output_swap_buffer(output, output_buffer);
998 }
999
1000 static void
1001 draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
1002 {
1003     struct ds_buffer *buffer;
1004     pixman_image_t *src_image;
1005
1006     buffer = ds_surface_get_buffer(
1007             ds_xdg_surface_get_surface(view->xdg_surface));
1008     if (!buffer)
1009         return;
1010
1011     src_image = pixman_image_from_buffer(buffer,
1012             DS_BUFFER_DATA_PTR_ACCESS_READ);
1013     pixman_image_composite32(PIXMAN_OP_OVER,
1014             src_image,
1015             NULL,
1016             dst_image,
1017             0, 0, 0, 0,
1018             view->x, view->y,
1019             pixman_image_get_width(src_image),
1020             pixman_image_get_height(src_image));
1021     pixman_image_unref(src_image);
1022
1023     view_send_frame_done(view);
1024 }
1025 #endif
1026
1027 static void
1028 draw_output(struct tinyds_output *output)
1029 {
1030 #ifdef USE_TDM_BUFFER_QUEUE
1031     output_draw_with_renderer(output);
1032 #else
1033     output_draw_with_swapchain(output);
1034 #endif
1035
1036     ds_dbg("output:%p draw", output);
1037 }
1038
1039 static void
1040 output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
1041 {
1042     ds_output_attach_buffer(output->ds_output, buffer);
1043
1044     if (output->front_buffer)
1045         ds_buffer_unlock(output->front_buffer);
1046     output->front_buffer = buffer;
1047 }
1048
1049 static void
1050 view_send_frame_done(struct tinyds_view *view)
1051 {
1052     struct timespec now;
1053     clock_gettime(CLOCK_MONOTONIC, &now);
1054     ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
1055             &now);
1056 }
1057
1058 static int
1059 server_dispatch_stdin(int fd, uint32_t mask, void *data)
1060 {
1061     struct tinyds_server *server = data;
1062
1063     wl_display_terminate(server->display);
1064
1065     return 1;
1066 }
1067
1068 static void
1069 keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
1070 {
1071     struct tinyds_keyboard *kbd;
1072
1073     kbd = wl_container_of(listener, kbd, destroy);
1074
1075     ds_inf("Keyboard(%p) destroyed", kbd);
1076
1077     wl_list_remove(&kbd->destroy.link);
1078     wl_list_remove(&kbd->key.link);
1079     wl_list_remove(&kbd->link);
1080
1081     free(kbd);
1082 }
1083
1084 static bool
1085 server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
1086 {
1087     switch (sym) {
1088         case XKB_KEY_BackSpace:
1089             wl_display_terminate(server->display);
1090             break;
1091         default:
1092             return false;
1093     }
1094
1095     return true;
1096 }
1097
1098 static void
1099 keyboard_handle_key(struct wl_listener *listener, void *data)
1100 {
1101     struct tinyds_keyboard *kbd;
1102     struct ds_keyboard_event_key *event = data;
1103     struct ds_keyboard *ds_keyboard;
1104     struct xkb_state *xkb_state;
1105     const xkb_keysym_t *syms;
1106     int nsyms;
1107     bool handled = false;
1108
1109     kbd = wl_container_of(listener, kbd, key);
1110
1111     ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
1112             "update_state(%d)", kbd->dev,
1113             event->keycode, event->state, event->time_msec,
1114             event->update_state);
1115
1116     ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
1117
1118     if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1119         xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
1120         if (xkb_state) {
1121             nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
1122                     &syms);
1123             for (int i = 0; i < nsyms; i++) {
1124                 handled = server_handle_keybinding(kbd->server, syms[i]);
1125             }
1126         }
1127     }
1128
1129     if (!handled) {
1130         ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec,
1131                 event->keycode, event->state);
1132     }
1133 }
1134
1135 static void
1136 server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
1137 {
1138     struct tinyds_keyboard *kbd;
1139     struct xkb_context *context;
1140     struct xkb_keymap *keymap;
1141
1142     kbd = calloc(1, sizeof *kbd);
1143     assert(kbd);
1144
1145     kbd->dev = dev;
1146     kbd->server = server;
1147
1148     context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
1149     if (!context)
1150         goto err;
1151
1152     keymap = xkb_keymap_new_from_names(context, NULL,
1153             XKB_KEYMAP_COMPILE_NO_FLAGS);
1154
1155     if (!keymap) {
1156         ds_err("Failed to compile keymap");
1157         xkb_context_unref(context);
1158         goto err;
1159     }
1160
1161     ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap);
1162
1163     xkb_keymap_unref(keymap);
1164     xkb_context_unref(context);
1165
1166     kbd->destroy.notify = keyboard_handle_device_destroy;
1167     ds_input_device_add_destroy_listener(dev, &kbd->destroy);
1168
1169     kbd->key.notify = keyboard_handle_key;
1170     ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
1171
1172     wl_list_insert(&server->keyboards, &kbd->link);
1173
1174     ds_inf("Keyboard(%p) added", kbd);
1175
1176     return;
1177
1178 err:
1179     free(kbd);
1180 }
1181
1182 struct tinyds_view *
1183 tinyds_server_view_at(struct tinyds_server *server, double lx, double ly,
1184         double *sx, double *sy)
1185 {
1186     struct tinyds_view *view;
1187     struct ds_surface *surface;
1188     struct ds_buffer *buffer;
1189     int x, y, w = 0, h = 0;
1190
1191     wl_list_for_each(view, &server->views, link) {
1192         surface = ds_xdg_surface_get_surface(view->xdg_surface);
1193         buffer = ds_surface_get_buffer(surface);
1194         ds_buffer_get_size(buffer, &w, &h);
1195
1196         x = view->x;
1197         y = view->y;
1198
1199         if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) {
1200             *sx = lx - x;
1201             *sy = ly - y;
1202
1203             return view;
1204         }
1205     }
1206
1207     return NULL;
1208 }
1209
1210 static void
1211 touch_handle_device_destroy(struct wl_listener *listener, void *data)
1212 {
1213     struct tinyds_touch *touch;
1214
1215     touch = wl_container_of(listener, touch, destroy);
1216
1217     ds_inf("Touch(%p) destroyed", touch);
1218
1219     wl_list_remove(&touch->destroy.link);
1220     wl_list_remove(&touch->down.link);
1221     wl_list_remove(&touch->up.link);
1222     wl_list_remove(&touch->motion.link);
1223
1224     free(touch);
1225 }
1226
1227 static void
1228 touch_handle_down(struct wl_listener *listener, void *data)
1229 {
1230     struct ds_touch_event_down *event = data;
1231     struct tinyds_touch *touch;
1232     struct tinyds_view *view;
1233     struct tinyds_server *server;
1234     double sx = 0.f, sy = 0.f;
1235
1236     touch = wl_container_of(listener, touch, down);
1237
1238     server = touch->server;
1239     if (server->output) {
1240         server->output_x = event->x * server->output->width;
1241         server->output_y = event->y * server->output->height;
1242     }
1243
1244     ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1245             touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1246
1247     view = tinyds_server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1248
1249     if (view) {
1250         ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface),
1251                 event->time_msec, event->id, sx, sy);
1252     }
1253
1254 #ifdef USE_CURSOR
1255     if (server->output && server->output->cursor_enabled) {
1256         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1257         draw_server_with_damage(server);
1258     }
1259 #endif
1260 }
1261
1262 static void
1263 touch_handle_up(struct wl_listener *listener, void *data)
1264 {
1265     struct ds_touch_event_up *event = data;
1266     struct tinyds_touch *touch;
1267
1268     touch = wl_container_of(listener, touch, up);
1269
1270     ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
1271             touch->dev, event->id, event->time_msec);
1272
1273     ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id);
1274 }
1275
1276 static void
1277 touch_handle_motion(struct wl_listener *listener, void *data)
1278 {
1279     struct ds_touch_event_motion *event = data;
1280     struct tinyds_touch *touch;
1281     struct tinyds_view *view;
1282     struct tinyds_server *server;
1283     double sx = 0.f, sy = 0.f;
1284
1285     touch = wl_container_of(listener, touch, motion);
1286
1287     server = touch->server;
1288     if (server->output) {
1289         server->output_x = event->x * server->output->width;
1290         server->output_y = event->y * server->output->height;
1291     }
1292
1293     ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1294             touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1295
1296     view = tinyds_server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1297
1298     if (view) {
1299         ds_seat_touch_notify_motion(server->seat, event->time_msec,
1300                 event->id, sx, sy);
1301     }
1302
1303 #ifdef USE_CURSOR
1304     if (server->output && server->output->cursor_enabled) {
1305         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1306         draw_server_with_damage(server);
1307     }
1308 #endif
1309 }
1310
1311 static void
1312 server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
1313 {
1314     struct tinyds_touch *touch;
1315
1316     touch = calloc(1, sizeof *touch);
1317     assert(touch);
1318
1319     touch->dev = dev;
1320     touch->server = server;
1321
1322     touch->destroy.notify = touch_handle_device_destroy;
1323     ds_input_device_add_destroy_listener(dev, &touch->destroy);
1324
1325     touch->down.notify = touch_handle_down;
1326     ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
1327
1328     touch->up.notify = touch_handle_up;
1329     ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
1330
1331     touch->motion.notify = touch_handle_motion;
1332     ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
1333
1334     ds_inf("Touch(%p) added", touch);
1335 }
1336
1337 static void
1338 pointer_handle_device_destroy(struct wl_listener *listener, void *data)
1339 {
1340     struct tinyds_pointer *pointer;
1341     struct tinyds_server *server;
1342
1343     pointer = wl_container_of(listener, pointer, destroy);
1344
1345     ds_inf("Pointer(%p) destroyed", pointer);
1346
1347     wl_list_remove(&pointer->destroy.link);
1348     wl_list_remove(&pointer->motion.link);
1349     wl_list_remove(&pointer->button.link);
1350     wl_list_remove(&pointer->frame.link);
1351     wl_list_remove(&pointer->link);
1352
1353 #ifdef USE_CURSOR
1354     server = pointer->server;
1355     if (server->output && wl_list_empty(&server->pointers))
1356     {
1357         server->output->cursor_enabled = false;
1358         renderer_cursor_destroy(&server->output->renderer);
1359
1360         if (server->output->cursor_hwc_window)
1361         {
1362             ds_tdm_output_hwc_window_destroy(server->output->cursor_hwc_window);
1363             server->output->cursor_hwc_window = NULL;
1364         }
1365         draw_server_with_damage(server);
1366     }
1367 #endif
1368
1369     free(pointer);
1370 }
1371
1372 static void
1373 pointer_handle_motion(struct wl_listener *listener, void *data)
1374 {
1375     struct tinyds_pointer *pointer;
1376     struct ds_pointer_event_motion *event = data;
1377     struct tinyds_view *view;
1378     struct tinyds_server *server;
1379     int ow = 0, oh = 0;
1380     double sx, sy;
1381
1382     pointer = wl_container_of(listener, pointer, motion);
1383
1384     server = pointer->server;
1385     if (server->output) {
1386         ow = server->output->width;
1387         oh = server->output->height;
1388     }
1389
1390     if (server->output_x + event->delta_x >= ow)
1391         server->output_x = ow;
1392     else if(server->output_x + event->delta_x <= 0.f)
1393         server->output_x = 0.f;
1394     else
1395         server->output_x = server->output_x + event->delta_x ;
1396     if (server->output_y + event->delta_y >= oh)
1397         server->output_y = oh;
1398     else if(server->output_y + event->delta_y <= 0.f)
1399         server->output_y = 0.f;
1400     else
1401         server->output_y = server->output_y + event->delta_y ;
1402
1403     ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f",
1404             pointer, event->delta_x, event->delta_y, server->output_x, server->output_y);
1405
1406     view = tinyds_server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy);
1407
1408     if (pointer->focused_view != view) {
1409         if (pointer->focused_view) {
1410             ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
1411             ds_seat_pointer_notify_clear_focus(pointer->server->seat);
1412             pointer->focused_view = NULL;
1413         }
1414
1415         if (view) {
1416             ds_inf("Set pointer focus to view(%p)", view);
1417             ds_seat_pointer_notify_enter(pointer->server->seat,
1418                     ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
1419             pointer->focused_view = view;
1420         }
1421     }
1422
1423     if (view) {
1424         ds_seat_pointer_notify_motion(pointer->server->seat,
1425                 event->time_msec, sx, sy);
1426     }
1427
1428 #ifdef USE_CURSOR
1429     if (server->output && server->output->cursor_enabled) {
1430         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1431         draw_server_with_damage(server);
1432     }
1433 #endif
1434 }
1435
1436 static void
1437 pointer_handle_button(struct wl_listener *listener, void *data)
1438 {
1439     struct tinyds_pointer *pointer;
1440     struct ds_pointer_event_button *event = data;
1441
1442     pointer = wl_container_of(listener, pointer, button);
1443
1444     ds_inf("Pointer(%p) button(%d): state(%s) time(%d)",
1445             pointer, event->button,
1446             (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released",
1447             event->time_msec);
1448
1449     ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state);
1450 }
1451
1452 static void
1453 pointer_handle_frame(struct wl_listener *listener, void *data)
1454 {
1455     struct tinyds_pointer *pointer;
1456
1457     pointer = wl_container_of(listener, pointer, frame);
1458
1459     ds_inf("Pointer(%p) frame", pointer);
1460     ds_seat_pointer_notify_frame(pointer->server->seat);
1461 }
1462
1463 static void
1464 server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev)
1465 {
1466     struct tinyds_pointer *pointer;
1467
1468     pointer = calloc(1, sizeof *pointer);
1469     assert(pointer);
1470
1471     pointer->dev = dev;
1472     pointer->server = server;
1473
1474     pointer->destroy.notify = pointer_handle_device_destroy;
1475     ds_input_device_add_destroy_listener(dev, &pointer->destroy);
1476
1477     pointer->motion.notify = pointer_handle_motion;
1478     ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev),
1479             &pointer->motion);
1480
1481     pointer->button.notify = pointer_handle_button;
1482     ds_pointer_add_button_listener(ds_input_device_get_pointer(dev),
1483             &pointer->button);
1484
1485     pointer->frame.notify = pointer_handle_frame;
1486     ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev),
1487             &pointer->frame);
1488
1489     pointer->focused_view = NULL;
1490
1491 #ifdef USE_CURSOR
1492     if (server->output && wl_list_empty(&server->pointers)) {
1493         server->output_x = (double)(server->output->width) / 2;
1494         server->output_y = (double)(server->output->height) / 2;
1495
1496         server->output->cursor_enabled = true;
1497         renderer_cursor_create(&server->output->renderer, 255, 0, 0, CURSOR_W, CURSOR_H);
1498         renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1499
1500         server->output->cursor_hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
1501         assert(server->output->cursor_hwc_window);
1502         draw_server_with_damage(server);
1503     }
1504 #endif
1505
1506     wl_list_insert(&server->pointers, &pointer->link);
1507
1508     ds_inf("Pointer(%p) added", pointer);
1509 }
1510
1511 static void
1512 output_schedule_commit_handle_idle_timer(void *data)
1513 {
1514     struct tinyds_output *output = data;
1515     output->idle_commit = NULL;
1516
1517     output_commit(output);
1518 }
1519
1520 static void
1521 output_schedule_commit(struct tinyds_output *output)
1522 {
1523     if (output->idle_commit)
1524         return;
1525
1526     struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display);
1527     output->idle_commit =
1528         wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output);
1529 }
1530
1531 static void
1532 text_input_mgr_handle_destroy(struct wl_listener *listener, void *data)
1533 {
1534     struct tinyds_text_input *text_input;
1535     struct tinyds_server *server;
1536
1537     ds_inf("text_input_mgr_handle_destroy");
1538     text_input = wl_container_of(listener, text_input, mgr_destroy);
1539
1540     wl_list_remove(&text_input->mgr_destroy.link);
1541     wl_list_remove(&text_input->new_text_input.link);
1542
1543     server = text_input->server;
1544     server->text_input = NULL;
1545 }
1546
1547 static void
1548 text_input_handle_destroy(struct wl_listener *listener, void *data)
1549 {
1550     struct tinyds_text_input *text_input;
1551
1552     ds_inf("text_input_handle_destroy");
1553
1554     text_input = wl_container_of(listener, text_input, destroy);
1555
1556     wl_list_remove(&text_input->destroy.link);
1557     wl_list_remove(&text_input->text_input_activate.link);
1558     wl_list_remove(&text_input->text_input_deactivate.link);
1559     wl_list_remove(&text_input->text_input_reset.link);
1560     wl_list_remove(&text_input->text_input_set_content_type.link);
1561     wl_list_remove(&text_input->text_input_invoke_action.link);
1562     wl_list_remove(&text_input->text_input_commit_state.link);
1563     wl_list_remove(&text_input->text_input_set_preferred_language.link);
1564
1565     free(text_input);
1566 }
1567
1568 static void
1569 text_input_handle_activate(struct wl_listener *listener, void *data)
1570 {
1571     struct tinyds_text_input *text_input;
1572     struct tinyds_input_method *input_method;
1573     struct ds_tizen_text_input_event_activate *event = data;
1574
1575     text_input = wl_container_of(listener, text_input, text_input_activate);
1576
1577     input_method = text_input->server->input_method;
1578
1579     ds_inf("text_input_handle_activate. text_input(%p) seat(%p) surface(%p) text_input(%p)",
1580         text_input, event->seat, event->surface, event->text_input);
1581
1582     if (input_method->input == text_input)
1583         return;
1584     if (input_method->input)
1585         ;//deactivate_input_method(server->input_method);
1586     input_method->input = text_input;
1587     wl_list_insert(&text_input->input_methods, &input_method->link);
1588
1589     text_input->surface = event->surface;
1590
1591     if (!add_new_input_method_context(input_method, text_input))
1592         return;
1593
1594     // ds_tizen_input_method_send_set_text_input_id();
1595 }
1596
1597 static void
1598 text_input_handle_deactivate(struct wl_listener *listener, void *data)
1599 {
1600     struct tinyds_text_input *text_input;
1601     struct tinyds_input_method *input_method, *tmp;
1602     struct ds_tizen_text_input_event_deactivate *event = data;
1603
1604     text_input = wl_container_of(listener, text_input, text_input_deactivate);
1605     ds_inf("text_input_handle_deactivate. text_input(%p) seat(%p) text_input(%p)",
1606         text_input, event->seat, event->text_input);
1607
1608     wl_list_for_each_safe(input_method, tmp, &text_input->input_methods, link) {
1609         if (!input_method->input_method || !input_method->context->context) continue;
1610         ds_tizen_input_method_send_deactivate(input_method->input_method, input_method->context->context);
1611         input_method->input = NULL;
1612         input_method->context = NULL;
1613         wl_list_remove(&input_method->link);
1614     }
1615
1616     text_input->surface = NULL;
1617     // ds_tizen_input_method_send_close_connection();
1618 }
1619
1620 static void
1621 text_input_handle_reset(struct wl_listener *listener, void *data)
1622 {
1623     struct tinyds_text_input *text_input;
1624     struct tinyds_input_method *input_method;
1625
1626     text_input = wl_container_of(listener, text_input, text_input_reset);
1627
1628     ds_inf("text_input_handle_reset. text_input(%p)", text_input);
1629
1630     wl_list_for_each(input_method, &text_input->input_methods, link) {
1631         if (!input_method->context || !input_method->context->context) continue;
1632         ds_tizen_input_method_context_send_reset(input_method->context->context);
1633     }
1634 }
1635
1636 static void
1637 text_input_handle_set_content_type(struct wl_listener *listener, void *data)
1638 {
1639     struct tinyds_text_input *text_input;
1640     struct ds_tizen_text_input_event_set_content_type *event = data;
1641     struct tinyds_input_method *input_method;
1642
1643     text_input = wl_container_of(listener, text_input, text_input_set_content_type);
1644
1645     ds_inf("text_input_handle_content_type. text_input(%p) hint(%u) purpose(%u)",
1646         text_input, event->hint, event->purpose);
1647
1648     wl_list_for_each(input_method, &text_input->input_methods, link) {
1649         if (!input_method->context || !input_method->context->context) continue;
1650         ds_tizen_input_method_context_send_content_type(input_method->context->context,
1651             event->hint, event->purpose);
1652     }
1653 }
1654
1655 static void
1656 text_input_handle_invoke_action(struct wl_listener *listener, void *data)
1657 {
1658     struct tinyds_text_input *text_input;
1659     struct ds_tizen_text_input_event_invoke_action *event = data;
1660     struct tinyds_input_method *input_method;
1661
1662     text_input = wl_container_of(listener, text_input, text_input_invoke_action);
1663
1664     ds_inf("text_input_handle_invoke_action. text_input(%p) button(%u) index(%u)",
1665         text_input, event->button, event->index);
1666
1667     wl_list_for_each(input_method, &text_input->input_methods, link) {
1668         if (!input_method->context || !input_method->context->context) continue;
1669         ds_tizen_input_method_context_send_invoke_action(input_method->context->context,
1670             event->button, event->index);
1671     }
1672 }
1673
1674 static void
1675 text_input_handle_commit_state(struct wl_listener *listener, void *data)
1676 {
1677     struct tinyds_text_input *text_input;
1678     struct ds_tizen_text_input_event_commit_state *event = data;
1679     struct tinyds_input_method *input_method;
1680
1681     text_input = wl_container_of(listener, text_input, text_input_commit_state);
1682
1683     ds_inf("text_input_handle_commit_state. text_input(%p) serial(%u)",
1684         text_input, event->serial);
1685
1686     wl_list_for_each(input_method, &text_input->input_methods, link) {
1687         if (!input_method->context || !input_method->context->context) continue;
1688         ds_tizen_input_method_context_send_commit_state(input_method->context->context,
1689             event->serial);
1690     }
1691 }
1692
1693 static void
1694 text_input_handle_set_preferred_language(struct wl_listener *listener, void *data)
1695 {
1696     struct tinyds_text_input *text_input;
1697     struct ds_tizen_text_input_event_set_preferred_language *event = data;
1698     struct tinyds_input_method *input_method;
1699
1700     text_input = wl_container_of(listener, text_input, text_input_set_preferred_language);
1701
1702     ds_inf("text_input_handle_set_preferred_language. text_input(%p) language(%s)",
1703         text_input, event->language);
1704
1705     wl_list_for_each(input_method, &text_input->input_methods, link) {
1706         if (!input_method->context || !input_method->context->context) continue;
1707         ds_tizen_input_method_context_send_preferred_language(input_method->context->context,
1708             event->language);
1709     }
1710 }
1711
1712 static void
1713 text_input_mgr_handle_new_text_input(struct wl_listener *listener, void *data)
1714 {
1715     struct tinyds_text_input *text_input;
1716     struct ds_tizen_text_input *input = data;
1717
1718     text_input = wl_container_of(listener, text_input, new_text_input);
1719
1720     ds_inf("text_input_mgr_handle_new_text_input");
1721
1722     text_input->input = input;
1723
1724     text_input->destroy.notify = text_input_handle_destroy;
1725     ds_tizen_text_input_add_destroy_listener(text_input->input,
1726         &text_input->destroy);
1727
1728     text_input->text_input_activate.notify = text_input_handle_activate;
1729     ds_tizen_text_input_add_activate_listener(text_input->input,
1730         &text_input->text_input_activate);
1731
1732     text_input->text_input_deactivate.notify = text_input_handle_deactivate;
1733     ds_tizen_text_input_add_deactivate_listener(text_input->input,
1734         &text_input->text_input_deactivate);
1735
1736     text_input->text_input_reset.notify = text_input_handle_reset;
1737     ds_tizen_text_input_add_reset_listener(text_input->input,
1738         &text_input->text_input_reset);
1739
1740     text_input->text_input_set_content_type.notify = text_input_handle_set_content_type;
1741     ds_tizen_text_input_add_set_content_type_listener(text_input->input,
1742         &text_input->text_input_set_content_type);
1743
1744     text_input->text_input_invoke_action.notify = text_input_handle_invoke_action;
1745     ds_tizen_text_input_add_invoke_action_listener(text_input->input,
1746         &text_input->text_input_invoke_action);
1747
1748     text_input->text_input_commit_state.notify = text_input_handle_commit_state;
1749     ds_tizen_text_input_add_commit_state_listener(text_input->input,
1750         &text_input->text_input_commit_state);
1751
1752     text_input->text_input_set_preferred_language.notify = text_input_handle_set_preferred_language;
1753     ds_tizen_text_input_add_set_preferred_language_listener(text_input->input,
1754         &text_input->text_input_set_preferred_language);
1755 }
1756
1757 static void
1758 input_method_mgr_handle_destroy(struct wl_listener *listener, void *data)
1759 {
1760     struct tinyds_input_method *input_method;
1761
1762     ds_inf("input_method_mgr_handle_destroy");
1763
1764     input_method = wl_container_of(listener, input_method, mgr_destroy);
1765
1766     wl_list_remove(&input_method->mgr_destroy.link);
1767 }
1768
1769 static void
1770 input_method_handle_destroy(struct wl_listener *listener, void *data)
1771 {
1772     struct tinyds_input_method *input_method;
1773     struct tinyds_server *server;
1774
1775     ds_inf("input_method_handle_destroy");
1776
1777     input_method = wl_container_of(listener, input_method, destroy);
1778
1779     wl_list_remove(&input_method->destroy.link);
1780
1781     server = input_method->server;
1782     server->input_method = NULL;
1783
1784     free(input_method);
1785 }
1786
1787 static void
1788 context_handle_destroy(struct wl_listener *listener, void *data)
1789 {
1790     struct tinyds_input_method_context *context;
1791     struct tinyds_server *server;
1792
1793     ds_inf("context_handle_destroy");
1794
1795     context = wl_container_of(listener, context, destroy);
1796
1797     wl_list_remove(&context->destroy.link);
1798
1799     wl_list_remove(&context->im_context_commit_string.link);
1800     wl_list_remove(&context->im_context_preedit_string.link);
1801     wl_list_remove(&context->im_context_preedit_styling.link);
1802     wl_list_remove(&context->im_context_preedit_cursor.link);
1803     wl_list_remove(&context->im_context_delete_surrounding_text.link);
1804     wl_list_remove(&context->im_context_cursor_position.link);
1805     wl_list_remove(&context->im_context_modifiers_map.link);
1806     wl_list_remove(&context->im_context_keysym.link);
1807     wl_list_remove(&context->im_context_grab_keyboard.link);
1808     wl_list_remove(&context->im_context_key.link);
1809     wl_list_remove(&context->im_context_modifiers.link);
1810     wl_list_remove(&context->im_context_language.link);
1811     wl_list_remove(&context->im_context_text_direction.link);
1812
1813     server = context->server;
1814     server->input_method->context = NULL;
1815
1816     free(context);
1817 }
1818
1819 static void
1820 context_handle_commit_string(struct wl_listener *listener, void *data)
1821 {
1822     struct tinyds_text_input *text_input;
1823     struct tinyds_input_method_context *context;
1824     struct ds_tizen_input_method_context_event_commit_string *event = data;
1825
1826     context = wl_container_of(listener, context, im_context_commit_string);
1827     text_input = context->server->text_input;
1828
1829     ds_inf("context_handle_commit_string. text_input(%p) serial(%u) text(%s)",
1830         text_input, event->serial, event->text);
1831
1832     ds_tizen_text_input_send_commit_string(text_input->input, event->serial, event->text);
1833 }
1834
1835 static void
1836 context_handle_preedit_string(struct wl_listener *listener, void *data)
1837 {
1838     struct tinyds_input_method_context *context;
1839     struct tinyds_text_input *text_input;
1840     struct ds_tizen_input_method_context_event_preedit_string *event = data;
1841
1842     context = wl_container_of(listener, context, im_context_preedit_string);
1843     text_input = context->server->text_input;
1844
1845     ds_inf("context_handle_preedit_string. text_input(%p) serial(%u) text(%s) commit(%s)",
1846         text_input, event->serial, event->text, event->commit);
1847
1848     ds_tizen_text_input_send_preedit_string(text_input->input, event->serial, event->text, event->commit);
1849 }
1850
1851 static void
1852 context_handle_preedit_styling(struct wl_listener *listener, void *data)
1853 {
1854     struct tinyds_input_method_context *context;
1855     struct tinyds_text_input *text_input;
1856     struct ds_tizen_input_method_context_event_preedit_styling *event = data;
1857
1858     context = wl_container_of(listener, context, im_context_preedit_styling);
1859     text_input = context->server->text_input;
1860
1861     ds_inf("context_handle_preedit_styling. text_input(%p) index(%u) length(%u) style(%u)",
1862         text_input, event->index, event->length, event->style);
1863
1864     ds_tizen_text_input_send_preedit_styling(text_input->input, event->index, event->length, event->style);
1865 }
1866
1867 static void
1868 context_handle_preedit_cursor(struct wl_listener *listener, void *data)
1869 {
1870     struct tinyds_input_method_context *context;
1871     struct tinyds_text_input *text_input;
1872     struct ds_tizen_input_method_context_event_preedit_cursor *event = data;
1873
1874     context = wl_container_of(listener, context, im_context_preedit_cursor);
1875     text_input = context->server->text_input;
1876
1877     ds_inf("context_handle_preedit_cursor. text_input(%p) index(%u)",
1878         text_input, event->index);
1879
1880     ds_tizen_text_input_send_preedit_cursor(text_input->input, event->index);
1881 }
1882
1883 static void
1884 context_handle_delete_surrounding_text(struct wl_listener *listener, void *data)
1885 {
1886     struct tinyds_input_method_context *context;
1887     struct tinyds_text_input *text_input;
1888     struct ds_tizen_input_method_context_event_delete_surrounding_text *event = data;
1889
1890     context = wl_container_of(listener, context, im_context_delete_surrounding_text);
1891     text_input = context->server->text_input;
1892
1893     ds_inf("context_handle_delete_surrounding_text. text_input(%p) index(%d) length(%u)",
1894         text_input, event->index, event->length);
1895
1896     ds_tizen_text_input_send_delete_surrounding_text(text_input->input, event->index, event->length);
1897 }
1898
1899 static void
1900 context_handle_cursor_position(struct wl_listener *listener, void *data)
1901 {
1902     struct tinyds_input_method_context *context;
1903     struct tinyds_text_input *text_input;
1904     struct ds_tizen_input_method_context_event_cursor_position *event = data;
1905
1906     context = wl_container_of(listener, context, im_context_cursor_position);
1907     text_input = context->server->text_input;
1908
1909     ds_inf("context_handle_cursor_position. text_input(%p) index(%d) length(%d)",
1910         text_input, event->index, event->anchor);
1911
1912     ds_tizen_text_input_send_cursor_position(text_input->input, event->index, event->anchor);
1913 }
1914
1915 static void
1916 context_handle_modifiers_map(struct wl_listener *listener, void *data)
1917 {
1918     struct tinyds_input_method_context *context;
1919     struct tinyds_text_input *text_input;
1920     struct ds_tizen_input_method_context_event_modifiers_map *event = data;
1921
1922     context = wl_container_of(listener, context, im_context_modifiers_map);
1923     text_input = context->server->text_input;
1924
1925     ds_inf("context_handle_modifiers_map. text_input(%p) map(%p)",
1926         text_input, event->map);
1927
1928     ds_tizen_text_input_send_modifiers_map(text_input->input, event->map);
1929 }
1930
1931 static void
1932 context_handle_keysym(struct wl_listener *listener, void *data)
1933 {
1934     struct tinyds_input_method_context *context;
1935     struct tinyds_text_input *text_input;
1936     struct ds_tizen_input_method_context_event_keysym *event = data;
1937
1938     context = wl_container_of(listener, context, im_context_keysym);
1939     text_input = context->server->text_input;
1940
1941     ds_inf("context_handle_keysym. text_input(%p) serial(%u) time(%u) sysm(%u) state(%u) modifiers(%u)",
1942         text_input, event->serial, event->time, event->sym, event->state, event->modifiers);
1943
1944     ds_tizen_text_input_send_keysym(text_input->input, event->serial, event->time, event->sym, event->state, event->modifiers);
1945 }
1946
1947 static void
1948 context_handle_grab_keyboard(struct wl_listener *listener, void *data)
1949 {
1950     struct tinyds_input_method_context *context;
1951     struct tinyds_text_input *text_input;
1952
1953     context = wl_container_of(listener, context, im_context_grab_keyboard);
1954     text_input = context->server->text_input;
1955
1956     ds_inf("context_handle_grab_keyboard. text_input(%p)",
1957         text_input);
1958
1959     //TODO
1960 }
1961
1962 static void
1963 context_handle_key(struct wl_listener *listener, void *data)
1964 {
1965     struct tinyds_input_method_context *context;
1966     struct tinyds_text_input *text_input;
1967
1968     context = wl_container_of(listener, context, im_context_key);
1969     text_input = context->server->text_input;
1970
1971     ds_inf("context_handle_key. text_input(%p)",
1972         text_input);
1973
1974    //TODO
1975 }
1976
1977 static void
1978 context_handle_modifiers(struct wl_listener *listener, void *data)
1979 {
1980     struct tinyds_input_method_context *context;
1981     struct tinyds_text_input *text_input;
1982
1983     context = wl_container_of(listener, context, im_context_modifiers);
1984     text_input = context->server->text_input;
1985
1986     ds_inf("context_handle_modifiers. text_input(%p)",
1987         text_input);
1988
1989    //TODO
1990 }
1991
1992 static void
1993 context_handle_language(struct wl_listener *listener, void *data)
1994 {
1995     struct tinyds_input_method_context *context;
1996     struct tinyds_text_input *text_input;
1997     struct ds_tizen_input_method_context_event_language *event = data;
1998
1999     context = wl_container_of(listener, context, im_context_language);
2000     text_input = context->server->text_input;
2001
2002     ds_inf("context_handle_language. text_input(%p) serial(%u), language(%s)",
2003         text_input, event->serial, event->language);
2004
2005     ds_tizen_text_input_send_language(text_input->input, event->serial, event->language);
2006 }
2007
2008 static void
2009 context_handle_text_direction(struct wl_listener *listener, void *data)
2010 {
2011     struct tinyds_input_method_context *context;
2012     struct tinyds_text_input *text_input;
2013     struct ds_tizen_input_method_context_event_text_direction *event = data;
2014
2015     context = wl_container_of(listener, context, im_context_text_direction);
2016     text_input = context->server->text_input;
2017
2018     ds_inf("context_handle_text_direction. text_input(%p) serial(%u), direction(%u)",
2019         text_input, event->serial, event->direction);
2020
2021     ds_tizen_text_input_send_text_direction(text_input->input, event->serial, event->direction);
2022 }
2023
2024 static bool
2025 add_new_text_input(struct tinyds_server *server)
2026 {
2027     struct tinyds_text_input *text_input;
2028
2029     text_input = calloc(1, sizeof *text_input);
2030     if (!text_input)
2031         return false;
2032
2033     text_input->text_input_mgr = ds_tizen_text_input_manager_create(server->display);
2034     if (!text_input->text_input_mgr) {
2035         free(text_input);
2036         ds_err("Could not create ds_tizen_text_input_manager");
2037         return false;
2038     }
2039
2040     wl_list_init(&text_input->input_methods);
2041
2042     text_input->mgr_destroy.notify = text_input_mgr_handle_destroy;
2043     ds_tizen_text_input_manager_add_destroy_listener(text_input->text_input_mgr,
2044             &text_input->mgr_destroy);
2045
2046     text_input->new_text_input.notify = text_input_mgr_handle_new_text_input;
2047     ds_tizen_text_input_manager_add_new_text_input_listener(text_input->text_input_mgr,
2048             &text_input->new_text_input);
2049
2050     text_input->server = server;
2051     server->text_input = text_input;
2052
2053     ds_inf("Text_Input (%p) added", text_input);
2054
2055     return true;
2056 }
2057
2058 static bool
2059 add_new_input_method(struct tinyds_server *server)
2060 {
2061     struct tinyds_input_method *input_method;
2062
2063     input_method = calloc(1, sizeof *input_method);
2064     if (!input_method)
2065         return false;
2066
2067     input_method->input_method = ds_tizen_input_method_create(server->display);
2068     if (!input_method->input_method) {
2069         free(input_method);
2070         ds_err("Could not create ds_tizen_input_method");
2071         return false;
2072     }
2073     input_method->destroy.notify = input_method_handle_destroy;
2074     ds_tizen_input_method_add_destroy_listener(input_method->input_method,
2075             &input_method->destroy);
2076
2077     input_method->input_method_mgr = ds_tizen_input_method_manager_create(server->display);
2078     if (!input_method->input_method_mgr) {
2079         free(input_method);
2080         ds_err("Could not create ds_tizen_input_method_manager");
2081         return false;
2082     }
2083
2084     input_method->mgr_destroy.notify = input_method_mgr_handle_destroy;
2085     ds_tizen_input_method_manager_add_destroy_listener(input_method->input_method_mgr,
2086             &input_method->mgr_destroy);
2087
2088     input_method->server = server;
2089     server->input_method = input_method;
2090
2091     ds_inf("Input_Method (%p) added", input_method);
2092
2093     return true;
2094 }
2095
2096 static bool
2097 add_new_input_method_context(struct tinyds_input_method *input_method,
2098         struct tinyds_text_input *text_input)
2099 {
2100     struct tinyds_input_method_context *context;
2101
2102     context = calloc(1, sizeof *context);
2103     if (context == NULL)
2104     {
2105         ds_err("calloc is failed. tinyds_input_method_context");
2106         return false;
2107     }
2108     input_method->context = context;
2109     context->input_method = input_method;
2110     context->server = input_method->server;
2111     context->input = text_input;
2112
2113     context->context = ds_tizen_input_method_create_context(input_method->input_method);
2114     if (context->context == NULL) {
2115         ds_err("ds_tizen_input_method_create_context() failed.");
2116         return false;
2117     }
2118
2119     context->destroy.notify = context_handle_destroy;
2120     ds_tizen_input_method_context_add_destroy_listener(context->context,
2121         &context->destroy);
2122
2123     context->im_context_commit_string.notify = context_handle_commit_string;
2124     ds_tizen_input_method_context_add_commit_string_listener(context->context,
2125         &context->im_context_commit_string);
2126
2127     context->im_context_preedit_string.notify = context_handle_preedit_string;
2128     ds_tizen_input_method_context_add_preedit_string_listener(context->context,
2129         &context->im_context_preedit_string);
2130
2131     context->im_context_preedit_styling.notify = context_handle_preedit_styling;
2132     ds_tizen_input_method_context_add_preedit_styling_listener(context->context,
2133         &context->im_context_preedit_styling);
2134
2135     context->im_context_preedit_cursor.notify = context_handle_preedit_cursor;
2136     ds_tizen_input_method_context_add_preedit_cursor_listener(context->context,
2137         &context->im_context_preedit_cursor);
2138
2139     context->im_context_delete_surrounding_text.notify = context_handle_delete_surrounding_text;
2140     ds_tizen_input_method_context_add_delete_surrounding_text_listener(context->context,
2141         &context->im_context_delete_surrounding_text);
2142
2143     context->im_context_cursor_position.notify = context_handle_cursor_position;
2144     ds_tizen_input_method_context_add_cursor_position_listener(context->context,
2145         &context->im_context_cursor_position);
2146
2147     context->im_context_modifiers_map.notify = context_handle_modifiers_map;
2148     ds_tizen_input_method_context_add_modifiers_map_listener(context->context,
2149         &context->im_context_modifiers_map);
2150
2151     context->im_context_keysym.notify = context_handle_keysym;
2152     ds_tizen_input_method_context_add_keysym_listener(context->context,
2153         &context->im_context_keysym);
2154
2155     context->im_context_grab_keyboard.notify = context_handle_grab_keyboard;
2156     ds_tizen_input_method_context_add_grab_keyboard_listener(context->context,
2157         &context->im_context_grab_keyboard);
2158
2159     context->im_context_key.notify = context_handle_key;
2160     ds_tizen_input_method_context_add_key_listener(context->context,
2161         &context->im_context_key);
2162
2163     context->im_context_modifiers.notify = context_handle_modifiers;
2164     ds_tizen_input_method_context_add_modifiers_listener(context->context,
2165         &context->im_context_modifiers);
2166
2167     context->im_context_language.notify = context_handle_language;
2168     ds_tizen_input_method_context_add_language_listener(context->context,
2169         &context->im_context_language);
2170
2171     context->im_context_text_direction.notify = context_handle_text_direction;
2172     ds_tizen_input_method_context_add_text_direction_listener(context->context,
2173         &context->im_context_text_direction);
2174
2175     return true;
2176 }
2177
2178 struct tinyds_view *
2179 tinyds_server_get_focused_view(struct tinyds_server *server)
2180 {
2181     struct tinyds_view *view = NULL;
2182     struct tinyds_pointer *pointer;
2183
2184     wl_list_for_each(pointer, &server->pointers, link){
2185         if (!pointer->focused_view) continue;
2186
2187         view = pointer->focused_view;
2188     }
2189
2190     return view;
2191 }
2192
2193 void
2194 tinyds_server_get_output_size(struct tinyds_server *server,
2195     int *output_w, int *output_h)
2196 {
2197     *output_w = server->output->width;
2198     *output_h = server->output->height;
2199 }