1 #include "tinyds-tdm.h"
5 struct tinyds_server *server;
6 struct ds_output *ds_output;
7 struct ds_allocator *allocator;
8 #ifdef USE_TDM_BUFFER_QUEUE
9 struct tinyds_renderer renderer;
10 struct ds_tdm_buffer_queue *buffer_queue;
11 struct wl_listener buffer_queue_acquirable;
13 struct ds_swapchain *swapchain;
15 struct ds_buffer *front_buffer;
17 struct wl_listener output_destroy;
18 struct wl_listener output_frame;
22 struct wl_event_source *idle_commit;
27 struct ds_tdm_output_hwc *hwc;
28 struct ds_tdm_output_hwc_window *bg_hwc_window;
32 struct ds_tdm_output_hwc_window *cursor_hwc_window;
38 struct ds_input_device *dev;
39 struct tinyds_server *server;
41 struct tinyds_view *focused_view;
43 struct wl_listener destroy;
44 struct wl_listener motion; //relative
45 struct wl_listener button;
46 struct wl_listener frame;
47 struct wl_list link; //tinyds_server::pointers
50 struct tinyds_keyboard
52 struct ds_input_device *dev;
53 struct tinyds_server *server;
55 struct wl_listener destroy;
56 struct wl_listener key;
57 struct wl_list link; //tinyds_server::keyboards
62 struct ds_input_device *dev;
63 struct tinyds_server *server;
65 struct wl_listener destroy;
66 struct wl_listener down;
67 struct wl_listener up;
68 struct wl_listener motion;
71 struct tinyds_text_input {
72 struct ds_tizen_text_input *input;
73 struct ds_tizen_text_input_manager *text_input_mgr;
75 struct tinyds_server *server;
76 struct ds_surface *surface;
78 struct wl_list input_methods;
80 struct wl_listener mgr_destroy;
81 struct wl_listener new_text_input;
83 struct wl_listener destroy;
84 struct wl_listener text_input_activate;
85 struct wl_listener text_input_deactivate;
86 struct wl_listener text_input_reset;
87 struct wl_listener text_input_set_content_type;
88 struct wl_listener text_input_invoke_action;
89 struct wl_listener text_input_commit_state;
90 struct wl_listener text_input_set_preferred_language;
93 struct tinyds_input_method {
94 struct ds_tizen_input_method *input_method;
95 struct ds_tizen_input_method_manager *input_method_mgr;
97 struct tinyds_server *server;
98 struct tinyds_text_input *input;
99 struct tinyds_input_method_context *context;
103 struct wl_listener destroy;
104 struct wl_listener mgr_destroy;
107 struct tinyds_input_method_context {
108 struct ds_tizen_input_method_context *context;
110 struct tinyds_server *server;
111 struct tinyds_text_input *input;
112 struct tinyds_input_method *input_method;
114 struct wl_listener destroy;
116 struct wl_listener im_context_commit_string;
117 struct wl_listener im_context_preedit_string;
118 struct wl_listener im_context_preedit_styling;
119 struct wl_listener im_context_preedit_cursor;
120 struct wl_listener im_context_delete_surrounding_text;
121 struct wl_listener im_context_cursor_position;
122 struct wl_listener im_context_modifiers_map;
123 struct wl_listener im_context_keysym;
124 struct wl_listener im_context_grab_keyboard;
125 struct wl_listener im_context_key;
126 struct wl_listener im_context_modifiers;
127 struct wl_listener im_context_language;
128 struct wl_listener im_context_text_direction;
131 struct tinyds_server tinyds;
133 static bool init_server(struct tinyds_server *server, struct wl_display *display);
134 static int server_dispatch_stdin(int fd, uint32_t mask, void *data);
135 static void output_handle_destroy(struct wl_listener *listener, void *data);
136 static void output_handle_frame(struct wl_listener *listener, void *data);
137 static void draw_server_with_damage(struct tinyds_server *server);
138 static void draw_output(struct tinyds_output *output);
139 static void output_swap_buffer(struct tinyds_output *output,
140 struct ds_buffer *buffer);
141 static void view_send_frame_done(struct tinyds_view *view);
142 static void output_hwc_init(struct tinyds_output *output);
143 static void output_schedule_commit(struct tinyds_output *output);
144 static void output_commit(struct tinyds_output *output);
145 #ifdef USE_TDM_BUFFER_QUEUE
146 static void output_buffer_queue_init(struct tinyds_output *output);
147 static void output_renderer_init(struct tinyds_output *output);
148 static void output_draw_with_renderer(struct tinyds_output *output);
150 static void output_swapchain_init(struct tinyds_output *output,
151 int width, int height, uint32_t format);
152 static void output_draw_with_swapchain(struct tinyds_output *output);
153 static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image);
155 static void server_add_keyboard(struct tinyds_server *server,
156 struct ds_input_device *dev);
157 static void server_add_pointer(struct tinyds_server *server,
158 struct ds_input_device *dev);
159 static void server_add_touch(struct tinyds_server *server,
160 struct ds_input_device *dev);
161 static bool add_new_text_input(struct tinyds_server *server);
162 static bool add_new_input_method(struct tinyds_server *server);
163 static bool add_new_input_method_context(
164 struct tinyds_input_method *input_method,
165 struct tinyds_text_input *text_input);
167 static void text_input_mgr_handle_destroy(struct wl_listener *listener,
168 void *data TINYDS_UNUSED);
169 static void text_input_mgr_handle_new_text_input(struct wl_listener *listener,
170 void *data TINYDS_UNUSED);
172 static void input_method_mgr_handle_destroy(struct wl_listener *listener,
173 void *data TINYDS_UNUSED);
175 static void input_method_handle_destroy(struct wl_listener *listener,
176 void *data TINYDS_UNUSED);
181 struct tinyds_server *server = &tinyds;
182 struct wl_display *display;
183 struct wl_event_loop *loop;
187 ds_log_init(DS_INF, NULL);
189 display = wl_display_create();
192 res = init_server(server, display);
195 socket = wl_display_add_socket_auto(display);
198 ds_backend_start(server->backend);
199 ds_backend_start(server->input_backend);
201 setenv("WAYLAND_DISPLAY", socket, true);
203 ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
205 loop = wl_display_get_event_loop(display);
206 server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
207 WL_EVENT_READABLE, server_dispatch_stdin, server);
209 wl_display_run(display);
211 protocol_trace_enable(false);
212 protocol_trace_fini();
214 wl_display_destroy_clients(display);
215 wl_display_destroy(display);
221 view_populate_pid(struct tinyds_view *view)
223 struct ds_surface *surface;
224 struct wl_client *client = NULL;
227 surface = ds_xdg_surface_get_surface(view->xdg_surface);
231 client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
235 wl_client_get_credentials(client, &pid, NULL, NULL);
238 ds_inf("view pid(%u)", pid);
240 view->effect_type = tinyds_launch_get_effect_type(
241 view->server->launch, pid);
242 tinyds_launch_unset_effect_type(view->server->launch, pid);
244 ds_inf("view effect_type(%d)", view->effect_type);
248 view_handle_xdg_surface_map(struct wl_listener *listener,
249 void *data TINYDS_UNUSED)
251 struct tinyds_view *view;
252 struct ds_keyboard *keyboard;
253 struct tinyds_keyboard *kbd;
255 view = wl_container_of(listener, view, xdg_surface_map);
258 view_populate_pid(view);
260 wl_list_for_each(kbd, &view->server->keyboards, link) {
261 keyboard = ds_input_device_get_keyboard(kbd->dev);
262 if (keyboard != NULL) {
263 ds_seat_keyboard_notify_enter(view->server->seat,
264 ds_xdg_surface_get_surface(view->xdg_surface),
265 keyboard->keycodes, keyboard->num_keycodes,
266 &keyboard->modifiers);
273 view_handle_xdg_surface_unmap(struct wl_listener *listener,
274 void *data TINYDS_UNUSED)
276 struct tinyds_view *view;
278 view = wl_container_of(listener, view, xdg_surface_unmap);
279 view->mapped = false;
283 view_handle_xdg_surface_destroy(struct wl_listener *listener,
284 void *data TINYDS_UNUSED)
286 struct tinyds_view *view;
288 view = wl_container_of(listener, view, xdg_surface_destroy);
290 draw_server_with_damage(view->server);
292 ds_tdm_output_hwc_window_destroy(view->hwc_window);
294 wl_list_remove(&view->xdg_surface_destroy.link);
295 wl_list_remove(&view->xdg_surface_map.link);
296 wl_list_remove(&view->xdg_surface_unmap.link);
297 wl_list_remove(&view->surface_commit.link);
298 wl_list_remove(&view->link);
303 view_handle_surface_commit(struct wl_listener *listener,
304 void *data TINYDS_UNUSED)
306 struct tinyds_view *view;
308 view = wl_container_of(listener, view, surface_commit);
309 draw_server_with_damage(view->server);
313 server_new_xdg_surface(struct wl_listener *listener, void *data)
315 static unsigned int seedx = 1;
316 static unsigned int seedy = 43210;
317 struct tinyds_server *server;
318 struct tinyds_view *view;
319 struct ds_xdg_surface *xdg_surface;
321 server = wl_container_of(listener, server, new_xdg_surface);
324 ds_inf("New xdg_surface(%p)", (void *)xdg_surface);
326 view = calloc(1, sizeof *view);
329 view->server = server;
330 view->xdg_surface = xdg_surface;
332 view->xdg_surface_map.notify = view_handle_xdg_surface_map;
333 ds_xdg_surface_add_map_listener(xdg_surface,
334 &view->xdg_surface_map);
336 view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap;
337 ds_xdg_surface_add_unmap_listener(xdg_surface,
338 &view->xdg_surface_unmap);
340 view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy;
341 ds_xdg_surface_add_destroy_listener(xdg_surface,
342 &view->xdg_surface_destroy);
344 view->surface_commit.notify = view_handle_surface_commit;
345 ds_surface_add_commit_listener(
346 ds_xdg_surface_get_surface(xdg_surface),
347 &view->surface_commit);
349 view->x = rand_r(&seedx) % 1000;
350 view->y = rand_r(&seedy) % 500;
352 view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
353 assert(view->hwc_window);
355 wl_list_insert(server->views.prev, &view->link);
358 view->effect_type = -1;
360 ds_inf("view at (%d, %d)", view->x, view->y);
364 backend_handle_new_output(struct wl_listener *listener, void *data)
366 struct tinyds_server *server;
367 struct tinyds_output *output;
368 struct ds_output *ds_output;
369 const struct ds_output_mode *mode;
370 struct ds_tdm_box src_box;
372 server = wl_container_of(listener, server, new_output);
375 ds_inf("New output(%p)", ds_output);
380 mode = ds_output_get_preferred_mode(ds_output);
381 ds_output_set_mode(ds_output, mode);
383 output = calloc(1, sizeof *output);
387 output->server = server;
388 output->ds_output = ds_output;
389 output->width = mode->width;
390 output->height = mode->height;
391 output->damaged = true;
392 output->committable = true;
394 output_hwc_init(output);
396 #ifdef USE_TDM_BUFFER_QUEUE
397 output_buffer_queue_init(output);
398 output_renderer_init(output);
400 output_swapchain_init(output, mode->width, mode->height,
401 DRM_FORMAT_XRGB8888);
404 output->bg_hwc_window = ds_tdm_output_hwc_window_create(output->hwc);
405 assert(output->bg_hwc_window);
409 src_box.width = output->width;
410 src_box.height = output->height;
412 ds_tdm_output_hwc_window_set_src_box(output->bg_hwc_window, &src_box);
413 ds_tdm_output_hwc_window_set_position(output->bg_hwc_window, 0, 0);
414 ds_tdm_output_hwc_window_set_dest_size(output->bg_hwc_window, output->width, output->height);
415 ds_tdm_output_hwc_window_set_transform(output->bg_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
418 output->cursor_enabled = false;
421 output->output_destroy.notify = output_handle_destroy;
422 ds_output_add_destroy_listener(ds_output, &output->output_destroy);
424 output->output_frame.notify = output_handle_frame;
425 ds_output_add_frame_listener(ds_output, &output->output_frame);
427 tinyds_input_devicemgr_set_output_size(server->input_devicemgr, (uint32_t)output->width, (uint32_t)output->height);
429 server->output = output;
430 server->output_x = (double)(output->width) / 2;
431 server->output_y = (double)(output->height) / 2;
433 output_schedule_commit(output);
437 backend_handle_new_input(struct wl_listener *listener, void *data)
439 struct tinyds_server *server;
440 struct ds_input_device *dev = data;
441 enum ds_input_device_type dev_type;
443 server = wl_container_of(listener, server, new_input);
445 dev_type = ds_input_device_get_type(dev);
448 case DS_INPUT_DEVICE_KEYBOARD:
449 server_add_keyboard(server, dev);
450 server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD;
452 case DS_INPUT_DEVICE_TOUCH:
453 server_add_touch(server, dev);
454 server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH;
456 case DS_INPUT_DEVICE_POINTER:
457 server_add_pointer(server, dev);
458 server->seat_caps |= WL_SEAT_CAPABILITY_POINTER;
461 ds_err("Unknown type(%d) of ds_input_device", dev_type);
465 ds_seat_set_capabilities(server->seat, server->seat_caps);
469 dpms_free_func(void *data)
471 struct tinyds_server *server = (struct tinyds_server *)data;
477 policy_free_func(void *data)
479 struct tinyds_server *server = (struct tinyds_server *)data;
481 server->policy = NULL;
485 launch_free_func(void *data)
487 struct tinyds_server *server = (struct tinyds_server *)data;
489 server->launch = NULL;
493 input_devicemgr_free_func(void *data)
495 struct tinyds_server *server = (struct tinyds_server *)data;
497 server->input_devicemgr = NULL;
501 init_server(struct tinyds_server *server, struct wl_display *display)
503 server->display = display;
505 wl_list_init(&server->views);
507 if (wl_display_init_shm(display) != 0)
510 server->backend = ds_tdm_backend_create(display);
511 if (!server->backend)
514 server->input_backend = ds_libinput_backend_create(display);
515 if (!server->input_backend) {
516 ds_backend_destroy(server->backend);
520 server->new_output.notify = backend_handle_new_output;
521 ds_backend_add_new_output_listener(server->backend,
522 &server->new_output);
524 wl_list_init(&server->keyboards);
525 wl_list_init(&server->pointers);
526 server->new_input.notify = backend_handle_new_input;
527 ds_backend_add_new_input_listener(server->input_backend, &server->new_input);
529 server->compositor = ds_compositor_create(display);
530 if (!server->compositor)
533 server->tbm_server = ds_tbm_server_create(display);
534 if (!server->tbm_server)
537 server->xdg_shell = ds_xdg_shell_create(display);
538 if (!server->xdg_shell)
541 server->new_xdg_surface.notify = server_new_xdg_surface;
542 ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
543 &server->new_xdg_surface);
545 server->dpms = tinyds_dpms_init(server->display, dpms_free_func, (void *)server);
549 server->policy = tinyds_policy_init(server->display, policy_free_func, (void *)server);
553 server->launch = tinyds_launch_init(server->display, launch_free_func, (void *)server);
557 server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
560 server->seat_caps = 0;
562 server->input_devicemgr = tinyds_input_devicemgr_init(server->input_backend,
563 server->seat, input_devicemgr_free_func, (void *)server);
564 if (!server->input_devicemgr)
567 if (!add_new_text_input(server))
570 if (!add_new_input_method(server))
573 if (protocol_trace_init(display))
574 protocol_trace_enable(true);
579 ds_backend_destroy(server->backend);
580 ds_backend_destroy(server->input_backend);
586 output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
588 struct tinyds_output *output =
589 wl_container_of(listener, output, output_destroy);
591 if (output->bg_hwc_window)
592 ds_tdm_output_hwc_window_destroy(output->bg_hwc_window);
594 wl_list_remove(&output->output_destroy.link);
595 wl_list_remove(&output->output_frame.link);
597 if (output->front_buffer)
598 ds_buffer_unlock(output->front_buffer);
600 #ifdef USE_TDM_BUFFER_QUEUE
601 fini_renderer(&output->renderer);
603 if (output->swapchain)
604 ds_swapchain_destroy(output->swapchain);
606 if (output->allocator)
607 ds_allocator_destroy(output->allocator);
610 wl_display_terminate(output->server->display);
612 output->server->output = NULL;
618 output_commit(struct tinyds_output *output)
620 uint32_t num_changed = 0;
621 uint32_t num_windows = 0, current_num_windows = 0;
622 struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL;
623 struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL;
624 enum ds_tdm_output_hwc_window_composition composition;
625 struct tinyds_view *view;
627 bool need_target = false;
628 bool fully_obscured = false;
629 struct ds_buffer *ds_buffer;
630 struct ds_tdm_box src_box;
633 if (!output->committable)
636 if (!output->damaged && !output->target_updated)
639 wl_list_for_each_reverse(view, &output->server->views, link) {
640 if (!view->hwc_window)
643 ds_buffer = ds_surface_get_buffer(
644 ds_xdg_surface_get_surface(view->xdg_surface));
653 ds_buffer_get_size(ds_buffer, &w, &h);
655 if ((output->width <= w) && (output->height <= h))
656 fully_obscured = true;
659 if (fully_obscured) {
660 ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
661 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
663 ds_tdm_output_hwc_window_set_composition(output->bg_hwc_window,
664 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
670 if (output->cursor_hwc_window) {
673 src_box.width = CURSOR_W;
674 src_box.height = CURSOR_H;
676 ds_tdm_output_hwc_window_set_src_box(output->cursor_hwc_window, &src_box);
677 ds_tdm_output_hwc_window_set_position(output->cursor_hwc_window, output->server->output_x, output->server->output_y);
678 ds_tdm_output_hwc_window_set_dest_size(output->cursor_hwc_window, CURSOR_W, CURSOR_H);
679 ds_tdm_output_hwc_window_set_transform(output->cursor_hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
681 ds_tdm_output_hwc_window_set_composition(output->cursor_hwc_window,
682 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
689 composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows);
690 if (!composited_hwc_windows)
693 wl_list_for_each_reverse(view, &output->server->views, link) {
694 if (!view->hwc_window)
697 ds_buffer = ds_surface_get_buffer(
698 ds_xdg_surface_get_surface(view->xdg_surface));
702 ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer);
704 ds_buffer_get_size(ds_buffer, &w, &h);
711 ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box);
712 ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y);
713 ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h);
714 ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL);
718 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
719 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT);
721 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
722 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE);
724 composited_hwc_windows[current_num_windows] = view->hwc_window;
725 current_num_windows++;
727 ds_tdm_output_hwc_window_set_composition(view->hwc_window,
728 DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE);
732 if (!fully_obscured) {
733 composited_hwc_windows[current_num_windows] = output->bg_hwc_window;
734 current_num_windows++;
738 if (output->cursor_hwc_window) {
739 composited_hwc_windows[current_num_windows] = output->cursor_hwc_window;
740 current_num_windows++;
745 if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows,
746 num_windows, &num_changed)) {
747 free(composited_hwc_windows);
748 ds_err("Could not hwc validate");
752 if (composited_hwc_windows)
753 free(composited_hwc_windows);
755 if (num_changed > 0) {
756 changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows);
757 if (!changed_hwc_windows)
760 if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed,
761 changed_hwc_windows)) {
762 free(changed_hwc_windows);
763 ds_err("Could not get chaged composition");
767 for (i = 0; i < num_changed; i++) {
768 composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]);
769 if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) {
776 if (changed_hwc_windows)
777 free(changed_hwc_windows);
779 if (need_target && output->damaged)
782 #ifdef USE_TDM_BUFFER_QUEUE
783 struct ds_buffer *buffer;
785 buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue);
787 if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, buffer)) {
788 ds_err("Could not set hwc client target buffer");
792 output_swap_buffer(output, buffer);
796 if (!ds_tdm_output_hwc_accept_validation(output->hwc)) {
797 ds_err("Could not hwc accept validateion");
801 ds_output_commit(output->ds_output);
803 output->committable = false;
804 output->damaged = false;
805 output->target_updated = false;
807 wl_list_for_each(view, &output->server->views, link) {
808 enum ds_tdm_output_hwc_window_composition composition;
813 composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
814 if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
815 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
816 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
817 view_send_frame_done(view);
820 ds_dbg("output:%p commit", output);
824 output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED)
826 struct tinyds_output *output =
827 wl_container_of(listener, output, output_frame);
829 ds_dbg("output:%p handle frame", output);
831 output->committable = true;
833 output_commit(output);
837 draw_server_with_damage(struct tinyds_server *server)
839 server->output->damaged = true;
840 output_schedule_commit(server->output);
844 output_hwc_init(struct tinyds_output *output)
846 struct ds_tdm_output *tdm_output;
848 tdm_output = ds_tdm_output_from_output(output->ds_output);
851 output->hwc = ds_tdm_output_get_hwc(tdm_output);
854 ds_tdm_output_hwc_set_enabled(output->hwc, true);
857 #ifdef USE_TDM_BUFFER_QUEUE
859 output_handle_buffer_queue_acquirable(struct wl_listener *listener,
860 void *data TINYDS_UNUSED)
862 struct tinyds_output *output;
864 output = wl_container_of(listener, output, buffer_queue_acquirable);
866 output->target_updated = true;
867 output_schedule_commit(output);
871 output_buffer_queue_init(struct tinyds_output *output)
873 struct ds_tdm_output *tdm_output;
875 tdm_output = ds_tdm_output_from_output(output->ds_output);
878 output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output);
879 assert(output->buffer_queue);
881 output->buffer_queue_acquirable.notify =
882 output_handle_buffer_queue_acquirable;
883 ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue,
884 &output->buffer_queue_acquirable);
888 output_renderer_init(struct tinyds_output *output)
890 init_renderer(&output->renderer);
892 renderer_set_surface_queue(&output->renderer,
893 ds_tdm_buffer_queue_get_native_queue(output->buffer_queue));
895 renderer_set_bg_color(&output->renderer, 80, 80, 80);
899 output_draw_with_renderer(struct tinyds_output *output)
901 struct tinyds_view *view;
903 ds_dbg(">> BEGIN UPDATE TEXTURES");
905 wl_list_for_each(view, &output->server->views, link) {
906 struct ds_buffer *ds_buffer;
907 struct ds_tbm_client_buffer *tbm_buffer;
908 tbm_surface_h surface;
909 enum ds_tdm_output_hwc_window_composition composition;
914 composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
915 if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
916 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
917 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
920 ds_buffer = ds_surface_get_buffer(
921 ds_xdg_surface_get_surface(view->xdg_surface));
925 tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer);
929 surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer);
933 renderer_add_texture(&output->renderer, surface, view->x, view->y);
935 view_send_frame_done(view);
938 ds_dbg("<< END UPDATE TEXTURES");
940 renderer_draw(&output->renderer);
944 output_swapchain_init(struct tinyds_output *output,
945 int width, int height, uint32_t format)
948 output->allocator = ds_tbm_allocator_create();
949 assert(output->allocator);
951 output->swapchain = ds_swapchain_create(output->allocator,
952 width, height, format);
953 assert(output->swapchain);
957 output_draw_with_swapchain(struct tinyds_output *output)
959 struct tinyds_view *view;
960 struct ds_buffer *output_buffer;
961 pixman_image_t *output_image;
962 enum ds_tdm_output_hwc_window_composition composition;
964 output_buffer = ds_swapchain_acquire(output->swapchain, NULL);
968 output_image = pixman_image_from_buffer(output_buffer,
969 DS_BUFFER_DATA_PTR_ACCESS_WRITE);
971 ds_buffer_unlock(output_buffer);
975 pixman_image_fill_color(output_image, 80, 80, 80);
977 wl_list_for_each(view, &output->server->views, link) {
981 composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window);
982 if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) ||
983 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) ||
984 (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR))
987 draw_view(view, output_image);
989 pixman_image_unref(output_image);
991 if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, output_buffer)) {
992 ds_err("Could not set hwc client target buffer");
993 ds_buffer_unlock(output_buffer);
997 output_swap_buffer(output, output_buffer);
1001 draw_view(struct tinyds_view *view, pixman_image_t *dst_image)
1003 struct ds_buffer *buffer;
1004 pixman_image_t *src_image;
1006 buffer = ds_surface_get_buffer(
1007 ds_xdg_surface_get_surface(view->xdg_surface));
1011 src_image = pixman_image_from_buffer(buffer,
1012 DS_BUFFER_DATA_PTR_ACCESS_READ);
1013 pixman_image_composite32(PIXMAN_OP_OVER,
1019 pixman_image_get_width(src_image),
1020 pixman_image_get_height(src_image));
1021 pixman_image_unref(src_image);
1023 view_send_frame_done(view);
1028 draw_output(struct tinyds_output *output)
1030 #ifdef USE_TDM_BUFFER_QUEUE
1031 output_draw_with_renderer(output);
1033 output_draw_with_swapchain(output);
1036 ds_dbg("output:%p draw", output);
1040 output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer)
1042 ds_output_attach_buffer(output->ds_output, buffer);
1044 if (output->front_buffer)
1045 ds_buffer_unlock(output->front_buffer);
1046 output->front_buffer = buffer;
1050 view_send_frame_done(struct tinyds_view *view)
1052 struct timespec now;
1053 clock_gettime(CLOCK_MONOTONIC, &now);
1054 ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface),
1059 server_dispatch_stdin(int fd, uint32_t mask, void *data)
1061 struct tinyds_server *server = data;
1063 wl_display_terminate(server->display);
1069 keyboard_handle_device_destroy(struct wl_listener *listener, void *data)
1071 struct tinyds_keyboard *kbd;
1073 kbd = wl_container_of(listener, kbd, destroy);
1075 ds_inf("Keyboard(%p) destroyed", kbd);
1077 wl_list_remove(&kbd->destroy.link);
1078 wl_list_remove(&kbd->key.link);
1079 wl_list_remove(&kbd->link);
1085 server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
1088 case XKB_KEY_BackSpace:
1089 wl_display_terminate(server->display);
1099 keyboard_handle_key(struct wl_listener *listener, void *data)
1101 struct tinyds_keyboard *kbd;
1102 struct ds_keyboard_event_key *event = data;
1103 struct ds_keyboard *ds_keyboard;
1104 struct xkb_state *xkb_state;
1105 const xkb_keysym_t *syms;
1107 bool handled = false;
1109 kbd = wl_container_of(listener, kbd, key);
1111 ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), "
1112 "update_state(%d)", kbd->dev,
1113 event->keycode, event->state, event->time_msec,
1114 event->update_state);
1116 ds_keyboard = ds_input_device_get_keyboard(kbd->dev);
1118 if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1119 xkb_state = ds_keyboard_get_xkb_state(ds_keyboard);
1121 nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8,
1123 for (int i = 0; i < nsyms; i++) {
1124 handled = server_handle_keybinding(kbd->server, syms[i]);
1130 ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec,
1131 event->keycode, event->state);
1136 server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev)
1138 struct tinyds_keyboard *kbd;
1139 struct xkb_context *context;
1140 struct xkb_keymap *keymap;
1142 kbd = calloc(1, sizeof *kbd);
1146 kbd->server = server;
1148 context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
1152 keymap = xkb_keymap_new_from_names(context, NULL,
1153 XKB_KEYMAP_COMPILE_NO_FLAGS);
1156 ds_err("Failed to compile keymap");
1157 xkb_context_unref(context);
1161 ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap);
1163 xkb_keymap_unref(keymap);
1164 xkb_context_unref(context);
1166 kbd->destroy.notify = keyboard_handle_device_destroy;
1167 ds_input_device_add_destroy_listener(dev, &kbd->destroy);
1169 kbd->key.notify = keyboard_handle_key;
1170 ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
1172 wl_list_insert(&server->keyboards, &kbd->link);
1174 ds_inf("Keyboard(%p) added", kbd);
1182 struct tinyds_view *
1183 tinyds_server_view_at(struct tinyds_server *server, double lx, double ly,
1184 double *sx, double *sy)
1186 struct tinyds_view *view;
1187 struct ds_surface *surface;
1188 struct ds_buffer *buffer;
1189 int x, y, w = 0, h = 0;
1191 wl_list_for_each(view, &server->views, link) {
1192 surface = ds_xdg_surface_get_surface(view->xdg_surface);
1193 buffer = ds_surface_get_buffer(surface);
1194 ds_buffer_get_size(buffer, &w, &h);
1199 if (lx >= x && lx <= x + w && ly >= y && ly <= y + h) {
1211 touch_handle_device_destroy(struct wl_listener *listener, void *data)
1213 struct tinyds_touch *touch;
1215 touch = wl_container_of(listener, touch, destroy);
1217 ds_inf("Touch(%p) destroyed", touch);
1219 wl_list_remove(&touch->destroy.link);
1220 wl_list_remove(&touch->down.link);
1221 wl_list_remove(&touch->up.link);
1222 wl_list_remove(&touch->motion.link);
1228 touch_handle_down(struct wl_listener *listener, void *data)
1230 struct ds_touch_event_down *event = data;
1231 struct tinyds_touch *touch;
1232 struct tinyds_view *view;
1233 struct tinyds_server *server;
1234 double sx = 0.f, sy = 0.f;
1236 touch = wl_container_of(listener, touch, down);
1238 server = touch->server;
1239 if (server->output) {
1240 server->output_x = event->x * server->output->width;
1241 server->output_y = event->y * server->output->height;
1244 ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1245 touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1247 view = tinyds_server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1250 ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface),
1251 event->time_msec, event->id, sx, sy);
1255 if (server->output && server->output->cursor_enabled) {
1256 renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1257 draw_server_with_damage(server);
1263 touch_handle_up(struct wl_listener *listener, void *data)
1265 struct ds_touch_event_up *event = data;
1266 struct tinyds_touch *touch;
1268 touch = wl_container_of(listener, touch, up);
1270 ds_inf("Touch(%p) event up: id(%d) time_msec(%d)",
1271 touch->dev, event->id, event->time_msec);
1273 ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id);
1277 touch_handle_motion(struct wl_listener *listener, void *data)
1279 struct ds_touch_event_motion *event = data;
1280 struct tinyds_touch *touch;
1281 struct tinyds_view *view;
1282 struct tinyds_server *server;
1283 double sx = 0.f, sy = 0.f;
1285 touch = wl_container_of(listener, touch, motion);
1287 server = touch->server;
1288 if (server->output) {
1289 server->output_x = event->x * server->output->width;
1290 server->output_y = event->y * server->output->height;
1293 ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f",
1294 touch->dev, event->id, event->x, event->y, server->output_x, server->output_y);
1296 view = tinyds_server_view_at(server, server->output_x, server->output_y, &sx, &sy);
1299 ds_seat_touch_notify_motion(server->seat, event->time_msec,
1304 if (server->output && server->output->cursor_enabled) {
1305 renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1306 draw_server_with_damage(server);
1312 server_add_touch(struct tinyds_server *server, struct ds_input_device *dev)
1314 struct tinyds_touch *touch;
1316 touch = calloc(1, sizeof *touch);
1320 touch->server = server;
1322 touch->destroy.notify = touch_handle_device_destroy;
1323 ds_input_device_add_destroy_listener(dev, &touch->destroy);
1325 touch->down.notify = touch_handle_down;
1326 ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down);
1328 touch->up.notify = touch_handle_up;
1329 ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up);
1331 touch->motion.notify = touch_handle_motion;
1332 ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion);
1334 ds_inf("Touch(%p) added", touch);
1338 pointer_handle_device_destroy(struct wl_listener *listener, void *data)
1340 struct tinyds_pointer *pointer;
1341 struct tinyds_server *server;
1343 pointer = wl_container_of(listener, pointer, destroy);
1345 ds_inf("Pointer(%p) destroyed", pointer);
1347 wl_list_remove(&pointer->destroy.link);
1348 wl_list_remove(&pointer->motion.link);
1349 wl_list_remove(&pointer->button.link);
1350 wl_list_remove(&pointer->frame.link);
1351 wl_list_remove(&pointer->link);
1354 server = pointer->server;
1355 if (server->output && wl_list_empty(&server->pointers))
1357 server->output->cursor_enabled = false;
1358 renderer_cursor_destroy(&server->output->renderer);
1360 if (server->output->cursor_hwc_window)
1362 ds_tdm_output_hwc_window_destroy(server->output->cursor_hwc_window);
1363 server->output->cursor_hwc_window = NULL;
1365 draw_server_with_damage(server);
1373 pointer_handle_motion(struct wl_listener *listener, void *data)
1375 struct tinyds_pointer *pointer;
1376 struct ds_pointer_event_motion *event = data;
1377 struct tinyds_view *view;
1378 struct tinyds_server *server;
1382 pointer = wl_container_of(listener, pointer, motion);
1384 server = pointer->server;
1385 if (server->output) {
1386 ow = server->output->width;
1387 oh = server->output->height;
1390 if (server->output_x + event->delta_x >= ow)
1391 server->output_x = ow;
1392 else if(server->output_x + event->delta_x <= 0.f)
1393 server->output_x = 0.f;
1395 server->output_x = server->output_x + event->delta_x ;
1396 if (server->output_y + event->delta_y >= oh)
1397 server->output_y = oh;
1398 else if(server->output_y + event->delta_y <= 0.f)
1399 server->output_y = 0.f;
1401 server->output_y = server->output_y + event->delta_y ;
1403 ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f",
1404 pointer, event->delta_x, event->delta_y, server->output_x, server->output_y);
1406 view = tinyds_server_view_at(pointer->server, server->output_x, server->output_y, &sx, &sy);
1408 if (pointer->focused_view != view) {
1409 if (pointer->focused_view) {
1410 ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
1411 ds_seat_pointer_notify_clear_focus(pointer->server->seat);
1412 pointer->focused_view = NULL;
1416 ds_inf("Set pointer focus to view(%p)", view);
1417 ds_seat_pointer_notify_enter(pointer->server->seat,
1418 ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
1419 pointer->focused_view = view;
1424 ds_seat_pointer_notify_motion(pointer->server->seat,
1425 event->time_msec, sx, sy);
1429 if (server->output && server->output->cursor_enabled) {
1430 renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1431 draw_server_with_damage(server);
1437 pointer_handle_button(struct wl_listener *listener, void *data)
1439 struct tinyds_pointer *pointer;
1440 struct ds_pointer_event_button *event = data;
1442 pointer = wl_container_of(listener, pointer, button);
1444 ds_inf("Pointer(%p) button(%d): state(%s) time(%d)",
1445 pointer, event->button,
1446 (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released",
1449 ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state);
1453 pointer_handle_frame(struct wl_listener *listener, void *data)
1455 struct tinyds_pointer *pointer;
1457 pointer = wl_container_of(listener, pointer, frame);
1459 ds_inf("Pointer(%p) frame", pointer);
1460 ds_seat_pointer_notify_frame(pointer->server->seat);
1464 server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev)
1466 struct tinyds_pointer *pointer;
1468 pointer = calloc(1, sizeof *pointer);
1472 pointer->server = server;
1474 pointer->destroy.notify = pointer_handle_device_destroy;
1475 ds_input_device_add_destroy_listener(dev, &pointer->destroy);
1477 pointer->motion.notify = pointer_handle_motion;
1478 ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev),
1481 pointer->button.notify = pointer_handle_button;
1482 ds_pointer_add_button_listener(ds_input_device_get_pointer(dev),
1485 pointer->frame.notify = pointer_handle_frame;
1486 ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev),
1489 pointer->focused_view = NULL;
1492 if (server->output && wl_list_empty(&server->pointers)) {
1493 server->output_x = (double)(server->output->width) / 2;
1494 server->output_y = (double)(server->output->height) / 2;
1496 server->output->cursor_enabled = true;
1497 renderer_cursor_create(&server->output->renderer, 255, 0, 0, CURSOR_W, CURSOR_H);
1498 renderer_cursor_update(&server->output->renderer, server->output_x, server->output_y);
1500 server->output->cursor_hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc);
1501 assert(server->output->cursor_hwc_window);
1502 draw_server_with_damage(server);
1506 wl_list_insert(&server->pointers, &pointer->link);
1508 ds_inf("Pointer(%p) added", pointer);
1512 output_schedule_commit_handle_idle_timer(void *data)
1514 struct tinyds_output *output = data;
1515 output->idle_commit = NULL;
1517 output_commit(output);
1521 output_schedule_commit(struct tinyds_output *output)
1523 if (output->idle_commit)
1526 struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display);
1527 output->idle_commit =
1528 wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output);
1532 text_input_mgr_handle_destroy(struct wl_listener *listener, void *data)
1534 struct tinyds_text_input *text_input;
1535 struct tinyds_server *server;
1537 ds_inf("text_input_mgr_handle_destroy");
1538 text_input = wl_container_of(listener, text_input, mgr_destroy);
1540 wl_list_remove(&text_input->mgr_destroy.link);
1541 wl_list_remove(&text_input->new_text_input.link);
1543 server = text_input->server;
1544 server->text_input = NULL;
1548 text_input_handle_destroy(struct wl_listener *listener, void *data)
1550 struct tinyds_text_input *text_input;
1552 ds_inf("text_input_handle_destroy");
1554 text_input = wl_container_of(listener, text_input, destroy);
1556 wl_list_remove(&text_input->destroy.link);
1557 wl_list_remove(&text_input->text_input_activate.link);
1558 wl_list_remove(&text_input->text_input_deactivate.link);
1559 wl_list_remove(&text_input->text_input_reset.link);
1560 wl_list_remove(&text_input->text_input_set_content_type.link);
1561 wl_list_remove(&text_input->text_input_invoke_action.link);
1562 wl_list_remove(&text_input->text_input_commit_state.link);
1563 wl_list_remove(&text_input->text_input_set_preferred_language.link);
1569 text_input_handle_activate(struct wl_listener *listener, void *data)
1571 struct tinyds_text_input *text_input;
1572 struct tinyds_input_method *input_method;
1573 struct ds_tizen_text_input_event_activate *event = data;
1575 text_input = wl_container_of(listener, text_input, text_input_activate);
1577 input_method = text_input->server->input_method;
1579 ds_inf("text_input_handle_activate. text_input(%p) seat(%p) surface(%p) text_input(%p)",
1580 text_input, event->seat, event->surface, event->text_input);
1582 if (input_method->input == text_input)
1584 if (input_method->input)
1585 ;//deactivate_input_method(server->input_method);
1586 input_method->input = text_input;
1587 wl_list_insert(&text_input->input_methods, &input_method->link);
1589 text_input->surface = event->surface;
1591 if (!add_new_input_method_context(input_method, text_input))
1594 // ds_tizen_input_method_send_set_text_input_id();
1598 text_input_handle_deactivate(struct wl_listener *listener, void *data)
1600 struct tinyds_text_input *text_input;
1601 struct tinyds_input_method *input_method, *tmp;
1602 struct ds_tizen_text_input_event_deactivate *event = data;
1604 text_input = wl_container_of(listener, text_input, text_input_deactivate);
1605 ds_inf("text_input_handle_deactivate. text_input(%p) seat(%p) text_input(%p)",
1606 text_input, event->seat, event->text_input);
1608 wl_list_for_each_safe(input_method, tmp, &text_input->input_methods, link) {
1609 if (!input_method->input_method || !input_method->context->context) continue;
1610 ds_tizen_input_method_send_deactivate(input_method->input_method, input_method->context->context);
1611 input_method->input = NULL;
1612 input_method->context = NULL;
1613 wl_list_remove(&input_method->link);
1616 text_input->surface = NULL;
1617 // ds_tizen_input_method_send_close_connection();
1621 text_input_handle_reset(struct wl_listener *listener, void *data)
1623 struct tinyds_text_input *text_input;
1624 struct tinyds_input_method *input_method;
1626 text_input = wl_container_of(listener, text_input, text_input_reset);
1628 ds_inf("text_input_handle_reset. text_input(%p)", text_input);
1630 wl_list_for_each(input_method, &text_input->input_methods, link) {
1631 if (!input_method->context || !input_method->context->context) continue;
1632 ds_tizen_input_method_context_send_reset(input_method->context->context);
1637 text_input_handle_set_content_type(struct wl_listener *listener, void *data)
1639 struct tinyds_text_input *text_input;
1640 struct ds_tizen_text_input_event_set_content_type *event = data;
1641 struct tinyds_input_method *input_method;
1643 text_input = wl_container_of(listener, text_input, text_input_set_content_type);
1645 ds_inf("text_input_handle_content_type. text_input(%p) hint(%u) purpose(%u)",
1646 text_input, event->hint, event->purpose);
1648 wl_list_for_each(input_method, &text_input->input_methods, link) {
1649 if (!input_method->context || !input_method->context->context) continue;
1650 ds_tizen_input_method_context_send_content_type(input_method->context->context,
1651 event->hint, event->purpose);
1656 text_input_handle_invoke_action(struct wl_listener *listener, void *data)
1658 struct tinyds_text_input *text_input;
1659 struct ds_tizen_text_input_event_invoke_action *event = data;
1660 struct tinyds_input_method *input_method;
1662 text_input = wl_container_of(listener, text_input, text_input_invoke_action);
1664 ds_inf("text_input_handle_invoke_action. text_input(%p) button(%u) index(%u)",
1665 text_input, event->button, event->index);
1667 wl_list_for_each(input_method, &text_input->input_methods, link) {
1668 if (!input_method->context || !input_method->context->context) continue;
1669 ds_tizen_input_method_context_send_invoke_action(input_method->context->context,
1670 event->button, event->index);
1675 text_input_handle_commit_state(struct wl_listener *listener, void *data)
1677 struct tinyds_text_input *text_input;
1678 struct ds_tizen_text_input_event_commit_state *event = data;
1679 struct tinyds_input_method *input_method;
1681 text_input = wl_container_of(listener, text_input, text_input_commit_state);
1683 ds_inf("text_input_handle_commit_state. text_input(%p) serial(%u)",
1684 text_input, event->serial);
1686 wl_list_for_each(input_method, &text_input->input_methods, link) {
1687 if (!input_method->context || !input_method->context->context) continue;
1688 ds_tizen_input_method_context_send_commit_state(input_method->context->context,
1694 text_input_handle_set_preferred_language(struct wl_listener *listener, void *data)
1696 struct tinyds_text_input *text_input;
1697 struct ds_tizen_text_input_event_set_preferred_language *event = data;
1698 struct tinyds_input_method *input_method;
1700 text_input = wl_container_of(listener, text_input, text_input_set_preferred_language);
1702 ds_inf("text_input_handle_set_preferred_language. text_input(%p) language(%s)",
1703 text_input, event->language);
1705 wl_list_for_each(input_method, &text_input->input_methods, link) {
1706 if (!input_method->context || !input_method->context->context) continue;
1707 ds_tizen_input_method_context_send_preferred_language(input_method->context->context,
1713 text_input_mgr_handle_new_text_input(struct wl_listener *listener, void *data)
1715 struct tinyds_text_input *text_input;
1716 struct ds_tizen_text_input *input = data;
1718 text_input = wl_container_of(listener, text_input, new_text_input);
1720 ds_inf("text_input_mgr_handle_new_text_input");
1722 text_input->input = input;
1724 text_input->destroy.notify = text_input_handle_destroy;
1725 ds_tizen_text_input_add_destroy_listener(text_input->input,
1726 &text_input->destroy);
1728 text_input->text_input_activate.notify = text_input_handle_activate;
1729 ds_tizen_text_input_add_activate_listener(text_input->input,
1730 &text_input->text_input_activate);
1732 text_input->text_input_deactivate.notify = text_input_handle_deactivate;
1733 ds_tizen_text_input_add_deactivate_listener(text_input->input,
1734 &text_input->text_input_deactivate);
1736 text_input->text_input_reset.notify = text_input_handle_reset;
1737 ds_tizen_text_input_add_reset_listener(text_input->input,
1738 &text_input->text_input_reset);
1740 text_input->text_input_set_content_type.notify = text_input_handle_set_content_type;
1741 ds_tizen_text_input_add_set_content_type_listener(text_input->input,
1742 &text_input->text_input_set_content_type);
1744 text_input->text_input_invoke_action.notify = text_input_handle_invoke_action;
1745 ds_tizen_text_input_add_invoke_action_listener(text_input->input,
1746 &text_input->text_input_invoke_action);
1748 text_input->text_input_commit_state.notify = text_input_handle_commit_state;
1749 ds_tizen_text_input_add_commit_state_listener(text_input->input,
1750 &text_input->text_input_commit_state);
1752 text_input->text_input_set_preferred_language.notify = text_input_handle_set_preferred_language;
1753 ds_tizen_text_input_add_set_preferred_language_listener(text_input->input,
1754 &text_input->text_input_set_preferred_language);
1758 input_method_mgr_handle_destroy(struct wl_listener *listener, void *data)
1760 struct tinyds_input_method *input_method;
1762 ds_inf("input_method_mgr_handle_destroy");
1764 input_method = wl_container_of(listener, input_method, mgr_destroy);
1766 wl_list_remove(&input_method->mgr_destroy.link);
1770 input_method_handle_destroy(struct wl_listener *listener, void *data)
1772 struct tinyds_input_method *input_method;
1773 struct tinyds_server *server;
1775 ds_inf("input_method_handle_destroy");
1777 input_method = wl_container_of(listener, input_method, destroy);
1779 wl_list_remove(&input_method->destroy.link);
1781 server = input_method->server;
1782 server->input_method = NULL;
1788 context_handle_destroy(struct wl_listener *listener, void *data)
1790 struct tinyds_input_method_context *context;
1791 struct tinyds_server *server;
1793 ds_inf("context_handle_destroy");
1795 context = wl_container_of(listener, context, destroy);
1797 wl_list_remove(&context->destroy.link);
1799 wl_list_remove(&context->im_context_commit_string.link);
1800 wl_list_remove(&context->im_context_preedit_string.link);
1801 wl_list_remove(&context->im_context_preedit_styling.link);
1802 wl_list_remove(&context->im_context_preedit_cursor.link);
1803 wl_list_remove(&context->im_context_delete_surrounding_text.link);
1804 wl_list_remove(&context->im_context_cursor_position.link);
1805 wl_list_remove(&context->im_context_modifiers_map.link);
1806 wl_list_remove(&context->im_context_keysym.link);
1807 wl_list_remove(&context->im_context_grab_keyboard.link);
1808 wl_list_remove(&context->im_context_key.link);
1809 wl_list_remove(&context->im_context_modifiers.link);
1810 wl_list_remove(&context->im_context_language.link);
1811 wl_list_remove(&context->im_context_text_direction.link);
1813 server = context->server;
1814 server->input_method->context = NULL;
1820 context_handle_commit_string(struct wl_listener *listener, void *data)
1822 struct tinyds_text_input *text_input;
1823 struct tinyds_input_method_context *context;
1824 struct ds_tizen_input_method_context_event_commit_string *event = data;
1826 context = wl_container_of(listener, context, im_context_commit_string);
1827 text_input = context->server->text_input;
1829 ds_inf("context_handle_commit_string. text_input(%p) serial(%u) text(%s)",
1830 text_input, event->serial, event->text);
1832 ds_tizen_text_input_send_commit_string(text_input->input, event->serial, event->text);
1836 context_handle_preedit_string(struct wl_listener *listener, void *data)
1838 struct tinyds_input_method_context *context;
1839 struct tinyds_text_input *text_input;
1840 struct ds_tizen_input_method_context_event_preedit_string *event = data;
1842 context = wl_container_of(listener, context, im_context_preedit_string);
1843 text_input = context->server->text_input;
1845 ds_inf("context_handle_preedit_string. text_input(%p) serial(%u) text(%s) commit(%s)",
1846 text_input, event->serial, event->text, event->commit);
1848 ds_tizen_text_input_send_preedit_string(text_input->input, event->serial, event->text, event->commit);
1852 context_handle_preedit_styling(struct wl_listener *listener, void *data)
1854 struct tinyds_input_method_context *context;
1855 struct tinyds_text_input *text_input;
1856 struct ds_tizen_input_method_context_event_preedit_styling *event = data;
1858 context = wl_container_of(listener, context, im_context_preedit_styling);
1859 text_input = context->server->text_input;
1861 ds_inf("context_handle_preedit_styling. text_input(%p) index(%u) length(%u) style(%u)",
1862 text_input, event->index, event->length, event->style);
1864 ds_tizen_text_input_send_preedit_styling(text_input->input, event->index, event->length, event->style);
1868 context_handle_preedit_cursor(struct wl_listener *listener, void *data)
1870 struct tinyds_input_method_context *context;
1871 struct tinyds_text_input *text_input;
1872 struct ds_tizen_input_method_context_event_preedit_cursor *event = data;
1874 context = wl_container_of(listener, context, im_context_preedit_cursor);
1875 text_input = context->server->text_input;
1877 ds_inf("context_handle_preedit_cursor. text_input(%p) index(%u)",
1878 text_input, event->index);
1880 ds_tizen_text_input_send_preedit_cursor(text_input->input, event->index);
1884 context_handle_delete_surrounding_text(struct wl_listener *listener, void *data)
1886 struct tinyds_input_method_context *context;
1887 struct tinyds_text_input *text_input;
1888 struct ds_tizen_input_method_context_event_delete_surrounding_text *event = data;
1890 context = wl_container_of(listener, context, im_context_delete_surrounding_text);
1891 text_input = context->server->text_input;
1893 ds_inf("context_handle_delete_surrounding_text. text_input(%p) index(%d) length(%u)",
1894 text_input, event->index, event->length);
1896 ds_tizen_text_input_send_delete_surrounding_text(text_input->input, event->index, event->length);
1900 context_handle_cursor_position(struct wl_listener *listener, void *data)
1902 struct tinyds_input_method_context *context;
1903 struct tinyds_text_input *text_input;
1904 struct ds_tizen_input_method_context_event_cursor_position *event = data;
1906 context = wl_container_of(listener, context, im_context_cursor_position);
1907 text_input = context->server->text_input;
1909 ds_inf("context_handle_cursor_position. text_input(%p) index(%d) length(%d)",
1910 text_input, event->index, event->anchor);
1912 ds_tizen_text_input_send_cursor_position(text_input->input, event->index, event->anchor);
1916 context_handle_modifiers_map(struct wl_listener *listener, void *data)
1918 struct tinyds_input_method_context *context;
1919 struct tinyds_text_input *text_input;
1920 struct ds_tizen_input_method_context_event_modifiers_map *event = data;
1922 context = wl_container_of(listener, context, im_context_modifiers_map);
1923 text_input = context->server->text_input;
1925 ds_inf("context_handle_modifiers_map. text_input(%p) map(%p)",
1926 text_input, event->map);
1928 ds_tizen_text_input_send_modifiers_map(text_input->input, event->map);
1932 context_handle_keysym(struct wl_listener *listener, void *data)
1934 struct tinyds_input_method_context *context;
1935 struct tinyds_text_input *text_input;
1936 struct ds_tizen_input_method_context_event_keysym *event = data;
1938 context = wl_container_of(listener, context, im_context_keysym);
1939 text_input = context->server->text_input;
1941 ds_inf("context_handle_keysym. text_input(%p) serial(%u) time(%u) sysm(%u) state(%u) modifiers(%u)",
1942 text_input, event->serial, event->time, event->sym, event->state, event->modifiers);
1944 ds_tizen_text_input_send_keysym(text_input->input, event->serial, event->time, event->sym, event->state, event->modifiers);
1948 context_handle_grab_keyboard(struct wl_listener *listener, void *data)
1950 struct tinyds_input_method_context *context;
1951 struct tinyds_text_input *text_input;
1953 context = wl_container_of(listener, context, im_context_grab_keyboard);
1954 text_input = context->server->text_input;
1956 ds_inf("context_handle_grab_keyboard. text_input(%p)",
1963 context_handle_key(struct wl_listener *listener, void *data)
1965 struct tinyds_input_method_context *context;
1966 struct tinyds_text_input *text_input;
1968 context = wl_container_of(listener, context, im_context_key);
1969 text_input = context->server->text_input;
1971 ds_inf("context_handle_key. text_input(%p)",
1978 context_handle_modifiers(struct wl_listener *listener, void *data)
1980 struct tinyds_input_method_context *context;
1981 struct tinyds_text_input *text_input;
1983 context = wl_container_of(listener, context, im_context_modifiers);
1984 text_input = context->server->text_input;
1986 ds_inf("context_handle_modifiers. text_input(%p)",
1993 context_handle_language(struct wl_listener *listener, void *data)
1995 struct tinyds_input_method_context *context;
1996 struct tinyds_text_input *text_input;
1997 struct ds_tizen_input_method_context_event_language *event = data;
1999 context = wl_container_of(listener, context, im_context_language);
2000 text_input = context->server->text_input;
2002 ds_inf("context_handle_language. text_input(%p) serial(%u), language(%s)",
2003 text_input, event->serial, event->language);
2005 ds_tizen_text_input_send_language(text_input->input, event->serial, event->language);
2009 context_handle_text_direction(struct wl_listener *listener, void *data)
2011 struct tinyds_input_method_context *context;
2012 struct tinyds_text_input *text_input;
2013 struct ds_tizen_input_method_context_event_text_direction *event = data;
2015 context = wl_container_of(listener, context, im_context_text_direction);
2016 text_input = context->server->text_input;
2018 ds_inf("context_handle_text_direction. text_input(%p) serial(%u), direction(%u)",
2019 text_input, event->serial, event->direction);
2021 ds_tizen_text_input_send_text_direction(text_input->input, event->serial, event->direction);
2025 add_new_text_input(struct tinyds_server *server)
2027 struct tinyds_text_input *text_input;
2029 text_input = calloc(1, sizeof *text_input);
2033 text_input->text_input_mgr = ds_tizen_text_input_manager_create(server->display);
2034 if (!text_input->text_input_mgr) {
2036 ds_err("Could not create ds_tizen_text_input_manager");
2040 wl_list_init(&text_input->input_methods);
2042 text_input->mgr_destroy.notify = text_input_mgr_handle_destroy;
2043 ds_tizen_text_input_manager_add_destroy_listener(text_input->text_input_mgr,
2044 &text_input->mgr_destroy);
2046 text_input->new_text_input.notify = text_input_mgr_handle_new_text_input;
2047 ds_tizen_text_input_manager_add_new_text_input_listener(text_input->text_input_mgr,
2048 &text_input->new_text_input);
2050 text_input->server = server;
2051 server->text_input = text_input;
2053 ds_inf("Text_Input (%p) added", text_input);
2059 add_new_input_method(struct tinyds_server *server)
2061 struct tinyds_input_method *input_method;
2063 input_method = calloc(1, sizeof *input_method);
2067 input_method->input_method = ds_tizen_input_method_create(server->display);
2068 if (!input_method->input_method) {
2070 ds_err("Could not create ds_tizen_input_method");
2073 input_method->destroy.notify = input_method_handle_destroy;
2074 ds_tizen_input_method_add_destroy_listener(input_method->input_method,
2075 &input_method->destroy);
2077 input_method->input_method_mgr = ds_tizen_input_method_manager_create(server->display);
2078 if (!input_method->input_method_mgr) {
2080 ds_err("Could not create ds_tizen_input_method_manager");
2084 input_method->mgr_destroy.notify = input_method_mgr_handle_destroy;
2085 ds_tizen_input_method_manager_add_destroy_listener(input_method->input_method_mgr,
2086 &input_method->mgr_destroy);
2088 input_method->server = server;
2089 server->input_method = input_method;
2091 ds_inf("Input_Method (%p) added", input_method);
2097 add_new_input_method_context(struct tinyds_input_method *input_method,
2098 struct tinyds_text_input *text_input)
2100 struct tinyds_input_method_context *context;
2102 context = calloc(1, sizeof *context);
2103 if (context == NULL)
2105 ds_err("calloc is failed. tinyds_input_method_context");
2108 input_method->context = context;
2109 context->input_method = input_method;
2110 context->server = input_method->server;
2111 context->input = text_input;
2113 context->context = ds_tizen_input_method_create_context(input_method->input_method);
2114 if (context->context == NULL) {
2115 ds_err("ds_tizen_input_method_create_context() failed.");
2119 context->destroy.notify = context_handle_destroy;
2120 ds_tizen_input_method_context_add_destroy_listener(context->context,
2123 context->im_context_commit_string.notify = context_handle_commit_string;
2124 ds_tizen_input_method_context_add_commit_string_listener(context->context,
2125 &context->im_context_commit_string);
2127 context->im_context_preedit_string.notify = context_handle_preedit_string;
2128 ds_tizen_input_method_context_add_preedit_string_listener(context->context,
2129 &context->im_context_preedit_string);
2131 context->im_context_preedit_styling.notify = context_handle_preedit_styling;
2132 ds_tizen_input_method_context_add_preedit_styling_listener(context->context,
2133 &context->im_context_preedit_styling);
2135 context->im_context_preedit_cursor.notify = context_handle_preedit_cursor;
2136 ds_tizen_input_method_context_add_preedit_cursor_listener(context->context,
2137 &context->im_context_preedit_cursor);
2139 context->im_context_delete_surrounding_text.notify = context_handle_delete_surrounding_text;
2140 ds_tizen_input_method_context_add_delete_surrounding_text_listener(context->context,
2141 &context->im_context_delete_surrounding_text);
2143 context->im_context_cursor_position.notify = context_handle_cursor_position;
2144 ds_tizen_input_method_context_add_cursor_position_listener(context->context,
2145 &context->im_context_cursor_position);
2147 context->im_context_modifiers_map.notify = context_handle_modifiers_map;
2148 ds_tizen_input_method_context_add_modifiers_map_listener(context->context,
2149 &context->im_context_modifiers_map);
2151 context->im_context_keysym.notify = context_handle_keysym;
2152 ds_tizen_input_method_context_add_keysym_listener(context->context,
2153 &context->im_context_keysym);
2155 context->im_context_grab_keyboard.notify = context_handle_grab_keyboard;
2156 ds_tizen_input_method_context_add_grab_keyboard_listener(context->context,
2157 &context->im_context_grab_keyboard);
2159 context->im_context_key.notify = context_handle_key;
2160 ds_tizen_input_method_context_add_key_listener(context->context,
2161 &context->im_context_key);
2163 context->im_context_modifiers.notify = context_handle_modifiers;
2164 ds_tizen_input_method_context_add_modifiers_listener(context->context,
2165 &context->im_context_modifiers);
2167 context->im_context_language.notify = context_handle_language;
2168 ds_tizen_input_method_context_add_language_listener(context->context,
2169 &context->im_context_language);
2171 context->im_context_text_direction.notify = context_handle_text_direction;
2172 ds_tizen_input_method_context_add_text_direction_listener(context->context,
2173 &context->im_context_text_direction);
2178 struct tinyds_view *
2179 tinyds_server_get_focused_view(struct tinyds_server *server)
2181 struct tinyds_view *view = NULL;
2182 struct tinyds_pointer *pointer;
2184 wl_list_for_each(pointer, &server->pointers, link){
2185 if (!pointer->focused_view) continue;
2187 view = pointer->focused_view;
2194 tinyds_server_get_output_size(struct tinyds_server *server,
2195 int *output_w, int *output_h)
2197 *output_w = server->output->width;
2198 *output_h = server->output->height;