8 #include <drm_fourcc.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>
34 #define USE_TDM_BUFFER_QUEUE
36 #ifdef USE_TDM_BUFFER_QUEUE
37 #include "pixman-tbm-helper.h"
38 #include "tinyds-tdm-renderer.h"
40 #include <libds/swapchain.h>
43 #include "pixman-helper.h"
45 #define TINYDS_UNUSED __attribute__((unused))
46 struct tinyds_keyboard;
47 struct tinyds_pointer;
51 struct tinyds_server *server;
52 struct ds_output *ds_output;
53 struct ds_allocator *allocator;
54 #ifdef USE_TDM_BUFFER_QUEUE
55 struct tinyds_renderer renderer;
56 struct ds_tdm_buffer_queue *buffer_queue;
57 struct wl_listener buffer_queue_acquirable;
59 struct ds_swapchain *swapchain;
61 struct ds_buffer *front_buffer;
63 struct wl_listener output_destroy;
64 struct wl_listener output_frame;
68 struct wl_event_source *idle_commit;
73 struct ds_tdm_output_hwc *hwc;
74 struct ds_tdm_output_hwc_window *bg_hwc_window;
79 struct ds_tizen_dpms *ds_dpms;
80 struct tinyds_server *server;
82 struct wl_listener destroy;
83 struct wl_listener set_dpms;
84 struct wl_listener get_dpms;
89 struct ds_tbm_server *tbm_server;
91 struct wl_display *display;
93 struct ds_backend *backend;
94 struct ds_backend *input_backend;
95 struct ds_compositor *compositor;
96 struct ds_xdg_shell *xdg_shell;
99 double output_x, output_y;
100 struct ds_tizen_input_devicemgr *devicemgr;
101 struct ds_tizen_launch_effect *effect;
102 struct ds_tizen_launch_splash *splash;
104 struct tinyds_output *output;
105 struct tinyds_dpms *dpms;
106 struct wl_event_source *stdin_source;
108 struct wl_list views;
110 struct wl_listener new_output;
111 struct wl_listener new_input;
112 struct wl_listener new_xdg_surface;
113 struct wl_listener devicemgr_destroy;
114 struct wl_listener pointer_warp;
115 struct wl_listener effect_destroy;
116 struct wl_listener effect_type_set;
117 struct wl_listener effect_type_unset;
118 struct wl_listener new_splash;
119 struct wl_listener splash_owner;
121 struct wl_list keyboards;
122 struct wl_list pointers;
124 struct tinyds_text_input *text_input;
125 struct tinyds_input_method *input_method;
130 struct tinyds_server *server;
132 struct tinyds_texture *texture;
133 struct ds_xdg_surface *xdg_surface;
135 struct wl_listener xdg_surface_map;
136 struct wl_listener xdg_surface_unmap;
137 struct wl_listener xdg_surface_destroy;
138 struct wl_listener surface_commit;
139 struct wl_list link; // tinyds_server::views
141 struct ds_tdm_output_hwc_window *hwc_window;
150 struct tinyds_pointer
152 struct ds_input_device *dev;
153 struct tinyds_server *server;
155 struct tinyds_view *focused_view;
157 struct wl_listener destroy;
158 struct wl_listener motion; //relative
159 struct wl_listener button;
160 struct wl_listener frame;
161 struct wl_list link; //tinyds_server::pointers
164 struct tinyds_keyboard
166 struct ds_input_device *dev;
167 struct tinyds_server *server;
169 struct wl_listener destroy;
170 struct wl_listener key;
171 struct wl_list link; //tinyds_server::keyboards
176 struct ds_input_device *dev;
177 struct tinyds_server *server;
179 struct wl_listener destroy;
180 struct wl_listener down;
181 struct wl_listener up;
182 struct wl_listener motion;
185 struct tinyds_text_input {
186 struct ds_tizen_text_input *input;
187 struct ds_tizen_text_input_manager *text_input_mgr;
189 struct tinyds_server *server;
190 struct ds_surface *surface;
192 struct wl_list input_methods;
194 struct wl_listener destroy;
195 struct wl_listener mgr_destroy;
197 struct wl_listener new_text_input;
199 struct wl_listener text_input_activate;
200 struct wl_listener text_input_deactivate;
201 struct wl_listener text_input_reset;
202 struct wl_listener text_input_set_content_type;
203 struct wl_listener text_input_invoke_action;
204 struct wl_listener text_input_commit_state;
205 struct wl_listener text_input_set_preferred_language;
208 struct tinyds_input_method {
209 struct ds_tizen_input_method *input_method;
210 struct ds_tizen_input_method_manager *input_method_mgr;
212 struct tinyds_server *server;
213 struct tinyds_text_input *input;
214 struct tinyds_input_method_context *context;
218 struct wl_listener destroy;
219 struct wl_listener mgr_destroy;
221 struct wl_listener new_im_context;
224 struct tinyds_input_method_context {
225 struct ds_tizen_input_method_context *context;
227 struct tinyds_server *server;
228 struct tinyds_text_input *input;
229 struct tinyds_input_method *input_method;
231 struct wl_listener destroy;
233 struct wl_listener im_context_commit_string;
234 struct wl_listener im_context_preedit_string;
235 struct wl_listener im_context_preedit_styling;
236 struct wl_listener im_context_preedit_cursor;
237 struct wl_listener im_context_delete_surrounding_text;
238 struct wl_listener im_context_cursor_position;
239 struct wl_listener im_context_modifiers_map;
240 struct wl_listener im_context_keysym;
241 struct wl_listener im_context_grab_keyboard;
242 struct wl_listener im_context_key;
243 struct wl_listener im_context_modifiers;
244 struct wl_listener im_context_language;
245 struct wl_listener im_context_text_direction;
248 struct tinyds_server tinyds;
250 static bool init_server(struct tinyds_server *server, struct wl_display *display);
251 static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
252 static void output_handle_destroy(struct wl_listener *listener, void *data);
253 static void output_handle_frame(struct wl_listener *listener, void *data);
254 static void draw_server_with_damage(struct tinyds_server *server);
255 static void draw_output(struct tinyds_output *output);
256 static void output_swap_buffer(struct tinyds_output *output,
257 struct ds_buffer *buffer);
258 static void view_send_frame_done(struct tinyds_view *view);
259 static void output_hwc_init(struct tinyds_output *output);
260 static void output_schedule_commit(struct tinyds_output *output);
261 static void output_commit(struct tinyds_output *output);
262 #ifdef USE_TDM_BUFFER_QUEUE
263 static void output_buffer_queue_init(struct tinyds_output *output);
264 static void output_renderer_init(struct tinyds_output *output);
265 static void output_draw_with_renderer(struct tinyds_output *output);
267 static void output_swapchain_init(struct tinyds_output *output,
268 int width, int height, uint32_t format);
269 static void output_draw_with_swapchain(struct tinyds_output *output);
270 static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
272 static void dpms_handle_destroy(struct wl_listener *listener, void *data);
273 static void dpms_handle_set_dpms(struct wl_listener *listener, void *data);
274 static void dpms_handle_get_dpms(struct wl_listener *listener, void *data);
275 static void server_add_keyboard(struct tinyds_server *server,
276 struct ds_input_device *dev);
277 static void server_add_pointer(struct tinyds_server *server,
278 struct ds_input_device *dev);
279 static void server_add_touch(struct tinyds_server *server,
280 struct ds_input_device *dev);
282 static struct tinyds_view *
283 server_view_at(struct tinyds_server *server, double lx, double ly,
284 double *sx, double *sy);
286 static bool add_new_text_input(struct tinyds_server *server);
287 static bool add_new_input_method(struct tinyds_server *server);
289 static void text_input_mgr_handle_destroy(struct wl_listener *listener,
290 void *data TINYDS_UNUSED);
291 static void text_input_mgr_handle_new_text_input(struct wl_listener *listener,
292 void *data TINYDS_UNUSED);
294 static void input_method_mgr_handle_destroy(struct wl_listener *listener,
295 void *data TINYDS_UNUSED);
297 static void input_method_handle_destroy(struct wl_listener *listener,
298 void *data TINYDS_UNUSED);
299 static void input_method_handle_new_im_context(struct wl_listener *listener,
300 void *data TINYDS_UNUSED);
305 struct tinyds_server *server = &tinyds;
306 struct wl_display *display;
307 struct wl_event_loop *loop;
311 ds_log_init(DS_INF, NULL);
313 display = wl_display_create();
316 res = init_server(server, display);
319 socket = wl_display_add_socket_auto(display);
322 ds_backend_start(server->backend);
323 ds_backend_start(server->input_backend);
325 setenv("WAYLAND_DISPLAY", socket, true);
327 ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
329 loop = wl_display_get_event_loop(display);
330 server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
331 WL_EVENT_READABLE, server_dispatch_stdin, server);
333 wl_display_run(display);
335 wl_display_destroy_clients(display);
336 wl_display_destroy(display);
342 view_populate_pid(struct tinyds_view *view)
345 struct wl_client *client = NULL;
346 struct ds_surface *surface;
348 surface = ds_xdg_surface_get_surface(view->xdg_surface);
352 client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
356 wl_client_get_credentials(client, &pid, NULL, NULL);
358 ds_inf("view pid(%u)", pid);
361 view->effect_type = ds_tizen_launch_effect_get_effect_type(view->server->effect, pid);
362 ds_tizen_launch_effect_unset_effect_type(view->server->effect, pid);
363 ds_inf("view effect_type(%d)", view->effect_type);
367 view_handle_xdg_surface_map(struct wl_listener *listener,
368 void *data TINYDS_UNUSED)
370 struct tinyds_view *view;
371 struct ds_keyboard *keyboard;
372 struct tinyds_keyboard *kbd;
374 view = wl_container_of(listener, view, xdg_surface_map);
377 view_populate_pid(view);
379 wl_list_for_each(kbd, &view->server->keyboards, link) {
380 keyboard = ds_input_device_get_keyboard(kbd->dev);
381 if (keyboard != NULL) {
382 ds_seat_keyboard_notify_enter(view->server->seat,
383 ds_xdg_surface_get_surface(view->xdg_surface),
384 keyboard->keycodes, keyboard->num_keycodes,
385 &keyboard->modifiers);
392 view_handle_xdg_surface_unmap(struct wl_listener *listener,
393 void *data TINYDS_UNUSED)
395 struct tinyds_view *view;
397 view = wl_container_of(listener, view, xdg_surface_unmap);
398 view->mapped = false;
402 view_handle_xdg_surface_destroy(struct wl_listener *listener,
403 void *data TINYDS_UNUSED)
405 struct tinyds_view *view;
407 view = wl_container_of(listener, view, xdg_surface_destroy);
409 draw_server_with_damage(view->server);
411 ds_tdm_output_hwc_window_destroy(view->hwc_window);
413 wl_list_remove(&view->xdg_surface_destroy.link);
414 wl_list_remove(&view->xdg_surface_map.link);
415 wl_list_remove(&view->xdg_surface_unmap.link);
416 wl_list_remove(&view->surface_commit.link);
417 wl_list_remove(&view->link);
422 view_handle_surface_commit(struct wl_listener *listener,
423 void *data TINYDS_UNUSED)
425 struct tinyds_view *view;
427 view = wl_container_of(listener, view, surface_commit);
428 draw_server_with_damage(view->server);
432 server_new_xdg_surface(struct wl_listener *listener, void *data)
434 struct tinyds_server *server;
435 struct tinyds_view *view;
436 struct ds_xdg_surface *xdg_surface;
438 server = wl_container_of(listener, server, new_xdg_surface);
441 ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
443 view = calloc(1, sizeof *view);
446 view->server = server;
447 view->xdg_surface = xdg_surface;
449 view->xdg_surface_map.notify = view_handle_xdg_surface_map;
450 ds_xdg_surface_add_map_listener(xdg_surface,
451 &view->xdg_surface_map);
453 view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
454 ds_xdg_surface_add_unmap_listener(xdg_surface,
455 &view->xdg_surface_unmap);
457 view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
458 ds_xdg_surface_add_destroy_listener(xdg_surface,
459 &view->xdg_surface_destroy);
461 view->surface_commit.notify = view_handle_surface_commit;
462 ds_surface_add_commit_listener(
463 ds_xdg_surface_get_surface(xdg_surface),
464 &view->surface_commit);
466 view->x = rand() % 1000;
467 view->y = rand() % 500;
469 view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
470 assert(view->hwc_window);
472 wl_list_insert(server->views.prev, &view->link);
475 view->effect_type = -1;
477 ds_inf("view at (%d, %d)", view->x, view->y);
481 backend_handle_new_output(struct wl_listener *listener, void *data)
483 struct tinyds_server *server;
484 struct tinyds_output *output;
485 struct ds_output *ds_output;
486 const struct ds_output_mode *mode;
487 struct ds_tdm_box src_box;
489 server = wl_container_of(listener, server, new_output);
492 ds_inf("New output(%p)", ds_output);
497 mode = ds_output_get_preferred_mode(ds_output);
498 ds_output_set_mode(ds_output, mode);
500 output = calloc(1, sizeof *output);
504 output->server = server;
505 output->ds_output = ds_output;
506 output->width = mode->width;
507 output->height = mode->height;
508 output->damaged = true;
509 output->committable = true;
511 output_hwc_init(output);
513 #ifdef USE_TDM_BUFFER_QUEUE
514 output_buffer_queue_init(output);
515 output_renderer_init(output);
517 output_swapchain_init(output, mode->width, mode->height,
518 DRM_FORMAT_XRGB8888);
521 output->bg_hwc_window = ds_tdm_output_hwc_window_create(output->hwc);
522 assert(output->bg_hwc_window);
526 src_box.width = output->width;
527 src_box.height = output->height;
529 ds_tdm_output_hwc_window_set_src_box(output->bg_hwc_window, &src_box);
530 ds_tdm_output_hwc_window_set_position(output->bg_hwc_window, 0, 0);
531 ds_tdm_output_hwc_window_set_dest_size(output->bg_hwc_window, output->width, output->height);
532 ds_tdm_output_hwc_window_set_transform(output->bg_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
534 output->output_destroy.notify = output_handle_destroy;
535 ds_output_add_destroy_listener(ds_output, &output->output_destroy);
537 output->output_frame.notify = output_handle_frame;
538 ds_output_add_frame_listener(ds_output, &output->output_frame);
540 ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height);
542 server->output = output;
544 output_schedule_commit(output);
548 add_new_dpms(struct tinyds_server *server)
550 struct tinyds_dpms *dpms;
552 dpms = calloc(1, sizeof *dpms);
556 dpms->ds_dpms = ds_tizen_dpms_create(server->display);
557 if (!dpms->ds_dpms) {
559 ds_err("Could not create ds_tizen_dpms");
563 dpms->destroy.notify = dpms_handle_destroy;
564 ds_tizen_dpms_add_destroy_listener(dpms->ds_dpms, &dpms->destroy);
566 dpms->set_dpms.notify = dpms_handle_set_dpms;
567 ds_tizen_dpms_add_set_dpms_listener(dpms->ds_dpms, &dpms->set_dpms);
569 dpms->get_dpms.notify = dpms_handle_get_dpms;
570 ds_tizen_dpms_add_get_dpms_listener(dpms->ds_dpms, &dpms->get_dpms);
574 ds_inf("Dpms (%p) added", dpms);
580 backend_handle_new_input(struct wl_listener *listener, void *data)
582 struct tinyds_server *server;
583 struct ds_input_device *dev = data;
584 enum ds_input_device_type dev_type;
586 server = wl_container_of(listener, server, new_input);
588 dev_type = ds_input_device_get_type(dev);
591 case DS_INPUT_DEVICE_KEYBOARD:
592 server_add_keyboard(server, dev);
593 server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD;
595 case DS_INPUT_DEVICE_TOUCH:
596 server_add_touch(server, dev);
597 server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH;
599 case DS_INPUT_DEVICE_POINTER:
600 server_add_pointer(server, dev);
601 server->seat_caps |= WL_SEAT_CAPABILITY_POINTER;
604 ds_err("Unknown type(%d) of ds_input_device", dev_type);
608 ds_seat_set_capabilities(server->seat, server->seat_caps);
612 devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode)
614 struct ds_tizen_input_devicemgr_keymap_data *data;
616 data = calloc(1, sizeof *data);
618 ds_err("Failed to alloc memory");
622 data->name = strdup(name);
623 data->keycode = keycode;
625 wl_list_insert(list, &data->link);
629 devicemgr_cleanup_keymap_list(struct wl_list *list)
631 struct ds_tizen_input_devicemgr_keymap_data *data, *tmp;
633 wl_list_for_each_safe(data, tmp, list, link) {
634 wl_list_remove(&data->link);
641 devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr)
643 struct wl_list keymap_list;
646 wl_list_init(&keymap_list);
648 devicemgr_add_keymap_data(&keymap_list, "XF86VolumeRaise", 455);
649 devicemgr_add_keymap_data(&keymap_list, "XF86VolumeLower", 456);
650 devicemgr_add_keymap_data(&keymap_list, "XF86LightOn", 457);
651 devicemgr_add_keymap_data(&keymap_list, "XF86LightOff", 458);
653 res = ds_tizen_input_devicemgr_set_keymap_list(devicemgr, &keymap_list);
655 ds_inf("Failed to set keymap");
657 devicemgr_cleanup_keymap_list(&keymap_list);
661 devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data)
663 struct tinyds_server *server;
664 struct tinyds_pointer *pointer;
665 struct ds_tizen_input_devicemgr_event_pointer_warp *event = data;
666 double sx = 0.f, sy = 0.f;
667 struct tinyds_view *view = NULL;
669 server = wl_container_of(listener, server, pointer_warp);
671 ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface,
674 wl_list_for_each(pointer, &server->pointers, link){
675 if (!pointer->focused_view) continue;
676 view = pointer->focused_view;
680 if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) {
681 ds_inf("Pointer is not on the requested surface");
685 server->output_x = view->x + (event->x * server->output->width);
686 server->output_y = view->y + (event->y * server->output->height);
688 server_view_at(server, server->output_x, server->output_y, &sx, &sy);
690 ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f",
691 sx, sy, server->output_x, server->output_y);
693 ds_seat_pointer_notify_motion(server->seat,
694 event->time_msec, sx, sy);
698 devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
700 struct tinyds_server *server =
701 wl_container_of(listener, server, devicemgr_destroy);
703 wl_list_remove(&server->devicemgr_destroy.link);
704 wl_list_remove(&server->pointer_warp.link);
706 server->devicemgr = NULL;
710 launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
712 struct tinyds_server *server =
713 wl_container_of(listener, server, effect_destroy);
715 wl_list_remove(&server->effect_destroy.link);
716 wl_list_remove(&server->effect_type_set.link);
717 wl_list_remove(&server->effect_type_unset.link);
718 wl_list_remove(&server->new_splash.link);
720 server->effect = NULL;
724 launch_effect_handle_type_set(struct wl_listener *listener, void *data)
726 struct tinyds_server *server;
727 struct ds_tizen_launch_effect_event_type_set *event = data;
728 struct tinyds_view *view = NULL;
729 bool existing = false;
731 server = wl_container_of(listener, server, effect_type_set);
733 ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch");
735 wl_list_for_each(view, &server->views, link) {
736 if (view->pid == event->pid) {
737 view->effect_type = event->effect_type;
738 ds_inf("Launch effect. existing pid");
743 ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid);
745 ds_tizen_launch_effect_set_effect_type(server->effect, event->pid, event->effect_type);
750 launch_effect_handle_type_unset(struct wl_listener *listener, void *data)
752 struct tinyds_server *server;
753 struct ds_tizen_launch_effect_event_type_unset *event = data;
754 struct tinyds_view *view = NULL;
756 server = wl_container_of(listener, server, effect_type_unset);
758 ds_inf("Launch effect. type_unset: pid(%u)", event->pid);
760 wl_list_for_each(view, &server->views, link) {
761 if (view->pid == event->pid) {
762 view->effect_type = -1;
763 ds_inf("Launch effect. pid found");
766 ds_tizen_launch_effect_unset_effect_type(server->effect, event->pid);
770 launch_splash_handle_owner(struct wl_listener *listener, void *data)
772 struct tinyds_server *server;
773 struct ds_tizen_launch_splash_event_owner *event = data;
774 struct tinyds_view *view = NULL;
776 server = wl_container_of(listener, server, splash_owner);
778 ds_inf("Splash owner. pid(%u)", event->pid);
780 wl_list_for_each(view, &server->views, link) {
781 if (view->pid == event->pid) {
782 if (event->pid == ds_tizen_launch_splash_get_pid(server->splash))
785 ds_tizen_launch_splash_set_pid(server->splash, event->pid);
792 launch_effect_handle_new_splash(struct wl_listener *listener, void *data)
794 struct tinyds_server *server;
795 struct ds_tizen_launch_splash *splash = data;
796 struct tinyds_view *view = NULL;
798 server = wl_container_of(listener, server, new_splash);
800 ds_inf("Launch new splash. splash(%p)", splash);
803 server->splash = splash;
805 // new view for "Launchscreen"
806 view = calloc(1, sizeof *view);
808 wl_list_insert(server->views.prev, &view->link);
809 view->pid = ds_tizen_launch_splash_get_pid(splash);
811 server->splash_owner.notify = launch_splash_handle_owner;
812 ds_tizen_launch_splash_add_owner_listener(server->splash,
813 &server->splash_owner);
817 init_server(struct tinyds_server *server, struct wl_display *display)
819 server->display = display;
821 wl_list_init(&server->views);
823 if (wl_display_init_shm(display) != 0)
826 server->backend = ds_tdm_backend_create(display);
827 if (!server->backend)
830 server->input_backend = ds_libinput_backend_create(display);
831 if (!server->input_backend) {
832 ds_backend_destroy(server->backend);
836 server->new_output.notify = backend_handle_new_output;
837 ds_backend_add_new_output_listener(server->backend,
838 &server->new_output);
840 wl_list_init(&server->keyboards);
841 wl_list_init(&server->pointers);
842 server->new_input.notify = backend_handle_new_input;
843 ds_backend_add_new_input_listener(server->input_backend, &server->new_input);
845 server->compositor = ds_compositor_create(display);
846 if (!server->compositor)
849 server->tbm_server = ds_tbm_server_create(display);
850 if (!server->tbm_server)
853 server->xdg_shell = ds_xdg_shell_create(display);
854 if (!server->xdg_shell)
857 server->new_xdg_surface.notify = server_new_xdg_surface;
858 ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
859 &server->new_xdg_surface);
861 if (!add_new_dpms(server))
864 server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
867 server->seat_caps = 0;
869 server->devicemgr = ds_tizen_input_devicemgr_create(
870 server->input_backend, server->seat);
871 if (!server->devicemgr) {
872 ds_err("Could not create ds_tizen_input_devicemgr");
876 devicemgr_set_keymap(server->devicemgr);
878 server->devicemgr_destroy.notify = devicemgr_handle_destroy;
879 ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr,
880 &server->devicemgr_destroy);
882 server->pointer_warp.notify = devicemgr_handle_pointer_warp;
883 ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr,
884 &server->pointer_warp);
886 server->effect = ds_tizen_launch_effect_create(display);
887 if (!server->effect) {
891 server->effect_destroy.notify = launch_effect_handle_destroy;
892 ds_tizen_launch_effect_add_destroy_listener(server->effect,
893 &server->effect_destroy);
895 server->effect_type_set.notify = launch_effect_handle_type_set;
896 ds_tizen_launch_effect_add_type_set_listener(server->effect,
897 &server->effect_type_set);
899 server->effect_type_unset.notify = launch_effect_handle_type_unset;
900 ds_tizen_launch_effect_add_type_unset_listener(server->effect,
901 &server->effect_type_unset);
903 server->new_splash.notify = launch_effect_handle_new_splash;
904 ds_tizen_launch_effect_add_new_splash_listener(server->effect,
905 &server->new_splash);
907 if (!add_new_text_input(server))
910 if (!add_new_input_method(server))
916 ds_backend_destroy(server->backend);
917 ds_backend_destroy(server->input_backend);
923 output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
925 struct tinyds_output *output =
926 wl_container_of(listener, output, output_destroy);
928 if (output->bg_hwc_window)
929 ds_tdm_output_hwc_window_destroy(output->bg_hwc_window);
931 wl_list_remove(&output->output_destroy.link);
932 wl_list_remove(&output->output_frame.link);
934 if (output->front_buffer)
935 ds_buffer_unlock(output->front_buffer);
937 #ifdef USE_TDM_BUFFER_QUEUE
938 fini_renderer(&output->renderer);
940 if (output->swapchain)
941 ds_swapchain_destroy(output->swapchain);
943 if (output->allocator)
944 ds_allocator_destroy(output->allocator);
947 wl_display_terminate(output->server->display);
949 output->server->output = NULL;
955 output_commit(struct tinyds_output *output)
957 uint32_t num_changed = 0;
958 uint32_t num_windows = 0, current_num_windows = 0;
959 struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL;
960 struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL;
961 enum ds_tdm_output_hwc_window_composition composition;
962 struct tinyds_view *view;
964 bool need_target = false;
965 bool fully_obscured = false;
966 struct ds_buffer *ds_buffer;
967 struct ds_tdm_box src_box;
970 if (!output->committable)
973 if (!output->damaged && !output->target_updated)
976 wl_list_for_each_reverse(view, &output->server->views, link) {
977 if (!view->hwc_window)
980 ds_buffer = ds_surface_get_buffer(
981 ds_xdg_surface_get_surface(view->xdg_surface));
990 ds_buffer_get_size(ds_buffer, &w, &h);
992 if ((output->width <= w) && (output->height <= h))
993 fully_obscured = true;
996 if (fully_obscured) {
997 ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
998 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
1000 ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
1001 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
1007 composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows);
1008 if (!composited_hwc_windows)
1011 wl_list_for_each_reverse(view, &output->server->views, link) {
1012 if (!view->hwc_window)
1015 ds_buffer = ds_surface_get_buffer(
1016 ds_xdg_surface_get_surface(view->xdg_surface));
1020 ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer);
1022 ds_buffer_get_size(ds_buffer, &w, &h);
1029 ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box);
1030 ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y);
1031 ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h);
1032 ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
1035 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
1036 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE);
1038 composited_hwc_windows[current_num_windows] = view->hwc_window;
1039 current_num_windows++;
1041 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
1042 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
1046 if (!fully_obscured) {
1047 composited_hwc_windows[current_num_windows] = output->bg_hwc_window;
1048 current_num_windows++;
1052 if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows,
1053 num_windows, &num_changed)) {
1054 free(composited_hwc_windows);
1055 ds_err("Could not hwc validate");
1059 if (composited_hwc_windows)
1060 free(composited_hwc_windows);
1062 if (num_changed > 0) {
1063 changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows);
1064 if (!changed_hwc_windows)
1067 if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed,
1068 changed_hwc_windows)) {
1069 free(changed_hwc_windows);
1070 ds_err("Could not get chaged composition");
1074 for (i = 0; i < num_changed; i++) {
1075 composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]);
1076 if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) {
1083 if (changed_hwc_windows)
1084 free(changed_hwc_windows);
1086 if (need_target && output->damaged)
1087 draw_output(output);
1089 #ifdef USE_TDM_BUFFER_QUEUE
1090 struct ds_buffer *buffer;
1092 buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
1094 if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, buffer)) {
1095 ds_err("Could not set hwc client target buffer");
1099 output_swap_buffer(output, buffer);
1103 if (!ds_tdm_output_hwc_accept_validation(output->hwc)) {
1104 ds_err("Could not hwc accept validateion");
1108 ds_output_commit(output->ds_output);
1110 output->committable = false;
1111 output->damaged = false;
1112 output->target_updated = false;
1114 wl_list_for_each(view, &output->server->views, link) {
1115 enum ds_tdm_output_hwc_window_composition composition;
1120 composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
1121 if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
1122 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
1123 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
1124 view_send_frame_done(view);
1127 ds_dbg("output:%p commit", output);
1131 output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
1133 struct tinyds_output *output =
1134 wl_container_of(listener, output, output_frame);
1136 ds_dbg("output:%p handle frame", output);
1138 output->committable = true;
1140 output_commit(output);
1144 draw_server_with_damage(struct tinyds_server *server)
1146 server->output->damaged = true;
1147 output_schedule_commit(server->output);
1151 output_hwc_init(struct tinyds_output *output)
1153 struct ds_tdm_output *tdm_output;
1155 tdm_output = ds_tdm_output_from_output(output->ds_output);
1158 output->hwc = ds_tdm_output_get_hwc(tdm_output);
1159 assert(output->hwc);
1161 ds_tdm_output_hwc_set_enabled(output->hwc, true);
1164 #ifdef USE_TDM_BUFFER_QUEUE
1166 output_handle_buffer_queue_acquirable(struct wl_listener *listener,
1167 void *data TINYDS_UNUSED)
1169 struct tinyds_output *output;
1171 output = wl_container_of(listener, output, buffer_queue_acquirable);
1173 output->target_updated = true;
1174 output_schedule_commit(output);
1178 output_buffer_queue_init(struct tinyds_output *output)
1180 struct ds_tdm_output *tdm_output;
1182 tdm_output = ds_tdm_output_from_output(output->ds_output);
1185 output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
1186 assert(output->buffer_queue);
1188 output->buffer_queue_acquirable.notify =
1189 output_handle_buffer_queue_acquirable;
1190 ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
1191 &output->buffer_queue_acquirable);
1195 output_renderer_init(struct tinyds_output *output)
1197 init_renderer(&output->renderer);
1199 renderer_set_surface_queue(&output->renderer,
1200 ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
1202 renderer_set_bg_color(&output->renderer, 80, 80, 80);
1206 output_draw_with_renderer(struct tinyds_output *output)
1208 struct tinyds_view *view;
1210 ds_dbg(">> BEGIN UPDATE TEXTURES");
1212 wl_list_for_each(view, &output->server->views, link) {
1213 struct ds_buffer *ds_buffer;
1214 struct ds_tbm_client_buffer *tbm_buffer;
1215 tbm_surface_h surface;
1216 enum ds_tdm_output_hwc_window_composition composition;
1221 composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
1222 if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
1223 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
1224 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
1227 ds_buffer = ds_surface_get_buffer(
1228 ds_xdg_surface_get_surface(view->xdg_surface));
1232 tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
1236 surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
1240 renderer_add_texture(&output->renderer, surface, view->x, view->y);
1242 view_send_frame_done(view);
1245 ds_dbg("<< END UPDATE TEXTURES");
1247 renderer_draw(&output->renderer);
1251 output_swapchain_init(struct tinyds_output *output,
1252 int width, int height, uint32_t format)
1255 output->allocator = ds_tbm_allocator_create();
1256 assert(output->allocator);
1258 output->swapchain = ds_swapchain_create(output->allocator,
1259 width, height, format);
1260 assert(output->swapchain);
1264 output_draw_with_swapchain(struct tinyds_output *output)
1266 struct tinyds_view *view;
1267 struct ds_buffer *output_buffer;
1268 pixman_image_t *output_image;
1269 enum ds_tdm_output_hwc_window_composition composition;
1271 output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
1275 output_image = pixman_image_from_buffer(output_buffer,
1276 DS_BUFFER_DATA_PTR_ACCESS_WRITE);
1277 if (!output_image) {
1278 ds_buffer_unlock(output_buffer);
1282 pixman_image_fill_color(output_image, 80, 80, 80);
1284 wl_list_for_each(view, &output->server->views, link) {
1288 composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
1289 if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
1290 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
1291 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
1294 draw_view(view, output_image);
1296 pixman_image_unref(output_image);
1298 if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, output_buffer)) {
1299 ds_err("Could not set hwc client target buffer");
1300 ds_buffer_unlock(output_buffer);
1304 output_swap_buffer(output, output_buffer);
1308 draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
1310 struct ds_buffer *buffer;
1311 pixman_image_t *src_image;
1313 buffer = ds_surface_get_buffer(
1314 ds_xdg_surface_get_surface(view->xdg_surface));
1318 src_image = pixman_image_from_buffer(buffer,
1319 DS_BUFFER_DATA_PTR_ACCESS_READ);
1320 pixman_image_composite32(PIXMAN_OP_OVER,
1326 pixman_image_get_width(src_image),
1327 pixman_image_get_height(src_image));
1328 pixman_image_unref(src_image);
1330 view_send_frame_done(view);
1335 draw_output(struct tinyds_output *output)
1337 #ifdef USE_TDM_BUFFER_QUEUE
1338 output_draw_with_renderer(output);
1340 output_draw_with_swapchain(output);
1343 ds_dbg("output:%p draw", output);
1347 output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
1349 ds_output_attach_buffer(output->ds_output, buffer);
1351 if (output->front_buffer)
1352 ds_buffer_unlock(output->front_buffer);
1353 output->front_buffer = buffer;
1357 view_send_frame_done(struct tinyds_view *view)
1359 struct timespec now;
1360 clock_gettime(CLOCK_MONOTONIC, &now);
1361 ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
1366 server_dispatch_stdin(int fd, uint32_t mask, void *data)
1368 struct tinyds_server *server = data;
1370 wl_display_terminate(server->display);
1376 dpms_handle_destroy(struct wl_listener *listener, void *data)
1378 struct tinyds_dpms *dpms;
1380 dpms = wl_container_of(listener, dpms, destroy);
1382 ds_inf("Dpms(%p) destroyed", dpms);
1384 wl_list_remove(&dpms->destroy.link);
1385 wl_list_remove(&dpms->set_dpms.link);
1386 wl_list_remove(&dpms->get_dpms.link);
1392 dpms_handle_set_dpms(struct wl_listener *listener, void *data)
1394 struct tinyds_dpms *dpms;
1395 struct ds_tizen_dpms_event *event = data;
1397 dpms = wl_container_of(listener, dpms, set_dpms);
1399 ds_inf("Dpms(%p) set dpms : %d", dpms, event->mode);
1402 //set dpms mode to output
1403 ds_tizen_dpms_send_set_result(dpms->ds_dpms, event->mode,
1404 DS_TIZEN_DPMS_ERROR_NONE);
1408 dpms_handle_get_dpms(struct wl_listener *listener, void *data)
1410 struct tinyds_dpms *dpms;
1412 dpms = wl_container_of(listener, dpms, get_dpms);
1414 ds_inf("Dpms(%p) get dpms", dpms);
1417 //get dpms mode from output
1418 ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON,
1419 DS_TIZEN_DPMS_ERROR_NONE);
1423 keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
1425 struct tinyds_keyboard *kbd;
1427 kbd = wl_container_of(listener, kbd, destroy);
1429 ds_inf("Keyboard(%p) destroyed", kbd);
1431 wl_list_remove(&kbd->destroy.link);
1432 wl_list_remove(&kbd->key.link);
1433 wl_list_remove(&kbd->link);
1439 server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
1442 case XKB_KEY_BackSpace:
1443 wl_display_terminate(server->display);
1453 keyboard_handle_key(struct wl_listener *listener, void *data)
1455 struct tinyds_keyboard *kbd;
1456 struct ds_event_keyboard_key *event = data;
1457 struct ds_keyboard *ds_keyboard;
1458 struct xkb_state *xkb_state;
1459 const xkb_keysym_t *syms;
1461 bool handled = false;
1463 kbd = wl_container_of(listener, kbd, key);
1465 ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
1466 "update_state(%d)", kbd->dev,
1467 event->keycode, event->state, event->time_msec,
1468 event->update_state);
1470 ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
1472 if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1473 xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
1475 nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
1477 for (int i = 0; i < nsyms; i++) {
1478 handled = server_handle_keybinding(kbd->server, syms[i]);
1484 ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec,
1485 event->keycode, event->state);
1490 server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
1492 struct tinyds_keyboard *kbd;
1493 struct xkb_context *context;
1494 struct xkb_keymap *keymap;
1496 kbd = calloc(1, sizeof *kbd);
1500 kbd->server = server;
1502 context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
1506 keymap = xkb_keymap_new_from_names(context, NULL,
1507 XKB_KEYMAP_COMPILE_NO_FLAGS);
1510 ds_err("Failed to compile keymap");
1511 xkb_context_unref(context);
1515 ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap);
1517 xkb_keymap_unref(keymap);
1518 xkb_context_unref(context);
1520 kbd->destroy.notify = keyboard_handle_device_destroy;
1521 ds_input_device_add_destroy_listener(dev, &kbd->destroy);
1523 kbd->key.notify = keyboard_handle_key;
1524 ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
1526 wl_list_insert(&server->keyboards, &kbd->link);
1528 ds_inf("Keyboard(%p) added", kbd);
1536 static struct tinyds_view *
1537 server_view_at(struct tinyds_server *server, double lx, double ly,
1538 double *sx, double *sy)
1540 struct tinyds_view *view;
1541 struct ds_surface *surface;
1542 struct ds_buffer *buffer;
1543 int x, y, w = 0, h = 0;
1545 wl_list_for_each(view, &server->views, link) {
1546 surface = ds_xdg_surface_get_surface(view->xdg_surface);
1547 buffer = ds_surface_get_buffer(surface);
1548 ds_buffer_get_size(buffer, &w, &h);
1553 if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) {
1565 touch_handle_device_destroy(struct wl_listener *listener, void *data)
1567 struct tinyds_touch *touch;
1569 touch = wl_container_of(listener, touch, destroy);
1571 ds_inf("Touch(%p) destroyed", touch);
1573 wl_list_remove(&touch->destroy.link);
1574 wl_list_remove(&touch->down.link);
1575 wl_list_remove(&touch->up.link);
1576 wl_list_remove(&touch->motion.link);
1582 touch_handle_down(struct wl_listener *listener, void *data)
1584 struct ds_event_touch_down *event = data;
1585 struct tinyds_touch *touch;
1586 struct tinyds_view *view;
1587 struct tinyds_server *server;
1588 double sx = 0.f, sy = 0.f;
1590 touch = wl_container_of(listener, touch, down);
1592 server = touch->server;
1593 server->output_x = event->x * server->output->width;
1594 server->output_y = event->y * server->output->height;
1596 ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1597 touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1599 view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1602 ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface),
1603 event->time_msec, event->id, sx, sy);
1608 touch_handle_up(struct wl_listener *listener, void *data)
1610 struct ds_event_touch_up *event = data;
1611 struct tinyds_touch *touch;
1613 touch = wl_container_of(listener, touch, up);
1615 ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
1616 touch->dev, event->id, event->time_msec);
1618 ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id);
1622 touch_handle_motion(struct wl_listener *listener, void *data)
1624 struct ds_event_touch_motion *event = data;
1625 struct tinyds_touch *touch;
1626 struct tinyds_view *view;
1627 struct tinyds_server *server;
1628 double sx = 0.f, sy = 0.f;
1630 touch = wl_container_of(listener, touch, motion);
1632 server = touch->server;
1633 server->output_x = event->x * server->output->width;
1634 server->output_y = event->y * server->output->height;
1636 ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1637 touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1639 view = server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1642 ds_seat_touch_notify_motion(server->seat, event->time_msec,
1648 server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
1650 struct tinyds_touch *touch;
1652 touch = calloc(1, sizeof *touch);
1656 touch->server = server;
1658 touch->destroy.notify = touch_handle_device_destroy;
1659 ds_input_device_add_destroy_listener(dev, &touch->destroy);
1661 touch->down.notify = touch_handle_down;
1662 ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
1664 touch->up.notify = touch_handle_up;
1665 ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
1667 touch->motion.notify = touch_handle_motion;
1668 ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
1670 ds_inf("Touch(%p) added", touch);
1674 pointer_handle_device_destroy(struct wl_listener *listener, void *data)
1676 struct tinyds_pointer *pointer;
1678 pointer = wl_container_of(listener, pointer, destroy);
1680 ds_inf("Pointer(%p) destroyed", pointer);
1682 wl_list_remove(&pointer->destroy.link);
1683 wl_list_remove(&pointer->motion.link);
1684 wl_list_remove(&pointer->button.link);
1685 wl_list_remove(&pointer->frame.link);
1686 wl_list_remove(&pointer->link);
1692 pointer_handle_motion(struct wl_listener *listener, void *data)
1694 struct tinyds_pointer *pointer;
1695 struct ds_event_pointer_motion *event = data;
1696 struct tinyds_view *view;
1697 struct tinyds_server *server;
1701 pointer = wl_container_of(listener, pointer, motion);
1703 server = pointer->server;
1704 if (server->output) {
1705 ow = server->output->width;
1706 oh = server->output->height;
1709 if (server->output_x + event->delta_x >= ow)
1710 server->output_x = ow;
1711 else if(server->output_x + event->delta_x <= 0.f)
1712 server->output_x = 0.f;
1714 server->output_x = server->output_x + event->delta_x ;
1715 if (server->output_y + event->delta_y >= oh)
1716 server->output_y = oh;
1717 else if(server->output_y + event->delta_y <= 0.f)
1718 server->output_y = 0.f;
1720 server->output_y = server->output_y + event->delta_y ;
1722 ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f",
1723 pointer, event->delta_x, event->delta_y, server->output_x, server->output_y);
1725 view = server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy);
1727 if (pointer->focused_view != view) {
1728 if (pointer->focused_view) {
1729 ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
1730 ds_seat_pointer_notify_clear_focus(pointer->server->seat);
1731 pointer->focused_view = NULL;
1735 ds_inf("Set pointer focus to view(%p)", view);
1736 ds_seat_pointer_notify_enter(pointer->server->seat,
1737 ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
1738 pointer->focused_view = view;
1743 ds_seat_pointer_notify_motion(pointer->server->seat,
1744 event->time_msec, sx, sy);
1749 pointer_handle_button(struct wl_listener *listener, void *data)
1751 struct tinyds_pointer *pointer;
1752 struct ds_event_pointer_button *event = data;
1754 pointer = wl_container_of(listener, pointer, button);
1756 ds_inf("Pointer(%p) button(%d): state(%s) time(%d)",
1757 pointer, event->button,
1758 (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released",
1761 ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state);
1765 pointer_handle_frame(struct wl_listener *listener, void *data)
1767 struct tinyds_pointer *pointer;
1769 pointer = wl_container_of(listener, pointer, frame);
1771 ds_inf("Pointer(%p) frame", pointer);
1772 ds_seat_pointer_notify_frame(pointer->server->seat);
1776 server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev)
1778 struct tinyds_pointer *pointer;
1780 pointer = calloc(1, sizeof *pointer);
1784 pointer->server = server;
1785 server->output_x = 200;
1786 server->output_y = 200;
1788 pointer->destroy.notify = pointer_handle_device_destroy;
1789 ds_input_device_add_destroy_listener(dev, &pointer->destroy);
1791 pointer->motion.notify = pointer_handle_motion;
1792 ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev),
1795 pointer->button.notify = pointer_handle_button;
1796 ds_pointer_add_button_listener(ds_input_device_get_pointer(dev),
1799 pointer->frame.notify = pointer_handle_frame;
1800 ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev),
1803 pointer->focused_view = NULL;
1805 wl_list_insert(&server->pointers, &pointer->link);
1807 ds_inf("Pointer(%p) added", pointer);
1811 output_schedule_commit_handle_idle_timer(void *data)
1813 struct tinyds_output *output = data;
1814 output->idle_commit = NULL;
1816 output_commit(output);
1820 output_schedule_commit(struct tinyds_output *output)
1822 if (output->idle_commit)
1825 struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display);
1826 output->idle_commit =
1827 wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output);
1831 add_new_text_input(struct tinyds_server *server)
1833 struct tinyds_text_input *text_input;
1835 text_input = calloc(1, sizeof *text_input);
1839 text_input->text_input_mgr = ds_tizen_text_input_manager_create(server->display);
1840 if (!text_input->text_input_mgr) {
1842 ds_err("Could not create ds_tizen_text_input_manager");
1846 wl_list_init(&text_input->input_methods);
1848 text_input->destroy.notify = text_input_mgr_handle_destroy;
1849 ds_tizen_text_input_manager_add_destroy_listener(text_input->text_input_mgr,
1850 &text_input->destroy);
1852 text_input->new_text_input.notify = text_input_mgr_handle_new_text_input;
1853 ds_tizen_text_input_manager_add_new_text_input_listener(text_input->text_input_mgr,
1854 &text_input->new_text_input);
1856 text_input->server = server;
1857 server->text_input = text_input;
1859 ds_inf("Text_Input (%p) added", text_input);
1865 add_new_input_method(struct tinyds_server *server)
1867 struct tinyds_input_method *input_method;
1869 input_method = calloc(1, sizeof *input_method);
1873 input_method->input_method = ds_tizen_input_method_create(server->display);
1874 if (!input_method->input_method) {
1876 ds_err("Could not create ds_tizen_input_method");
1879 input_method->destroy.notify = input_method_handle_destroy;
1880 ds_tizen_input_method_add_destroy_listener(input_method->input_method,
1881 &input_method->destroy);
1883 input_method->input_method_mgr = ds_tizen_input_method_manager_create(server->display);
1884 if (!input_method->input_method_mgr) {
1886 ds_err("Could not create ds_tizen_input_method_manager");
1890 input_method->mgr_destroy.notify = input_method_mgr_handle_destroy;
1891 ds_tizen_input_method_manager_add_destroy_listener(input_method->input_method_mgr,
1892 &input_method->mgr_destroy);
1894 input_method->new_im_context.notify = input_method_handle_new_im_context;
1895 ds_tizen_input_method_add_new_input_method_context_listener(input_method->input_method,
1896 &input_method->new_im_context);
1898 input_method->server = server;
1899 server->input_method = input_method;
1901 ds_inf("Input_Method (%p) added", input_method);
1907 text_input_mgr_handle_destroy(struct wl_listener *listener, void *data)
1909 struct tinyds_text_input *text_input;
1910 struct tinyds_server *server;
1912 ds_inf("text_input_mgr_handle_destroy");
1913 text_input = wl_container_of(listener, text_input, mgr_destroy);
1915 wl_list_remove(&text_input->mgr_destroy.link);
1916 wl_list_remove(&text_input->destroy.link);
1918 wl_list_remove(&text_input->new_text_input.link);
1920 wl_list_remove(&text_input->text_input_activate.link);
1921 wl_list_remove(&text_input->text_input_deactivate.link);
1922 wl_list_remove(&text_input->text_input_reset.link);
1923 wl_list_remove(&text_input->text_input_set_content_type.link);
1924 wl_list_remove(&text_input->text_input_invoke_action.link);
1925 wl_list_remove(&text_input->text_input_commit_state.link);
1926 wl_list_remove(&text_input->text_input_set_preferred_language.link);
1928 server = text_input->server;
1929 server->text_input = NULL;
1935 text_input_handle_destroy(struct wl_listener *listener, void *data)
1937 struct tinyds_text_input *text_input;
1939 ds_inf("text_input_handle_destroy");
1941 text_input = wl_container_of(listener, text_input, destroy);
1943 wl_list_remove(&text_input->destroy.link);
1947 text_input_handle_activate(struct wl_listener *listener, void *data)
1949 struct tinyds_text_input *text_input;
1950 struct tinyds_input_method *input_method;
1951 struct tinyds_input_method_context *context;
1952 struct ds_tizen_text_input_event_activate *event = data;
1954 text_input = wl_container_of(listener, text_input, text_input_activate);
1956 input_method = text_input->server->input_method;
1958 ds_inf("text_input_handle_activate. text_input(%p) seat(%p) surface(%p) text_input(%p)",
1959 text_input, event->seat, event->surface, event->text_input);
1961 if (input_method->input == text_input)
1963 if (input_method->input)
1964 ;//deactivate_input_method(server->input_method);
1965 input_method->input = text_input;
1966 wl_list_insert(&text_input->input_methods, &input_method->link);
1968 text_input->surface = event->surface;
1970 context = calloc(1, sizeof *context);
1971 if (context == NULL)
1973 ds_err("calloc is failed. tinyds_input_method_context");
1976 input_method->context = context;
1977 context->server = text_input->server;
1978 context->context = ds_tizen_input_method_create_context(input_method->input_method);
1979 context->input = text_input;
1980 context->input_method = input_method;
1982 // ds_tizen_input_method_send_set_text_input_id();
1986 text_input_handle_deactivate(struct wl_listener *listener, void *data)
1988 struct tinyds_text_input *text_input;
1989 struct tinyds_input_method *input_method, *tmp;
1990 struct ds_tizen_text_input_event_deactivate *event = data;
1992 text_input = wl_container_of(listener, text_input, text_input_deactivate);
1993 ds_inf("text_input_handle_deactivate. text_input(%p) seat(%p) text_input(%p)",
1994 text_input, event->seat, event->text_input);
1996 wl_list_for_each_safe(input_method, tmp, &text_input->input_methods, link) {
1997 if (!input_method->input_method || !input_method->context->context) continue;
1998 ds_tizen_input_method_send_deactivate(input_method->input_method, input_method->context->context);
1999 input_method->input = NULL;
2000 input_method->context = NULL;
2001 wl_list_remove(&input_method->link);
2004 text_input->surface = NULL;
2005 // ds_tizen_input_method_send_close_connection();
2009 text_input_handle_reset(struct wl_listener *listener, void *data)
2011 struct tinyds_text_input *text_input;
2012 struct tinyds_input_method *input_method;
2014 text_input = wl_container_of(listener, text_input, text_input_reset);
2016 ds_inf("text_input_handle_reset. text_input(%p)", text_input);
2018 wl_list_for_each(input_method, &text_input->input_methods, link) {
2019 if (!input_method->context || !input_method->context->context) continue;
2020 ds_tizen_input_method_context_send_reset(input_method->context->context);
2025 text_input_handle_set_content_type(struct wl_listener *listener, void *data)
2027 struct tinyds_text_input *text_input;
2028 struct ds_tizen_text_input_event_set_content_type *event = data;
2029 struct tinyds_input_method *input_method;
2031 text_input = wl_container_of(listener, text_input, text_input_set_content_type);
2033 ds_inf("text_input_handle_content_type. text_input(%p) hint(%u) purpose(%u)",
2034 text_input, event->hint, event->purpose);
2036 wl_list_for_each(input_method, &text_input->input_methods, link) {
2037 if (!input_method->context || !input_method->context->context) continue;
2038 ds_tizen_input_method_context_send_content_type(input_method->context->context,
2039 event->hint, event->purpose);
2044 text_input_handle_invoke_action(struct wl_listener *listener, void *data)
2046 struct tinyds_text_input *text_input;
2047 struct ds_tizen_text_input_event_invoke_action *event = data;
2048 struct tinyds_input_method *input_method;
2050 text_input = wl_container_of(listener, text_input, text_input_invoke_action);
2052 ds_inf("text_input_handle_invoke_action. text_input(%p) button(%u) index(%u)",
2053 text_input, event->button, event->index);
2055 wl_list_for_each(input_method, &text_input->input_methods, link) {
2056 if (!input_method->context || !input_method->context->context) continue;
2057 ds_tizen_input_method_context_send_invoke_action(input_method->context->context,
2058 event->button, event->index);
2063 text_input_handle_commit_state(struct wl_listener *listener, void *data)
2065 struct tinyds_text_input *text_input;
2066 struct ds_tizen_text_input_event_commit_state *event = data;
2067 struct tinyds_input_method *input_method;
2069 text_input = wl_container_of(listener, text_input, text_input_commit_state);
2071 ds_inf("text_input_handle_commit_state. text_input(%p) serial(%u)",
2072 text_input, event->serial);
2074 wl_list_for_each(input_method, &text_input->input_methods, link) {
2075 if (!input_method->context || !input_method->context->context) continue;
2076 ds_tizen_input_method_context_send_commit_state(input_method->context->context,
2082 text_input_handle_set_preferred_language(struct wl_listener *listener, void *data)
2084 struct tinyds_text_input *text_input;
2085 struct ds_tizen_text_input_event_set_preferred_language *event = data;
2086 struct tinyds_input_method *input_method;
2088 text_input = wl_container_of(listener, text_input, text_input_set_preferred_language);
2090 ds_inf("text_input_handle_set_preferred_language. text_input(%p) language(%s)",
2091 text_input, event->language);
2093 wl_list_for_each(input_method, &text_input->input_methods, link) {
2094 if (!input_method->context || !input_method->context->context) continue;
2095 ds_tizen_input_method_context_send_preferred_language(input_method->context->context,
2101 text_input_mgr_handle_new_text_input(struct wl_listener *listener, void *data)
2103 struct tinyds_text_input *text_input;
2104 struct ds_tizen_text_input *input = data;
2106 text_input = wl_container_of(listener, text_input, new_text_input);
2108 ds_inf("text_input_mgr_handle_new_text_input");
2110 text_input->input = input;
2112 text_input->destroy.notify = text_input_handle_destroy;
2113 ds_tizen_text_input_add_destroy_listener(text_input->input,
2114 &text_input->destroy);
2116 text_input->text_input_activate.notify = text_input_handle_activate;
2117 ds_tizen_text_input_add_activate_listener(text_input->input,
2118 &text_input->text_input_activate);
2120 text_input->text_input_deactivate.notify = text_input_handle_deactivate;
2121 ds_tizen_text_input_add_deactivate_listener(text_input->input,
2122 &text_input->text_input_deactivate);
2124 text_input->text_input_reset.notify = text_input_handle_reset;
2125 ds_tizen_text_input_add_reset_listener(text_input->input,
2126 &text_input->text_input_reset);
2128 text_input->text_input_set_content_type.notify = text_input_handle_set_content_type;
2129 ds_tizen_text_input_add_set_content_type_listener(text_input->input,
2130 &text_input->text_input_set_content_type);
2132 text_input->text_input_invoke_action.notify = text_input_handle_invoke_action;
2133 ds_tizen_text_input_add_invoke_action_listener(text_input->input,
2134 &text_input->text_input_invoke_action);
2136 text_input->text_input_commit_state.notify = text_input_handle_commit_state;
2137 ds_tizen_text_input_add_commit_state_listener(text_input->input,
2138 &text_input->text_input_commit_state);
2140 text_input->text_input_set_preferred_language.notify = text_input_handle_set_preferred_language;
2141 ds_tizen_text_input_add_set_preferred_language_listener(text_input->input,
2142 &text_input->text_input_set_preferred_language);
2146 input_method_mgr_handle_destroy(struct wl_listener *listener, void *data)
2148 struct tinyds_input_method *input_method;
2150 ds_inf("input_method_mgr_handle_destroy");
2152 input_method = wl_container_of(listener, input_method, mgr_destroy);
2154 wl_list_remove(&input_method->mgr_destroy.link);
2158 input_method_handle_destroy(struct wl_listener *listener, void *data)
2160 struct tinyds_input_method *input_method;
2161 struct tinyds_server *server;
2163 ds_inf("input_method_handle_destroy");
2165 input_method = wl_container_of(listener, input_method, destroy);
2167 wl_list_remove(&input_method->destroy.link);
2168 wl_list_remove(&input_method->new_im_context.link);
2170 server = input_method->server;
2171 server->input_method = NULL;
2177 context_handle_destroy(struct wl_listener *listener, void *data)
2179 struct tinyds_input_method_context *context;
2180 struct tinyds_server *server;
2182 ds_inf("context_handle_destroy");
2184 context = wl_container_of(listener, context, destroy);
2186 wl_list_remove(&context->destroy.link);
2188 wl_list_remove(&context->im_context_commit_string.link);
2189 wl_list_remove(&context->im_context_preedit_string.link);
2190 wl_list_remove(&context->im_context_preedit_styling.link);
2191 wl_list_remove(&context->im_context_preedit_cursor.link);
2192 wl_list_remove(&context->im_context_delete_surrounding_text.link);
2193 wl_list_remove(&context->im_context_cursor_position.link);
2194 wl_list_remove(&context->im_context_modifiers_map.link);
2195 wl_list_remove(&context->im_context_keysym.link);
2196 wl_list_remove(&context->im_context_grab_keyboard.link);
2197 wl_list_remove(&context->im_context_key.link);
2198 wl_list_remove(&context->im_context_modifiers.link);
2199 wl_list_remove(&context->im_context_language.link);
2200 wl_list_remove(&context->im_context_text_direction.link);
2202 server = context->server;
2203 server->input_method->context = NULL;
2209 context_handle_commit_string(struct wl_listener *listener, void *data)
2211 struct tinyds_text_input *text_input;
2212 struct tinyds_input_method_context *context;
2213 struct ds_tizen_input_method_context_event_commit_string *event = data;
2215 context = wl_container_of(listener, context, im_context_commit_string);
2216 text_input = context->server->text_input;
2218 ds_inf("context_handle_commit_string. text_input(%p) serial(%u) text(%s)",
2219 text_input, event->serial, event->text);
2221 ds_tizen_text_input_send_commit_string(text_input->input, event->serial, event->text);
2225 context_handle_preedit_string(struct wl_listener *listener, void *data)
2227 struct tinyds_input_method_context *context;
2228 struct tinyds_text_input *text_input;
2229 struct ds_tizen_input_method_context_event_preedit_string *event = data;
2231 context = wl_container_of(listener, context, im_context_preedit_string);
2232 text_input = context->server->text_input;
2234 ds_inf("context_handle_preedit_string. text_input(%p) serial(%u) text(%s) commit(%s)",
2235 text_input, event->serial, event->text, event->commit);
2237 ds_tizen_text_input_send_preedit_string(text_input->input, event->serial, event->text, event->commit);
2241 context_handle_preedit_styling(struct wl_listener *listener, void *data)
2243 struct tinyds_input_method_context *context;
2244 struct tinyds_text_input *text_input;
2245 struct ds_tizen_input_method_context_event_preedit_styling *event = data;
2247 context = wl_container_of(listener, context, im_context_preedit_styling);
2248 text_input = context->server->text_input;
2250 ds_inf("context_handle_preedit_styling. text_input(%p) index(%u) length(%u) style(%u)",
2251 text_input, event->index, event->length, event->style);
2253 ds_tizen_text_input_send_preedit_styling(text_input->input, event->index, event->length, event->style);
2257 context_handle_preedit_cursor(struct wl_listener *listener, void *data)
2259 struct tinyds_input_method_context *context;
2260 struct tinyds_text_input *text_input;
2261 struct ds_tizen_input_method_context_event_preedit_cursor *event = data;
2263 context = wl_container_of(listener, context, im_context_preedit_cursor);
2264 text_input = context->server->text_input;
2266 ds_inf("context_handle_preedit_cursor. text_input(%p) index(%u)",
2267 text_input, event->index);
2269 ds_tizen_text_input_send_preedit_cursor(text_input->input, event->index);
2273 context_handle_delete_surrounding_text(struct wl_listener *listener, void *data)
2275 struct tinyds_input_method_context *context;
2276 struct tinyds_text_input *text_input;
2277 struct ds_tizen_input_method_context_event_delete_surrounding_text *event = data;
2279 context = wl_container_of(listener, context, im_context_delete_surrounding_text);
2280 text_input = context->server->text_input;
2282 ds_inf("context_handle_delete_surrounding_text. text_input(%p) index(%d) length(%u)",
2283 text_input, event->index, event->length);
2285 ds_tizen_text_input_send_delete_surrounding_text(text_input->input, event->index, event->length);
2289 context_handle_cursor_position(struct wl_listener *listener, void *data)
2291 struct tinyds_input_method_context *context;
2292 struct tinyds_text_input *text_input;
2293 struct ds_tizen_input_method_context_event_cursor_position *event = data;
2295 context = wl_container_of(listener, context, im_context_cursor_position);
2296 text_input = context->server->text_input;
2298 ds_inf("context_handle_cursor_position. text_input(%p) index(%d) length(%d)",
2299 text_input, event->index, event->anchor);
2301 ds_tizen_text_input_send_cursor_position(text_input->input, event->index, event->anchor);
2305 context_handle_modifiers_map(struct wl_listener *listener, void *data)
2307 struct tinyds_input_method_context *context;
2308 struct tinyds_text_input *text_input;
2309 struct ds_tizen_input_method_context_event_modifiers_map *event = data;
2311 context = wl_container_of(listener, context, im_context_modifiers_map);
2312 text_input = context->server->text_input;
2314 ds_inf("context_handle_modifiers_map. text_input(%p) map(%p)",
2315 text_input, event->map);
2317 ds_tizen_text_input_send_modifiers_map(text_input->input, event->map);
2321 context_handle_keysym(struct wl_listener *listener, void *data)
2323 struct tinyds_input_method_context *context;
2324 struct tinyds_text_input *text_input;
2325 struct ds_tizen_input_method_context_event_keysym *event = data;
2327 context = wl_container_of(listener, context, im_context_keysym);
2328 text_input = context->server->text_input;
2330 ds_inf("context_handle_keysym. text_input(%p) serial(%u) time(%u) sysm(%u) state(%u) modifiers(%u)",
2331 text_input, event->serial, event->time, event->sym, event->state, event->modifiers);
2333 ds_tizen_text_input_send_keysym(text_input->input, event->serial, event->time, event->sym, event->state, event->modifiers);
2337 context_handle_grab_keyboard(struct wl_listener *listener, void *data)
2339 struct tinyds_input_method_context *context;
2340 struct tinyds_text_input *text_input;
2342 context = wl_container_of(listener, context, im_context_grab_keyboard);
2343 text_input = context->server->text_input;
2345 ds_inf("context_handle_grab_keyboard. text_input(%p)",
2352 context_handle_key(struct wl_listener *listener, void *data)
2354 struct tinyds_input_method_context *context;
2355 struct tinyds_text_input *text_input;
2357 context = wl_container_of(listener, context, im_context_key);
2358 text_input = context->server->text_input;
2360 ds_inf("context_handle_key. text_input(%p)",
2367 context_handle_modifiers(struct wl_listener *listener, void *data)
2369 struct tinyds_input_method_context *context;
2370 struct tinyds_text_input *text_input;
2372 context = wl_container_of(listener, context, im_context_modifiers);
2373 text_input = context->server->text_input;
2375 ds_inf("context_handle_modifiers. text_input(%p)",
2382 context_handle_language(struct wl_listener *listener, void *data)
2384 struct tinyds_input_method_context *context;
2385 struct tinyds_text_input *text_input;
2386 struct ds_tizen_input_method_context_event_language *event = data;
2388 context = wl_container_of(listener, context, im_context_language);
2389 text_input = context->server->text_input;
2391 ds_inf("context_handle_language. text_input(%p) serial(%u), language(%s)",
2392 text_input, event->serial, event->language);
2394 ds_tizen_text_input_send_language(text_input->input, event->serial, event->language);
2398 context_handle_text_direction(struct wl_listener *listener, void *data)
2400 struct tinyds_input_method_context *context;
2401 struct tinyds_text_input *text_input;
2402 struct ds_tizen_input_method_context_event_text_direction *event = data;
2404 context = wl_container_of(listener, context, im_context_text_direction);
2405 text_input = context->server->text_input;
2407 ds_inf("context_handle_text_direction. text_input(%p) serial(%u), direction(%u)",
2408 text_input, event->serial, event->direction);
2410 ds_tizen_text_input_send_text_direction(text_input->input, event->serial, event->direction);
2414 input_method_handle_new_im_context(struct wl_listener *listener, void *data)
2416 struct ds_tizen_input_method_context *context = data;
2417 struct tinyds_input_method *input_method;
2418 struct tinyds_input_method_context *ctx;
2420 ds_inf("input_method_handle_new_im_context");
2422 input_method = wl_container_of(listener, input_method, new_im_context);
2423 ctx = input_method->context;
2425 ctx->destroy.notify = context_handle_destroy;
2426 ds_tizen_input_method_context_add_destroy_listener(context,
2429 ctx->im_context_commit_string.notify = context_handle_commit_string;
2430 ds_tizen_input_method_context_add_commit_string_listener(context,
2431 &ctx->im_context_commit_string);
2433 ctx->im_context_preedit_string.notify = context_handle_preedit_string;
2434 ds_tizen_input_method_context_add_preedit_string_listener(context,
2435 &ctx->im_context_preedit_string);
2437 ctx->im_context_preedit_styling.notify = context_handle_preedit_styling;
2438 ds_tizen_input_method_context_add_preedit_styling_listener(context,
2439 &ctx->im_context_preedit_styling);
2441 ctx->im_context_preedit_cursor.notify = context_handle_preedit_cursor;
2442 ds_tizen_input_method_context_add_preedit_cursor_listener(context,
2443 &ctx->im_context_preedit_cursor);
2445 ctx->im_context_delete_surrounding_text.notify = context_handle_delete_surrounding_text;
2446 ds_tizen_input_method_context_add_delete_surrounding_text_listener(context,
2447 &ctx->im_context_delete_surrounding_text);
2449 ctx->im_context_cursor_position.notify = context_handle_cursor_position;
2450 ds_tizen_input_method_context_add_cursor_position_listener(context,
2451 &ctx->im_context_cursor_position);
2453 ctx->im_context_modifiers_map.notify = context_handle_modifiers_map;
2454 ds_tizen_input_method_context_add_modifiers_map_listener(context,
2455 &ctx->im_context_modifiers_map);
2457 ctx->im_context_keysym.notify = context_handle_keysym;
2458 ds_tizen_input_method_context_add_keysym_listener(context,
2459 &ctx->im_context_keysym);
2461 ctx->im_context_grab_keyboard.notify = context_handle_grab_keyboard;
2462 ds_tizen_input_method_context_add_grab_keyboard_listener(context,
2463 &ctx->im_context_grab_keyboard);
2465 ctx->im_context_key.notify = context_handle_key;
2466 ds_tizen_input_method_context_add_key_listener(context,
2467 &ctx->im_context_key);
2469 ctx->im_context_modifiers.notify = context_handle_modifiers;
2470 ds_tizen_input_method_context_add_modifiers_listener(context,
2471 &ctx->im_context_modifiers);
2473 ctx->im_context_language.notify = context_handle_language;
2474 ds_tizen_input_method_context_add_language_listener(context,
2475 &ctx->im_context_language);
2477 ctx->im_context_text_direction.notify = context_handle_text_direction;
2478 ds_tizen_input_method_context_add_text_direction_listener(context,
2479 &ctx->im_context_text_direction);