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