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