From f090d9ed2f37041cf3d7497a567d1ae7e509b611 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 3 Jun 2022 18:05:12 +0900 Subject: [PATCH 01/16] keyrouter: Fix wrong return value According to implementation of pepper keyrouter which is a reference of libds keyrouter, keyrouter_grab_check_grabbed() is supposed to return true if a list of MODE_EXCLUSIVE is not empty. This error seems to have been introduced by mistake during the migration from pepper. Change-Id: Ibc0d35bb4b7ba2c6381c248ddc0c861c83f6c8c1 --- src/libds-tizen/keyrouter/keyrouter_grab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libds-tizen/keyrouter/keyrouter_grab.c b/src/libds-tizen/keyrouter/keyrouter_grab.c index f5467ae..053b3e8 100644 --- a/src/libds-tizen/keyrouter/keyrouter_grab.c +++ b/src/libds-tizen/keyrouter/keyrouter_grab.c @@ -79,9 +79,9 @@ keyrouter_grab_check_grabbed(struct ds_tizen_keyrouter_grab *keyrouter_grab, switch(type) { case TIZEN_KEYROUTER_MODE_EXCLUSIVE: if (wl_list_empty(list) == false) - ret = false; - else ret = true; + else + ret = false; break; case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: ret = keyrouter_grab_check_duplicated_data(list, data); -- 2.7.4 From 8a986fd3ccc17f3faaf11ae4ed87a30c0a56ce43 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 3 Jun 2022 18:12:29 +0900 Subject: [PATCH 02/16] keyrouter: Return an appropriate value The return value of keyrouter_grab_check_grabbed() is boolean. So let's make it right. Change-Id: Ic3c5b7fc16cb571633bd8a299cb12a2c3fee1797 --- src/libds-tizen/keyrouter/keyrouter_grab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libds-tizen/keyrouter/keyrouter_grab.c b/src/libds-tizen/keyrouter/keyrouter_grab.c index 053b3e8..a836292 100644 --- a/src/libds-tizen/keyrouter/keyrouter_grab.c +++ b/src/libds-tizen/keyrouter/keyrouter_grab.c @@ -93,7 +93,7 @@ keyrouter_grab_check_grabbed(struct ds_tizen_keyrouter_grab *keyrouter_grab, ret = keyrouter_grab_check_duplicated_data(list, data); break; default: - ret = TIZEN_KEYROUTER_ERROR_INVALID_MODE; + ret = true; break; } -- 2.7.4 From b890aa59286a411d11a1a0b012efbb5290d86844 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:29:44 +0900 Subject: [PATCH 03/16] dpms: fix build error Change-Id: I1190b3d14494921bc657ba8d6dd37bc42fd215f9 Signed-off-by: Junkyeong Kim --- include/libds-tizen/dpms.h | 2 +- src/libds-tizen/dpms.c | 15 ++++++++------- src/libds-tizen/meson.build | 2 ++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/libds-tizen/dpms.h b/include/libds-tizen/dpms.h index 3293ae8..10df4c1 100644 --- a/include/libds-tizen/dpms.h +++ b/include/libds-tizen/dpms.h @@ -30,7 +30,7 @@ enum ds_tizen_dpms_error struct ds_tizen_dpms_event { //struct ds_output *output; - ds_tizen_dpms_mode mode; + enum ds_tizen_dpms_mode mode; }; struct ds_tizen_dpms * diff --git a/src/libds-tizen/dpms.c b/src/libds-tizen/dpms.c index c5bcabb..315d6c0 100644 --- a/src/libds-tizen/dpms.c +++ b/src/libds-tizen/dpms.c @@ -3,9 +3,10 @@ #include #include #include "libds/log.h" -#include "libds-tizen/dpms.h" #include "libds/output.h" +#include "libds-tizen/dpms.h" #include "tizen-dpms-server-protocol.h" +#include "util.h" struct ds_tizen_dpms { @@ -53,8 +54,8 @@ ds_tizen_dpms_create(struct wl_display *display) wl_signal_init(&dpms->events.set_dpms); wl_signal_init(&dpms->events.get_dpms); - dpms->display_destroy.notify = dpms_handle_display_destroy; - wl_display_add_destroy_listener(display, &dpms->display_destroy); + dpms->destroy.notify = dpms_handle_display_destroy; + wl_display_add_destroy_listener(display, &dpms->destroy); ds_inf("global create : tizen_dpms_manager(%p)", dpms); @@ -103,12 +104,12 @@ dpms_handle_display_destroy(struct wl_listener *listener, void *data) { struct ds_tizen_dpms *dpms; - dpms = wl_container_of(listener, dpms, display_destroy); + dpms = wl_container_of(listener, dpms, destroy); ds_inf("global destroy : tizen_dpms_manager(%p)", dpms); wl_signal_emit(&dpms->events.destroy, dpms); - wl_list_remove(&dpms->display_destroy.link); + wl_list_remove(&dpms->destroy.link); wl_resource_set_user_data(dpms->res, NULL); wl_global_destroy(dpms->global); free(dpms); @@ -132,8 +133,8 @@ _tizen_dpms_manager_handle_set_dpms(struct wl_client *client, if (mode > DS_TIZEN_DPMS_MODE_OFF) { ds_err("set dpms error : not supported mode(%d)", mode); - tizen_dpms_manager_send_set_state(resource, E_DPMS_MODE_OFF, - E_DPMS_MANAGER_ERROR_INVALID_PARAMETER); + tizen_dpms_manager_send_set_state(resource, DS_TIZEN_DPMS_MODE_OFF, + DS_TIZEN_DPMS_ERROR_INVALID_PARAMETER); return; } diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build index 0d780a3..6779a72 100644 --- a/src/libds-tizen/meson.build +++ b/src/libds-tizen/meson.build @@ -1,6 +1,7 @@ libds_tizen_files = [ 'pixel_format.c', 'tbm_server.c', + 'dpms.c', ] libds_tizen_deps = [ @@ -8,6 +9,7 @@ libds_tizen_deps = [ dependency('libdrm', required: true), dependency('libtbm', required: true), dependency('wayland-tbm-server', required: true), + dependency('tizen-dpms-server', required: true), ] subdir('allocator') -- 2.7.4 From 94bded6e661616d177c7a6318a44ae044c3553a7 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:31:32 +0900 Subject: [PATCH 04/16] example: add tinyds-tdm-dpms Change-Id: I6845876ee8240eba2d8569bdef5c799bd56ee0ce Signed-off-by: Junkyeong Kim --- packaging/libds.spec | 1 + src/examples/meson.build | 13 + src/examples/tinyds-tdm-dpms.c | 672 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 686 insertions(+) create mode 100644 src/examples/tinyds-tdm-dpms.c diff --git a/packaging/libds.spec b/packaging/libds.spec index ed21c53..aefff95 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -107,6 +107,7 @@ ninja -C builddir install %{_bindir}/ds-simple-tbm %{_bindir}/tinyds-tdm-libinput %{_bindir}/ds-simple-shm-shell +%{_bindir}/tinyds-tdm-dpms %files tizen-keyrouter %manifest %{name}.manifest diff --git a/src/examples/meson.build b/src/examples/meson.build index 5c5c437..aad893e 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -82,4 +82,17 @@ if get_option('tizen') install_dir: libds_bindir, install : true ) + executable('tinyds-tdm-dpms', + 'tinyds-tdm-dpms.c', + 'pixman-helper.c', + 'pixman-tbm-helper.c', + 'tinyds-tdm-renderer.c', + dependencies: [ + common_deps, + dependency('pixman-1', required: true), + dependency('threads', required: true), + ], + install_dir: libds_bindir, + install : true + ) endif diff --git a/src/examples/tinyds-tdm-dpms.c b/src/examples/tinyds-tdm-dpms.c new file mode 100644 index 0000000..dc32e8f --- /dev/null +++ b/src/examples/tinyds-tdm-dpms.c @@ -0,0 +1,672 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USE_TDM_BUFFER_QUEUE + +#ifdef USE_TDM_BUFFER_QUEUE +#include "pixman-tbm-helper.h" +#include "tinyds-tdm-renderer.h" +#else +#include +#endif + +#include "pixman-helper.h" + +#define TINYDS_UNUSED __attribute__((unused)) + +struct tinyds_output +{ + struct tinyds_server *server; + struct ds_output *ds_output; + struct ds_allocator *allocator; +#ifdef USE_TDM_BUFFER_QUEUE + struct tinyds_renderer renderer; + struct ds_tdm_buffer_queue *buffer_queue; + struct wl_listener buffer_queue_acquirable; +#else + struct ds_swapchain *swapchain; +#endif + struct ds_buffer *front_buffer; + + struct wl_listener output_destroy; + struct wl_listener output_frame; + + int width, height; + + bool drawable; + bool damaged; +}; + +struct tinyds_dpms +{ + struct ds_tizen_dpms *ds_dpms; + struct tinyds_server *server; + + struct wl_listener destroy; + struct wl_listener set_dpms; + struct wl_listener get_dpms; +}; + +struct tinyds_server +{ + struct ds_tbm_server *tbm_server; + + struct wl_display *display; + + struct ds_backend *backend; + struct ds_compositor *compositor; + struct ds_xdg_shell *xdg_shell; + + struct tinyds_output *output; + struct tinyds_dpms *dpms; + struct wl_event_source *stdin_source; + + struct wl_list views; + + struct wl_listener new_output; + struct wl_listener new_xdg_surface; +}; + +struct tinyds_view +{ + struct tinyds_server *server; + + struct tinyds_texture *texture; + struct ds_xdg_surface *xdg_surface; + + struct wl_listener xdg_surface_map; + struct wl_listener xdg_surface_unmap; + struct wl_listener xdg_surface_destroy; + struct wl_listener surface_commit; + struct wl_list link; // tinyds_server::views + + int x, y; + bool mapped; +}; + +struct tinyds_server tinyds; + +static bool init_server(struct tinyds_server *server, struct wl_display *display); +static int server_dispatch_stdin(int fd, uint32_t mask, void *data); +static void output_handle_destroy(struct wl_listener *listener, void *data); +static void output_handle_frame(struct wl_listener *listener, void *data); +static void draw_server_with_damage(struct tinyds_server *server); +static void draw_output(struct tinyds_output *output); +static void output_swap_buffer(struct tinyds_output *output, + struct ds_buffer *buffer); +static void view_send_frame_done(struct tinyds_view *view); +#ifdef USE_TDM_BUFFER_QUEUE +static void output_buffer_queue_init(struct tinyds_output *output); +static void output_renderer_init(struct tinyds_output *output); +static void output_draw_with_renderer(struct tinyds_output *output); +#else +static void output_swapchain_init(struct tinyds_output *output, + int width, int height, uint32_t format); +static void output_draw_with_swapchain(struct tinyds_output *output); +static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); +#endif +static void dpms_handle_destroy(struct wl_listener *listener, void *data); +static void dpms_handle_set_dpms(struct wl_listener *listener, void *data); +static void dpms_handle_get_dpms(struct wl_listener *listener, void *data); + + +int +main(void) +{ + struct tinyds_server *server = &tinyds; + struct wl_display *display; + struct wl_event_loop *loop; + const char *socket; + bool res; + + ds_log_init(DS_INF, NULL); + + display = wl_display_create(); + assert(display); + + res = init_server(server, display); + assert(res); + + socket = wl_display_add_socket_auto(display); + assert(socket); + + ds_backend_start(server->backend); + + setenv("WAYLAND_DISPLAY", socket, true); + + ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); + + loop = wl_display_get_event_loop(display); + server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO, + WL_EVENT_READABLE, server_dispatch_stdin, server); + + wl_display_run(display); + + wl_display_destroy_clients(display); + wl_display_destroy(display); + + return 0; +} + +static void +view_handle_xdg_surface_map(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + + view = wl_container_of(listener, view, xdg_surface_map); + view->mapped = true; +} + +static void +view_handle_xdg_surface_unmap(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + + view = wl_container_of(listener, view, xdg_surface_unmap); + view->mapped = false; +} + +static void +view_handle_xdg_surface_destroy(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + struct tinyds_server *server; + + view = wl_container_of(listener, view, xdg_surface_destroy); + server = view->server; + + wl_list_remove(&view->xdg_surface_destroy.link); + wl_list_remove(&view->xdg_surface_map.link); + wl_list_remove(&view->xdg_surface_unmap.link); + wl_list_remove(&view->surface_commit.link); + wl_list_remove(&view->link); + free(view); + + draw_server_with_damage(server); +} + +static void +view_handle_surface_commit(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + + view = wl_container_of(listener, view, surface_commit); + draw_server_with_damage(view->server); +} + +static void +server_new_xdg_surface(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct tinyds_view *view; + struct ds_xdg_surface *xdg_surface; + + server = wl_container_of(listener, server, new_xdg_surface); + xdg_surface = data; + + ds_inf("New xdg_surface(%p)", (void *)xdg_surface); + + view = calloc(1, sizeof *view); + assert(view); + + view->server = server; + view->xdg_surface = xdg_surface; + + view->xdg_surface_map.notify = view_handle_xdg_surface_map; + ds_xdg_surface_add_map_listener(xdg_surface, + &view->xdg_surface_map); + + view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap; + ds_xdg_surface_add_unmap_listener(xdg_surface, + &view->xdg_surface_unmap); + + view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy; + ds_xdg_surface_add_destroy_listener(xdg_surface, + &view->xdg_surface_destroy); + + view->surface_commit.notify = view_handle_surface_commit; + ds_surface_add_commit_listener( + ds_xdg_surface_get_surface(xdg_surface), + &view->surface_commit); + + wl_list_insert(server->views.prev, &view->link); + + view->x = rand() % 1000; + view->y = rand() % 500; +} + +static void +backend_handle_new_output(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct tinyds_output *output; + struct ds_output *ds_output; + const struct ds_output_mode *mode; + + server = wl_container_of(listener, server, new_output); + ds_output = data; + + ds_inf("New output(%p)", ds_output); + + if (server->output) + return; + + mode = ds_output_get_preferred_mode(ds_output); + ds_output_set_mode(ds_output, mode); + + output = calloc(1, sizeof *output); + if (!output) + return; + + output->server = server; + output->ds_output = ds_output; + output->width = mode->width; + output->height = mode->height; + output->drawable = true; + output->damaged = true; + +#ifdef USE_TDM_BUFFER_QUEUE + output_buffer_queue_init(output); + output_renderer_init(output); +#else + output_swapchain_init(output, mode->width, mode->height, + DRM_FORMAT_XRGB8888); +#endif + + output->output_destroy.notify = output_handle_destroy; + ds_output_add_destroy_listener(ds_output, &output->output_destroy); + + output->output_frame.notify = output_handle_frame; + ds_output_add_frame_listener(ds_output, &output->output_frame); + + server->output = output; + + draw_output(output); +} + +static bool +add_new_dpms(struct tinyds_server *server) +{ + struct tinyds_dpms *dpms; + + dpms = calloc(1, sizeof *dpms); + if (!dpms) + return false; + + dpms->ds_dpms = ds_tizen_dpms_create(server->display); + if (!dpms->ds_dpms) + return false; + + dpms->destroy.notify = dpms_handle_destroy; + ds_tizen_dpms_add_destroy_listener(dpms->ds_dpms, &dpms->destroy); + + dpms->set_dpms.notify = dpms_handle_set_dpms; + ds_tizen_dpms_add_set_dpms_listener(dpms->ds_dpms, &dpms->set_dpms); + + dpms->get_dpms.notify = dpms_handle_get_dpms; + ds_tizen_dpms_add_get_dpms_listener(dpms->ds_dpms, &dpms->get_dpms); + + server->dpms = dpms; + + ds_inf("Dpms (%p) added", dpms); + + return true; +} + +static bool +init_server(struct tinyds_server *server, struct wl_display *display) +{ + server->display = display; + + wl_list_init(&server->views); + + if (wl_display_init_shm(display) != 0) + return false; + + server->backend = ds_tdm_backend_create(display); + if (!server->backend) + return false; + + server->new_output.notify = backend_handle_new_output; + ds_backend_add_new_output_listener(server->backend, + &server->new_output); + + server->compositor = ds_compositor_create(display); + if (!server->compositor) { + ds_backend_destroy(server->backend); + return false; + } + + server->tbm_server = ds_tbm_server_create(display); + if (!server->tbm_server) { + ds_backend_destroy(server->backend); + return false; + } + + server->xdg_shell = ds_xdg_shell_create(display); + if (!server->xdg_shell) { + ds_backend_destroy(server->backend); + return false; + } + + server->new_xdg_surface.notify = server_new_xdg_surface; + ds_xdg_shell_add_new_surface_listener(server->xdg_shell, + &server->new_xdg_surface); + + if (!add_new_dpms(server)) { + ds_backend_destroy(server->backend); + return false; + } + + return true; +} + +static void +output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_output *output = + wl_container_of(listener, output, output_destroy); + + wl_list_remove(&output->output_destroy.link); + wl_list_remove(&output->output_frame.link); + + if (output->front_buffer) + ds_buffer_unlock(output->front_buffer); + +#ifdef USE_TDM_BUFFER_QUEUE + fini_renderer(&output->renderer); +#else + if (output->swapchain) + ds_swapchain_destroy(output->swapchain); + + if (output->allocator) + ds_allocator_destroy(output->allocator); +#endif + + wl_display_terminate(output->server->display); + + output->server->output = NULL; + + free(output); +} + +static void +output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_output *output = + wl_container_of(listener, output, output_frame); + + output->drawable = true; + draw_output(output); +} + +static void +draw_server_with_damage(struct tinyds_server *server) +{ + server->output->damaged = true; + draw_output(server->output); +} + +#ifdef USE_TDM_BUFFER_QUEUE +static void +output_handle_buffer_queue_acquirable(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_output *output; + struct ds_buffer *buffer; + + output = wl_container_of(listener, output, buffer_queue_acquirable); + + buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue); + assert(buffer); + + output_swap_buffer(output, buffer); +} + +static void +output_buffer_queue_init(struct tinyds_output *output) +{ + struct ds_tdm_output *tdm_output; + + tdm_output = ds_tdm_output_from_output(output->ds_output); + assert(tdm_output); + + output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output); + assert(output->buffer_queue); + + output->buffer_queue_acquirable.notify = + output_handle_buffer_queue_acquirable; + ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue, + &output->buffer_queue_acquirable); +} + +static void +output_renderer_init(struct tinyds_output *output) +{ + init_renderer(&output->renderer); + + renderer_set_surface_queue(&output->renderer, + ds_tdm_buffer_queue_get_native_queue(output->buffer_queue)); + + renderer_set_bg_color(&output->renderer, 80, 80, 80); +} + +static void +output_draw_with_renderer(struct tinyds_output *output) +{ + struct tinyds_view *view; + + ds_dbg(">> BEGIN UPDATE TEXTURES"); + + wl_list_for_each(view, &output->server->views, link) { + struct ds_buffer *ds_buffer; + struct ds_tbm_client_buffer *tbm_buffer; + tbm_surface_h surface; + + if (!view->mapped) + continue; + + ds_buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + assert(ds_buffer); + + tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer); + assert(tbm_buffer); + + surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer); + + renderer_add_texture(&output->renderer, surface, view->x, view->y); + + view_send_frame_done(view); + } + + ds_dbg("<< END UPDATE TEXTURES"); + + renderer_draw(&output->renderer); + +} +#else +static void +output_swapchain_init(struct tinyds_output *output, + int width, int height, uint32_t format); + +{ + output->allocator = ds_tbm_allocator_create(); + assert(output->allocator); + + output->swapchain = ds_swapchain_create(output->allocator, + width, height, format); + assert(output->swapchain); +} + +static void +output_draw_with_swapchain(struct tinyds_output *output) +{ + struct tinyds_view *view; + struct ds_buffer *output_buffer; + pixman_image_t *output_image; + + output_buffer = ds_swapchain_acquire(output->swapchain, NULL); + if (!output_buffer) + return; + + output_image = pixman_image_from_buffer(output_buffer, + DS_BUFFER_DATA_PTR_ACCESS_WRITE); + if (!output_image) { + ds_buffer_unlock(output_buffer); + return; + } + + pixman_image_fill_color(output_image, 80, 80, 80); + + wl_list_for_each(view, &output->server->views, link) { + if (!view->mapped) + continue; + draw_view(view, output_image); + } + pixman_image_unref(output_image); + + output_swap_buffer(output, output_buffer); +} + +static void +draw_view(struct tinyds_view *view, pixman_image_t *dst_image) +{ + struct ds_buffer *buffer; + pixman_image_t *src_image; + + buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + if (!buffer) + return; + + src_image = pixman_image_from_buffer(buffer, + DS_BUFFER_DATA_PTR_ACCESS_READ); + pixman_image_composite32(PIXMAN_OP_OVER, + src_image, + NULL, + dst_image, + 0, 0, 0, 0, + view->x, view->y, + pixman_image_get_width(src_image), + pixman_image_get_height(src_image)); + pixman_image_unref(src_image); + + view_send_frame_done(view); +} +#endif + +static void +draw_output(struct tinyds_output *output) +{ + + if (!output->drawable || !output->damaged) + return; + +#ifdef USE_TDM_BUFFER_QUEUE + output_draw_with_renderer(output); +#else + output_draw_with_swapchain(output); +#endif + + output->drawable = false; + output->damaged = false; +} + +static void +output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer) +{ + ds_output_attach_buffer(output->ds_output, buffer); + ds_output_commit(output->ds_output); + + if (output->front_buffer) + ds_buffer_unlock(output->front_buffer); + output->front_buffer = buffer; +} + +static void +view_send_frame_done(struct tinyds_view *view) +{ + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), + &now); +} + +static int +server_dispatch_stdin(int fd, uint32_t mask, void *data) +{ + struct tinyds_server *server = data; + + wl_display_terminate(server->display); + + return 1; +} + +static void +dpms_handle_destroy(struct wl_listener *listener, void *data) +{ + struct tinyds_dpms *dpms; + + dpms = wl_container_of(listener, dpms, destroy); + + ds_inf("Dpms(%p) destroyed", dpms); + + wl_list_remove(&dpms->destroy.link); + wl_list_remove(&dpms->set_dpms.link); + wl_list_remove(&dpms->get_dpms.link); + + free(dpms); +} + +static void +dpms_handle_set_dpms(struct wl_listener *listener, void *data) +{ + struct tinyds_dpms *dpms; + struct ds_tizen_dpms_event *event = data; + + dpms = wl_container_of(listener, dpms, set_dpms); + + ds_inf("Dpms(%p) set dpms : %d", dpms, event->mode); + + //To do + //set dpms mode to output + ds_tizen_dpms_send_set_result(dpms->ds_dpms, event->mode, + DS_TIZEN_DPMS_ERROR_NONE); +} + +static void +dpms_handle_get_dpms(struct wl_listener *listener, void *data) +{ + struct tinyds_dpms *dpms; + + dpms = wl_container_of(listener, dpms, get_dpms); + + ds_inf("Dpms(%p) get dpms", dpms); + + //To do + //get dpms mode from output + ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON, + DS_TIZEN_DPMS_ERROR_NONE); +} \ No newline at end of file -- 2.7.4 From 86d9c43ef128f42ed834dffc0373dd24ddf41884 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:34:43 +0900 Subject: [PATCH 05/16] client: add simple-dpms Change-Id: Idf32c869b660f568ab6514d542396c40f32dc6c6 Signed-off-by: Junkyeong Kim --- packaging/libds.spec | 2 + src/clients/meson.build | 10 ++ src/clients/simple-dpms.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 src/clients/simple-dpms.c diff --git a/packaging/libds.spec b/packaging/libds.spec index aefff95..6260ed2 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -23,6 +23,7 @@ BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(wayland-tbm-server) BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(tizen-dpms-server) +BuildRequires: pkgconfig(tizen-dpms-client) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(libsmack) @@ -108,6 +109,7 @@ ninja -C builddir install %{_bindir}/tinyds-tdm-libinput %{_bindir}/ds-simple-shm-shell %{_bindir}/tinyds-tdm-dpms +%{_bindir}/ds-simple-dpms %files tizen-keyrouter %manifest %{name}.manifest diff --git a/src/clients/meson.build b/src/clients/meson.build index 009016c..6fcd3f8 100644 --- a/src/clients/meson.build +++ b/src/clients/meson.build @@ -55,3 +55,13 @@ executable('ds-simple-tbm', install_dir: libds_bindir, install: true, ) + +executable('ds-simple-dpms', + 'simple-dpms.c', + dependencies: [ + dependency('wayland-client', required: true), + dependency('tizen-dpms-client', required: true), + ], + install_dir: libds_bindir, + install: true, +) diff --git a/src/clients/simple-dpms.c b/src/clients/simple-dpms.c new file mode 100644 index 0000000..9b4d22c --- /dev/null +++ b/src/clients/simple-dpms.c @@ -0,0 +1,239 @@ +/* +Copyright (C) 2015 - 2016 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: + SooChan Lim + Changyeon Lee + JunKyeong Kim + Boram Park + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +struct wl_dpms_info { + char *app_name; + + struct wl_display *display; + struct wl_registry *registry; + struct wl_output *output; + struct tizen_dpms_manager *tz_dpms_mng; + int got_dpms_state; +}; + +void +usage(const char *app_name) +{ + printf("usage: %s \n", app_name); + printf("%s output_num option(set1/get0) state\nex)\n", app_name); + printf("%s 1 0 => set dpms_on\n", app_name); + printf("%s 1 3 => set dpms_off\n", app_name); + printf("%s 0 0 => get state\n", app_name); +} + +static struct wl_dpms_info * +_create_wl_dpms_info (void) +{ + struct wl_dpms_info *test_info = NULL; + + test_info = calloc(1, sizeof(struct wl_dpms_info)); + if (test_info == NULL) { + printf("alloc fail"); + return NULL; + } + + return test_info; +} + +static void +_destroy_wl_dpms_info (struct wl_dpms_info *test_info) +{ + if (!test_info) return; + + if (test_info->app_name) + free(test_info->app_name); + if (test_info->tz_dpms_mng) + tizen_dpms_manager_destroy(test_info->tz_dpms_mng); + if (test_info->registry) + wl_registry_destroy(test_info->registry); + if (test_info->display) + wl_display_disconnect(test_info->display); + + free(test_info); +} + +static void +dpms_handle_set_state(void *data, struct tizen_dpms_manager *tz_dpms, uint32_t mode, uint32_t error) +{ + struct wl_dpms_info *test_info = (struct wl_dpms_info *)data; + printf("dpms_set_state_cb - mode:%d, error:%d\n", mode, error); + test_info->got_dpms_state = 1; +} + +static void +dpms_handle_get_state(void *data, struct tizen_dpms_manager *tz_dpms, uint32_t mode, uint32_t error) +{ + struct wl_dpms_info *test_info = (struct wl_dpms_info *)data; + printf("dpms_get_state_cb - mode:%d, error:%d\n", mode, error); + test_info->got_dpms_state = 1; +} + +static const struct tizen_dpms_manager_listener dpms_listener = { + dpms_handle_set_state, + dpms_handle_get_state +}; + +static void +handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) +{ + struct wl_dpms_info *test_info = (struct wl_dpms_info *)data; + + if (strcmp(interface, "wl_output") == 0) { + test_info->output = wl_registry_bind(registry, name, &wl_output_interface, 2); + if (!test_info->output) + printf("bind wl_output fail\n"); + else + printf("bind wl_output\n"); + } else if (strcmp(interface, "tizen_dpms_manager") == 0) { + test_info->tz_dpms_mng = wl_registry_bind(registry, name, &tizen_dpms_manager_interface, 1); + if (!test_info->tz_dpms_mng) + printf("bind tizen_dpms_manager fail\n"); + else { + tizen_dpms_manager_add_listener(test_info->tz_dpms_mng, &dpms_listener, test_info); + printf("bind tizen_dpms_manager\n"); + } + } +} + +static void +handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ +} + +static const struct wl_registry_listener registry_listener = { + handle_global, + handle_global_remove +}; + +int +main(int argc, char *argv[]) +{ + struct wl_dpms_info *test_info = NULL; + char *opt = NULL; + int option; + char *sta = NULL; + int state = 0; + + test_info = _create_wl_dpms_info(); + if (test_info == NULL) return 0; + + test_info->app_name = strdup(argv[0]); + if (test_info->app_name == NULL) { + printf("alloc fail"); + goto done; + } + if (argc != 3) { + usage(test_info->app_name); + goto done; + } + + opt = strdup(argv[1]); + if (opt == NULL) { + printf("alloc fail"); + goto done; + } + option = opt[0] - '0'; + free(opt); + if (!(option == 0 || option == 1)) { + usage(test_info->app_name); + goto done; + } + + if (option == 1) { + sta = strdup(argv[2]); + if (sta == NULL) { + printf("alloc fail"); + goto done; + } + state = sta [0] - '0'; + free(sta); + if (!(state == 0 || state == 1 || state == 2 || state == 3)) { + usage(test_info->app_name); + goto done; + } + } + + test_info->display = wl_display_connect(NULL); + if (test_info->display == NULL) { + printf("wl_display_connect fail"); + goto done; + } + + test_info->registry = wl_display_get_registry(test_info->display); + if (test_info->registry == NULL) { + printf("wl_display_get_registry fail"); + goto done; + } + + wl_registry_add_listener(test_info->registry, ®istry_listener, test_info); + wl_display_roundtrip(test_info->display); + + if (!test_info->output || !test_info->tz_dpms_mng) { + printf("bind fail\n"); + goto done; + } + + if (option == 1) { + tizen_dpms_manager_set_dpms(test_info->tz_dpms_mng, test_info->output, state); + printf("set dpms %d\n", state); + } else { + tizen_dpms_manager_get_dpms(test_info->tz_dpms_mng, test_info->output); + printf("get dpms\n"); + } + + test_info->got_dpms_state = 0; + while (!test_info->got_dpms_state) { + wl_display_roundtrip(test_info->display); + } + +done: + _destroy_wl_dpms_info(test_info); + + return 0; +} + -- 2.7.4 From dc8d92eacfadc35ebff24b2fc63fccb1b80aab4a Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:35:51 +0900 Subject: [PATCH 06/16] dpms: set ds_tizen_dpms enum value by tizen dpms protocol enum value Change-Id: I1f02952b83bfcedfa60cfb045d710b0edb354492 Signed-off-by: Junkyeong Kim --- include/libds-tizen/dpms.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/include/libds-tizen/dpms.h b/include/libds-tizen/dpms.h index 10df4c1..c614e66 100644 --- a/include/libds-tizen/dpms.h +++ b/include/libds-tizen/dpms.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -12,19 +13,19 @@ struct ds_tizen_dpms; enum ds_tizen_dpms_mode { - DS_TIZEN_DPMS_MODE_ON = 0, - DS_TIZEN_DPMS_MODE_STANDBY = 1, - DS_TIZEN_DPMS_MODE_SUSPEND = 2, - DS_TIZEN_DPMS_MODE_OFF = 3, + DS_TIZEN_DPMS_MODE_ON = TIZEN_DPMS_MANAGER_MODE_ON, + DS_TIZEN_DPMS_MODE_STANDBY = TIZEN_DPMS_MANAGER_MODE_STANDBY, + DS_TIZEN_DPMS_MODE_SUSPEND = TIZEN_DPMS_MANAGER_MODE_SUSPEND, + DS_TIZEN_DPMS_MODE_OFF = TIZEN_DPMS_MANAGER_MODE_OFF, }; enum ds_tizen_dpms_error { - DS_TIZEN_DPMS_ERROR_NONE = 0, - DS_TIZEN_DPMS_ERROR_INVALID_PERMISSION = 1, - DS_TIZEN_DPMS_ERROR_INVALID_PARAMETER = 2, - DS_TIZEN_DPMS_ERROR_NOT_SUPPORTED = 3, - DS_TIZEN_DPMS_ERROR_ALREADY_DONE = 4, + DS_TIZEN_DPMS_ERROR_NONE = TIZEN_DPMS_MANAGER_ERROR_NONE, + DS_TIZEN_DPMS_ERROR_INVALID_PERMISSION = TIZEN_DPMS_MANAGER_ERROR_INVALID_PERMISSION, + DS_TIZEN_DPMS_ERROR_INVALID_PARAMETER = TIZEN_DPMS_MANAGER_ERROR_INVALID_PARAMETER, + DS_TIZEN_DPMS_ERROR_NOT_SUPPORTED = TIZEN_DPMS_MANAGER_ERROR_NOT_SUPPORTED, + DS_TIZEN_DPMS_ERROR_ALREADY_DONE = TIZEN_DPMS_MANAGER_ERROR_ALREADY_DONE, }; struct ds_tizen_dpms_event -- 2.7.4 From e3462b591507924fe3516e005f5a5fbce06076dd Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Tue, 7 Jun 2022 19:38:39 +0900 Subject: [PATCH 07/16] devicemgr: implement libds-tizen-input-devicemgr Change-Id: I3e0451c47fea0c5dac467d45143d594f36161907 --- include/libds-tizen/input-devicemgr.h | 40 + include/libds/input_device.h | 3 + include/libds/interfaces/backend.h | 3 +- packaging/libds.spec | 30 + src/clients/input-generator.c | 540 +++++++++++ src/clients/meson.build | 15 + src/clients/simple-tbm.c | 84 +- src/examples/meson.build | 1 + src/examples/tinyds-tdm-libinput.c | 141 ++- src/libds-tizen/backend/tdm/backend.c | 2 +- src/libds-tizen/input-devicemgr/input-devicemgr.c | 1063 +++++++++++++++++++++ src/libds-tizen/input-devicemgr/input-devicemgr.h | 59 ++ src/libds-tizen/input-devicemgr/meson.build | 30 + src/libds-tizen/meson.build | 1 + src/libds/backend.c | 2 + src/libds/backend/libinput/backend.c | 4 +- src/libds/backend/libinput/input.c | 2 + src/libds/backend/wayland/backend.c | 2 +- src/libds/input_device.c | 9 + src/libds/seat/seat_keyboard.c | 2 +- 20 files changed, 2018 insertions(+), 15 deletions(-) create mode 100644 include/libds-tizen/input-devicemgr.h create mode 100644 src/clients/input-generator.c create mode 100644 src/libds-tizen/input-devicemgr/input-devicemgr.c create mode 100644 src/libds-tizen/input-devicemgr/input-devicemgr.h create mode 100644 src/libds-tizen/input-devicemgr/meson.build diff --git a/include/libds-tizen/input-devicemgr.h b/include/libds-tizen/input-devicemgr.h new file mode 100644 index 0000000..a9ed808 --- /dev/null +++ b/include/libds-tizen/input-devicemgr.h @@ -0,0 +1,40 @@ +#ifndef LIBDS_TIZEN_INPUT_DEVICEMGR_H +#define LIBDS_TIZEN_INPUT_DEVICEMGR_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tizen_input_devicemgr; +struct ds_backend; +struct ds_seat; + +struct ds_tizen_input_devicemgr_keymap_data +{ + char *name; + int keycode; + + struct wl_list link; +}; + +struct ds_tizen_input_devicemgr * +ds_tizen_input_devicemgr_create(struct ds_backend *backend, + struct ds_seat *seat); + +void +ds_tizen_input_devicemgr_add_destroy_listener( + struct ds_tizen_input_devicemgr *devicemgr, + struct wl_listener *listener); + +bool +ds_tizen_input_devicemgr_set_keymap_list( + struct ds_tizen_input_devicemgr *devicemgr, + struct wl_list *list); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libds/input_device.h b/include/libds/input_device.h index 1a3652b..55aabbd 100644 --- a/include/libds/input_device.h +++ b/include/libds/input_device.h @@ -25,6 +25,9 @@ enum ds_input_device_type enum ds_input_device_type ds_input_device_get_type(struct ds_input_device *dev); +const char * +ds_input_device_get_name(struct ds_input_device *dev); + struct ds_pointer * ds_input_device_get_pointer(struct ds_input_device *dev); diff --git a/include/libds/interfaces/backend.h b/include/libds/interfaces/backend.h index bad37a0..55a2475 100644 --- a/include/libds/interfaces/backend.h +++ b/include/libds/interfaces/backend.h @@ -29,7 +29,8 @@ struct ds_backend }; void -ds_backend_init(struct ds_backend *backend, const struct ds_backend_interface *iface); +ds_backend_init(struct ds_backend *backend, struct wl_display *display, + const struct ds_backend_interface *iface); void ds_backend_finish(struct ds_backend *backend); diff --git a/packaging/libds.spec b/packaging/libds.spec index 6260ed2..f53efa9 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -12,6 +12,7 @@ BuildRequires: pkgconfig(wayland-server) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-protocols) BuildRequires: pkgconfig(tizen-extension-server) +BuildRequires: pkgconfig(tizen-extension-client) BuildRequires: pkgconfig(pixman-1) BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(xkbcommon) @@ -59,6 +60,20 @@ Group: Development/Libraries %description tizen-keyrouter-devel Keyrouter Development package for Wayland Compositor Library +%package tizen-input-devicemgr +Summary: Library for tizen input devicemgr +Group: Development/Libraries + +%description tizen-input-devicemgr +Library for tizen input devicemgr + +%package tizen-input-devicemgr-devel +Summary: Development package for tizen input devicemgr +Group: Development/Libraries + +%description tizen-input-devicemgr-devel +Development package for tizen input devicemgr + %prep %setup -q cp %{SOURCE1001} . @@ -110,6 +125,7 @@ ninja -C builddir install %{_bindir}/ds-simple-shm-shell %{_bindir}/tinyds-tdm-dpms %{_bindir}/ds-simple-dpms +%{_bindir}/input-generator %files tizen-keyrouter %manifest %{name}.manifest @@ -124,3 +140,17 @@ ninja -C builddir install %{_includedir}/libds-tizen/keyrouter.h %{_libdir}/pkgconfig/libds-tizen-keyrouter.pc %{_libdir}/libds-tizen-keyrouter.so + +%files tizen-input-devicemgr +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-input-devicemgr.so.* + +%files tizen-input-devicemgr-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/input-devicemgr.h +%{_libdir}/pkgconfig/libds-tizen-input-devicemgr.pc +%{_libdir}/libds-tizen-input-devicemgr.so diff --git a/src/clients/input-generator.c b/src/clients/input-generator.c new file mode 100644 index 0000000..f61e84b --- /dev/null +++ b/src/clients/input-generator.c @@ -0,0 +1,540 @@ +#include +#include +#include +#include +#include + +#include +#include + +#define MAX_STR 1024 +#define SIZE_EPOLL 16 + +enum enum_key_type +{ + KEY_UP = 0, + KEY_DOWN, + KEY_ALL +}; + +enum enum_touch_type +{ + TOUCH_BEGIN = 0, + TOUCH_UPDATE, + TOUCH_END, + TOUCH_ALL +}; + +struct display +{ + struct wl_display *display; + struct wl_registry *registry; + struct wl_compositor *compositor; + + struct tizen_input_device_manager *devicemgr; + enum tizen_input_device_manager_clas clas; + struct wl_event_queue *queue; + + int run; + int fd_epoll; + int fd_display; + + int request_notified; + int init; + + int enable_log; +}; + +struct display data_wl; + +static void +usage(void) +{ + printf(" Supported commands: init (Initialize input generator)\n"); + printf(" : deinit (Deinitialize input generator)\n"); + printf(" : key (Generate key events)\n"); + printf(" : touch (Generate touch events)\n"); + printf(" : help (Print this help text)\n"); + printf(" : q/quit (Quit program)\n"); + printf(" : log (Print detailed logs)\n"); + printf("init {device type}\n"); + printf(" : device type:\n"); + printf(" - default: all\n"); + printf(" - key/keyboard: keyboard\n"); + printf(" - touch: touch screen\n"); + printf(" - all: all of devices\n"); + printf(" : ex> init keyboard / init\n"); + printf("\n"); + printf("deinit\n"); + printf(" : ex> deinit\n"); + printf("\n"); + printf("key [keyname] {pressed}\n"); + printf(" : pressed:\n"); + printf(" - default: down&up pair\n"); + printf(" - key down: 1\n"); + printf(" - key up: 0\n"); + printf(" : ex> key XF86Back 1\n"); + printf("\n"); + printf("touch {index} {type} {x} {y}\n"); + printf(" : index:\n"); + printf(" - default: first finger(0)\n"); + printf(" - first finger is 0\n"); + printf(" : type:\n"); + printf(" - default: generate sample touch events\n"); + printf(" - touch begin: 1\n"); + printf(" - touch update: 2\n"); + printf(" - touch end: 3\n"); + printf(" : x/y:\n"); + printf(" - default: 0\n"); + printf(" : ex> touch / touch 0 1 100 100\n"); + printf("\n"); +} + +static void +init_input_generator(enum tizen_input_device_manager_clas clas) +{ + if (data_wl.init) { + printf("Already init input generator\n"); + return; + } + + tizen_input_device_manager_init_generator(data_wl.devicemgr, clas); + + while (data_wl.request_notified == -1) + wl_display_dispatch_queue(data_wl.display, data_wl.queue); + + if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + data_wl.init = 1; + printf("Success to init input generator\n"); + } else { + printf("Failed to init input generator: %d\n", data_wl.request_notified); + } + + data_wl.clas = clas; + data_wl.request_notified = -1; +} + +static void +deinit_input_generator(void) +{ + if (!data_wl.init) { + printf("input generator is not initialized\n"); + return; + } + + tizen_input_device_manager_deinit_generator(data_wl.devicemgr, data_wl.clas); + + while (data_wl.request_notified == -1) + wl_display_dispatch_queue(data_wl.display, data_wl.queue); + + if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + data_wl.init = 0; + printf("Success to deinit input generator\n"); + } else { + printf("Failed to deinit input generator: %d\n", data_wl.request_notified); + } + + data_wl.request_notified = -1; +} + +static void +input_generator_key(char *name, int type) +{ + tizen_input_device_manager_generate_key(data_wl.devicemgr, name, !!type); + + while (data_wl.request_notified == -1) + wl_display_dispatch_queue(data_wl.display, data_wl.queue); + + if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + if (data_wl.enable_log) { + printf("Success to generate key: %s key %s\n", name, type?"down":"up"); + } + } else { + printf("Failed to generate %s key %s: %d\n", name, type?"down":"up", data_wl.request_notified); + } + + data_wl.request_notified = -1; +} + +static void +key_generate(char *name, int type) +{ + printf("name: %s, type: %d\n", name, type); + + if (!data_wl.init) { + printf("Input genrator is not initialized\n"); + return; + } + + if (!name) { + printf("Type which key is generated\n"); + return; + } + + if (type == KEY_ALL) { + input_generator_key(name, 1); + input_generator_key(name, 0); + } else { + input_generator_key(name, !!type); + } +} + +static char * +touch_type_string_get(int type) +{ + switch (type) { + case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN: + return "begin"; + case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE: + return "update"; + case TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END: + return "end"; + default: + return "Unknown"; + } +} + +static void +input_generator_touch(int idx, int type, int x, int y) +{ + tizen_input_device_manager_generate_touch(data_wl.devicemgr, type, x, y, idx); + + while (data_wl.request_notified == -1) + wl_display_dispatch_queue(data_wl.display, data_wl.queue); + + if (data_wl.request_notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + if (data_wl.enable_log) { + printf("Success to generate touch: %d finger %s on (%d, %d)\n", idx, touch_type_string_get(type), x, y); + } + } else { + printf("Failed to generate touch(%d finger %s on (%d, %d)): %d\n", idx, touch_type_string_get(type), x, y, data_wl.request_notified); + } + + data_wl.request_notified = -1; +} + +static void +touch_generate(int idx, int type, int x, int y) +{ + if (!data_wl.init) { + printf("Input genrator is not initialized\n"); + return; + } + + if (type == TOUCH_ALL) { + input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 100, 100); + input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 200, 200); + input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_BEGIN, 300, 300); + + input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 110, 110); + input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 210, 210); + input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 310, 310); + + input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 120, 120); + input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 220, 220); + input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_UPDATE, 320, 320); + + input_generator_touch(0, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 120, 120); + input_generator_touch(1, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 220, 220); + input_generator_touch(2, TIZEN_INPUT_DEVICE_MANAGER_POINTER_EVENT_TYPE_END, 320, 320); + } else { + input_generator_touch(idx, type, x, y); + } +} + +static void +stdin_read(void) +{ + int c; + char buf[MAX_STR] = {0, }, *tmp, *buf_ptr, key_name[MAX_STR] = {0, }; + int count = 0; + int key_type = KEY_ALL, touch_idx = 0, touch_type = TOUCH_ALL, touch_x = 0, touch_y = 0; + + while ((c = getchar()) != EOF) { + if (c == '\n') break; + if (count >= MAX_STR) break; + + buf[count] = c; + count++; + } + + count = 0; + tmp = strtok_r(buf, " ", &buf_ptr); + if (!tmp) return; + + if (!strncmp(tmp, "init", sizeof("init"))) { + while (tmp) { + tmp = strtok_r(NULL, " ", &buf_ptr); + if (tmp) { + switch (count) { + case 0: + if (!strncmp("keyboard", tmp, MAX_STR-1)) + init_input_generator(TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD); + else if (!strncmp("touch", tmp, MAX_STR-1)) + init_input_generator(TIZEN_INPUT_DEVICE_MANAGER_CLAS_TOUCHSCREEN); + break; + default: + break; + } + } + count++; + } + } else if (!strncmp(tmp, "deinit", sizeof("deinit"))) { + deinit_input_generator(); + } else if (!strncmp(tmp, "key", sizeof("key"))) { + while (tmp) { + tmp = strtok_r(NULL, " ", &buf_ptr); + if (tmp) { + switch (count) { + case 0: + strncpy(key_name, tmp, MAX_STR-1); + break; + case 1: + key_type = atoi(tmp); + break; + default: + break; + } + } + count++; + } + key_generate(key_name, key_type); + } else if (!strncmp(tmp, "touch", sizeof("touch"))) { + while (tmp) { + tmp = strtok_r(NULL, " ", &buf_ptr); + if (tmp) { + switch (count) { + case 0: + touch_idx = atoi(tmp); + break; + case 1: + touch_type = atoi(tmp); + break; + case 2: + touch_x = atoi(tmp); + break; + case 3: + touch_y = atoi(tmp); + break; + default: + break; + } + } + count++; + } + touch_generate(touch_idx, touch_type, touch_x, touch_y); + } else if (!strncmp(buf, "q", MAX_STR) || !strncmp(buf, "quit", MAX_STR)) { + data_wl.run = 0; + } else if (!strncmp(buf, "help", MAX_STR)) { + usage(); + } else if (!strncmp(buf, "log", MAX_STR)) { + if (data_wl.enable_log) + printf("Disable detailed logs\n"); + else + printf("Enable detailed logs\n"); + + data_wl.enable_log = !data_wl.enable_log; + } else { + printf("Invalid arguments\n"); + usage(); + } +} + +static void +input_device_manager_handle_error(void *data, + struct tizen_input_device_manager *tizen_input_device_manager, + uint32_t errorcode) +{ + if (data_wl.enable_log) + printf("errorcode: %d\n", errorcode); + data_wl.request_notified = errorcode; +} + +static const struct tizen_input_device_manager_listener _input_device_manager_listener = +{ + .device_add = NULL, + .device_remove = NULL, + .error = input_device_manager_handle_error, + .block_expired = NULL, +}; + +static void +registry_handle_global(void * data, struct wl_registry * registry, uint32_t id, + const char * interface, uint32_t version) +{ + if (strcmp(interface, "wl_compositor") == 0) { + data_wl.compositor = wl_registry_bind(registry, id, + &wl_compositor_interface, version); + if (!data_wl.compositor) { + printf("Failed to bind compositor."); + return; + } + if (data_wl.enable_log) + printf("Success to bind compositor."); + } else if (strcmp(interface, "tizen_input_device_manager") == 0) { + data_wl.devicemgr = wl_registry_bind(registry, id, + &tizen_input_device_manager_interface, version); + if (!data_wl.devicemgr) { + printf("Failed to bind input device manager"); + return; + } + if (data_wl.enable_log) + printf("Success to bind tizen input device manager."); + tizen_input_device_manager_add_listener(data_wl.devicemgr, + &_input_device_manager_listener, data_wl.display); + } +} + +static void +registry_handle_global_remove(void * data, struct wl_registry * registry, uint32_t id) +{ + if (data_wl.enable_log) + printf("registry is removed. id: %d !\n", id); +} + +static const struct wl_registry_listener _registry_listener = { + registry_handle_global, + registry_handle_global_remove +}; + +static int +wayland_init(void) +{ + memset(&data_wl, 0, sizeof(struct display)); + data_wl.request_notified = -1; + + data_wl.display = wl_display_connect(NULL); + if (!data_wl.display) { + printf("Failed to connect wayland display\n"); + return 0; + } + + data_wl.queue = wl_display_create_queue(data_wl.display); + if (!data_wl.queue) { + printf("Failed to create queue\n"); + return 0; + } + + data_wl.registry = wl_display_get_registry(data_wl.display); + if (!data_wl.registry) { + printf("Failed to get registry\n"); + return 0; + } + + wl_proxy_set_queue((struct wl_proxy*)data_wl.registry, data_wl.queue); + wl_registry_add_listener(data_wl.registry, &_registry_listener, NULL); + + if (wl_display_dispatch_queue(data_wl.display, data_wl.queue) == -1) { + printf("Failed to dispatch display\n"); + return 0; + } + if (wl_display_roundtrip_queue(data_wl.display, data_wl.queue) == -1) { + printf("Failed to roundtrip display\n"); + return 0; + } + + return 1; +} + +static void +wayland_deinit(void) +{ + if (data_wl.enable_log) + printf("Shutdown wayland system\n"); + + if (data_wl.init) deinit_input_generator(); + + if (data_wl.queue) wl_event_queue_destroy(data_wl.queue); + if (data_wl.devicemgr) tizen_input_device_manager_destroy(data_wl.devicemgr); + if (data_wl.display) { + wl_registry_destroy(data_wl.registry); + wl_display_flush(data_wl.display); + wl_display_disconnect(data_wl.display); + } +} + +static int +epoll_init(void) +{ + struct epoll_event ep[2]; + + data_wl.fd_epoll = epoll_create(SIZE_EPOLL); + if (data_wl.fd_epoll <= 0) { + printf("Failed to epoll create: %d\n", SIZE_EPOLL); + return 0; + } + + data_wl.fd_display = wl_display_get_fd(data_wl.display); + + memset(ep, 0, sizeof(struct epoll_event)*2); + + ep[0].events = EPOLLIN | EPOLLERR | EPOLLHUP; + ep[0].data.fd = data_wl.fd_display; + epoll_ctl(data_wl.fd_epoll, EPOLL_CTL_ADD, data_wl.fd_display, &ep[0]); + ep[1].events = EPOLLIN | EPOLLERR | EPOLLHUP; + ep[1].data.fd = STDIN_FILENO; + epoll_ctl(data_wl.fd_epoll, EPOLL_CTL_ADD, 0, &ep[1]); + + return 1; +} + +static void +mainloop(void) +{ + struct epoll_event ep[SIZE_EPOLL]; + int res, count, i; + + res = epoll_init(); + if (!res) { + printf("Failed to init epoll\n"); + return; + } + + data_wl.run = 1; + while (data_wl.run) { + res = wl_display_dispatch_queue_pending(data_wl.display, data_wl.queue); + if (res < 0) { + printf("Failed to dispatch pending. result: %d\n", res); + data_wl.run = 0; + break; + } + res = wl_display_flush(data_wl.display); + if (res < 0) { + printf("Failed to flush display. result: %d\n", res); + data_wl.run = 0; + break; + } + + count = epoll_wait(data_wl.fd_epoll, ep, SIZE_EPOLL, -1); + for (i = 0; i < count; i++) { + if (ep[i].events & EPOLLIN) { + if (ep[i].data.fd == data_wl.fd_display) { + wl_display_dispatch_queue(data_wl.display, data_wl.queue); + } else { + stdin_read(); + } + } + if (ep[i].events & EPOLLERR) { + data_wl.run = 0; + } + if (ep[i].events & EPOLLHUP) { + data_wl.run = 0; + } + } + } +} + +int +main(int argc, char **argv) +{ + int res; + + res = wayland_init(); + if (!res) return 0; + + mainloop(); + + wayland_deinit(); + + return 0; +} diff --git a/src/clients/meson.build b/src/clients/meson.build index 6fcd3f8..ba09b32 100644 --- a/src/clients/meson.build +++ b/src/clients/meson.build @@ -12,6 +12,7 @@ executable('ds-simple-shm-shell', wayland_tbm_client = dependency('wayland-tbm-client', required: false) libtbm = dependency('libtbm', required: false) +tizen_extension_client = dependency('tizen-extension-client', required: true) if not wayland_tbm_client.found() or not libtbm.found() subdir_done() @@ -22,6 +23,7 @@ simple_tbm_deps = [ dependency('wayland-client', required: true), wayland_tbm_client, libtbm, + tizen_extension_client, ] protocols = { @@ -65,3 +67,16 @@ executable('ds-simple-dpms', install_dir: libds_bindir, install: true, ) + +input_generator_files = ['input-generator.c'] +input_generator_deps = [ + dependency('wayland-client', required: true), + tizen_extension_client, +] + +executable('input-generator', + input_generator_files, + dependencies: input_generator_deps, + install_dir: libds_bindir, + install: true, +) diff --git a/src/clients/simple-tbm.c b/src/clients/simple-tbm.c index 4fd9847..c82349f 100644 --- a/src/clients/simple-tbm.c +++ b/src/clients/simple-tbm.c @@ -38,6 +38,7 @@ #include #include #include "xdg-shell-client-protocol.h" +#include static uint64_t buffer_info_key; #define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key) @@ -51,6 +52,10 @@ struct display { struct wl_seat *seat; struct wayland_tbm_client *wl_tbm; bool has_xrgb; + + struct tizen_input_device_manager *devicemgr; + int notified; + bool blocked; }; struct window { @@ -385,12 +390,43 @@ static void touch_handle_down(void *data, struct wl_touch *wl_touch, { fprintf(stderr, "touch_handle_down id:%d, x:%d, y:%d\n", id, wl_fixed_to_int(x), wl_fixed_to_int(y)); + + struct display *d = data; + + tizen_input_device_manager_block_events(d->devicemgr, 0, TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD, 50000); + + while (d->notified == -1) + wl_display_roundtrip(d->display); + + if (d->notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + printf("Success to block keyboard events\n"); + } else { + printf("Failed to block keyboard events: %d\n", d->notified); + } + d->notified = -1; + d->blocked = true; } static void touch_handle_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, int32_t id) { fprintf(stderr, "touch_handle_up id:%d\n", id); + + struct display *d = data; + + if (!d->blocked) return; + tizen_input_device_manager_unblock_events(d->devicemgr, 0); + + while (d->notified == -1) + wl_display_roundtrip(d->display); + + if (d->notified == TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + printf("Success to unblock keyboard events\n"); + } else { + printf("Failed to unblock keyboard events: %d\n", d->notified); + } + d->notified = -1; + d->blocked = false; } static void touch_handle_motion(void *data, struct wl_touch *wl_touch, @@ -446,9 +482,9 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - fprintf(stderr, "keyboard_handle_key: PRESSED\n"); + fprintf(stderr, "keyboard_handle_key: key:%d, PRESSED\n", key); } else { - fprintf(stderr, "keyboard_handle_key: RELEASED\n"); + fprintf(stderr, "keyboard_handle_key: key:%d, RELEASED\n", key); } } @@ -464,6 +500,7 @@ static struct wl_keyboard_listener keyboard_listener = { static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { + struct display *d = data; if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat); wl_keyboard_add_listener(keyboard, &keyboard_listener, NULL); @@ -476,7 +513,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, } if ((caps & WL_SEAT_CAPABILITY_TOUCH)) { struct wl_touch *touch = wl_seat_get_touch(wl_seat); - wl_touch_add_listener(touch, &touch_listener, NULL); + wl_touch_add_listener(touch, &touch_listener, d); fprintf(stderr, "seat_handle_capabilities: touch\n"); } } @@ -493,6 +530,31 @@ const struct wl_seat_listener seat_listener = { }; static void +input_device_manager_handle_error(void *data, + struct tizen_input_device_manager *tizen_input_device_manager, + uint32_t errorcode) +{ + struct display *d = data; + fprintf(stderr, "errorcode: %d\n", errorcode); + d->notified = errorcode; +} + +static void +input_device_manager_handle_block_expired(void *data, + struct tizen_input_device_manager *tizen_input_device_manager) +{ + fprintf(stderr, "block expired\n"); +} + +static const struct tizen_input_device_manager_listener _input_device_manager_listener = +{ + .device_add = NULL, + .device_remove = NULL, + .error = input_device_manager_handle_error, + .block_expired = input_device_manager_handle_block_expired, +}; + +static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { @@ -515,7 +577,13 @@ registry_handle_global(void *data, struct wl_registry *registry, id, &wl_seat_interface, 7); wl_seat_add_listener(d->seat, &seat_listener, d); fprintf(stderr, "wl_seat bound!\n"); - } + } else if (strcmp(interface, "tizen_input_device_manager") == 0) { + d->devicemgr = wl_registry_bind(registry, + id, &tizen_input_device_manager_interface, version); + tizen_input_device_manager_add_listener(d->devicemgr, + &_input_device_manager_listener, d); + fprintf(stderr, "tizen input device manager bound!\n"); + } } static void @@ -605,12 +673,20 @@ create_display(void) exit(1); } + display->notified = -1; + return display; } static void destroy_display(struct display *display) { + if (display->seat) + wl_seat_destroy(display->seat); + + if (display->devicemgr) + tizen_input_device_manager_destroy(display->devicemgr); + if (display->shm) wl_shm_destroy(display->shm); diff --git a/src/examples/meson.build b/src/examples/meson.build index aad893e..eb9ae29 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -76,6 +76,7 @@ if get_option('tizen') tinyds_tdm_libinput_files, dependencies: [ common_deps, + dep_libds_tizen_input_devicemgr, dependency('pixman-1', required: true), dependency('threads', required: true), ], diff --git a/src/examples/tinyds-tdm-libinput.c b/src/examples/tinyds-tdm-libinput.c index f4e9319..5634707 100644 --- a/src/examples/tinyds-tdm-libinput.c +++ b/src/examples/tinyds-tdm-libinput.c @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #define USE_TDM_BUFFER_QUEUE @@ -36,6 +39,7 @@ #include "pixman-helper.h" #define TINYDS_UNUSED __attribute__((unused)) +struct tinyds_keyboard; struct tinyds_output { @@ -73,6 +77,7 @@ struct tinyds_server struct ds_seat *seat; uint32_t seat_caps; double output_x, output_y; + struct ds_tizen_input_devicemgr *devicemgr; struct tinyds_output *output; struct wl_event_source *stdin_source; @@ -82,6 +87,8 @@ struct tinyds_server struct wl_listener new_output; struct wl_listener new_input; struct wl_listener new_xdg_surface; + + struct tinyds_keyboard *keyboard; }; struct tinyds_view @@ -206,9 +213,18 @@ view_handle_xdg_surface_map(struct wl_listener *listener, void *data TINYDS_UNUSED) { struct tinyds_view *view; - + struct ds_keyboard *keyboard; view = wl_container_of(listener, view, xdg_surface_map); view->mapped = true; + + if (!view->server->keyboard) return; + keyboard = ds_input_device_get_keyboard(view->server->keyboard->dev); + if (keyboard != NULL) { + ds_seat_keyboard_notify_enter(view->server->seat, + ds_xdg_surface_get_surface(view->xdg_surface), + keyboard->keycodes, keyboard->num_keycodes, + &keyboard->modifiers); + } } static void @@ -373,6 +389,59 @@ backend_handle_new_input(struct wl_listener *listener, void *data) ds_seat_set_capabilities(server->seat, server->seat_caps); } +static void +devicemgr_add_keymap_data(struct wl_list *list, const char *name, int keycode) +{ + struct ds_tizen_input_devicemgr_keymap_data *data; + + data = calloc(1, sizeof *data); + if (!data) { + ds_err("Failed to alloc memory\n"); + return; + } + + data->name = strdup(name); + data->keycode = keycode; + + wl_list_insert(list, &data->link); +} + +static void +devicemgr_remove_keymap_data(struct wl_list *list, int keycode) +{ + struct ds_tizen_input_devicemgr_keymap_data *data, *tmp; + + wl_list_for_each_safe(data, tmp, list, link) { + if (data->keycode == keycode) { + wl_list_remove(&data->link); + free(data); + } + } +} + +static void +devicemgr_set_keymap(struct ds_tizen_input_devicemgr *devicemgr) +{ + struct wl_list keymap_list; + bool res; + + wl_list_init(&keymap_list); + + devicemgr_add_keymap_data(&keymap_list, "XF86VolumeRaise", 455); + devicemgr_add_keymap_data(&keymap_list, "XF86VolumeLower", 456); + devicemgr_add_keymap_data(&keymap_list, "XF86LightOn", 457); + devicemgr_add_keymap_data(&keymap_list, "XF86LightOff", 458); + + res = ds_tizen_input_devicemgr_set_keymap_list(devicemgr, &keymap_list); + if (!res) + ds_inf("Failed to set keymap"); + + devicemgr_remove_keymap_data(&keymap_list, 455); + devicemgr_remove_keymap_data(&keymap_list, 456); + devicemgr_remove_keymap_data(&keymap_list, 457); + devicemgr_remove_keymap_data(&keymap_list, 458); +} + static bool init_server(struct tinyds_server *server, struct wl_display *display) { @@ -388,8 +457,10 @@ init_server(struct tinyds_server *server, struct wl_display *display) return false; server->input_backend = ds_libinput_backend_create(display); - if (!server->input_backend) + if (!server->input_backend) { + ds_backend_destroy(server->backend); return false; + } server->new_output.notify = backend_handle_new_output; ds_backend_add_new_output_listener(server->backend, @@ -419,6 +490,13 @@ init_server(struct tinyds_server *server, struct wl_display *display) goto err; server->seat_caps = 0; + server->devicemgr = ds_tizen_input_devicemgr_create( + server->input_backend, server->seat); + if (!server->devicemgr) { + goto err; + } + + devicemgr_set_keymap(server->devicemgr); return true; err: @@ -683,14 +761,35 @@ keyboard_handle_device_destroy(struct wl_listener *listener, void *data) wl_list_remove(&kbd->destroy.link); wl_list_remove(&kbd->key.link); + kbd->server->keyboard = NULL; + free(kbd); } +static bool +server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) +{ + switch (sym) { + case XKB_KEY_BackSpace: + wl_display_terminate(server->display); + break; + default: + return false; + } + + return true; +} + static void keyboard_handle_key(struct wl_listener *listener, void *data) { struct tinyds_keyboard *kbd; struct ds_event_keyboard_key *event = data; + struct ds_keyboard *ds_keyboard; + struct xkb_state *xkb_state; + const xkb_keysym_t *syms; + int nsyms; + bool handled = false; kbd = wl_container_of(listener, kbd, key); @@ -698,14 +797,32 @@ keyboard_handle_key(struct wl_listener *listener, void *data) "update_state(%d)", kbd->dev, event->keycode, event->state, event->time_msec, event->update_state); - //TODO: - //ds_seat_keyboard_notify_key() + + ds_keyboard = ds_input_device_get_keyboard(kbd->dev); + + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); + if (xkb_state) { + nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, + &syms); + for (int i = 0; i < nsyms; i++) { + handled = server_handle_keybinding(kbd->server, syms[i]); + } + } + } + + if (!handled) { + ds_seat_keyboard_notify_key(kbd->server->seat, event->time_msec, + event->keycode, event->state); + } } static void server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) { struct tinyds_keyboard *kbd; + struct xkb_context *context; + struct xkb_keymap *keymap; kbd = calloc(1, sizeof *kbd); assert(kbd); @@ -713,12 +830,28 @@ server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) kbd->dev = dev; kbd->server = server; + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + keymap = xkb_keymap_new_from_names(context, NULL, + XKB_KEYMAP_COMPILE_NO_FLAGS); + + if (!keymap) { + ds_err("Failed to compile keymap"); + xkb_context_unref(context); + } + + ds_keyboard_set_keymap(ds_input_device_get_keyboard(dev), keymap); + + xkb_keymap_unref(keymap); + xkb_context_unref(context); + kbd->destroy.notify = keyboard_handle_device_destroy; ds_input_device_add_destroy_listener(dev, &kbd->destroy); kbd->key.notify = keyboard_handle_key; ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); + server->keyboard = kbd; + ds_inf("Keyboard(%p) added", kbd); } diff --git a/src/libds-tizen/backend/tdm/backend.c b/src/libds-tizen/backend/tdm/backend.c index e756ac1..21fb025 100644 --- a/src/libds-tizen/backend/tdm/backend.c +++ b/src/libds-tizen/backend/tdm/backend.c @@ -25,7 +25,7 @@ ds_tdm_backend_create(struct wl_display *display) if (!tdm) return NULL; - ds_backend_init(&tdm->base, &tdm_backend_iface); + ds_backend_init(&tdm->base, display, &tdm_backend_iface); tdm->wl_display = display; tdm->clock = CLOCK_MONOTONIC; // FIXME diff --git a/src/libds-tizen/input-devicemgr/input-devicemgr.c b/src/libds-tizen/input-devicemgr/input-devicemgr.c new file mode 100644 index 0000000..84700d7 --- /dev/null +++ b/src/libds-tizen/input-devicemgr/input-devicemgr.c @@ -0,0 +1,1063 @@ +#include +#include // gettimeofday() +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "input-devicemgr.h" +#include "src/libds/seat.h" + +#define TIZEN_INPUT_DEVICEMGR_VERSION 4 +#define TIZEN_PRIV_INPUT_GENERATOR "http://tizen.org/privilege/inputgenerator" +#define TIZEN_PRIV_INPUT_BLOCK "http://tizen.org/privilege/internal/inputdevice.block" + +static const struct ds_keyboard_grab_interface devicemgr_keyboard_grab_iface; + +//listeners +static void +backend_handle_destroy(struct wl_listener *listener, void *data); +static void +backend_handle_input_device_add(struct wl_listener *listener, void *data); +static void +seat_handle_destroy(struct wl_listener *listener, void *data); + +//tizen_input_device_manager bind/unbind +static void +device_manager_handle_bind(struct wl_client *client, void *data, + uint32_t version, uint32_t id); +static void +device_manager_client_handle_resource_destroy(struct wl_resource *resource); + +//tizen_input_device_manager's handlers for requests +static void +device_manager_handle_block_events(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, + uint32_t clas, uint32_t duration); +static void +device_manager_handle_unblock_events(struct wl_client *client, + struct wl_resource *resource, uint32_t serial); +static void +device_manager_handle_init_generator(struct wl_client *client, + struct wl_resource *resource, uint32_t clas); +static void +device_manager_handle_init_generator_with_name(struct wl_client *client, + struct wl_resource *resource, uint32_t clas, const char *name); +static void +device_manager_handle_deinit_generator(struct wl_client *client, + struct wl_resource *resource, uint32_t clas); +static void +device_manager_handle_generate_key(struct wl_client *client, + struct wl_resource *resource, + const char *keyname, uint32_t pressed); +static void +device_manager_handle_destroy(struct wl_client *client, + struct wl_resource *resource); + +// +static void tz_devicemgr_destroy(struct ds_tizen_input_devicemgr *tz_devicemgr); +static int +tz_devicemgr_init_generator(struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_resource *resource, const char *name); +static int +tz_devicemgr_deinit_generator(struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_resource *resource); +static bool +tz_devicemgr_generate_key(struct ds_input_device *device, int keycode, + int pressed); +static bool +tz_devicemgr_pressed_keys_update(struct ds_tizen_input_devicemgr *tz_devicemgr, + int keycode, bool pressed); +static void +tz_devicemgr_pressed_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr); +static void +tz_devicemgr_keymap_list_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr); +static int +tz_devicemgr_keyname_to_keycode(struct wl_list *list, const char *name); + +static bool +tz_devicemgr_check_privilege(struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_client *client, const char *rule); + +static void +tz_devicemgr_grab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr); +static void +tz_devicemgr_ungrab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr); +static void +tz_devicemgr_ungrab_keyboard_check(struct ds_tizen_input_devicemgr *tz_devicemgr); +static void +tz_devicemgr_blocked_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr); + +WL_EXPORT struct ds_tizen_input_devicemgr * +ds_tizen_input_devicemgr_create(struct ds_backend *backend, + struct ds_seat *seat) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + + tz_devicemgr = calloc(1, sizeof *tz_devicemgr); + if (!tz_devicemgr) { + ds_err("Fail to allocate ds_tizen_input_devicemgr"); + return NULL; + } + + tz_devicemgr->backend = backend; + tz_devicemgr->backend_destroy.notify = backend_handle_destroy; + ds_backend_add_destroy_listener(backend, &tz_devicemgr->backend_destroy); + + tz_devicemgr->seat = seat; + tz_devicemgr->seat_destroy.notify = seat_handle_destroy; + ds_seat_add_destroy_listener(seat, &tz_devicemgr->seat_destroy); + + tz_devicemgr->new_input.notify = backend_handle_input_device_add; + ds_backend_add_new_input_listener(backend, &tz_devicemgr->new_input); + + tz_devicemgr->global = wl_global_create(backend->display, + &tizen_input_device_manager_interface, + TIZEN_INPUT_DEVICEMGR_VERSION, + tz_devicemgr, device_manager_handle_bind); + if (!tz_devicemgr->global) { + goto err_global; + } + + tz_devicemgr->devices.kbd = calloc(1, + sizeof(struct ds_tizen_input_devicemgr_device)); + if (!tz_devicemgr->devices.kbd) { + goto err_kbd; + } + + tz_devicemgr->grab = calloc(1, sizeof(struct ds_seat_keyboard_grab)); + if (!tz_devicemgr->grab) + { + goto err_grab; + } + + tz_devicemgr->grab->iface = &devicemgr_keyboard_grab_iface; + tz_devicemgr->grab->seat = tz_devicemgr->seat; + tz_devicemgr->grab->data = tz_devicemgr; + + wl_signal_init(&tz_devicemgr->events.destroy); + wl_list_init(&tz_devicemgr->clients); + wl_list_init(&tz_devicemgr->pressed_keys); + wl_list_init(&tz_devicemgr->keymap_list); + wl_list_init(&tz_devicemgr->blocked_keys); + + if (!tizen_security_init()) { + ds_inf("tizen_security_init() is failed. go on without security"); + } + + ds_inf("Global created: ds_tizen_input_devicemgr(%p) ", tz_devicemgr); + return tz_devicemgr; +err_grab: + free(tz_devicemgr->devices.kbd); +err_kbd: + wl_global_destroy(tz_devicemgr->global); +err_global: + wl_list_remove(&tz_devicemgr->backend_destroy.link); + wl_list_remove(&tz_devicemgr->seat_destroy.link); + wl_list_remove(&tz_devicemgr->new_input.link); + free(tz_devicemgr); + return NULL; +} + +WL_EXPORT void +ds_tizen_input_devicemgr_add_destroy_listener( + struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_listener *listener) +{ + wl_signal_add(&tz_devicemgr->events.destroy, listener); +} + +WL_EXPORT bool +ds_tizen_input_devicemgr_set_keymap_list( + struct ds_tizen_input_devicemgr *tz_devicemgr, struct wl_list *list) +{ + struct ds_tizen_input_devicemgr_keymap_data *data, *new_data; + + if (!tz_devicemgr || !list) { + ds_err("Please insert correct data\n"); + return false; + } + + wl_list_for_each(data, list, link) { + new_data = calloc(1, sizeof *data); + if (!new_data) { + ds_err("Failed to alloc memory"); + return false; + } + new_data->name = strdup(data->name); + new_data->keycode = data->keycode; + wl_list_insert(&tz_devicemgr->keymap_list, &new_data->link); + } + ds_inf("keymap set. length:%d", + wl_list_length(&tz_devicemgr->keymap_list)); + + return true; +} + +static void +tz_devicemgr_destroy(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + struct ds_tizen_input_devicemgr_client *client_data, *tmp; + + tizen_security_finish(); + + tz_devicemgr_keymap_list_cleanup(tz_devicemgr); + tz_devicemgr_blocked_keys_cleanup(tz_devicemgr); + tz_devicemgr_ungrab_keyboard(tz_devicemgr); + + wl_signal_emit(&tz_devicemgr->events.destroy, tz_devicemgr); + wl_list_remove(&tz_devicemgr->backend_destroy.link); + wl_list_remove(&tz_devicemgr->seat_destroy.link); + wl_list_remove(&tz_devicemgr->new_input.link); + + wl_global_destroy(tz_devicemgr->global); + + wl_list_for_each_safe(client_data, tmp, &tz_devicemgr->clients, link) { + wl_list_remove(&client_data->link); + tz_devicemgr_deinit_generator(tz_devicemgr, client_data->resource); + + wl_resource_set_user_data(client_data->resource, NULL); + free(client_data); + } + + free(tz_devicemgr->devices.kbd); + free(tz_devicemgr->grab); + free(tz_devicemgr); +} + +static void +backend_handle_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + + tz_devicemgr = wl_container_of(listener, tz_devicemgr, backend_destroy); + + ds_inf("Global destroy: ds_tizen_input_devicemgr(%p)", tz_devicemgr); + + tz_devicemgr_destroy(tz_devicemgr); +} + +static void +seat_handle_destroy(struct wl_listener *listener, void *data) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + + tz_devicemgr = wl_container_of(listener, tz_devicemgr, backend_destroy); + + wl_list_remove(&tz_devicemgr->seat_destroy.link); + wl_list_init(&tz_devicemgr->seat_destroy.link); + tz_devicemgr->seat = NULL; +} + +static void +backend_handle_input_device_add(struct wl_listener *listener, void *data) +{ + struct ds_input_device *dev = data; + struct ds_tizen_input_devicemgr *tz_devicemgr; + enum ds_input_device_type dev_type; + + tz_devicemgr = wl_container_of(listener, tz_devicemgr, new_input); + + dev_type = ds_input_device_get_type(dev); + if (dev_type == DS_INPUT_DEVICE_KEYBOARD) { + if (tz_devicemgr->devices.kbd->input_device) return; + ds_inf("devicemgr's kbd device is set"); + tz_devicemgr->devices.kbd->input_device = dev; + } + else if (dev_type == DS_INPUT_DEVICE_POINTER) { + //TODO: assign input_device 'dev' to devices.ptr + } + else if (dev_type == DS_INPUT_DEVICE_TOUCH) { + //TODO: assign input_device 'dev' to devices.ptr + } +} + +static const struct tizen_input_device_manager_interface _devicemgr_impl = { + .block_events = device_manager_handle_block_events, + .unblock_events = device_manager_handle_unblock_events, + .init_generator = device_manager_handle_init_generator, + .deinit_generator = device_manager_handle_deinit_generator, + .generate_key = device_manager_handle_generate_key, + .generate_pointer = NULL, + .generate_touch = NULL, + .pointer_warp = NULL, + .init_generator_with_name = + device_manager_handle_init_generator_with_name, // v2 + .destroy = device_manager_handle_destroy, // v3 + .generate_axis = NULL, // v3 + .set_touch_count = NULL, // v4 +}; + +static void +device_manager_client_handle_resource_destroy(struct wl_resource *resource) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + struct ds_tizen_input_devicemgr_client *client_data, *tmp; + + tz_devicemgr = wl_resource_get_user_data(resource); + + tz_devicemgr_deinit_generator(tz_devicemgr, resource); + + if (resource == tz_devicemgr->block_resource) { + tz_devicemgr_ungrab_keyboard_check(tz_devicemgr); + if (tz_devicemgr->timer) { + wl_event_source_remove(tz_devicemgr->timer); + tz_devicemgr->timer = NULL; + } + } + + wl_list_for_each_safe(client_data, tmp, &tz_devicemgr->clients, link) { + if (client_data->resource == resource) { + wl_list_remove(&client_data->link); + free(client_data); + } + } +} + +static void +device_manager_handle_bind(struct wl_client *client, void *data, + uint32_t version, uint32_t id) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr = data; + struct ds_tizen_input_devicemgr_client *client_data; + + client_data = calloc(1, sizeof *client_data); + if (!client_data) { + ds_err("Failed to allocate memory !\n"); + wl_client_post_no_memory(client); + return; + } + + client_data->resource = wl_resource_create(client, + &tizen_input_device_manager_interface, MIN(version,4), id); + if (!client_data->resource) { + ds_err("Failed to create resource! (ver. :%d, id:%d)", version, id); + free(client_data); + wl_client_post_no_memory(client); + return; + } + + client_data->init = false; + wl_list_init(&client_data->link); + wl_list_insert(&tz_devicemgr->clients, &client_data->link); + + wl_resource_set_implementation(client_data->resource, &_devicemgr_impl, + tz_devicemgr, device_manager_client_handle_resource_destroy); +} + +static void +device_manager_handle_init_generator(struct wl_client *client, + struct wl_resource *resource, uint32_t clas) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + + tz_devicemgr = wl_resource_get_user_data(resource); + + if (!tz_devicemgr_check_privilege(tz_devicemgr, client, + TIZEN_PRIV_INPUT_GENERATOR)) { + ds_err("No permission to input generate"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + goto finish; + } + + if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) { + ds_err("only support keyboard device. (requested: 0x%x)\n", clas); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; + goto finish; + } + + ret = tz_devicemgr_init_generator(tz_devicemgr, resource, + "Input Generator"); + if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + ds_err("Failed to init input generator\n"); + goto finish; + } + +finish: + tizen_input_device_manager_send_error(resource, ret); +} + +static void +device_manager_handle_init_generator_with_name(struct wl_client *client, + struct wl_resource *resource, uint32_t clas, const char *name) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + + tz_devicemgr = wl_resource_get_user_data(resource); + + if (!name) { + ds_err("no name for device"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; + goto finish; + } + + if (!tz_devicemgr_check_privilege(tz_devicemgr, client, + TIZEN_PRIV_INPUT_GENERATOR)) { + ds_err("No permission to input generate"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + goto finish; + } + + if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) { + ds_err("only support keyboard device. (requested: 0x%x)\n", clas); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; + goto finish; + } + + ret = tz_devicemgr_init_generator(tz_devicemgr, resource, + name); + if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + ds_err("Failed to init input generator\n"); + goto finish; + } + +finish: + tizen_input_device_manager_send_error(resource, ret); +} + +static void +device_manager_handle_deinit_generator(struct wl_client *client, + struct wl_resource *resource, uint32_t clas) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + + tz_devicemgr = wl_resource_get_user_data(resource); + + if (!tz_devicemgr_check_privilege(tz_devicemgr, client, + TIZEN_PRIV_INPUT_GENERATOR)) { + ds_err("No permission to input generate"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + goto finish; + } + + if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) { + ds_err("only support keyboard device. (requested: 0x%x)\n", clas); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; + goto finish; + } + + ret = tz_devicemgr_deinit_generator(tz_devicemgr, resource); + if (ret != TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE) { + ds_err("Failed to deinit input generator\n"); + goto finish; + } + +finish: + tizen_input_device_manager_send_error(resource, ret); +} + +struct keycode_map{ + xkb_keysym_t keysym; + xkb_keycode_t keycode; +}; + +static void +find_keycode(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) +{ + struct keycode_map *found_keycodes = (struct keycode_map *)data; + xkb_keysym_t keysym = found_keycodes->keysym; + int nsyms = 0; + const xkb_keysym_t *syms_out = NULL; + + if (found_keycodes->keycode) return; + + nsyms = xkb_keymap_key_get_syms_by_level(keymap, key, 0, 0, &syms_out); + if (nsyms && syms_out) { + if (*syms_out == keysym) { + found_keycodes->keycode = key; + } + } +} + +static void +tz_devicemgr_xkb_keycode_from_keysym(struct xkb_keymap *keymap, + xkb_keysym_t keysym, xkb_keycode_t *keycode) +{ + struct keycode_map found_keycodes = {0,}; + found_keycodes.keysym = keysym; + xkb_keymap_key_for_each(keymap, find_keycode, &found_keycodes); + + *keycode = found_keycodes.keycode; +} + +static int +tz_devicemgr_xkb_keyname_to_keycode(struct xkb_keymap *keymap, + const char *name) +{ + xkb_keysym_t keysym = 0x0; + xkb_keycode_t keycode = 0; + + if (!strncmp(name, "Keycode-", sizeof("Keycode-")-1)) { + keycode = atoi(name + 8); + } else { + keysym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS); + tz_devicemgr_xkb_keycode_from_keysym(keymap, keysym, &keycode); + } + + return keycode; +} + +static void +device_manager_handle_generate_key(struct wl_client *client, + struct wl_resource *resource, const char *keyname, uint32_t pressed) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + int keycode = 0; + bool res; + struct ds_keyboard *kbd; + + tz_devicemgr = wl_resource_get_user_data(resource); + + if (!tz_devicemgr->devices.kbd || + !tz_devicemgr->devices.kbd->input_device) { + ds_err("Keyboard device is not initialized\n"); + goto finish; + } + + if (!tz_devicemgr_check_privilege(tz_devicemgr, client, + TIZEN_PRIV_INPUT_GENERATOR)) { + ds_err("No permission to input generate"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + goto finish; + } + + // keyname to keycode using xkb_info + kbd = ds_input_device_get_keyboard( + tz_devicemgr->devices.kbd->input_device); + if (kbd->keymap) { + keycode = tz_devicemgr_xkb_keyname_to_keycode(kbd->keymap, keyname); + } + + if (keycode <= 0) { + keycode = tz_devicemgr_keyname_to_keycode(&tz_devicemgr->keymap_list, + keyname); + } + if (keycode <= 0) + goto finish; + + res = tz_devicemgr_generate_key(tz_devicemgr->devices.kbd->input_device, + keycode, pressed); + if (!res) { + ds_err("Generating key is failed. key: %s, pressed: %d", + keyname, pressed); + goto finish; + } + res = tz_devicemgr_pressed_keys_update(tz_devicemgr, keycode, pressed); + if (!res) { + ds_err("Updating pressed keys is failed. key: %s, pressed: %d", + keyname, pressed); + goto finish; + } + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + +finish: + tizen_input_device_manager_send_error(resource, ret); +} + +static void +device_manager_handle_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static bool +tz_devicemgr_check_privilege(struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_client *client, const char *rule) +{ + pid_t pid = 0; + uid_t uid = 0; + gid_t gid = 0; + + if (!client) return false; + + wl_client_get_credentials(client, &pid, &uid, &gid); + + return tizen_security_check_privilege(pid, uid, rule); +} + +static const struct ds_input_device_interface input_device_iface = +{ + .destroy = NULL, +}; + +static struct ds_keyboard * +create_ds_keyboard() +{ + struct ds_keyboard *kbd; + kbd = calloc(1, sizeof *kbd); + if (!kbd) { + ds_err("Could not allocate memory"); + return NULL; + } + ds_keyboard_init(kbd, NULL); + + return kbd; +} + +static int +tz_devicemgr_init_generator(struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_resource *resource, const char *name) +{ + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + struct ds_tizen_input_devicemgr_client *client_data; + struct ds_tizen_input_devicemgr_device *kbd; + + ds_inf("Init generator. name:%s", name); + + kbd = tz_devicemgr->devices.kbd; + if (strlen(kbd->name) > 0) { + ds_inf("devices.kbd already has name. name:%s", kbd->name); + return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + } + + if (kbd->input_device) { + ds_inf("devices.kbd is already set. name:%s", + ds_input_device_get_name(kbd->input_device)); + return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + } + + //input_device create + kbd->input_device = calloc(1, sizeof(struct ds_input_device)); + if(!kbd->input_device) { + ds_err("Failed to create input device !\n"); + return ret; + } + + ds_input_device_init(kbd->input_device, DS_INPUT_DEVICE_KEYBOARD, + &input_device_iface, name, -1, -1); + kbd->input_device->keyboard = create_ds_keyboard(); + + wl_signal_emit(&tz_devicemgr->backend->events.new_input, + kbd->input_device); + + kbd->created = true; + strncpy(kbd->name, name, UINPUT_MAX_NAME_SIZE); + + wl_list_for_each(client_data, &tz_devicemgr->clients, link) { + if (client_data->resource == resource) { + if (client_data->init == false) { + client_data->init = true; + tz_devicemgr->ref++; + } + break; + } + } + + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + + return ret; +} + +static int +tz_devicemgr_keyname_to_keycode(struct wl_list *list, const char *name) +{ + struct ds_tizen_input_devicemgr_keymap_data *data; + + if (!wl_list_empty(list)) { + wl_list_for_each(data, list, link) { + if (!strcmp(data->name, name)) { + return data->keycode; + } + } + } + + return 0; +} + +static bool +tz_devicemgr_generate_key(struct ds_input_device *device, int keycode, + int pressed) +{ + struct ds_event_keyboard_key ds_event; + struct timeval time; + unsigned int timestamp; + struct ds_keyboard *kbd; + + kbd = ds_input_device_get_keyboard(device); + if (!kbd) { + ds_err("No ds_keyboard to notify event"); + return false; + } + + gettimeofday(&time, NULL); + timestamp = time.tv_sec * 1000 + time.tv_usec / 1000; + + ds_event.time_msec = timestamp; + ds_event.keycode = keycode - 8; + if (pressed) + ds_event.state = WL_KEYBOARD_KEY_STATE_PRESSED; + else + ds_event.state = WL_KEYBOARD_KEY_STATE_RELEASED; + + ds_inf("Generate key. kbd:%p, key:%d, state:%s", kbd, ds_event.keycode, + (ds_event.state == WL_KEYBOARD_KEY_STATE_PRESSED) ? + "PRESSED" : "RELEASED"); + + ds_keyboard_notify_key(kbd, &ds_event); + + return true; +} + +static bool +tz_devicemgr_pressed_keys_update(struct ds_tizen_input_devicemgr *tz_devicemgr, + int keycode, bool pressed) +{ + struct ds_tizen_input_devicemgr_key_info *key, *tmp; + + if (pressed) { + key = calloc(1, sizeof(*key)); + if (!key) { + ds_err("Failed to alloc keydata memory.\n"); + return false; + } + key->keycode = keycode; + wl_list_init(&key->link); + wl_list_insert(&tz_devicemgr->pressed_keys, &key->link); + } + else { + wl_list_for_each_safe(key, tmp, &tz_devicemgr->pressed_keys, link) { + if (key->keycode == keycode) { + wl_list_remove(&key->link); + free(key); + break; + } + } + } + + ds_inf("Update pressed keys. length: %d, keycode:%d, pressed:%d", + wl_list_length(&tz_devicemgr->pressed_keys), keycode, pressed); + + return true; +} + +static void +tz_devicemgr_pressed_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + struct ds_tizen_input_devicemgr_key_info *keydata, *tmp; + + ds_inf("Clean up the pressed_keys. length: %d", + wl_list_length(&tz_devicemgr->pressed_keys)); + + wl_list_for_each_safe(keydata, tmp, &tz_devicemgr->pressed_keys, link) { + if (tz_devicemgr->devices.kbd) + tz_devicemgr_generate_key(tz_devicemgr->devices.kbd->input_device, + keydata->keycode, false); + wl_list_remove(&keydata->link); + free(keydata); + } +} + +static void +tz_devicemgr_keymap_list_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + struct ds_tizen_input_devicemgr_keymap_data *keymap, *tmp; + + ds_inf("Clean up the keymap_list. length: %d", + wl_list_length(&tz_devicemgr->keymap_list)); + + wl_list_for_each_safe(keymap, tmp, &tz_devicemgr->keymap_list, link) { + free(keymap->name); + wl_list_remove(&keymap->link); + free(keymap); + } +} + +static void +tz_devicemgr_keyboard_close(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + if (!tz_devicemgr->devices.kbd->input_device) return; + ds_input_device_destroy(tz_devicemgr->devices.kbd->input_device); + tz_devicemgr->devices.kbd->input_device = NULL; + tz_devicemgr->devices.kbd->created = false; +} + +static int +tz_devicemgr_deinit_generator(struct ds_tizen_input_devicemgr *tz_devicemgr, + struct wl_resource *resource) +{ + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + struct ds_tizen_input_devicemgr_client *client_data; + + ds_inf("Deinit generator."); + wl_list_for_each(client_data, &tz_devicemgr->clients, link) { + if (client_data->resource == resource) { + if (client_data->init == true) { + client_data->init = false; + tz_devicemgr->ref--; + if (tz_devicemgr->ref < 0) tz_devicemgr->ref = 0; + break; + } else { + return ret; + } + } + } + + if (tz_devicemgr->ref <= 0) { + tz_devicemgr_pressed_keys_cleanup(tz_devicemgr); + + if (!tz_devicemgr->devices.kbd) + return TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + + if (tz_devicemgr->devices.kbd->created) + tz_devicemgr_keyboard_close(tz_devicemgr); + memset(tz_devicemgr->devices.kbd->name, 0, UINPUT_MAX_NAME_SIZE); + } + + return ret; +} + +static void +devicemgr_keyboard_grab_iface_enter(struct ds_seat_keyboard_grab *grab, + struct ds_surface *surface, uint32_t keycodes[], + size_t num_keycodes, struct ds_keyboard_modifiers *modifiers) +{ + ds_inf("devicemgr. keyboard_grab_iface_enter"); +} + +static void +devicemgr_keyboard_grab_iface_clear_focus(struct ds_seat_keyboard_grab *grab) +{ + ds_inf("devicemgr. keyboard_grab_iface_clear_focus"); +} + +static void +tz_devicemgr_blocked_keys_cleanup(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + struct ds_tizen_input_devicemgr_key_info *keydata, *tmp; + + ds_inf("Clean up the blocked keys. length: %d", + wl_list_length(&tz_devicemgr->blocked_keys)); + + wl_list_for_each_safe(keydata, tmp, &tz_devicemgr->blocked_keys, link) { + wl_list_remove(&keydata->link); + free(keydata); + } +} + +static void +devicemgr_keyboard_grab_iface_key(struct ds_seat_keyboard_grab *grab, + uint32_t time_msec, uint32_t key, uint32_t state) +{ + struct ds_tizen_input_devicemgr *devicemgr = grab->data; + struct ds_tizen_input_devicemgr_key_info *keydata, *tmp; + bool key_blocked = false; + + ds_inf("devicemgr. keyboard_grab_iface_key"); + + if (!devicemgr->block_resource) { + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { + goto finish; + } + else { + wl_list_for_each_safe(keydata, tmp, &devicemgr->blocked_keys, link) { + if (keydata->keycode == (int)key) { + wl_list_remove(&keydata->link); + free(keydata); + key_blocked = true; + break; + } + } + if (wl_list_empty(&devicemgr->blocked_keys)) { + tz_devicemgr_ungrab_keyboard(devicemgr); + } + if (key_blocked) { + goto finish; + } + } + } + + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { + keydata = calloc(1, sizeof (*keydata)); + if (!keydata) + goto finish; + keydata->keycode = key; + wl_list_init(&keydata->link); + wl_list_insert(&devicemgr->blocked_keys, &keydata->link); + key_blocked = true; + } + else { + if (wl_list_empty(&devicemgr->blocked_keys)) + goto finish; + wl_list_for_each_safe(keydata, tmp, &devicemgr->blocked_keys, link) { + if (keydata->keycode == (int)key) { + wl_list_remove(&keydata->link); + free(keydata); + key_blocked = true; + } + } + } + +finish: + if (!key_blocked) + ds_inf("block key event: (%d %s)\n", key, (state ? "press" : "release")); +} + +static void +devicemgr_modifiers_grab_iface_key(struct ds_seat_keyboard_grab *grab, + struct ds_keyboard_modifiers *modifiers) +{ + ds_inf("devicemgr. modifiers_grab_iface_key"); +} + +static void +devicemgr_cancel_grab_iface_key(struct ds_seat_keyboard_grab *grab) +{ + ds_inf("devicemgr. cancel_grab_iface_key"); +} + +static const struct ds_keyboard_grab_interface devicemgr_keyboard_grab_iface = { + .enter = devicemgr_keyboard_grab_iface_enter, + .clear_focus = devicemgr_keyboard_grab_iface_clear_focus, + .key = devicemgr_keyboard_grab_iface_key, + .modifiers = devicemgr_modifiers_grab_iface_key, + .cancel = devicemgr_cancel_grab_iface_key, +}; + +static void +tz_devicemgr_grab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + ds_seat_keyboard_start_grab(tz_devicemgr->seat, tz_devicemgr->grab); +} + +static void +tz_devicemgr_ungrab_keyboard(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + ds_seat_keyboard_end_grab(tz_devicemgr->seat); +} + +static void +tz_devicemgr_ungrab_keyboard_check(struct ds_tizen_input_devicemgr *tz_devicemgr) +{ + if (wl_list_empty(&tz_devicemgr->blocked_keys)) + tz_devicemgr_ungrab_keyboard(tz_devicemgr); + + tz_devicemgr->block_resource = NULL; +} + +static bool +devicemgr_add_timer(struct ds_tizen_input_devicemgr *tz_devicemgr, + wl_event_loop_timer_func_t func, int time) +{ + struct wl_event_loop *event_loop; + + event_loop = wl_display_get_event_loop(tz_devicemgr->backend->display); + if (!event_loop) { + ds_err("Failed to get event_loop from display: %p", + tz_devicemgr->backend->display); + return false; + } + + tz_devicemgr->timer = wl_event_loop_add_timer(event_loop, func, + tz_devicemgr); + if (!tz_devicemgr->timer) { + ds_err("Failed to timer"); + return false; + } + wl_event_source_timer_update(tz_devicemgr->timer, time); + + return true; +} + +static int +devicemgr_block_timer(void *data) +{ + struct ds_tizen_input_devicemgr *devicemgr = data; + + tizen_input_device_manager_send_block_expired(devicemgr->block_resource); + + tz_devicemgr_ungrab_keyboard_check(devicemgr); + + wl_event_source_remove(devicemgr->timer); + devicemgr->timer = NULL; + + return 1; +} + +static void +device_manager_handle_block_events(struct wl_client *client, + struct wl_resource *resource, uint32_t serial, uint32_t clas, + uint32_t duration) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + bool res; + + tz_devicemgr = wl_resource_get_user_data(resource); + + if (!tz_devicemgr_check_privilege(tz_devicemgr, client, + TIZEN_PRIV_INPUT_BLOCK)) { + ds_err("No permission to input generate"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + goto finish; + } + + if (clas != TIZEN_INPUT_DEVICE_MANAGER_CLAS_KEYBOARD) { + ds_err("only support keyboard device. (requested: 0x%x)\n", clas); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; + goto finish; + } + + if(tz_devicemgr->block_resource) { + ds_err("currently the input system is already blocked\n"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; + goto finish; + } + + res = devicemgr_add_timer(tz_devicemgr, devicemgr_block_timer, duration); + if (!res) { + ds_err("Failed to add a timer\n"); + goto finish; + } + + tz_devicemgr_grab_keyboard(tz_devicemgr); + tz_devicemgr->block_resource = resource; + ds_inf("Block events. clas: %d, duration:%d", clas, duration); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + +finish: + tizen_input_device_manager_send_error(resource, ret); +} + +static void +device_manager_handle_unblock_events(struct wl_client *client, + struct wl_resource *resource, uint32_t serial) +{ + struct ds_tizen_input_devicemgr *tz_devicemgr; + int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES; + + tz_devicemgr = wl_resource_get_user_data(resource); + + if (!tz_devicemgr_check_privilege(tz_devicemgr, client, + TIZEN_PRIV_INPUT_BLOCK)) { + ds_err("No permission to input generate"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_PERMISSION; + goto finish; + } + + if (tz_devicemgr->block_resource != resource) { + ds_err("currently the input system is blocked by another resource"); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_INVALID_PARAMETER; + goto finish; + } + + tz_devicemgr_ungrab_keyboard_check(tz_devicemgr); + tz_devicemgr->block_resource = NULL; + ds_inf("Unblock events."); + ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NONE; + + if (tz_devicemgr->timer) { + wl_event_source_remove(tz_devicemgr->timer); + tz_devicemgr->timer = NULL; + } + +finish: + tizen_input_device_manager_send_error(resource, ret); +} \ No newline at end of file diff --git a/src/libds-tizen/input-devicemgr/input-devicemgr.h b/src/libds-tizen/input-devicemgr/input-devicemgr.h new file mode 100644 index 0000000..8418b16 --- /dev/null +++ b/src/libds-tizen/input-devicemgr/input-devicemgr.h @@ -0,0 +1,59 @@ +#ifndef DS_TIZEN_DEVICEMGR_H +#define DS_TIZEN_DEVICEMGR_H + +#include +#include +#include +#include +#include "libds/interfaces/input_device.h" +#include + +struct ds_tizen_input_devicemgr_device { + char name[UINPUT_MAX_NAME_SIZE + 1]; + struct ds_input_device *input_device; + bool created; +}; + +struct ds_tizen_input_devicemgr { + struct wl_global *global; + struct wl_display *display; + struct ds_backend *backend; + struct ds_seat *seat; + + struct { + struct wl_signal destroy; + } events; + + struct wl_listener new_input; + struct wl_listener backend_destroy; + struct wl_listener seat_destroy; + struct { + struct ds_tizen_input_devicemgr_device *kbd; + struct ds_tizen_input_devicemgr_device *ptr; + struct ds_tizen_input_devicemgr_device *touch; + } devices; + + struct wl_list clients; + int ref; + + struct wl_list pressed_keys; + struct wl_list keymap_list; + + struct wl_list blocked_keys; + struct wl_resource *block_resource; + struct wl_event_source *timer; + struct ds_seat_keyboard_grab *grab; +}; + +struct ds_tizen_input_devicemgr_client { + struct wl_resource *resource; + bool init; + struct wl_list link; // ds_tizen_input_devicemgr::clients +}; + +struct ds_tizen_input_devicemgr_key_info { + int keycode; + struct wl_list link; // ds_tizen_input_devicemgr::pressed_keys; +}; + +#endif diff --git a/src/libds-tizen/input-devicemgr/meson.build b/src/libds-tizen/input-devicemgr/meson.build new file mode 100644 index 0000000..30924a4 --- /dev/null +++ b/src/libds-tizen/input-devicemgr/meson.build @@ -0,0 +1,30 @@ +libds_tizen_input_devicemgr_files = [ + 'input-devicemgr.c', +] + +libds_tizen_input_devicemgr_deps = [ + dep_libds, + dep_libds_tizen, + dependency('tizen-extension-server', required: true), +] + +lib_libds_tizen_input_devicemgr = shared_library('ds-tizen-input-devicemgr', libds_tizen_input_devicemgr_files, + dependencies: libds_tizen_input_devicemgr_deps, + include_directories: [ common_inc, include_directories('.'), include_directories('..') ], + version: meson.project_version(), + install: true +) + +dep_libds_tizen_input_devicemgr = declare_dependency( + link_with: lib_libds_tizen_input_devicemgr, + dependencies: libds_tizen_input_devicemgr_deps, + include_directories: [ common_inc, include_directories('.') ], +) + +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen_input_devicemgr, + version: meson.project_version(), + filebase: 'libds-tizen-input-devicemgr', + name: 'libds-tizen-input-devicemgr', + description: 'tizen input devicemgr extension of libds-tizen for tizen platform', +) diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build index 6779a72..8c7673b 100644 --- a/src/libds-tizen/meson.build +++ b/src/libds-tizen/meson.build @@ -38,4 +38,5 @@ pkgconfig.generate(lib_libds_tizen, ) subdir('keyrouter') +subdir('input-devicemgr') diff --git a/src/libds/backend.c b/src/libds/backend.c index 641374a..dee97ca 100644 --- a/src/libds/backend.c +++ b/src/libds/backend.c @@ -50,9 +50,11 @@ ds_backend_add_new_input_listener(struct ds_backend *backend, void ds_backend_init(struct ds_backend *backend, + struct wl_display *display, const struct ds_backend_interface *iface) { backend->iface = iface; + backend->display = display; wl_signal_init(&backend->events.destroy); wl_signal_init(&backend->events.new_output); wl_signal_init(&backend->events.new_input); diff --git a/src/libds/backend/libinput/backend.c b/src/libds/backend/libinput/backend.c index b6dc4f1..b7e1bc4 100644 --- a/src/libds/backend/libinput/backend.c +++ b/src/libds/backend/libinput/backend.c @@ -25,7 +25,7 @@ ds_libinput_backend_create(struct wl_display *display) return NULL; } - ds_backend_init(&libinput_backend->base, &libinput_backend_interface); + ds_backend_init(&libinput_backend->base, display, &libinput_backend_interface); libinput_backend->display = display; wl_list_init(&libinput_backend->devices); @@ -52,9 +52,7 @@ void destroy_libinput_input_device(struct ds_libinput_input_device *dev) { ds_input_device_destroy(&dev->base); - libinput_device_unref(dev->handle); wl_list_remove(&dev->link); - free(dev); } static void diff --git a/src/libds/backend/libinput/input.c b/src/libds/backend/libinput/input.c index 2457a06..b6e943f 100644 --- a/src/libds/backend/libinput/input.c +++ b/src/libds/backend/libinput/input.c @@ -25,6 +25,8 @@ input_device_iface_destroy(struct ds_input_device *ds_dev) dev = get_libinput_input_device_from_input_device(ds_dev); + libinput_device_unref(dev->handle); + free(dev); } diff --git a/src/libds/backend/wayland/backend.c b/src/libds/backend/wayland/backend.c index 5719e09..fd663f4 100644 --- a/src/libds/backend/wayland/backend.c +++ b/src/libds/backend/wayland/backend.c @@ -33,7 +33,7 @@ ds_wl_backend_create(struct wl_display *display, const char *server_name) return NULL; } - ds_backend_init(&wl_backend->base, &wl_backend_interface); + ds_backend_init(&wl_backend->base, display, &wl_backend_interface); wl_backend->display = display; wl_list_init(&wl_backend->buffers); diff --git a/src/libds/input_device.c b/src/libds/input_device.c index ad18e71..534bced 100644 --- a/src/libds/input_device.c +++ b/src/libds/input_device.c @@ -15,6 +15,12 @@ ds_input_device_get_type(struct ds_input_device *dev) return dev->type; } +WL_EXPORT const char * +ds_input_device_get_name(struct ds_input_device *dev) +{ + return dev->name; +} + WL_EXPORT struct ds_pointer * ds_input_device_get_pointer(struct ds_input_device *dev) { @@ -81,6 +87,9 @@ ds_input_device_destroy(struct ds_input_device *dev) case DS_INPUT_DEVICE_KEYBOARD: ds_keyboard_destroy(dev->keyboard); break; + case DS_INPUT_DEVICE_TOUCH: + ds_touch_destroy(dev->touch); + break; default: ds_err("Warning: leaking memory %p %p %d", dev->_device, dev, dev->type); diff --git a/src/libds/seat/seat_keyboard.c b/src/libds/seat/seat_keyboard.c index 381e2d6..8931a5c 100644 --- a/src/libds/seat/seat_keyboard.c +++ b/src/libds/seat/seat_keyboard.c @@ -362,7 +362,7 @@ seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client, struct wl_resource *resource; uint32_t serial; - serial = wl_display_next_serial(seat_client->seat->display); + serial = wl_display_next_serial(wl_client_get_display(seat_client->wl_client)); wl_resource_for_each(resource, &seat_client->keyboards) { wl_keyboard_send_leave(resource, serial, ds_surface_get_wl_resource(surface)); -- 2.7.4 From 640885bf3df9de2bc5f839d6eb48a019b7ed2ed2 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 8 Jun 2022 08:30:48 +0900 Subject: [PATCH 08/16] keyrouter: Fix wrong validity check Change-Id: I4339bc6ffb8c111679e00276fdfdd1f3500ffb1e --- src/libds-tizen/keyrouter/keyrouter_grab.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libds-tizen/keyrouter/keyrouter_grab.c b/src/libds-tizen/keyrouter/keyrouter_grab.c index a836292..35c249a 100644 --- a/src/libds-tizen/keyrouter/keyrouter_grab.c +++ b/src/libds-tizen/keyrouter/keyrouter_grab.c @@ -130,7 +130,7 @@ keyrouter_grab_key_process(struct ds_tizen_keyrouter_grab *keyrouter_grab, struct ds_tizen_keyrouter_key_info *info, *delivery; int count = 0; - if (keycode <= 0 && keycode >= KEYROUTER_MAX_KEYS) { + if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) { ds_err("Invalid keycode(%d)", keycode); return 0; } @@ -215,7 +215,7 @@ keyrouter_grab_grab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, struct ds_tizen_keyrouter_key_info *info = NULL; struct wl_list *list = NULL; - if (keycode <= 0 && keycode >= KEYROUTER_MAX_KEYS) { + if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) { ds_err("Invalid keycode(%d)", keycode); return TIZEN_KEYROUTER_ERROR_INVALID_KEY; } @@ -269,7 +269,7 @@ keyrouter_grab_ungrab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, { struct wl_list *list; - if (keycode <= 0 && keycode >= KEYROUTER_MAX_KEYS) { + if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) { ds_err("Invalid keycode(%d)", keycode); return; } -- 2.7.4 From 0df84773a29742c50a26cd7d6e50cec3ffe2f3d5 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Sat, 4 Jun 2022 10:36:16 +0900 Subject: [PATCH 09/16] remove libds stuffs It remains libds-tizen sources here and it depends on libds Change-Id: I63661dd7ff67db7e1cbb218798908006de2a7c81 --- LICENSE | 2 - TODO.md | 6 - include/libds/allocator.h | 27 - include/libds/allocator/shm.h | 17 - include/libds/backend.h | 42 -- include/libds/backend/libinput.h | 17 - include/libds/backend/wayland.h | 21 - include/libds/buffer.h | 85 --- include/libds/compositor.h | 27 - include/libds/input_device.h | 44 -- include/libds/interfaces/allocator.h | 33 - include/libds/interfaces/backend.h | 38 - include/libds/interfaces/buffer.h | 48 -- include/libds/interfaces/input_device.h | 44 -- include/libds/interfaces/keyboard.h | 68 -- include/libds/interfaces/output.h | 89 --- include/libds/interfaces/pointer.h | 30 - include/libds/interfaces/touch.h | 30 - include/libds/keyboard.h | 66 -- include/libds/log.h | 59 -- include/libds/output.h | 62 -- include/libds/pointer.h | 45 -- include/libds/presentation.h | 20 - include/libds/seat.h | 117 --- include/libds/shell.h | 50 -- include/libds/subsurface.h | 18 - include/libds/surface.h | 45 -- include/libds/swapchain.h | 30 - include/libds/touch.h | 46 -- include/libds/xdg_shell.h | 58 -- include/meson.build | 8 +- meson.build | 24 +- meson_options.txt | 1 - packaging/{libds.manifest => libds-tizen.manifest} | 0 packaging/{libds.spec => libds-tizen.spec} | 47 +- src/clients/meson.build | 14 +- src/clients/simple-shm-shell.c | 339 --------- src/examples/input-device-test.c | 391 ---------- src/examples/libinput-backend.c | 340 --------- src/examples/meson.build | 130 ++-- src/examples/tinyds.c | 811 --------------------- src/examples/wl-backend.c | 226 ------ src/libds-tizen/allocator/tbm.c | 6 +- src/libds-tizen/backend/tdm/backend.c | 2 +- src/libds-tizen/backend/tdm/output.c | 2 +- src/libds-tizen/backend/tdm/tdm.h | 4 +- src/libds-tizen/backend/tdm/tdm_buffer_queue.c | 2 +- src/libds-tizen/dpms.c | 6 +- src/libds-tizen/keyrouter/keyrouter.c | 2 +- src/libds-tizen/keyrouter/keyrouter_grab.c | 2 +- src/libds-tizen/keyrouter/meson.build | 1 - src/libds-tizen/meson.build | 23 +- src/libds-tizen/pixel_format.c | 2 +- src/libds-tizen/tbm_server.c | 2 +- src/libds-tizen/tbm_server.h | 2 +- src/libds-tizen/util/security.c | 2 +- src/libds/addon.c | 60 -- src/libds/addon.h | 38 - src/libds/allocator.c | 38 - src/libds/allocator/meson.build | 1 - src/libds/allocator/shm.c | 173 ----- src/libds/backend.c | 67 -- src/libds/backend/libinput/backend.c | 229 ------ src/libds/backend/libinput/backend.h | 73 -- src/libds/backend/libinput/input.c | 212 ------ src/libds/backend/libinput/keyboard.c | 35 - src/libds/backend/libinput/meson.build | 15 - src/libds/backend/libinput/pointer.c | 94 --- src/libds/backend/libinput/touch.c | 101 --- src/libds/backend/meson.build | 2 - src/libds/backend/wayland/backend.c | 315 -------- src/libds/backend/wayland/backend.h | 142 ---- src/libds/backend/wayland/meson.build | 27 - src/libds/backend/wayland/output.c | 376 ---------- src/libds/backend/wayland/seat.c | 719 ------------------ src/libds/buffer.c | 203 ------ src/libds/buffer.h | 8 - src/libds/client_buffer.h | 30 - src/libds/client_buffer/shm_client_buffer.c | 160 ---- src/libds/compositor.c | 147 ---- src/libds/input_device.c | 105 --- src/libds/keyboard.c | 304 -------- src/libds/log.c | 101 --- src/libds/meson.build | 101 --- src/libds/output.c | 215 ------ src/libds/output.h | 11 - src/libds/pixel_format.c | 16 - src/libds/pixel_format.h | 9 - src/libds/pointer.c | 55 -- src/libds/presentation.c | 115 --- src/libds/region.c | 197 ----- src/libds/region.h | 24 - src/libds/seat.h | 135 ---- src/libds/seat/seat.c | 390 ---------- src/libds/seat/seat_keyboard.c | 383 ---------- src/libds/seat/seat_pointer.c | 512 ------------- src/libds/seat/seat_private.h | 172 ----- src/libds/seat/seat_touch.c | 432 ----------- src/libds/shell.c | 175 ----- src/libds/shell.h | 157 ---- src/libds/shell_surface.c | 540 -------------- src/libds/subcompositor.c | 101 --- src/libds/subcompositor.h | 18 - src/libds/surface.h | 52 -- src/libds/surface/subsurface.c | 336 --------- src/libds/surface/surface-private.h | 110 --- src/libds/surface/surface.c | 757 ------------------- src/libds/swapchain.c | 202 ----- src/libds/touch.c | 55 -- src/libds/util.h | 19 - src/libds/util/shm.c | 248 ------- src/libds/util/time.c | 19 - src/libds/xdg_shell/xdg_shell.c | 217 ------ src/libds/xdg_shell/xdg_shell.h | 189 ----- src/libds/xdg_shell/xdg_surface.c | 487 ------------- src/libds/xdg_shell/xdg_toplevel.c | 329 --------- src/meson.build | 7 +- src/tests/meson.build | 8 +- 118 files changed, 117 insertions(+), 14124 deletions(-) delete mode 100644 include/libds/allocator.h delete mode 100644 include/libds/allocator/shm.h delete mode 100644 include/libds/backend.h delete mode 100644 include/libds/backend/libinput.h delete mode 100644 include/libds/backend/wayland.h delete mode 100644 include/libds/buffer.h delete mode 100644 include/libds/compositor.h delete mode 100644 include/libds/input_device.h delete mode 100644 include/libds/interfaces/allocator.h delete mode 100644 include/libds/interfaces/backend.h delete mode 100644 include/libds/interfaces/buffer.h delete mode 100644 include/libds/interfaces/input_device.h delete mode 100644 include/libds/interfaces/keyboard.h delete mode 100644 include/libds/interfaces/output.h delete mode 100644 include/libds/interfaces/pointer.h delete mode 100644 include/libds/interfaces/touch.h delete mode 100644 include/libds/keyboard.h delete mode 100644 include/libds/log.h delete mode 100644 include/libds/output.h delete mode 100644 include/libds/pointer.h delete mode 100644 include/libds/presentation.h delete mode 100644 include/libds/seat.h delete mode 100644 include/libds/shell.h delete mode 100644 include/libds/subsurface.h delete mode 100644 include/libds/surface.h delete mode 100644 include/libds/swapchain.h delete mode 100644 include/libds/touch.h delete mode 100644 include/libds/xdg_shell.h rename packaging/{libds.manifest => libds-tizen.manifest} (100%) rename packaging/{libds.spec => libds-tizen.spec} (76%) delete mode 100644 src/clients/simple-shm-shell.c delete mode 100644 src/examples/input-device-test.c delete mode 100644 src/examples/libinput-backend.c delete mode 100644 src/examples/tinyds.c delete mode 100644 src/examples/wl-backend.c delete mode 100644 src/libds/addon.c delete mode 100644 src/libds/addon.h delete mode 100644 src/libds/allocator.c delete mode 100644 src/libds/allocator/meson.build delete mode 100644 src/libds/allocator/shm.c delete mode 100644 src/libds/backend.c delete mode 100644 src/libds/backend/libinput/backend.c delete mode 100644 src/libds/backend/libinput/backend.h delete mode 100644 src/libds/backend/libinput/input.c delete mode 100644 src/libds/backend/libinput/keyboard.c delete mode 100644 src/libds/backend/libinput/meson.build delete mode 100644 src/libds/backend/libinput/pointer.c delete mode 100644 src/libds/backend/libinput/touch.c delete mode 100644 src/libds/backend/meson.build delete mode 100644 src/libds/backend/wayland/backend.c delete mode 100644 src/libds/backend/wayland/backend.h delete mode 100644 src/libds/backend/wayland/meson.build delete mode 100644 src/libds/backend/wayland/output.c delete mode 100644 src/libds/backend/wayland/seat.c delete mode 100644 src/libds/buffer.c delete mode 100644 src/libds/buffer.h delete mode 100644 src/libds/client_buffer.h delete mode 100644 src/libds/client_buffer/shm_client_buffer.c delete mode 100644 src/libds/compositor.c delete mode 100644 src/libds/input_device.c delete mode 100644 src/libds/keyboard.c delete mode 100644 src/libds/log.c delete mode 100644 src/libds/meson.build delete mode 100644 src/libds/output.c delete mode 100644 src/libds/output.h delete mode 100644 src/libds/pixel_format.c delete mode 100644 src/libds/pixel_format.h delete mode 100644 src/libds/pointer.c delete mode 100644 src/libds/presentation.c delete mode 100644 src/libds/region.c delete mode 100644 src/libds/region.h delete mode 100644 src/libds/seat.h delete mode 100644 src/libds/seat/seat.c delete mode 100644 src/libds/seat/seat_keyboard.c delete mode 100644 src/libds/seat/seat_pointer.c delete mode 100644 src/libds/seat/seat_private.h delete mode 100644 src/libds/seat/seat_touch.c delete mode 100644 src/libds/shell.c delete mode 100644 src/libds/shell.h delete mode 100644 src/libds/shell_surface.c delete mode 100644 src/libds/subcompositor.c delete mode 100644 src/libds/subcompositor.h delete mode 100644 src/libds/surface.h delete mode 100644 src/libds/surface/subsurface.c delete mode 100644 src/libds/surface/surface-private.h delete mode 100644 src/libds/surface/surface.c delete mode 100644 src/libds/swapchain.c delete mode 100644 src/libds/touch.c delete mode 100644 src/libds/util.h delete mode 100644 src/libds/util/shm.c delete mode 100644 src/libds/util/time.c delete mode 100644 src/libds/xdg_shell/xdg_shell.c delete mode 100644 src/libds/xdg_shell/xdg_shell.h delete mode 100644 src/libds/xdg_shell/xdg_surface.c delete mode 100644 src/libds/xdg_shell/xdg_toplevel.c diff --git a/LICENSE b/LICENSE index 54e4ef7..3910a9e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,4 @@ Copyright (c) 2022 Samsung Electronics co., Ltd. All Rights Reserved. -Copyright (c) 2017, 2018 Drew DeVault -Copyright (c) 2014 Jari Vetoniemi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/TODO.md b/TODO.md index f9681ed..09737c9 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,2 @@ -[] Implement a xdg shell -[] Implement a KMS/DRM backend -[] Implement a libinput backend -[] Implement an input -[] Implement a viewporter -[] Make up a ds output interface [] Make up tests [] Document APIs diff --git a/include/libds/allocator.h b/include/libds/allocator.h deleted file mode 100644 index 7f26a96..0000000 --- a/include/libds/allocator.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef LIBDS_ALLOCATOR_H -#define LIBDS_ALLOCATOR_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_allocator; - -void -ds_allocator_destroy(struct ds_allocator *alloc); - -struct ds_buffer * -ds_allocator_create_buffer(struct ds_allocator *alloc, int width, int height, - uint32_t format); - -void -ds_allocator_add_destroy_listener(struct ds_allocator *alloc, - struct wl_listener *listener); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/allocator/shm.h b/include/libds/allocator/shm.h deleted file mode 100644 index c151183..0000000 --- a/include/libds/allocator/shm.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef LIBDS_ALLOCATOR_SHM_H -#define LIBDS_ALLOCATOR_SHM_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_allocator * -ds_shm_allocator_create(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/backend.h b/include/libds/backend.h deleted file mode 100644 index d6a266f..0000000 --- a/include/libds/backend.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef LIBDS_BACKEND_H -#define LIBDS_BACKEND_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_backend; - -bool -ds_backend_start(struct ds_backend *backend); - -void -ds_backend_destroy(struct ds_backend *backend); - -int -ds_backend_get_drm_fd(struct ds_backend *backend); - -enum ds_buffer_caps -ds_backend_get_buffer_caps(struct ds_backend *backend); - -void -ds_backend_add_destroy_listener(struct ds_backend *backend, - struct wl_listener *listener); - -void -ds_backend_add_new_output_listener(struct ds_backend *backend, - struct wl_listener *listener); - -void -ds_backend_add_new_input_listener(struct ds_backend *backend, - struct wl_listener *listener); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/backend/libinput.h b/include/libds/backend/libinput.h deleted file mode 100644 index 29efb0c..0000000 --- a/include/libds/backend/libinput.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef LIBDS_BACKEND_LIBINPUT_H -#define LIBDS_BACKEND_LIBINPUT_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_backend * -ds_libinput_backend_create(struct wl_display *display); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/backend/wayland.h b/include/libds/backend/wayland.h deleted file mode 100644 index 2be8d76..0000000 --- a/include/libds/backend/wayland.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef LIBDS_BACKEND_WAYLAND_H -#define LIBDS_BACKEND_WAYLAND_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_backend * -ds_wl_backend_create(struct wl_display *display, const char *server_name); - -struct ds_output * -ds_wl_backend_create_output(struct ds_backend *backend); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/buffer.h b/include/libds/buffer.h deleted file mode 100644 index b3d38fa..0000000 --- a/include/libds/buffer.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef LIBDS_BUFFER_H -#define LIBDS_BUFFER_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_buffer; - -enum ds_buffer_caps -{ - DS_BUFFER_CAP_DATA_PTR = 1 << 0, - DS_BUFFER_CAP_DMABUF = 1 << 1, - DS_BUFFER_CAP_SHM = 1 << 2, -}; - -enum ds_buffer_data_ptr_access_flag -{ - DS_BUFFER_DATA_PTR_ACCESS_READ = 1 << 0, - DS_BUFFER_DATA_PTR_ACCESS_WRITE = 1 << 1, -}; - -struct ds_shm_attributes -{ - int fd; - uint32_t format; - int width, height, stride; - off_t offset; -}; - -struct ds_buffer_resource_interface -{ - const char *name; - bool (*is_instance)(struct wl_resource *resource); - struct ds_buffer *(*from_resource)(struct wl_resource *resource); -}; - -struct ds_buffer * -ds_buffer_from_resource(struct wl_resource *resource); - -void -ds_buffer_drop(struct ds_buffer *buffer); - -struct ds_buffer * -ds_buffer_lock(struct ds_buffer *buffer); - -void -ds_buffer_unlock(struct ds_buffer *buffer); - -bool -ds_buffer_get_shm(struct ds_buffer *buffer, struct ds_shm_attributes *attribs); - -void -ds_buffer_get_size(struct ds_buffer *buffer, int *out_width, int *out_height); - -void -ds_buffer_add_destroy_listener(struct ds_buffer *buffer, - struct wl_listener *listener); - -void -ds_buffer_add_release_listener(struct ds_buffer *buffer, - struct wl_listener *listener); - -bool -ds_buffer_begin_data_ptr_access(struct ds_buffer *buffer, - enum ds_buffer_data_ptr_access_flag flags, void **data, - uint32_t *format, size_t *stride); - -void -ds_buffer_end_data_ptr_access(struct ds_buffer *buffer); - -void -ds_buffer_register_resource_interface( - const struct ds_buffer_resource_interface *iface); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/compositor.h b/include/libds/compositor.h deleted file mode 100644 index 343fa0c..0000000 --- a/include/libds/compositor.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef LIBDS_COMPOSITOR_H -#define LIBDS_COMPOSITOR_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_compositor; - -struct ds_compositor * -ds_compositor_create(struct wl_display *display); - -void -ds_compositor_add_new_surface_listener(struct ds_compositor *compositor, - struct wl_listener *listener); - -void -ds_compositor_add_destroy_listener(struct ds_compositor *compositor, - struct wl_listener *listener); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/input_device.h b/include/libds/input_device.h deleted file mode 100644 index 55aabbd..0000000 --- a/include/libds/input_device.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef LIBDS_INPUT_DEVICE_H -#define LIBDS_INPUT_DEVICE_H - -struct ds_input_device; - -struct ds_pointer; - -struct ds_keyboard; - -struct ds_touch; - -enum ds_button_state -{ - DS_BUTTON_RELEASED, - DS_BUTTON_PRESSED, -}; - -enum ds_input_device_type -{ - DS_INPUT_DEVICE_POINTER, - DS_INPUT_DEVICE_KEYBOARD, - DS_INPUT_DEVICE_TOUCH, -}; - -enum ds_input_device_type -ds_input_device_get_type(struct ds_input_device *dev); - -const char * -ds_input_device_get_name(struct ds_input_device *dev); - -struct ds_pointer * -ds_input_device_get_pointer(struct ds_input_device *dev); - -struct ds_keyboard * -ds_input_device_get_keyboard(struct ds_input_device *dev); - -struct ds_touch * -ds_input_device_get_touch(struct ds_input_device *dev); - -void -ds_input_device_add_destroy_listener(struct ds_input_device *dev, - struct wl_listener *listener); - -#endif diff --git a/include/libds/interfaces/allocator.h b/include/libds/interfaces/allocator.h deleted file mode 100644 index 1e60668..0000000 --- a/include/libds/interfaces/allocator.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef LIBDS_INTERFACES_ALLOCATOR_H -#define LIBDS_INTERFACES_ALLOCATOR_H - -#include -#include - -struct ds_allocator; - -struct ds_allocator_interface { - struct ds_buffer *(*create_buffer)(struct ds_allocator *alloc, - int width, int height, uint32_t format); - void (*destroy)(struct ds_allocator *alloc); -}; - -struct ds_allocator -{ - const struct ds_allocator_interface *iface; - - uint32_t buffer_caps; - - struct { - struct wl_signal destroy; - } events; -}; - -void -ds_allocator_init(struct ds_allocator *alloc, - const struct ds_allocator_interface *iface, uint32_t buffer_caps); - -void -ds_allocator_destroy(struct ds_allocator *alloc); - -#endif diff --git a/include/libds/interfaces/backend.h b/include/libds/interfaces/backend.h deleted file mode 100644 index 55a2475..0000000 --- a/include/libds/interfaces/backend.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef LIBDS_INTERFACES_BACKEND_H -#define LIBDS_INTERFACES_BACKEND_H - -#include - -struct ds_backend; - -struct ds_backend_interface -{ - bool (*start)(struct ds_backend *backend); - void (*destroy)(struct ds_backend *backend); - int (*get_drm_fd)(struct ds_backend *backend); -}; - -struct ds_backend -{ - const struct ds_backend_interface *iface; - - struct wl_display *display; - - struct - { - struct wl_signal destroy; - struct wl_signal new_output; - struct wl_signal new_input; - } events; - - bool started; -}; - -void -ds_backend_init(struct ds_backend *backend, struct wl_display *display, - const struct ds_backend_interface *iface); - -void -ds_backend_finish(struct ds_backend *backend); - -#endif diff --git a/include/libds/interfaces/buffer.h b/include/libds/interfaces/buffer.h deleted file mode 100644 index 3e288aa..0000000 --- a/include/libds/interfaces/buffer.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef LIBDS_INTERFACES_BUFFER_H -#define LIBDS_INTERFACES_BUFFER_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_buffer; - -struct ds_buffer_interface -{ - void (*destroy)(struct ds_buffer *buffer); - bool (*get_shm)(struct ds_buffer *buffer, - struct ds_shm_attributes *attribs); - bool (*begin_data_ptr_access)(struct ds_buffer *buffer, uint32_t flags, - void **data, uint32_t *format, size_t *stride); - void (*end_data_ptr_access)(struct ds_buffer *buffer); -}; - -struct ds_buffer -{ - const struct ds_buffer_interface *iface; - void *iface_data; - - int width, height; - size_t n_locks; - - bool dropped; - bool accessing_data_ptr; - - struct { - struct wl_signal destroy; - struct wl_signal release; - } events; -}; - -void -ds_buffer_init(struct ds_buffer *buffer, - const struct ds_buffer_interface *iface, int width, int height); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/interfaces/input_device.h b/include/libds/interfaces/input_device.h deleted file mode 100644 index e39fecc..0000000 --- a/include/libds/interfaces/input_device.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef LIBDS_INTERFACES_INPUT_DEVICE_H -#define LIBDS_INTERFACES_INPUT_DEVICE_H - -#include -#include -#include -#include -#include - -struct ds_input_device_interface -{ - void (*destroy)(struct ds_input_device *dev); -}; - -struct ds_input_device -{ - const struct ds_input_device_interface *iface; - - char *name; - double width_mm, height_mm; - char *output_name; - - enum ds_input_device_type type; - union { - void *_device; - struct ds_pointer *pointer; - struct ds_keyboard *keyboard; - struct ds_touch *touch; - }; - - struct { - struct wl_signal destroy; - } events; - - struct wl_list link; -}; - -void ds_input_device_init(struct ds_input_device *dev, - enum ds_input_device_type type, - const struct ds_input_device_interface *iface, - const char *name, int vendor, int product); -void ds_input_device_destroy(struct ds_input_device *dev); - -#endif diff --git a/include/libds/interfaces/keyboard.h b/include/libds/interfaces/keyboard.h deleted file mode 100644 index 85a20a5..0000000 --- a/include/libds/interfaces/keyboard.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef LIBDS_INTERFACES_KEYBOARD_H -#define LIBDS_INTERFACES_KEYBOARD_H - -#include -#include - -#include - -#define DS_LED_COUNT 3 - -enum ds_keyboard_led { - DS_LED_NUM_LOCK = 1 << 0, - DS_LED_CAPS_LOCK = 1 << 1, - DS_LED_SCROLL_LOCK = 1 << 2, -}; - -#define DS_KEYBOARD_KEYS_CAP 32 - -struct ds_keyboard; - -struct ds_keyboard_interface -{ - void (*destroy)(struct ds_keyboard *keyboard); -}; - -struct ds_keyboard -{ - const struct ds_keyboard_interface *iface; - - char *keymap_string; - size_t keymap_size; - int keymap_fd; - struct xkb_keymap *keymap; - struct xkb_state *xkb_state; - xkb_led_index_t led_indexes[DS_LED_COUNT]; - xkb_mod_index_t mod_indexes[DS_MODIFIER_COUNT]; - - uint32_t keycodes[DS_KEYBOARD_KEYS_CAP]; - size_t num_keycodes; - struct ds_keyboard_modifiers modifiers; - - struct { - int32_t rate; - int32_t delay; - } repeat_info; - - struct { - struct wl_signal destroy; - struct wl_signal key; - struct wl_signal modifiers; - struct wl_signal keymap; - struct wl_signal repeat_info; - } events; -}; - -void ds_keyboard_init(struct ds_keyboard *keyboard, - const struct ds_keyboard_interface *iface); - -void ds_keyboard_destroy(struct ds_keyboard *keyboard); - -void ds_keyboard_notify_key(struct ds_keyboard *keyboard, - struct ds_event_keyboard_key *event); - -void ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group); - -#endif diff --git a/include/libds/interfaces/output.h b/include/libds/interfaces/output.h deleted file mode 100644 index 53a4e0c..0000000 --- a/include/libds/interfaces/output.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef LIBDS_INTERFACES_OUTPUT_H -#define LIBDS_INTERFACES_OUTPUT_H - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_output; - -enum ds_output_state_field -{ - DS_OUTPUT_STATE_BUFFER = 1 << 0, - DS_OUTPUT_STATE_DAMAGE = 1 << 1, - DS_OUTPUT_STATE_MODE = 1 << 2, - DS_OUTPUT_STATE_ENABLED = 1 << 3, - DS_OUTPUT_STATE_SCALE = 1 << 4, - DS_OUTPUT_STATE_TRANSFORM = 1 << 5, -}; - -enum ds_output_state_mode_type -{ - DS_OUTPUT_STATE_MODE_FIXED, - DS_OUTPUT_STATE_MODE_CUSTOM, -}; - -struct ds_output_interface -{ - void (*destroy)(struct ds_output *output); - bool (*commit)(struct ds_output *output); -}; - -struct ds_output_state -{ - enum ds_output_state_field committed; - struct ds_buffer *buffer; - - enum ds_output_state_mode_type mode_type; - const struct ds_output_mode *mode; - struct { - int32_t width, height; - int32_t refresh; // mHz, may be zero - } custom_mode; - - bool enabled; -}; - -struct ds_output -{ - const struct ds_output_interface *iface; - - struct ds_backend *backend; - - struct wl_display *display; - struct wl_global *global; - - struct ds_buffer *back_buffer, *front_buffer; - const struct ds_output_mode *current_mode; - int32_t width, height; - int32_t refresh; // mHz, may be zero - struct ds_output_state pending; - - struct wl_list modes; - - struct wl_listener display_destroy; - - struct { - struct wl_signal destroy; - struct wl_signal frame; - struct wl_signal commit; - } events; - - bool enabled; -}; - -void -ds_output_init(struct ds_output *output, struct ds_backend *backend, - const struct ds_output_interface *iface, struct wl_display *display); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/interfaces/pointer.h b/include/libds/interfaces/pointer.h deleted file mode 100644 index 84b0e23..0000000 --- a/include/libds/interfaces/pointer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LIBDS_INTERFACES_POINTER_H -#define LIBDS_INTERFACES_POINTER_H - -#include - -struct ds_pointer; - -struct ds_pointer_interface -{ - void (*destroy)(struct ds_pointer *pointer); -}; - -struct ds_pointer -{ - const struct ds_pointer_interface *iface; - - struct { - struct wl_signal motion; - struct wl_signal motion_absolute; - struct wl_signal button; - struct wl_signal frame; - } events; -}; - -void ds_pointer_init(struct ds_pointer *pointer, - const struct ds_pointer_interface *iface); - -void ds_pointer_destroy(struct ds_pointer *pointer); - -#endif diff --git a/include/libds/interfaces/touch.h b/include/libds/interfaces/touch.h deleted file mode 100644 index 25ff4e6..0000000 --- a/include/libds/interfaces/touch.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LIBDS_INTERFACES_TOUCH_H -#define LIBDS_INTERFACES_TOUCH_H - -#include - -struct ds_touch; - -struct ds_touch_interface -{ - void (*destroy)(struct ds_touch *touch); -}; - -struct ds_touch -{ - const struct ds_touch_interface *iface; - - struct { - struct wl_signal down; - struct wl_signal up; - struct wl_signal motion; - struct wl_signal frame; - } events; -}; - -void ds_touch_init(struct ds_touch *touch, - const struct ds_touch_interface *iface); - -void ds_touch_destroy(struct ds_touch *touch); - -#endif diff --git a/include/libds/keyboard.h b/include/libds/keyboard.h deleted file mode 100644 index 80165e6..0000000 --- a/include/libds/keyboard.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef LIBDS_KEYBOARD_H -#define LIBDS_KEYBOARD_H - -#include -#include - -#include -#include - -struct ds_keyboard; - -#define DS_MODIFIER_COUNT 8 - -enum ds_keyboard_modifier { - DS_MODIFIER_SHIFT = 1 << 0, - DS_MODIFIER_CAPS = 1 << 1, - DS_MODIFIER_CTRL = 1 << 2, - DS_MODIFIER_ALT = 1 << 3, - DS_MODIFIER_MOD2 = 1 << 4, - DS_MODIFIER_MOD3 = 1 << 5, - DS_MODIFIER_LOGO = 1 << 6, - DS_MODIFIER_MOD5 = 1 << 7, -}; - -struct ds_keyboard_modifiers -{ - xkb_mod_mask_t depressed; - xkb_mod_mask_t latched; - xkb_mod_mask_t locked; - xkb_mod_mask_t group; -}; - -struct ds_event_keyboard_key -{ - uint32_t time_msec; - uint32_t keycode; - bool update_state; - enum wl_keyboard_key_state state; -}; - -bool ds_keyboard_set_keymap(struct ds_keyboard *keyboard, - struct xkb_keymap *keymap); - -void ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard, - int32_t rate, int32_t delay); - -uint32_t ds_keyboard_get_modifiers(struct ds_keyboard *keyboard); - -struct xkb_state *ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard); - -void ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener); - -void ds_keyboard_add_key_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener); - -void ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener); - -void ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener); - -void ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener); - -#endif diff --git a/include/libds/log.h b/include/libds/log.h deleted file mode 100644 index 5296d89..0000000 --- a/include/libds/log.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef LIBDS_LOG_H -#define LIBDS_LOG_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -enum ds_log_level { - DS_SILENT = 0, - DS_ERR = 1, - DS_INF = 2, - DS_DBG = 3, - DS_LOG_LEVEL_LAST, -}; - -typedef void (*ds_log_func_t)(enum ds_log_level level, - const char *fmt, va_list args); - -void ds_log_init(enum ds_log_level level, ds_log_func_t callback); - -enum ds_log_level ds_log_get_level(void); - -#ifdef __GNUC__ -#define _DS_ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end))) -#else -#define _DS_ATTRIB_PRINTF(start, end) -#endif - -void _ds_log(enum ds_log_level level, const char *format, ...) _DS_ATTRIB_PRINTF(2, 3); -void _ds_vlog(enum ds_log_level level, const char *format, va_list args) _DS_ATTRIB_PRINTF(2, 0); - -#define ds_log(level, fmt, ...) \ - _ds_log(level, "[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__) - -#define ds_vlog(level, fmt, args) \ - _ds_vlog(level, "[%s:%d] " fmt, __FILE__, __LINE__, args) - -#define ds_log_errno(level, fmt, ...) \ - ds_log(level, fmt ": %s", ##__VA_ARGS__, strerror(errno)) - -#define ds_err(fmt, ...) \ - ds_log(DS_ERR, fmt, ##__VA_ARGS__) - -#define ds_inf(fmt, ...) \ - ds_log(DS_INF, fmt, ##__VA_ARGS__) - -#define ds_dbg(fmt, ...) \ - ds_log(DS_DBG, fmt, ##__VA_ARGS__) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/output.h b/include/libds/output.h deleted file mode 100644 index 5cf1fce..0000000 --- a/include/libds/output.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef LIBDS_OUTPUT_H -#define LIBDS_OUTPUT_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_output; - -struct ds_output_mode { - int32_t width, height; - int32_t refresh; // mHz - bool preferred; - struct wl_list link; -}; - -void -ds_output_destroy(struct ds_output *output); - -void -ds_output_enable(struct ds_output *output); - -void -ds_output_disable(struct ds_output *output); - -bool -ds_output_commit(struct ds_output *output); - -void -ds_output_attach_buffer(struct ds_output *output, struct ds_buffer *buffer); - -const struct ds_output_mode * -ds_output_get_preferred_mode(struct ds_output *output); - -void -ds_output_set_mode(struct ds_output *output, - const struct ds_output_mode *mode); - -void -ds_output_set_custom_mode(struct ds_output *output, - int32_t width, int32_t height, int32_t refresh); - -void -ds_output_add_destroy_listener(struct ds_output *output, - struct wl_listener *listener); - -void -ds_output_add_frame_listener(struct ds_output *output, - struct wl_listener *listener); - -void -ds_output_add_commit_listener(struct ds_output *output, - struct wl_listener *listener); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/pointer.h b/include/libds/pointer.h deleted file mode 100644 index 99545df..0000000 --- a/include/libds/pointer.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef LIBDS_POINTER_H -#define LIBDS_POINTER_H - -#include -#include -#include - -struct ds_pointer; - -struct ds_event_pointer_motion_absolute -{ - struct ds_input_device *device; - uint32_t time_msec; - // From 0..1 - double x, y; -}; - -struct ds_event_pointer_motion -{ - struct ds_input_device *device; - uint32_t time_msec; - double delta_x, delta_y; -}; - -struct ds_event_pointer_button -{ - struct ds_input_device *device; - uint32_t time_msec; - uint32_t button; - enum ds_button_state state; -}; - -void ds_pointer_add_motion_listener(struct ds_pointer *pointer, - struct wl_listener *listener); - -void ds_pointer_add_motion_absolute_listener(struct ds_pointer *pointer, - struct wl_listener *listener); - -void ds_pointer_add_button_listener(struct ds_pointer *pointer, - struct wl_listener *listener); - -void ds_pointer_add_frame_listener(struct ds_pointer *pointer, - struct wl_listener *listener); - -#endif diff --git a/include/libds/presentation.h b/include/libds/presentation.h deleted file mode 100644 index 2b496b4..0000000 --- a/include/libds/presentation.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef LIBstruct ds_presentationIME_H -#define LIBstruct ds_presentationIME_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_presentation; - -struct ds_presentation * -ds_presentation_create(struct wl_display *display, - clockid_t clk_id); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/seat.h b/include/libds/seat.h deleted file mode 100644 index dbae0ea..0000000 --- a/include/libds/seat.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef LIBDS_SEAT_H -#define LIBDS_SEAT_H - -#include -#include - -#include -#include -#include - -struct ds_seat; - -enum ds_axis_orientation -{ - DS_AXIS_ORIENTATION_VERTICAL, - DS_AXIS_ORIENTATION_HORIZONTAL, -}; - -enum ds_axis_source -{ - DS_AXIS_SOURCE_WHEEL, - DS_AXIS_SOURCE_FINGER, - DS_AXIS_SOURCE_CONTINUOUS, - DS_AXIS_SOURCE_WHEEL_TILT, -}; - -struct ds_event_seat_pointer_focus_change -{ - struct ds_seat *seat; - struct ds_surface *old_surface, *new_surface; - double sx, sy; -}; - -struct ds_event_seat_keyboard_focus_change -{ - struct ds_seat *seat; - struct ds_surface *old_surface, *new_surface; -}; - -struct ds_seat *ds_seat_create(struct wl_display *display, const char *name); - -void ds_seat_destroy(struct ds_seat *seat); - -void ds_seat_set_capabilities(struct ds_seat *seat, - enum wl_seat_capability capabilities); - -void ds_seat_set_name(struct ds_seat *seat, const char *name); - -void ds_seat_add_destroy_listener(struct ds_seat *seat, - struct wl_listener *listener); - -void ds_seat_pointer_notify_enter(struct ds_seat *seat, - struct ds_surface *surface, double sx, double sy); - -void ds_seat_pointer_notify_clear_focus(struct ds_seat *seat); - -void ds_seat_pointer_notify_motion(struct ds_seat *seat, uint32_t time_msec, - double sx, double sy); - -uint32_t ds_seat_pointer_notify_button(struct ds_seat *seat, - uint32_t time_msec, uint32_t button, enum ds_button_state state); - -void ds_seat_pointer_notify_axis(struct ds_seat *seat, uint32_t time_msec, - enum ds_axis_orientation orientation, double value, - int32_t value_discrete, enum ds_axis_source source); - -void ds_seat_pointer_notify_frame(struct ds_seat *seat); - -void ds_seat_pointer_add_grab_begin_listener(struct ds_seat *seat, - struct wl_listener *listener); - -void ds_seat_pointer_add_grab_end_listener(struct ds_seat *seat, - struct wl_listener *listener); - -void ds_seat_pointer_add_focus_change_listener(struct ds_seat *seat, - struct wl_listener *listener); - -void ds_seat_keyboard_notify_enter(struct ds_seat *seat, - struct ds_surface *surface, uint32_t keycodes[], size_t num_keycodes, - struct ds_keyboard_modifiers *modifiers); - -void ds_seat_keyboard_notify_clear_focus(struct ds_seat *seat); - -void ds_seat_keyboard_notify_modifiers(struct ds_seat *seat, - struct ds_keyboard_modifiers *modifiers); - -void ds_seat_keyboard_notify_key(struct ds_seat *seat, uint32_t time_msec, - uint32_t key, uint32_t state); - -void ds_seat_keyboard_add_grab_begin_listener(struct ds_seat *seat, - struct wl_listener *listener); - -void ds_seat_keyboard_add_grab_end_listener(struct ds_seat *seat, - struct wl_listener *listener); - -void ds_seat_keyboard_add_focus_change_listener(struct ds_seat *seat, - struct wl_listener *listener); - -void ds_seat_touch_end_grab_start_listener(struct ds_seat *seat, - struct wl_listener *listener); - -uint32_t ds_seat_touch_notify_down(struct ds_seat *seat, - struct ds_surface *surface, uint32_t time_msec, int32_t touch_id, - double sx, double sy); - -void ds_seat_touch_notify_up(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id); - -void ds_seat_touch_notify_motion(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id, double sx, double sy); - -void ds_seat_touch_notify_frame(struct ds_seat *seat); - -void ds_seat_touch_add_grab_start_listener(struct ds_seat *seat, - struct wl_listener *listener); - -#endif diff --git a/include/libds/shell.h b/include/libds/shell.h deleted file mode 100644 index b4fa688..0000000 --- a/include/libds/shell.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef LIBDS_SHELL_H -#define LIBDS_SHELL_H - -#include -#include - -#include "surface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_shell; - -struct ds_shell_surface; - -struct ds_shell * -ds_shell_create(struct wl_display *display); - -void -ds_shell_add_destroy_listener(struct ds_shell *shell, - struct wl_listener *listener); - -void -ds_shell_add_new_surface_listener(struct ds_shell *shell, - struct wl_listener *listener); - -void -ds_shell_surface_add_destroy_listener(struct ds_shell_surface *surface, - struct wl_listener *listener); - -void -ds_shell_surface_add_map_listener(struct ds_shell_surface *surface, - struct wl_listener *listener); - -void -ds_shell_surface_add_unmap_listener(struct ds_shell_surface *surface, - struct wl_listener *listener); - -void -ds_shell_surface_ping(struct ds_shell_surface *surface); - -struct ds_surface * -ds_shell_surface_get_surface(struct ds_shell_surface *surface); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/subsurface.h b/include/libds/subsurface.h deleted file mode 100644 index 72ed088..0000000 --- a/include/libds/subsurface.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef LIBDS_SUBSURFACE_H -#define LIBDS_SUBSURFACE_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_subsurface; - -bool ds_surface_is_subsurface(struct ds_surface *surface); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/surface.h b/include/libds/surface.h deleted file mode 100644 index 9c26cea..0000000 --- a/include/libds/surface.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef LIBDS_SURFACE_H -#define LIBDS_SURFACE_H - -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_surface; - -typedef bool (*ds_surface_for_each_func_t)(struct ds_surface *surface, - int sx, int sy, void *data); - -void -ds_surface_add_destroy_listener(struct ds_surface *surface, - struct wl_listener *listener); - -void -ds_surface_add_commit_listener(struct ds_surface *surface, - struct wl_listener *listener); - -void -ds_surface_add_new_subsurface_listener(struct ds_surface *surface, - struct wl_listener *listener); - -struct ds_buffer * -ds_surface_get_buffer(struct ds_surface *surface); - -void -ds_surface_for_each(struct ds_surface *surface, - ds_surface_for_each_func_t iterator, void *data); - -void -ds_surface_send_frame_done(struct ds_surface *surface, - const struct timespec *when); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/swapchain.h b/include/libds/swapchain.h deleted file mode 100644 index 61d8a68..0000000 --- a/include/libds/swapchain.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LIBDS_SWAPCHAIN_H -#define LIBDS_SWAPCHAIN_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_swapchain; - -struct ds_swapchain * -ds_swapchain_create(struct ds_allocator *alloc, int width, int height, - uint32_t format); - -void -ds_swapchain_destroy(struct ds_swapchain *swapchain); - -struct ds_buffer * -ds_swapchain_acquire(struct ds_swapchain *swapchain, int *age); - -void -ds_swapchain_set_buffer_submitted(struct ds_swapchain *swapchain, - struct ds_buffer *buffer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds/touch.h b/include/libds/touch.h deleted file mode 100644 index 4b69b90..0000000 --- a/include/libds/touch.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef LIBDS_TOUCH_H -#define LIBDS_TOUCH_H - -#include -#include -#include - -struct ds_touch; - -struct ds_event_touch_down -{ - struct ds_input_device *device; - uint32_t time_msec; - //wl_surface surface; - uint32_t id; - double x, y; -}; - -struct ds_event_touch_up -{ - struct ds_input_device *device; - uint32_t time_msec; - uint32_t id; -}; - -struct ds_event_touch_motion -{ - struct ds_input_device *device; - uint32_t time_msec; - uint32_t id; - double x, y; -}; - -void ds_touch_add_down_listener(struct ds_touch *touch, - struct wl_listener *listener); - -void ds_touch_add_up_listener(struct ds_touch *touch, - struct wl_listener *listener); - -void ds_touch_add_motion_listener(struct ds_touch *touch, - struct wl_listener *listener); - -void ds_touch_add_frame_listener(struct ds_touch *touch, - struct wl_listener *listener); - -#endif diff --git a/include/libds/xdg_shell.h b/include/libds/xdg_shell.h deleted file mode 100644 index 624c327..0000000 --- a/include/libds/xdg_shell.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef LIBDS_XDG_SHELL_H -#define LIBDS_XDG_SHELL_H - -#include -#include - -#include "surface.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_xdg_shell; - -struct ds_xdg_surface; - -struct ds_xdg_shell * -ds_xdg_shell_create(struct wl_display *display); - -void -ds_xdg_shell_add_destroy_listener(struct ds_xdg_shell *shell, - struct wl_listener *listener); - -void -ds_xdg_shell_add_new_surface_listener(struct ds_xdg_shell *shell, - struct wl_listener *listener); - -void -ds_xdg_surface_add_destroy_listener(struct ds_xdg_surface *surface, - struct wl_listener *listener); - -void -ds_xdg_surface_add_map_listener(struct ds_xdg_surface *surface, - struct wl_listener *listener); - -void -ds_xdg_surface_add_unmap_listener(struct ds_xdg_surface *surface, - struct wl_listener *listener); - -void -ds_xdg_surface_ping(struct ds_xdg_surface *surface); - -struct ds_surface * -ds_xdg_surface_get_surface(struct ds_xdg_surface *surface); - -uint32_t -ds_xdg_toplevel_set_size(struct ds_xdg_surface *surface, - uint32_t width, uint32_t height); - -uint32_t -ds_xdg_toplevel_set_activated(struct ds_xdg_surface *surface, - bool activated); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/meson.build b/include/meson.build index 0975c5d..7ce7964 100644 --- a/include/meson.build +++ b/include/meson.build @@ -1,9 +1,3 @@ -install_subdir('libds', +install_subdir('libds-tizen', install_dir: get_option('includedir'), ) - -if get_option('tizen') - install_subdir('libds-tizen', - install_dir: get_option('includedir'), - ) -endif diff --git a/meson.build b/meson.build index d3d2df0..410b271 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('libds', 'c', +project('libds_tizen', 'c', license: 'MIT', version: '0.1.2', default_options: [ @@ -8,22 +8,22 @@ project('libds', 'c', ] ) -libds_version = meson.project_version() -version_arr = libds_version.split('.') -libds_version_major = version_arr[0] -libds_version_minor = version_arr[1] -libds_version_patch = version_arr[2] +libds_tizen_version = meson.project_version() +version_arr = libds_tizen_version.split('.') +libds_tizen_version_major = version_arr[0] +libds_tizen_version_minor = version_arr[1] +libds_tizen_version_patch = version_arr[2] dir_prefix = get_option('prefix') -libds_bindir = join_paths(dir_prefix, get_option('bindir')) +libds_tizen_bindir = join_paths(dir_prefix, get_option('bindir')) -libds_inc = include_directories('include') -common_inc = [ include_directories('.'), libds_inc ] +libds_tizen_inc = include_directories('include') +common_inc = [ include_directories('.'), libds_tizen_inc ] cdata = configuration_data() -cdata.set('LIBDS_VERSION_MAJOR', libds_version_major) -cdata.set('LIBDS_VERSION_MINOR', libds_version_minor) -cdata.set('LIBDS_VERSION_PATCH', libds_version_patch) +cdata.set('LIBDS_VERSION_MAJOR', libds_tizen_version_major) +cdata.set('LIBDS_VERSION_MINOR', libds_tizen_version_minor) +cdata.set('LIBDS_VERSION_PATCH', libds_tizen_version_patch) subdir('src') subdir('include') diff --git a/meson_options.txt b/meson_options.txt index 1d6ff21..74ad5ca 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,2 +1 @@ -option('tizen', type: 'boolean', value: false, description: 'Build Tizen features') option('keylayout_dir', type: 'string', value: '', description: 'Directory where tizen key layout file is') \ No newline at end of file diff --git a/packaging/libds.manifest b/packaging/libds-tizen.manifest similarity index 100% rename from packaging/libds.manifest rename to packaging/libds-tizen.manifest diff --git a/packaging/libds.spec b/packaging/libds-tizen.spec similarity index 76% rename from packaging/libds.spec rename to packaging/libds-tizen.spec index f53efa9..ceb7b50 100644 --- a/packaging/libds.spec +++ b/packaging/libds-tizen.spec @@ -1,13 +1,14 @@ -Name: libds +Name: libds-tizen Version: 0.1.2 Release: 0 -Summary: Wayland Compositor Library +Summary: Wayland Compositor Library for Tizen License: MIT URL: http://www.tizen.org/ Source: %name-%version.tar.xz Source1001: %name.manifest BuildRequires: meson +BuildRequires: pkgconfig(libds) BuildRequires: pkgconfig(wayland-server) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-protocols) @@ -16,8 +17,6 @@ BuildRequires: pkgconfig(tizen-extension-client) BuildRequires: pkgconfig(pixman-1) BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(xkbcommon) -BuildRequires: pkgconfig(libinput) -BuildRequires: pkgconfig(libudev) BuildRequires: pkgconfig(libtdm) BuildRequires: pkgconfig(libtbm) @@ -30,34 +29,28 @@ BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(libsmack) %description -Wayland Compositor Library +Wayland Compositor Library for Tizen %package devel -Summary: Wayland Compositor Library +Summary: Wayland Compositor Library for Tizen Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description devel -Development package of Wayland Compositor Library +Development package of Wayland Compositor Library for Tizen -%package tizen-devel -Summary: Wayland Compositor development package on Tizen - -%description tizen-devel -Wayland Compositor development library for Tizen platform - -%package tizen-keyrouter +%package keyrouter Summary: Wayland Compositor Library for keyrouter Group: Development/Libraries -%description tizen-keyrouter +%description keyrouter Wayland Compositor Library for tizen keyrouter -%package tizen-keyrouter-devel +%package keyrouter-devel Summary: Keyrouter Development package for Wayland Compositor Library Group: Development/Libraries -%description tizen-keyrouter-devel +%description keyrouter-devel Keyrouter Development package for Wayland Compositor Library %package tizen-input-devicemgr @@ -84,7 +77,6 @@ meson setup \ --libdir %{_libdir} \ --bindir %{_bindir} \ builddir \ - -Dtizen=true \ -Dkeylayout_dir="%{TZ_SYS_RO_SHARE}/X11/xkb/tizen_key_layout.txt" ninja -C builddir all @@ -96,25 +88,12 @@ ninja -C builddir install %manifest %{name}.manifest %defattr(-,root,root,-) %license LICENSE -%{_libdir}/libds.so.* %{_libdir}/libds-tizen.so.* %files devel %manifest %{name}.manifest %defattr(-,root,root,-) %license LICENSE -%{_includedir}/libds/* -%{_libdir}/pkgconfig/libds.pc -%{_libdir}/libds.so -%{_bindir}/wl-backend -%{_bindir}/tinyds -%{_bindir}/input-device-test -%{_bindir}/libinput-backend - -%files tizen-devel -%manifest %{name}.manifest -%defattr(-,root,root,-) -%license LICENSE %{_includedir}/libds-tizen/* %{_libdir}/pkgconfig/libds-tizen.pc %{_libdir}/libds-tizen.so @@ -122,18 +101,16 @@ ninja -C builddir install %{_bindir}/tinyds-tdm %{_bindir}/ds-simple-tbm %{_bindir}/tinyds-tdm-libinput -%{_bindir}/ds-simple-shm-shell %{_bindir}/tinyds-tdm-dpms -%{_bindir}/ds-simple-dpms %{_bindir}/input-generator -%files tizen-keyrouter +%files keyrouter %manifest %{name}.manifest %defattr(-,root,root,-) %license LICENSE %{_libdir}/libds-tizen-keyrouter.so.* -%files tizen-keyrouter-devel +%files keyrouter-devel %manifest %{name}.manifest %defattr(-,root,root,-) %license LICENSE diff --git a/src/clients/meson.build b/src/clients/meson.build index ba09b32..b22419b 100644 --- a/src/clients/meson.build +++ b/src/clients/meson.build @@ -1,15 +1,3 @@ -simple_shm_shell_files = ['simple-shm-shell.c'] -simple_shm_shell_deps = [ - dependency('wayland-client', required: true), -] - -executable('ds-simple-shm-shell', - simple_shm_shell_files, - dependencies: simple_shm_shell_deps, - install_dir: libds_bindir, - install: true, -) - wayland_tbm_client = dependency('wayland-tbm-client', required: false) libtbm = dependency('libtbm', required: false) tizen_extension_client = dependency('tizen-extension-client', required: true) @@ -54,7 +42,7 @@ endforeach executable('ds-simple-tbm', simple_tbm_files, dependencies: simple_tbm_deps, - install_dir: libds_bindir, + install_dir: libds_tizen_bindir, install: true, ) diff --git a/src/clients/simple-shm-shell.c b/src/clients/simple-shm-shell.c deleted file mode 100644 index 52d9ed2..0000000 --- a/src/clients/simple-shm-shell.c +++ /dev/null @@ -1,339 +0,0 @@ -/* -Copyright (C) 2015 - 2016 Samsung Electronics co., Ltd. All Rights Reserved. - -Contact: - SooChan Lim - Changyeon Lee - JunKyeong Kim - Boram Park - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define BUF_WIDTH 1920 -#define BUF_HEIGHT 1080 - -#define RETURN_VAL_IF_FAIL(c,v) {\ - if(!((c))){\ - fprintf(stderr, "[%s(%d)] '%s' failed.", __func__, __LINE__, #c);\ - return (v);\ - }\ -} - -#define GOTO_IF_FAIL(c,l) {\ - if(!(c)) {\ - fprintf(stderr, "[%s(%d)] '%s' failed.", __func__, __LINE__, #c);\ - goto l;\ - }\ -} - -#define EXIT_IF_FAIL(c) {\ - if(!(c)) {\ - fprintf (stderr, "[%s(%d)] '%s' failed.\n",__func__,__LINE__,#c);\ - exit(0);\ - }\ -} - -struct wl_test_info { - int width; - int height; - int stride; - int format; - int size; - - struct wl_display *display; - struct wl_registry *registry; - - /* global objects */ - struct wl_compositor *compositor; - struct wl_shm *shm; - struct wl_shell *shell; - struct wl_shm_pool *shm_pool; - - /* objects */ - struct wl_surface *surface; - struct wl_shell_surface *shell_surface; - struct wl_buffer *buffer; -}; - -static int -_create_anonymous_file (off_t size) -{ - static const char template[] = - "/shooter-XXXXXX"; - const char *path; - char *name = NULL; - int fd = -1; - int ret = -1; - - path = getenv("XDG_RUNTIME_DIR"); - if (!path) { - errno = ENOENT; - return -1; - } - - name = malloc(strlen(path) + sizeof(template)); - GOTO_IF_FAIL(name != NULL, fail); - - strcpy(name, path); - strcat(name, template); - - fd = mkstemp(name); - if (fd >= 0) - unlink(name); - - ret = ftruncate(fd, size); - GOTO_IF_FAIL(ret >= 0, fail); - - free(name); - - return fd; -fail: - if (fd >= 0) - close(fd); - - if (name) - free(name); - - return -1; -} - -static void -_destroy_anonymous_file(int fd) -{ - if (fd < 0) return; - - close(fd); -} - - -static struct wl_test_info * -_create_wl_test_info (void) -{ - struct wl_test_info *test_info = NULL; - - test_info = calloc(1, sizeof(struct wl_test_info)); - RETURN_VAL_IF_FAIL(test_info != NULL, NULL); - - return test_info; -} - -static void -_destroy_wl_test_info (struct wl_test_info *test_info) -{ - if (!test_info) return; - - free(test_info); -} - -static struct wl_shm_pool * -_create_shm_pool(struct wl_shm *shm, int size) -{ - struct wl_shm_pool *shm_pool = NULL; - void *data = NULL; - int fd = -1; - - fd = _create_anonymous_file(size); - GOTO_IF_FAIL(fd >= 0, fail); - - data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - GOTO_IF_FAIL(data != NULL, fail); - - memset(data, 0xff, size); - munmap(data, size); - - shm_pool = wl_shm_create_pool(shm, fd, size); - GOTO_IF_FAIL(shm_pool != NULL, fail); - - _destroy_anonymous_file(fd); - - return shm_pool; - -fail: - if (fd > 0) - _destroy_anonymous_file(fd); - - return NULL; -} - -void -_destroy_shm_pool(struct wl_shm_pool *shm_pool) -{ - if (!shm_pool) return; - - wl_shm_pool_destroy(shm_pool); -} - -static void -handle_global(void *data, struct wl_registry *registry, uint32_t name, - const char *interface, uint32_t version) -{ - struct wl_test_info *ti = (struct wl_test_info *)data; - - if (strcmp(interface, "wl_compositor") == 0) { - ti->compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 3); - if (!ti->compositor) - printf("%s(%d): Error. fail to bind %s.\n", - __func__, __LINE__, interface); - else - printf("%s(%d): bind %s.\n", __func__, __LINE__, interface); - } else if (strcmp(interface, "wl_shm") == 0) { - ti->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); - if (!ti->shm) - printf("%s(%d): Error. fail to bind %s.\n", - __func__, __LINE__, interface); - else - printf("%s(%d): bind %s.\n", __func__, __LINE__, interface); - - ti->shm_pool = _create_shm_pool(ti->shm, ti->size); - if (!ti->shm_pool) - printf("%s(%d): Error. fail to create wl_shm_pool.\n", - __func__, __LINE__); - else - printf("%s(%d): success to create wl_shm_pool.\n", - __func__, __LINE__); - - } else if (strcmp(interface, "wl_shell") == 0) { - ti->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1); - if (!ti->shell) - printf("%s(%d): Error. fail to bind %s.\n", - __func__, __LINE__, interface); - else - printf("%s(%d): bind %s.\n", __func__, __LINE__, interface); - } else { - printf("%s(%d): Not bind %s.\n", __func__, __LINE__, interface); - } -} - -static void -handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) -{ - -} - -static const struct wl_registry_listener registry_listener = { - handle_global, - handle_global_remove -}; - -int main (void) -{ - struct wl_test_info *ti = NULL; - int ret = 0; - - /* create test info */ - ti = _create_wl_test_info (); - GOTO_IF_FAIL(ti != NULL, fail); - - /* init */ - ti->width = BUF_WIDTH; - ti->height = BUF_HEIGHT; - ti->stride = ti->width * 4; - ti->format = WL_SHM_FORMAT_XRGB8888; - ti->size = ti->stride * ti->height; - - /* connect display */ - ti->display = wl_display_connect(NULL); - GOTO_IF_FAIL(ti->display != NULL, fail); - - /* get the registry */ - ti->registry = wl_display_get_registry(ti->display); - GOTO_IF_FAIL(ti->registry != NULL, fail); - - /* get the global objects */ - wl_registry_add_listener(ti->registry, ®istry_listener, ti); - wl_display_dispatch(ti->display); - wl_display_roundtrip(ti->display); - - /* check the global objects */ - GOTO_IF_FAIL(ti->compositor != NULL, fail); - GOTO_IF_FAIL(ti->shm != NULL, fail); - GOTO_IF_FAIL(ti->shell != NULL, fail); - GOTO_IF_FAIL(ti->shm_pool != NULL, fail); - - /* create objects */ - ti->surface = wl_compositor_create_surface(ti->compositor); - GOTO_IF_FAIL(ti->surface != NULL, fail); - - ti->shell_surface = wl_shell_get_shell_surface(ti->shell, ti->surface); - GOTO_IF_FAIL(ti->shell_surface != NULL, fail); - - wl_shell_surface_set_toplevel(ti->shell_surface); - - ti->buffer = wl_shm_pool_create_buffer(ti->shm_pool, 0, - ti->width, ti->height, ti->stride, ti->format); - GOTO_IF_FAIL(ti->buffer != NULL, fail); - - wl_surface_attach(ti->surface, ti->buffer, 0, 0); - wl_surface_damage(ti->surface, 0, 0, ti->width, ti->height); - wl_surface_commit(ti->surface); - - wl_display_roundtrip(ti->display); - - /* main loop */ - printf("%s(%d): loop start.\n", __func__, __LINE__); - while (ret >= 0) { - ret = wl_display_dispatch(ti->display); - printf("%s(%d): loop running(ret=%d).\n", __func__, __LINE__, ret); - } - printf("%s(%d): loop end.\n", __func__, __LINE__); - -fail: - /* destory objects */ - if (ti->shell_surface) - wl_shell_surface_destroy(ti->shell_surface); - if (ti->surface) - wl_surface_destroy(ti->surface); - if (ti->buffer) - wl_buffer_destroy(ti->buffer); - - /* destroy global objects */ - if (ti->shell) - wl_shell_destroy(ti->shell); - if (ti->shm_pool) - _destroy_shm_pool(ti->shm_pool); - if (ti->shm) - wl_shm_destroy(ti->shm); - if (ti->compositor) - wl_compositor_destroy(ti->compositor); - - /* destory registry and display */ - if (ti->registry) - wl_registry_destroy(ti->registry); - if (ti->display) - wl_display_disconnect(ti->display); - - /* destroy test_info */ - if (ti) - _destroy_wl_test_info(ti); - - return 0; -} diff --git a/src/examples/input-device-test.c b/src/examples/input-device-test.c deleted file mode 100644 index 62fe8b0..0000000 --- a/src/examples/input-device-test.c +++ /dev/null @@ -1,391 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pixman-helper.h" - -#define WIDTH 700 -#define HEIGHT 400 - -struct pointer_device { - struct ds_pointer *ds_pointer; - - struct wl_listener destroy; - struct wl_listener motion_absolute; - struct wl_listener button; - struct wl_listener frame; -}; - -struct server; - -struct keyboard_device { - struct server *server; - struct ds_keyboard *ds_keyboard; - - struct wl_listener destroy; - struct wl_listener modifiers; - struct wl_listener key; -}; - -struct output -{ - struct server *server; - - struct ds_output *ds_output; - struct ds_allocator *allocator; - struct ds_swapchain *swapchain; - - struct ds_buffer *front_buffer; - - struct wl_listener destroy; -}; - -struct server -{ - struct wl_display *display; - - struct output output; - - struct ds_backend *backend; - - struct wl_listener backend_destroy; - struct wl_listener new_input; -}; - -struct server _server; - -static struct ds_backend *create_backend_auto(struct wl_display *display); -static void handle_backend_destroy(struct wl_listener *listener, void *data); -static void handle_new_input(struct wl_listener *listener, void *data); -static void output_init(struct output *output, struct server *sever); -static void output_draw(struct output *output); - -int -main(void) -{ - struct server *server = &_server; - - ds_log_init(DS_DBG, NULL); - - server->display = wl_display_create(); - assert(server->display); - - server->backend = create_backend_auto(server->display); - assert(server->backend); - - server->backend_destroy.notify = handle_backend_destroy; - ds_backend_add_destroy_listener(server->backend, &server->backend_destroy); - - server->new_input.notify = handle_new_input; - ds_backend_add_new_input_listener(server->backend, &server->new_input); - - output_init(&server->output, server); - - ds_backend_start(server->backend); - - output_draw(&server->output); - - wl_display_run(server->display); - - wl_display_destroy(server->display); - - return 0; -} - -static struct ds_backend * -create_backend_auto(struct wl_display *display) -{ - struct ds_backend *backend = NULL; - char name[512]; - int i; - - for (i = 0; i < 5; i++) { - snprintf(name, sizeof name, "wayland-%d", i); - backend = ds_wl_backend_create(display, name); - if (backend) - break; - } - - return backend; -} - -static void -handle_backend_destroy(struct wl_listener *listener, void *data) -{ - struct server *server; - - server = wl_container_of(listener, server, backend_destroy); - - wl_list_remove(&server->backend_destroy.link); - wl_list_remove(&server->new_input.link); -} - -static char * -device_type_to_string(enum ds_input_device_type type) -{ - switch (type) { - case DS_INPUT_DEVICE_POINTER: - return "pointer"; - break; - case DS_INPUT_DEVICE_KEYBOARD: - return "keyboard"; - break; - case DS_INPUT_DEVICE_TOUCH: - return "touch"; - break; - default: - return "Unknown"; - } -} - -static void -pointer_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct pointer_device *pointer; - - pointer = wl_container_of(listener, pointer, destroy); - - wl_list_remove(&pointer->destroy.link); - wl_list_remove(&pointer->motion_absolute.link); - wl_list_remove(&pointer->button.link); - wl_list_remove(&pointer->frame.link); - - free(pointer); -} - -static void -pointer_handle_motion_absolute(struct wl_listener *listener, void *data) -{ - struct ds_event_pointer_motion_absolute *event = data; - - ds_inf("Pointer device(%p): motion absolute (%f, %f) time(%d ms)", - event->device, event->x, event->y, event->time_msec); -} - -static void -pointer_handle_button(struct wl_listener *listener, void *data) -{ - struct ds_event_pointer_button *event = data; - - ds_inf("Pointer Device(%p): button(%d) state(%d) time(%d ms)", - event->device, event->button, event->state, event->time_msec); -} - -static void -pointer_handle_frame(struct wl_listener *listener, void *data) -{ - ds_inf("Pointer device(%p): frame", data); -} - -static void -add_pointer(struct ds_input_device *dev) -{ - struct pointer_device *pointer; - - pointer = calloc(1, sizeof *pointer); - if (!pointer) - return; - - pointer->ds_pointer = ds_input_device_get_pointer(dev); - - pointer->destroy.notify = pointer_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &pointer->destroy); - - pointer->motion_absolute.notify = pointer_handle_motion_absolute; - ds_pointer_add_motion_absolute_listener(pointer->ds_pointer, - &pointer->motion_absolute); - - pointer->button.notify = pointer_handle_button; - ds_pointer_add_button_listener(pointer->ds_pointer, - &pointer->button); - - pointer->frame.notify = pointer_handle_frame; - ds_pointer_add_frame_listener(pointer->ds_pointer, - &pointer->frame); -} - -static void -keyboard_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct keyboard_device *keyboard; - - keyboard = wl_container_of(listener, keyboard, destroy); - - wl_list_remove(&keyboard->destroy.link); - wl_list_remove(&keyboard->modifiers.link); - wl_list_remove(&keyboard->key.link); - - free(keyboard); -} - -static void -keyboard_handle_modifiers(struct wl_listener *listener, void *data) -{ - struct ds_keyboard *ds_keyboard = data; - uint32_t modifiers; - - modifiers = ds_keyboard_get_modifiers(ds_keyboard); - if (modifiers & DS_MODIFIER_CTRL) - ds_inf("Keyboard(%p) modifier: Ctrl", ds_keyboard); - if (modifiers & DS_MODIFIER_SHIFT) - ds_inf("Keyboard(%p) modifier: Shift", ds_keyboard); - if (modifiers & DS_MODIFIER_CAPS) - ds_inf("Keyboard(%p) modifier: Caps", ds_keyboard); - if (modifiers & DS_MODIFIER_ALT) - ds_inf("Keyboard(%p) modifier: Alt", ds_keyboard); - if (modifiers & DS_MODIFIER_MOD2) - ds_inf("Keyboard(%p) modifier: Mod2", ds_keyboard); - if (modifiers & DS_MODIFIER_MOD3) - ds_inf("Keyboard(%p) modifier: Mod3", ds_keyboard); - if (modifiers & DS_MODIFIER_LOGO) - ds_inf("Keyboard(%p) modifier: Logo", ds_keyboard); - if (modifiers & DS_MODIFIER_MOD5) - ds_inf("Keyboard(%p) modifier: Mod5", ds_keyboard); -} - -static void -keyboard_handle_key(struct wl_listener *listener, void *data) -{ - struct ds_event_keyboard_key *event = data; - struct keyboard_device *keyboard; - struct xkb_state *xkb_state; - const xkb_keysym_t *syms; - uint32_t modifiers; - int nsyms = 0; - - keyboard = wl_container_of(listener, keyboard, key); - - ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), " - "update_state(%d)", keyboard->ds_keyboard, - event->keycode, event->state, event->time_msec, - event->update_state); - - xkb_state = ds_keyboard_get_xkb_state(keyboard->ds_keyboard); - if (!xkb_state) - return; - - nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, &syms); - - modifiers = ds_keyboard_get_modifiers(keyboard->ds_keyboard); - if ((modifiers & DS_MODIFIER_CTRL) && - (modifiers & DS_MODIFIER_ALT) && - event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - for (int i = 0; i < nsyms; i++) { - if (syms[i] == XKB_KEY_BackSpace) - wl_display_terminate(keyboard->server->display); - } - } -} - -static void -add_keyboard(struct server *server, struct ds_input_device *dev) -{ - struct keyboard_device *keyboard; - - keyboard = calloc(1, sizeof *keyboard); - if (!keyboard) - return; - - keyboard->server = server; - keyboard->ds_keyboard = ds_input_device_get_keyboard(dev); - - ds_inf("Keyboard(%p) added", keyboard->ds_keyboard); - - keyboard->destroy.notify = keyboard_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &keyboard->destroy); - - keyboard->modifiers.notify = keyboard_handle_modifiers; - ds_keyboard_add_modifiers_listener(keyboard->ds_keyboard, - &keyboard->modifiers); - - keyboard->key.notify = keyboard_handle_key; - ds_keyboard_add_key_listener(keyboard->ds_keyboard, - &keyboard->key); -} - -static void -handle_new_input(struct wl_listener *listener, void *data) -{ - struct server *server; - struct ds_input_device *dev = data; - enum ds_input_device_type type; - - type = ds_input_device_get_type(dev); - - ds_inf("New device(%p) type(%s)", dev, device_type_to_string(type)); - - if (type == DS_INPUT_DEVICE_POINTER) - add_pointer(dev); - else if (type == DS_INPUT_DEVICE_KEYBOARD) { - server = wl_container_of(listener, server, new_input); - add_keyboard(server, dev); - } -} - -static void -output_handle_destroy(struct wl_listener *listener, void *data) -{ - struct output *output; - - output = wl_container_of(listener, output, destroy); - - wl_list_remove(&output->destroy.link); - - ds_swapchain_destroy(output->swapchain); - ds_allocator_destroy(output->allocator); -} - -static void -output_init(struct output *output, struct server *server) -{ - output->server = server; - - output->ds_output = ds_wl_backend_create_output(server->backend); - assert(output->ds_output); - - output->destroy.notify = output_handle_destroy; - ds_output_add_destroy_listener(output->ds_output, &output->destroy); - - output->allocator = ds_shm_allocator_create(); - assert(output->allocator); - - output->swapchain = ds_swapchain_create(output->allocator, - WIDTH, HEIGHT, DRM_FORMAT_XRGB8888); - assert(output->swapchain); -} - -static void -output_draw(struct output *output) -{ - struct ds_buffer *buffer; - pixman_image_t *img; - - ds_dbg("Redraw output"); - - buffer = ds_swapchain_acquire(output->swapchain, NULL); - assert(buffer); - - img = pixman_image_from_buffer(buffer, DS_BUFFER_DATA_PTR_ACCESS_WRITE); - assert(img); - - pixman_image_fill_color(img, 80, 80, 80); - - pixman_image_unref(img); - - ds_output_attach_buffer(output->ds_output, buffer); - ds_output_commit(output->ds_output); - - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); - - output->front_buffer = buffer; -} diff --git a/src/examples/libinput-backend.c b/src/examples/libinput-backend.c deleted file mode 100644 index 592fbc3..0000000 --- a/src/examples/libinput-backend.c +++ /dev/null @@ -1,340 +0,0 @@ -#include - #include - -#include -#include -#include -#include -#include -#include -#include - -#define UNUSED __attribute__((unused)) - -struct keyboard_device -{ - struct server *server; - struct ds_keyboard *ds_keyboard; - - struct wl_listener destroy; - struct wl_listener key; -}; - -struct pointer_device -{ - struct ds_pointer *ds_pointer; - - struct wl_listener destroy; - struct wl_listener motion; - struct wl_listener button; -}; - -struct touch_device -{ - struct ds_touch *ds_touch; - - struct wl_listener destroy; - struct wl_listener down; - struct wl_listener up; - struct wl_listener motion; -}; - -struct server -{ - struct wl_display *display; - - struct ds_backend *backend; - - struct wl_listener backend_destroy; - struct wl_listener new_input; -}; - -struct server _server; - -static struct ds_backend *create_backend_auto(struct wl_display *display); -static void handle_backend_destroy(struct wl_listener *listener, void *data); -static void handle_new_input(struct wl_listener *listener, void *data); - -int -main(void) -{ - struct server *server = &_server; - - ds_log_init(DS_DBG, NULL); - - server->display = wl_display_create(); - assert(server->display); - - server->backend = create_backend_auto(server->display); - assert(server->backend); - - server->backend_destroy.notify = handle_backend_destroy; - ds_backend_add_destroy_listener(server->backend, &server->backend_destroy); - - server->new_input.notify = handle_new_input; - ds_backend_add_new_input_listener(server->backend, &server->new_input); - - ds_backend_start(server->backend); - - wl_display_run(server->display); - - wl_display_destroy(server->display); - - return 0; -} - -static struct ds_backend * -create_backend_auto(struct wl_display *display) -{ - struct ds_backend *backend = NULL; - backend = ds_libinput_backend_create(display); - if (!backend) - ds_err("Failed to create libinput backend"); - - return backend; -} - -static void -handle_backend_destroy(struct wl_listener *listener, void *data) -{ - struct server *server; - - server = wl_container_of(listener, server, backend_destroy); - - wl_list_remove(&server->backend_destroy.link); - wl_list_remove(&server->new_input.link); -} - -static char * -device_type_to_string(enum ds_input_device_type type) -{ - switch (type) { - case DS_INPUT_DEVICE_POINTER: - return "pointer"; - break; - case DS_INPUT_DEVICE_KEYBOARD: - return "keyboard"; - break; - case DS_INPUT_DEVICE_TOUCH: - return "touch"; - break; - default: - return "Unknown"; - } -} - -static void -keyboard_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct keyboard_device *keyboard; - - keyboard = wl_container_of(listener, keyboard, destroy); - - wl_list_remove(&keyboard->destroy.link); - wl_list_remove(&keyboard->key.link); - - free(keyboard); -} - -static void -keyboard_handle_key(struct wl_listener *listener, void *data) -{ - struct ds_event_keyboard_key *event = data; - struct keyboard_device *keyboard; - - keyboard = wl_container_of(listener, keyboard, key); - - ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), " - "update_state(%d)", keyboard->ds_keyboard, - event->keycode, event->state, event->time_msec, - event->update_state); -} - -static void -add_keyboard(struct server *server, struct ds_input_device *dev) -{ - struct keyboard_device *keyboard; - - keyboard = calloc(1, sizeof *keyboard); - if (!keyboard) - return; - - keyboard->server = server; - keyboard->ds_keyboard = ds_input_device_get_keyboard(dev); - - ds_inf("Keyboard(%p) added", keyboard->ds_keyboard); - - keyboard->destroy.notify = keyboard_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &keyboard->destroy); - - keyboard->key.notify = keyboard_handle_key; - ds_keyboard_add_key_listener(keyboard->ds_keyboard, - &keyboard->key); -} - -static void -pointer_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct pointer_device *pointer; - - pointer = wl_container_of(listener, pointer, destroy); - - wl_list_remove(&pointer->destroy.link); - wl_list_remove(&pointer->button.link); - wl_list_remove(&pointer->motion.link); - - free(pointer); -} - -static void -pointer_handle_motion(struct wl_listener *listener, void *data) -{ - struct ds_event_pointer_motion *event = data; - struct pointer_device *pointer; - - pointer = wl_container_of(listener, pointer, motion); - - ds_inf("Pointer Device(%p): motion delta_x,y(%f, %f) time(%d ms)", - pointer->ds_pointer, event->delta_x, event->delta_y, - event->time_msec); -} - -static void -pointer_handle_button(struct wl_listener *listener, void *data) -{ - struct ds_event_pointer_button *event = data; - struct pointer_device *pointer; - - pointer = wl_container_of(listener, pointer, button); - ds_inf("Pointer Device(%p): button(%d) state(%d) time(%d ms)", - pointer->ds_pointer, event->button, event->state, - event->time_msec); -} - -static void -add_pointer(struct ds_input_device *dev) -{ - struct pointer_device *pointer; - - pointer = calloc(1, sizeof *pointer); - if (!pointer) - return; - - pointer->ds_pointer = ds_input_device_get_pointer(dev); - - ds_inf("Pointer(%p) added", pointer->ds_pointer); - - pointer->destroy.notify = pointer_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &pointer->destroy); - - pointer->motion.notify = pointer_handle_motion; - ds_pointer_add_motion_listener(pointer->ds_pointer, - &pointer->motion); - - pointer->button.notify = pointer_handle_button; - ds_pointer_add_button_listener(pointer->ds_pointer, - &pointer->button); -} - -static void -touch_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct touch_device *touch; - - touch = wl_container_of(listener, touch, destroy); - - wl_list_remove(&touch->destroy.link); - wl_list_remove(&touch->down.link); - wl_list_remove(&touch->up.link); - wl_list_remove(&touch->motion.link); - - free(touch); -} - -static void -touch_handle_down(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_down *event = data; - struct touch_device *touch; - - touch = wl_container_of(listener, touch, down); - - ds_inf("Touch(%p) event down: id(%d) x(%f) y(%f) time_msec(%d)", - touch->ds_touch, event->id, event->x, event->y, event->time_msec); -} - -static void -touch_handle_up(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_up *event = data; - struct touch_device *touch; - - touch = wl_container_of(listener, touch, up); - - ds_inf("Touch(%p) event up: id(%d) time_msec(%d)", - touch->ds_touch, event->id, event->time_msec); -} - -static void -touch_handle_motion(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_motion *event = data; - struct touch_device *touch; - - touch = wl_container_of(listener, touch, motion); - - ds_inf("Touch(%p) event motion: id(%d) x(%f) y(%f) time_msec(%d)", - touch->ds_touch, event->id, event->x, event->y, event->time_msec); -} - -static void -add_touch(struct server *server, struct ds_input_device *dev) -{ - struct touch_device *touch; - - touch = calloc(1, sizeof *touch); - if (!touch) - return; - - touch->ds_touch = ds_input_device_get_touch(dev); - - ds_inf("Touch(%p) added", touch->ds_touch); - - touch->destroy.notify = touch_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &touch->destroy); - - touch->down.notify = touch_handle_down; - ds_touch_add_down_listener(touch->ds_touch, - &touch->down); - - touch->up.notify = touch_handle_up; - ds_touch_add_up_listener(touch->ds_touch, - &touch->up); - - touch->motion.notify = touch_handle_motion; - ds_touch_add_motion_listener(touch->ds_touch, - &touch->motion); -} - -static void -handle_new_input(struct wl_listener *listener, void *data) -{ - struct server *server; - struct ds_input_device *dev = data; - enum ds_input_device_type type; - - type = ds_input_device_get_type(dev); - - ds_inf("New device(%p) type(%s)", dev, device_type_to_string(type)); - - if (type == DS_INPUT_DEVICE_POINTER) - add_pointer(dev); - else if (type == DS_INPUT_DEVICE_KEYBOARD) { - server = wl_container_of(listener, server, new_input); - add_keyboard(server, dev); - } - else if (type == DS_INPUT_DEVICE_TOUCH) { - server = wl_container_of(listener, server, new_input); - add_touch(server, dev); - } -} diff --git a/src/examples/meson.build b/src/examples/meson.build index eb9ae29..af04c50 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -1,99 +1,61 @@ common_deps = [ - dep_libds, + dep_libds_tizen, dependency('wayland-server', required: true), ] -executable('wl-backend', - 'wl-backend.c', - dependencies: common_deps, - install_dir: libds_bindir, - install : true) +executable('tdm-backend', + 'tdm-backend.c', + dependencies: common_deps, + install_dir: libds_tizen_bindir, + install : true +) -executable('tinyds', - [ - 'tinyds.c', - 'pixman-helper.c' +tinyds_tdm_files = [ + 'tinyds-tdm.c', + 'pixman-helper.c', + 'pixman-tbm-helper.c', + 'tinyds-tdm-renderer.c', +] + +executable('tinyds-tdm', + tinyds_tdm_files, + dependencies: [ + common_deps, + dependency('pixman-1', required: true), + dependency('threads', required: true), ], + install_dir: libds_tizen_bindir, + install : true +) + +tinyds_tdm_libinput_files = [ + 'tinyds-tdm-libinput.c', + 'pixman-helper.c', + 'pixman-tbm-helper.c', + 'tinyds-tdm-renderer.c', +] + +executable('tinyds-tdm-libinput', + tinyds_tdm_libinput_files, dependencies: [ common_deps, dependency('pixman-1', required: true), - dependency('libdrm', required: true), + dependency('threads', required: true), ], - install_dir: libds_bindir, + install_dir: libds_tizen_bindir, install : true ) -executable('input-device-test', - [ - 'input-device-test.c', - 'pixman-helper.c', +executable('tinyds-tdm-dpms', + 'tinyds-tdm-dpms.c', + 'pixman-helper.c', + 'pixman-tbm-helper.c', + 'tinyds-tdm-renderer.c', + dependencies: [ + common_deps, + dependency('pixman-1', required: true), + dependency('threads', required: true), ], - dependencies: common_deps, install_dir: libds_bindir, - install : true) - -if get_option('tizen') - common_deps += dep_libds_tizen - - executable('tdm-backend', - 'tdm-backend.c', - dependencies: common_deps, - install_dir: libds_bindir, - install : true - ) - - tinyds_tdm_files = [ - 'tinyds-tdm.c', - 'pixman-helper.c', - 'pixman-tbm-helper.c', - 'tinyds-tdm-renderer.c', - ] - executable('tinyds-tdm', - tinyds_tdm_files, - dependencies: [ - common_deps, - dependency('pixman-1', required: true), - dependency('threads', required: true), - ], - install_dir: libds_bindir, - install : true - ) - - executable('libinput-backend', - 'libinput-backend.c', - dependencies: common_deps, - install_dir: libds_bindir, - install : true - ) - - tinyds_tdm_libinput_files = [ - 'tinyds-tdm-libinput.c', - 'pixman-helper.c', - 'pixman-tbm-helper.c', - 'tinyds-tdm-renderer.c', - ] - executable('tinyds-tdm-libinput', - tinyds_tdm_libinput_files, - dependencies: [ - common_deps, - dep_libds_tizen_input_devicemgr, - dependency('pixman-1', required: true), - dependency('threads', required: true), - ], - install_dir: libds_bindir, - install : true - ) - executable('tinyds-tdm-dpms', - 'tinyds-tdm-dpms.c', - 'pixman-helper.c', - 'pixman-tbm-helper.c', - 'tinyds-tdm-renderer.c', - dependencies: [ - common_deps, - dependency('pixman-1', required: true), - dependency('threads', required: true), - ], - install_dir: libds_bindir, - install : true - ) -endif + install : true +) diff --git a/src/examples/tinyds.c b/src/examples/tinyds.c deleted file mode 100644 index 0e25462..0000000 --- a/src/examples/tinyds.c +++ /dev/null @@ -1,811 +0,0 @@ -#include "pixman-helper.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TINYDS_UNUSED __attribute__((unused)) - -#define OUTPUT_WIDTH 1280 -#define OUTPUT_HEIGHT 720 - -struct tinyds_server; - -struct tinyds_pointer -{ - struct ds_input_device *dev; - struct tinyds_server *server; - - struct tinyds_view *focused_view; - - struct wl_listener destroy; - struct wl_listener motion; - struct wl_listener motion_absolute; - struct wl_listener button; - struct wl_listener frame; -}; - -struct tinyds_keyboard -{ - struct ds_input_device *dev; - struct tinyds_server *server; - - struct wl_listener destroy; - struct wl_listener key; -}; - -struct tinyds_touch -{ - struct ds_input_device *dev; - struct tinyds_server *server; - - struct wl_listener destroy; - struct wl_listener down; - struct wl_listener up; - struct wl_listener motion; -}; - -struct tinyds_output -{ - struct tinyds_server *server; - struct ds_output *ds_output; - struct ds_allocator *allocator; - struct ds_swapchain *swapchain; - - struct wl_listener output_destroy; - struct wl_listener output_frame; - - int width, height; - - bool drawable; - bool damaged; -}; - -struct tinyds_server -{ - struct wl_display *display; - - struct ds_backend *backend; - struct ds_compositor *compositor; - struct ds_xdg_shell *xdg_shell; - struct ds_seat *seat; - - struct tinyds_output output; - - struct wl_list views; - - struct wl_listener new_output; - struct wl_listener new_input; - struct wl_listener new_xdg_surface; -}; - -struct tinyds_view -{ - struct tinyds_server *server; - - struct ds_xdg_surface *xdg_surface; - - struct wl_listener xdg_surface_map; - struct wl_listener xdg_surface_unmap; - struct wl_listener xdg_surface_destroy; - struct wl_listener surface_commit; - struct wl_list link; // tinyds_server::views - - int x, y; - bool mapped; -}; - -static bool server_init(struct tinyds_server *server, - struct wl_display *display); -static void server_fini(struct tinyds_server *server); -static void server_add_view(struct tinyds_server *server, - struct ds_xdg_surface *xdg_surface); -static struct tinyds_view *server_view_at(struct tinyds_server *server, - double lx, double ly, double *sx, double *sy); -static bool output_init(struct tinyds_output *output, - struct tinyds_server *server, struct ds_output *ds_output, - int width, int height); -static void output_fini(struct tinyds_output *output); -static void output_damage(struct tinyds_output *output); -static void output_redraw(struct tinyds_output *output); -static void view_destroy(struct tinyds_view *view); -static void view_composite(struct tinyds_view *view, - pixman_image_t *dst_image); - -int -main(void) -{ - struct tinyds_server server; - struct wl_display *display; - const char *socket; - - ds_log_init(DS_DBG, NULL); - - display = wl_display_create(); - assert(display); - - assert(server_init(&server, display) == true); - - socket = wl_display_add_socket_auto(display); - assert(socket); - - ds_backend_start(server.backend); - - output_damage(&server.output); - output_redraw(&server.output); - - setenv("WAYLAND_DISPLAY", socket, true); - - ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); - - wl_display_run(server.display); - - server_fini(&server); - wl_display_destroy(display); - - return 0; -} - -static struct ds_backend * -create_wl_backend(struct wl_display *display) -{ - if (!getenv("WAYLAND_DISPLAY") && !getenv("WAYLAND_SOCKET")) - return NULL; - - return ds_wl_backend_create(display, NULL); -} - -static void -server_handle_new_output(struct wl_listener *listener, void *data) -{ - struct tinyds_server *server; - struct ds_output *ds_output = data; - - server = wl_container_of(listener, server, new_output); - - assert(output_init(&server->output, server, ds_output, - OUTPUT_WIDTH, OUTPUT_HEIGHT) == true); -} - -static void -keyboard_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_keyboard *kbd; - - kbd = wl_container_of(listener, kbd, destroy); - - ds_inf("Keyboard(%p) destroyed", kbd); - - wl_list_remove(&kbd->destroy.link); - wl_list_remove(&kbd->key.link); - - free(kbd); -} - -static bool -server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym) -{ - switch (sym) { - case XKB_KEY_BackSpace: - wl_display_terminate(server->display); - break; - default: - return false; - } - - return true; -} - -static void -keyboard_handle_key(struct wl_listener *listener, void *data) -{ - struct tinyds_keyboard *kbd; - struct ds_event_keyboard_key *event = data; - struct ds_keyboard *ds_keyboard; - struct xkb_state *xkb_state; - const xkb_keysym_t *syms; - uint32_t modifiers; - int nsyms; - - kbd = wl_container_of(listener, kbd, key); - - ds_keyboard = ds_input_device_get_keyboard(kbd->dev); - - modifiers = ds_keyboard_get_modifiers(ds_keyboard); - if ((modifiers & DS_MODIFIER_CTRL) && - (modifiers & DS_MODIFIER_ALT) && - (modifiers & DS_MODIFIER_SHIFT) && - event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - xkb_state = ds_keyboard_get_xkb_state(ds_keyboard); - if (xkb_state) { - nsyms = xkb_state_key_get_syms(xkb_state, event->keycode + 8, - &syms); - for (int i = 0; i < nsyms; i++) { - server_handle_keybinding(kbd->server, syms[i]); - } - } - } -} - -static void -server_add_keyboard(struct tinyds_server *server, struct ds_input_device *dev) -{ - struct tinyds_keyboard *kbd; - - kbd = calloc(1, sizeof *kbd); - assert(kbd); - - kbd->dev = dev; - kbd->server = server; - - kbd->destroy.notify = keyboard_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &kbd->destroy); - - kbd->key.notify = keyboard_handle_key; - ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key); - - ds_inf("Keyboard(%p) added", kbd); -} - -static void -touch_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_touch *touch; - - touch = wl_container_of(listener, touch, destroy); - - ds_inf("Touch(%p) destroyed", touch); - - wl_list_remove(&touch->destroy.link); - wl_list_remove(&touch->down.link); - wl_list_remove(&touch->up.link); - wl_list_remove(&touch->motion.link); - - free(touch); -} - -static void -touch_handle_down(struct wl_listener *listener, void *data) -{ - ds_inf("Touch device(%p): down", data); -} - -static void -touch_handle_up(struct wl_listener *listener, void *data) -{ - ds_inf("Touch device(%p): up", data); -} - -static void -touch_handle_motion(struct wl_listener *listener, void *data) -{ - ds_inf("Touch device(%p): motion", data); -} - -static void -server_add_touch(struct tinyds_server *server, struct ds_input_device *dev) -{ - struct tinyds_touch *touch; - - touch = calloc(1, sizeof *touch); - assert(touch); - - touch->dev = dev; - touch->server = server; - - touch->destroy.notify = touch_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &touch->destroy); - - touch->down.notify = touch_handle_down; - ds_touch_add_down_listener(ds_input_device_get_touch(dev), &touch->down); - - touch->up.notify = touch_handle_up; - ds_touch_add_up_listener(ds_input_device_get_touch(dev), &touch->up); - - touch->motion.notify = touch_handle_motion; - ds_touch_add_motion_listener(ds_input_device_get_touch(dev), &touch->motion); - - ds_inf("Touch(%p) added", touch); -} - -static void -pointer_handle_device_destroy(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - - pointer = wl_container_of(listener, pointer, destroy); - - ds_inf("Pointer(%p) destroyed", pointer); - - wl_list_remove(&pointer->destroy.link); - wl_list_remove(&pointer->motion.link); - wl_list_remove(&pointer->motion_absolute.link); - wl_list_remove(&pointer->button.link); - wl_list_remove(&pointer->frame.link); - - free(pointer); -} - -static void -pointer_handle_motion(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - - pointer = wl_container_of(listener, pointer, motion); - - ds_inf("Pointer(%p) motion", pointer); -} - -static void -pointer_handle_motion_absolute(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - struct ds_event_pointer_motion_absolute *event = data; - struct tinyds_view *view; - double ox, oy, sx, sy; - - pointer = wl_container_of(listener, pointer, motion_absolute); - - ds_inf("Pointer(%p) motion absolute: (x %f y %f) time(%d)", - pointer, event->x, event->y, event->time_msec); - - ox = event->x * OUTPUT_WIDTH; - oy = event->y * OUTPUT_HEIGHT; - view = server_view_at(pointer->server, ox, oy, &sx, &sy); - - if (pointer->focused_view != view) { - if (pointer->focused_view) { - ds_inf("Clear pointer focus from view(%p)", pointer->focused_view); - ds_seat_pointer_notify_clear_focus(pointer->server->seat); - pointer->focused_view = NULL; - } - - if (view) { - ds_inf("Set pointer focus to view(%p)", view); - ds_seat_pointer_notify_enter(pointer->server->seat, - ds_xdg_surface_get_surface(view->xdg_surface), sx, sy); - pointer->focused_view = view; - } - } - - if (view) { - ds_seat_pointer_notify_motion(pointer->server->seat, - event->time_msec, sx, sy); - } -} - -static void -pointer_handle_button(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - struct ds_event_pointer_button *event = data; - - pointer = wl_container_of(listener, pointer, button); - - ds_inf("Pointer(%p) button(%d): state(%s) time(%d)", - pointer, event->button, - (event->state == DS_BUTTON_PRESSED) ? "Pressed" : "Released", - event->time_msec); -} - -static void -pointer_handle_frame(struct wl_listener *listener, void *data) -{ - struct tinyds_pointer *pointer; - - pointer = wl_container_of(listener, pointer, frame); - - ds_inf("Pointer(%p) frame", pointer); - ds_seat_pointer_notify_frame(pointer->server->seat); -} - -static void -server_add_pointer(struct tinyds_server *server, struct ds_input_device *dev) -{ - struct tinyds_pointer *pointer; - - pointer = calloc(1, sizeof *pointer); - assert(pointer); - - pointer->dev = dev; - pointer->server = server; - - pointer->destroy.notify = pointer_handle_device_destroy; - ds_input_device_add_destroy_listener(dev, &pointer->destroy); - - pointer->motion.notify = pointer_handle_motion; - ds_pointer_add_motion_listener(ds_input_device_get_pointer(dev), - &pointer->motion); - - pointer->motion_absolute.notify = pointer_handle_motion_absolute; - ds_pointer_add_motion_absolute_listener(ds_input_device_get_pointer(dev), - &pointer->motion_absolute); - - pointer->button.notify = pointer_handle_button; - ds_pointer_add_button_listener(ds_input_device_get_pointer(dev), - &pointer->button); - - pointer->frame.notify = pointer_handle_frame; - ds_pointer_add_frame_listener(ds_input_device_get_pointer(dev), - &pointer->frame); - - ds_inf("Pointer(%p) added", pointer); -} - -static void -server_handle_new_input(struct wl_listener *listener, void *data) -{ - struct tinyds_server *server; - struct ds_input_device *dev = data; - enum ds_input_device_type dev_type; - - server = wl_container_of(listener, server, new_input); - - dev_type = ds_input_device_get_type(dev); - switch (dev_type) { - case DS_INPUT_DEVICE_KEYBOARD: - server_add_keyboard(server, dev); - break; - case DS_INPUT_DEVICE_TOUCH: - server_add_touch(server, dev); - break; - case DS_INPUT_DEVICE_POINTER: - server_add_pointer(server, dev); - ds_seat_set_capabilities(server->seat, WL_SEAT_CAPABILITY_POINTER); - break; - default: - ds_err("Unknown type(%d) of ds_input_device", dev_type); - break; - } -} - -static void -view_handle_xdg_surface_map(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, xdg_surface_map); - view->mapped = true; -} - -static void -view_handle_xdg_surface_unmap(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, xdg_surface_unmap); - view->mapped = false; -} - -static void -view_handle_xdg_surface_destroy(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, xdg_surface_destroy); - - output_damage(&view->server->output); - output_redraw(&view->server->output); - - view_destroy(view); -} - -static void -view_handle_surface_commit(struct wl_listener *listener, - void *data TINYDS_UNUSED) -{ - struct tinyds_view *view; - - view = wl_container_of(listener, view, surface_commit); - - output_damage(&view->server->output); - output_redraw(&view->server->output); -} - -static void -server_new_xdg_surface(struct wl_listener *listener, void *data) -{ - struct tinyds_server *server; - - server = wl_container_of(listener, server, new_xdg_surface); - - server_add_view(server, (struct ds_xdg_surface *)data); -} - -static bool -server_init(struct tinyds_server *server, struct wl_display *display) -{ - server->display = display; - - wl_list_init(&server->views); - - if (wl_display_init_shm(display) != 0) - return false; - - server->backend = create_wl_backend(display); - if (!server->backend) - return false; - - ds_wl_backend_create_output(server->backend); - - server->new_input.notify = server_handle_new_input; - ds_backend_add_new_input_listener(server->backend, &server->new_input); - - server->new_output.notify = server_handle_new_output; - ds_backend_add_new_output_listener(server->backend, &server->new_output); - - server->compositor = ds_compositor_create(display); - if (!server->compositor) - goto err; - - server->xdg_shell = ds_xdg_shell_create(display); - if (!server->xdg_shell) - goto err; - - server->new_xdg_surface.notify = server_new_xdg_surface; - ds_xdg_shell_add_new_surface_listener(server->xdg_shell, - &server->new_xdg_surface); - - server->seat = ds_seat_create(display, "seat0" /* arbitrary name */); - if (!server->seat) - goto err; - - return true; - -err: - ds_backend_destroy(server->backend); - - return false; -} - -static void -server_fini(struct tinyds_server *server) -{ - struct tinyds_view *view, *tmp; - - wl_list_for_each_safe(view, tmp, &server->views, link) - view_destroy(view); - - output_fini(&server->output); - - wl_list_remove(&server->new_xdg_surface.link); -} - -static void -output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) -{ - struct tinyds_output *output = - wl_container_of(listener, output, output_destroy); - - wl_list_remove(&output->output_destroy.link); - wl_list_remove(&output->output_frame.link); - output->ds_output = NULL; - - wl_display_terminate(output->server->display); -} - -static void -output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) -{ - struct tinyds_output *output = - wl_container_of(listener, output, output_frame); - - output->drawable = true; - output_redraw(output); -} - -static bool -output_init(struct tinyds_output *output, struct tinyds_server *server, - struct ds_output *ds_output, int width, int height) -{ - output->server = server; - output->ds_output = ds_output; - output->width = width; - output->height = height; - output->drawable = true; - - ds_output_set_custom_mode(ds_output, OUTPUT_WIDTH, OUTPUT_HEIGHT, 0); - - output->allocator = ds_shm_allocator_create(); - if (!output->allocator) - return false; - - output->swapchain = ds_swapchain_create(output->allocator, - width, height, DRM_FORMAT_XRGB8888); - if (!output->swapchain) - goto err_swapchain; - - output->output_destroy.notify = output_handle_destroy; - ds_output_add_destroy_listener(output->ds_output, &output->output_destroy); - - output->output_frame.notify = output_handle_frame; - ds_output_add_frame_listener(output->ds_output, &output->output_frame); - - return true; - -err_swapchain: - ds_allocator_destroy(output->allocator); - - return false; -} - -static void -output_fini(struct tinyds_output *output) -{ - ds_output_destroy(output->ds_output); - ds_swapchain_destroy(output->swapchain); - ds_allocator_destroy(output->allocator); -} - -static void -output_damage(struct tinyds_output *output) -{ - output->damaged = true; -} - -static void -output_redraw(struct tinyds_output *output) -{ - struct ds_buffer *output_buffer; - pixman_image_t *output_image; - struct tinyds_view *view; - - if (!output->drawable || !output->damaged) - return; - - output_buffer = ds_swapchain_acquire(output->swapchain, NULL); - if (!output_buffer) - return; - - output_image = pixman_image_from_buffer(output_buffer, - DS_BUFFER_DATA_PTR_ACCESS_WRITE); - if (!output_image) - goto out; - - pixman_image_fill_color(output_image, 80, 80, 80); - - wl_list_for_each(view, &output->server->views, link) { - if (!view->mapped) - continue; - view_composite(view, output_image); - } - pixman_image_unref(output_image); - - ds_output_attach_buffer(output->ds_output, output_buffer); - ds_output_commit(output->ds_output); - - output->drawable = false; - output->damaged = false; - -out: - ds_buffer_unlock(output_buffer); -} - -static void -server_add_view(struct tinyds_server *server, struct ds_xdg_surface *xdg_surface) -{ - struct tinyds_view *view; - - view = calloc(1, sizeof *view); - view->server = server; - view->xdg_surface = xdg_surface; - - view->xdg_surface_map.notify = view_handle_xdg_surface_map; - ds_xdg_surface_add_map_listener(xdg_surface, - &view->xdg_surface_map); - - view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap; - ds_xdg_surface_add_unmap_listener(xdg_surface, - &view->xdg_surface_unmap); - - view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy; - ds_xdg_surface_add_destroy_listener(xdg_surface, - &view->xdg_surface_destroy); - - view->surface_commit.notify = view_handle_surface_commit; - ds_surface_add_commit_listener( - ds_xdg_surface_get_surface(xdg_surface), - &view->surface_commit); - - wl_list_insert(server->views.prev, &view->link); - - ds_inf("View(%p) added", view); -} - -static struct tinyds_view * -server_view_at(struct tinyds_server *server, double lx, double ly, - double *sx, double *sy) -{ - struct tinyds_view *view; - struct ds_surface *surface; - struct ds_buffer *buffer; - int x, y, w = 0, h = 0; - - wl_list_for_each(view, &server->views, link) { - surface = ds_xdg_surface_get_surface(view->xdg_surface); - buffer = ds_surface_get_buffer(surface); - ds_buffer_get_size(buffer, &w, &h); - - x = view->x; - y = view->y; - - if (lx >= x && lx <= w && ly >= y && ly <= h) { - *sx = lx - x; - *sy = ly - y; - - return view; - } - } - - return NULL; -} - -static void -view_destroy(struct tinyds_view *view) -{ - ds_inf("View(%p) destroyed", view); - - wl_list_remove(&view->xdg_surface_destroy.link); - wl_list_remove(&view->xdg_surface_map.link); - wl_list_remove(&view->xdg_surface_unmap.link); - wl_list_remove(&view->surface_commit.link); - wl_list_remove(&view->link); - free(view); -} - -static void -view_send_frame_done(struct tinyds_view *view) -{ - struct timespec now; - - clock_gettime(CLOCK_MONOTONIC, &now); - ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), - &now); -} - -static void -view_composite(struct tinyds_view *view, pixman_image_t *dst_image) -{ - struct ds_buffer *buffer; - pixman_image_t *src_image; - - buffer = ds_surface_get_buffer( - ds_xdg_surface_get_surface(view->xdg_surface)); - if (!buffer) - return; - - src_image = pixman_image_from_buffer(buffer, - DS_BUFFER_DATA_PTR_ACCESS_READ); - pixman_image_composite32(PIXMAN_OP_OVER, - src_image, - NULL, - dst_image, - 0, 0, 0, 0, 0, 0, - pixman_image_get_width(src_image), - pixman_image_get_height(src_image)); - pixman_image_unref(src_image); - - view_send_frame_done(view); -} diff --git a/src/examples/wl-backend.c b/src/examples/wl-backend.c deleted file mode 100644 index 38dea1b..0000000 --- a/src/examples/wl-backend.c +++ /dev/null @@ -1,226 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define WIDTH 700 -#define HEIGHT 400 - -struct server -{ - struct ds_backend *backend; - struct ds_output *output; - struct ds_allocator *allocator; - struct ds_swapchain *swapchain; - struct ds_buffer *front_buffer; - - struct wl_display *display; - - struct { - struct wl_listener output_destroy; - struct wl_listener output_frame; - } listener; - - int width, height; -}; - -struct server _server; - -static void init_server(struct server *server, struct wl_display *display); -static void fini_server(struct server *server); -static void output_handle_destroy(struct wl_listener *listener, void *data); -static void output_handle_frame(struct wl_listener *listener, void *data); -static void draw_output(struct server *server); - -int -main(void) -{ - struct server *server = &_server; - struct wl_display *display; - - ds_log_init(DS_DBG, NULL); - - display = wl_display_create(); - assert(display); - - server->width = WIDTH; - server->height = HEIGHT; - - init_server(server, display); - - server->listener.output_destroy.notify = output_handle_destroy; - ds_output_add_destroy_listener(server->output, - &server->listener.output_destroy); - - server->listener.output_frame.notify = output_handle_frame; - ds_output_add_frame_listener(server->output, - &server->listener.output_frame); - - ds_backend_start(server->backend); - - draw_output(server); - - wl_display_run(server->display); - - fini_server(server); - wl_display_destroy(display); - return 0; -} - -static struct ds_backend * -create_backend_auto(struct wl_display *display) -{ - struct ds_backend *backend = NULL; - char name[512]; - int i; - - for (i = 0; i < 5; i++) { - snprintf(name, sizeof name, "wayland-%d", i); - backend = ds_wl_backend_create(display, name); - if (backend) - break; - } - - return backend; -} - -static void -init_server(struct server *server, struct wl_display *display) -{ - server->display = display; - - server->backend = create_backend_auto(display); - assert(server->backend); - - server->allocator = ds_shm_allocator_create(); - assert(server->allocator); - - server->swapchain = ds_swapchain_create(server->allocator, - server->width, server->height, WL_SHM_FORMAT_XRGB8888); - assert(server->swapchain); - - server->output = - ds_wl_backend_create_output(server->backend); - assert(server->output); -} - -static void -fini_server(struct server *server) -{ - ds_buffer_unlock(server->front_buffer); - ds_swapchain_destroy(server->swapchain); - ds_allocator_destroy(server->allocator); -} - -static void -paint_pixels(void *image, int padding, int width, int height, uint32_t time) -{ - const int halfh = padding + (height - padding * 2) / 2; - const int halfw = padding + (width - padding * 2) / 2; - int ir, or; - uint32_t *pixel = image; - int y; - - /* squared radii thresholds */ - or = (halfw < halfh ? halfw : halfh) - 8; - ir = or - 32; - or *= or; - ir *= ir; - - pixel += padding * width; - for (y = padding; y < height - padding; y++) { - int x; - int y2 = (y - halfh) * (y - halfh); - - pixel += padding; - for (x = padding; x < width - padding; x++) { - uint32_t v; - - /* squared distance from center */ - int r2 = (x - halfw) * (x - halfw) + y2; - - if (r2 < ir) - v = (r2 / 32 + time / 64) * 0x0080401; - else if (r2 < or) - v = (y + time / 32) * 0x0080401; - else - v = (x + time / 16) * 0x0080401; - v &= 0x00ffffff; - - /* cross if compositor uses X from XRGB as alpha */ - if (abs(x - y) > 6 && abs(x + y - height) > 6) - v |= 0xff000000; - - *pixel++ = v; - } - - pixel += padding; - } -} - -static inline int64_t -timespec_to_msec(const struct timespec *a) -{ - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; -} - -static void -output_handle_destroy(struct wl_listener *listener, - void *data __attribute__((unused))) -{ - struct server *server = - wl_container_of(listener, server, listener.output_destroy); - wl_display_terminate(server->display); -} - -static void -output_handle_frame(struct wl_listener *listener, - void *data __attribute__((unused))) -{ - struct server *server = - wl_container_of(listener, server, listener.output_frame); - draw_output(server); -} - -static void -draw_output(struct server *server) -{ - struct ds_buffer *buffer; - void *data; - uint32_t format; - size_t stride; - struct timespec now; - uint32_t frame_time_msec; - - ds_dbg("Redraw output"); - - clock_gettime(CLOCK_MONOTONIC, &now); - frame_time_msec = timespec_to_msec(&now); - - buffer = ds_swapchain_acquire(server->swapchain, NULL); - assert(buffer); - - assert(ds_buffer_begin_data_ptr_access(buffer, - 0, &data, &format, &stride) == true); - - paint_pixels(data, 20, server->width, server->height, frame_time_msec); - - ds_buffer_end_data_ptr_access(buffer); - - ds_output_attach_buffer(server->output, buffer); - ds_output_commit(server->output); - - if (server->front_buffer) - ds_buffer_unlock(server->front_buffer); - - server->front_buffer = buffer; -} diff --git a/src/libds-tizen/allocator/tbm.c b/src/libds-tizen/allocator/tbm.c index dc3be42..0d00793 100644 --- a/src/libds-tizen/allocator/tbm.c +++ b/src/libds-tizen/allocator/tbm.c @@ -6,9 +6,9 @@ #include #include -#include "libds/interfaces/allocator.h" -#include "libds/interfaces/buffer.h" -#include "libds/log.h" +#include +#include +#include struct ds_tbm_allocator { diff --git a/src/libds-tizen/backend/tdm/backend.c b/src/libds-tizen/backend/tdm/backend.c index 21fb025..2337204 100644 --- a/src/libds-tizen/backend/tdm/backend.c +++ b/src/libds-tizen/backend/tdm/backend.c @@ -1,7 +1,7 @@ #include #include -#include "libds/log.h" +#include #include "tdm.h" diff --git a/src/libds-tizen/backend/tdm/output.c b/src/libds-tizen/backend/tdm/output.c index 10b9666..089c067 100644 --- a/src/libds-tizen/backend/tdm/output.c +++ b/src/libds-tizen/backend/tdm/output.c @@ -3,7 +3,7 @@ #include -#include "libds/log.h" +#include #include "libds-tizen/allocator/tbm.h" #include "tdm.h" diff --git a/src/libds-tizen/backend/tdm/tdm.h b/src/libds-tizen/backend/tdm/tdm.h index f19483f..a151f01 100644 --- a/src/libds-tizen/backend/tdm/tdm.h +++ b/src/libds-tizen/backend/tdm/tdm.h @@ -5,8 +5,8 @@ #include -#include "libds/interfaces/backend.h" -#include "libds/interfaces/output.h" +#include +#include enum ds_tdm_output_status { DS_TDM_OUTPUT_DISCONNECTED, diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.c b/src/libds-tizen/backend/tdm/tdm_buffer_queue.c index 7a2a1aa..3acec8f 100644 --- a/src/libds-tizen/backend/tdm/tdm_buffer_queue.c +++ b/src/libds-tizen/backend/tdm/tdm_buffer_queue.c @@ -3,7 +3,7 @@ #include #include -#include "libds/log.h" +#include #include "libds/interfaces/buffer.h" #include "tdm.h" diff --git a/src/libds-tizen/dpms.c b/src/libds-tizen/dpms.c index 315d6c0..a85834a 100644 --- a/src/libds-tizen/dpms.c +++ b/src/libds-tizen/dpms.c @@ -2,10 +2,10 @@ #include #include #include -#include "libds/log.h" -#include "libds/output.h" +#include +#include +#include #include "libds-tizen/dpms.h" -#include "tizen-dpms-server-protocol.h" #include "util.h" struct ds_tizen_dpms diff --git a/src/libds-tizen/keyrouter/keyrouter.c b/src/libds-tizen/keyrouter/keyrouter.c index 6b5b220..cba286e 100644 --- a/src/libds-tizen/keyrouter/keyrouter.c +++ b/src/libds-tizen/keyrouter/keyrouter.c @@ -6,7 +6,7 @@ #include #include -#include "libds/log.h" +#include #include "libds-tizen/keyrouter.h" #include "util.h" diff --git a/src/libds-tizen/keyrouter/keyrouter_grab.c b/src/libds-tizen/keyrouter/keyrouter_grab.c index 35c249a..5009985 100644 --- a/src/libds-tizen/keyrouter/keyrouter_grab.c +++ b/src/libds-tizen/keyrouter/keyrouter_grab.c @@ -1,7 +1,7 @@ #include #include -#include "libds/log.h" +#include #include "keyrouter.h" diff --git a/src/libds-tizen/keyrouter/meson.build b/src/libds-tizen/keyrouter/meson.build index 7b27d3b..7c9f01c 100644 --- a/src/libds-tizen/keyrouter/meson.build +++ b/src/libds-tizen/keyrouter/meson.build @@ -4,7 +4,6 @@ libds_tizen_keyrouter_files = [ ] libds_tizen_keyrouter_deps = [ - dep_libds, dep_libds_tizen, dependency('tizen-extension-server', required: true), ] diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build index 8c7673b..1ee9b99 100644 --- a/src/libds-tizen/meson.build +++ b/src/libds-tizen/meson.build @@ -4,8 +4,29 @@ libds_tizen_files = [ 'dpms.c', ] +math = meson.get_compiler('c').find_library('m') +wayland_server = dependency('wayland-server', required: true) +pixman = dependency('pixman-1', required: true) +libdrm = dependency('libdrm', required: true) +xkbcommon = dependency('xkbcommon', required: true) +rt = meson.get_compiler('c').find_library('rt') + +if wayland_server.version().version_compare('>= 1.19') + cdata.set('HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY', '1') +endif + +base_deps = [ + math, + wayland_server, + pixman, + libdrm, + xkbcommon, + rt, +] + libds_tizen_deps = [ - dep_libds, + base_deps, + dependency('libds', required: true), dependency('libdrm', required: true), dependency('libtbm', required: true), dependency('wayland-tbm-server', required: true), diff --git a/src/libds-tizen/pixel_format.c b/src/libds-tizen/pixel_format.c index 021652e..030f211 100644 --- a/src/libds-tizen/pixel_format.c +++ b/src/libds-tizen/pixel_format.c @@ -2,7 +2,7 @@ #include #include -#include "libds/log.h" +#include #include "pixel_format.h" #ifdef ARRAY_LENGTH diff --git a/src/libds-tizen/tbm_server.c b/src/libds-tizen/tbm_server.c index ecb46db..0fd25cd 100644 --- a/src/libds-tizen/tbm_server.c +++ b/src/libds-tizen/tbm_server.c @@ -4,7 +4,7 @@ #include -#include "libds/log.h" +#include #include "pixel_format.h" #include "tbm_server.h" diff --git a/src/libds-tizen/tbm_server.h b/src/libds-tizen/tbm_server.h index be56746..58e391b 100644 --- a/src/libds-tizen/tbm_server.h +++ b/src/libds-tizen/tbm_server.h @@ -4,7 +4,7 @@ #include #include #include -#include "libds/interfaces/buffer.h" +#include struct ds_tbm_server { diff --git a/src/libds-tizen/util/security.c b/src/libds-tizen/util/security.c index b592577..8a8a0ac 100644 --- a/src/libds-tizen/util/security.c +++ b/src/libds-tizen/util/security.c @@ -9,7 +9,7 @@ #include #include -#include "libds/log.h" +#include #include "util.h" #define CYNARA_BUFSIZE 128 diff --git a/src/libds/addon.c b/src/libds/addon.c deleted file mode 100644 index e1858ff..0000000 --- a/src/libds/addon.c +++ /dev/null @@ -1,60 +0,0 @@ -#include - -#include "addon.h" - -void -ds_addon_set_init(struct ds_addon_set *set) -{ - wl_list_init(&set->addons); -} - -void -ds_addon_set_finish(struct ds_addon_set *set) -{ - struct ds_addon *addon, *tmp; - - wl_list_for_each_safe(addon, tmp, &set->addons, link) { - ds_addon_finish(addon); - addon->impl->destroy(addon); - } -} - -void -ds_addon_init(struct ds_addon *addon, struct ds_addon_set *set, - const void *owner, const struct ds_addon_interface *impl) -{ - struct ds_addon *iter; - - assert(owner && impl); - - wl_list_for_each(iter, &set->addons, link) { - if (iter->owner == addon->owner && iter->impl == addon->impl) - assert(0 && "Can't have two addons of the same type with the same owner"); - } - - wl_list_insert(&set->addons, &addon->link); - - addon->owner = owner; - addon->impl = impl; -} - -void -ds_addon_finish(struct ds_addon *addon) -{ - wl_list_remove(&addon->link); - wl_list_init(&addon->link); -} - -struct ds_addon * -ds_addon_find(struct ds_addon_set *set, const void *owner, - const struct ds_addon_interface *impl) -{ - struct ds_addon *addon; - - wl_list_for_each(addon, &set->addons, link) { - if (addon->owner == owner && addon->impl == impl) - return addon; - } - - return NULL; -} diff --git a/src/libds/addon.h b/src/libds/addon.h deleted file mode 100644 index 2e7b0e1..0000000 --- a/src/libds/addon.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef DS_ADDON_H -#define DS_ADDON_H - -#include - -struct ds_addon_set { - struct wl_list addons; -}; - -struct ds_addon { - const struct ds_addon_interface *impl; - const void *owner; - struct wl_list link; -}; - -struct ds_addon_interface { - const char *name; - void (*destroy)(struct ds_addon *addon); -}; - -void -ds_addon_set_init(struct ds_addon_set *set); - -void -ds_addon_set_finish(struct ds_addon_set *set); - -void -ds_addon_init(struct ds_addon *addon, struct ds_addon_set *set, - const void *owner, const struct ds_addon_interface *impl); - -void -ds_addon_finish(struct ds_addon *addon); - -struct ds_addon * -ds_addon_find(struct ds_addon_set *set, const void *owner, - const struct ds_addon_interface *impl); - -#endif diff --git a/src/libds/allocator.c b/src/libds/allocator.c deleted file mode 100644 index c9769be..0000000 --- a/src/libds/allocator.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include - -#include - -#include "libds/log.h" -#include "libds/interfaces/allocator.h" - -WL_EXPORT void -ds_allocator_init(struct ds_allocator *alloc, - const struct ds_allocator_interface *iface, uint32_t buffer_caps) -{ - alloc->iface = iface; - alloc->buffer_caps = buffer_caps; - - wl_signal_init(&alloc->events.destroy); -} - -WL_EXPORT void -ds_allocator_destroy(struct ds_allocator *alloc) -{ - wl_signal_emit(&alloc->events.destroy, NULL); - alloc->iface->destroy(alloc); -} - -WL_EXPORT struct ds_buffer * -ds_allocator_create_buffer(struct ds_allocator *alloc, int width, int height, - uint32_t format) -{ - return alloc->iface->create_buffer(alloc, width, height, format); -} - -WL_EXPORT void -ds_allocator_add_destroy_listener(struct ds_allocator *alloc, - struct wl_listener *listener) -{ - wl_signal_add(&alloc->events.destroy, listener); -} diff --git a/src/libds/allocator/meson.build b/src/libds/allocator/meson.build deleted file mode 100644 index 173c219..0000000 --- a/src/libds/allocator/meson.build +++ /dev/null @@ -1 +0,0 @@ -libds_files += files('shm.c') diff --git a/src/libds/allocator/shm.c b/src/libds/allocator/shm.c deleted file mode 100644 index 3fad474..0000000 --- a/src/libds/allocator/shm.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#include -#include - -#include -#include - -#include "libds/allocator/shm.h" -#include "libds/interfaces/allocator.h" -#include "libds/interfaces/buffer.h" -#include "libds/log.h" -#include "util.h" - -struct ds_shm_allocator -{ - struct ds_allocator base; -}; - -struct ds_shm_buffer -{ - struct ds_buffer base; - struct ds_shm_attributes shm; - void *data; - size_t size; -}; - -static const struct ds_allocator_interface shm_allocator_iface; - -WL_EXPORT struct ds_allocator * -ds_shm_allocator_create(void) -{ - struct ds_shm_allocator *alloc; - - alloc = calloc(1, sizeof *alloc); - if (!alloc) - return NULL; - - ds_allocator_init(&alloc->base, &shm_allocator_iface, - DS_BUFFER_CAP_DATA_PTR | DS_BUFFER_CAP_SHM); - - ds_dbg("Shm allocator(%p) created", alloc); - - return &alloc->base; -} - -static struct ds_shm_allocator * -shm_allocator_from_allocator(struct ds_allocator *ds_allocator) -{ - assert(ds_allocator->iface == &shm_allocator_iface); - return (struct ds_shm_allocator *)ds_allocator; -} - -static void -shm_allocator_destroy(struct ds_allocator *ds_allocator) -{ - struct ds_shm_allocator *alloc; - - alloc = shm_allocator_from_allocator(ds_allocator); - ds_dbg("Destroy Shm allocator(%p)", alloc); - free(alloc); -} - -static const struct ds_buffer_interface shm_buffer_interface; - -static struct ds_shm_buffer * -shm_buffer_from_buffer(struct ds_buffer *buffer) -{ - assert(buffer->iface == &shm_buffer_interface); - return (struct ds_shm_buffer *)buffer; -} - -static void -shm_buffer_destroy(struct ds_buffer *ds_buffer) -{ - struct ds_shm_buffer *buffer; - - buffer = shm_buffer_from_buffer(ds_buffer); - - ds_dbg("Destroy shm buffer(%p)", buffer); - - munmap(buffer->data, buffer->size); - close(buffer->shm.fd); - free(buffer); -} - -static bool -shm_buffer_get_shm(struct ds_buffer *ds_buffer, struct ds_shm_attributes *shm) -{ - struct ds_shm_buffer *buffer; - - buffer = shm_buffer_from_buffer(ds_buffer); - memcpy(shm, &buffer->shm, sizeof *shm); - return true; -} - -static bool -shm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags, - void **data, uint32_t *format, size_t *stride) -{ - struct ds_shm_buffer *buffer; - - buffer = shm_buffer_from_buffer(ds_buffer); - *data = buffer->data; - *format = buffer->shm.format; - *stride = buffer->shm.stride; - return true; -} - -static void -shm_buffer_end_data_ptr_access(struct ds_buffer *buffer) -{ - (void) buffer; - - // This space is intentionally left blank -} - -static const struct ds_buffer_interface shm_buffer_interface = -{ - .destroy = shm_buffer_destroy, - .get_shm = shm_buffer_get_shm, - .begin_data_ptr_access = shm_buffer_begin_data_ptr_access, - .end_data_ptr_access = shm_buffer_end_data_ptr_access, -}; - -static struct ds_buffer * -shm_allocator_create_buffer(struct ds_allocator *ds_allocator, - int width, int height, uint32_t format) -{ - struct ds_shm_buffer *buffer; - int bytes_per_pixel, stride; - - buffer = calloc(1, sizeof *buffer); - if (!buffer) - return NULL; - - ds_buffer_init(&buffer->base, &shm_buffer_interface, width, height); - - // FIXME - bytes_per_pixel = 4; - stride = width * bytes_per_pixel; - buffer->size = stride * height; - buffer->shm.fd = allocate_shm_file(buffer->size); - if (buffer->shm.fd < 0) { - free(buffer); - return NULL; - } - - buffer->shm.format = format; - buffer->shm.width = width; - buffer->shm.height = height; - buffer->shm.stride = stride; - buffer->shm.offset = 0; - - buffer->data = mmap(NULL, buffer->size, PROT_READ | PROT_WRITE, MAP_SHARED, - buffer->shm.fd, 0); - if (buffer->data == MAP_FAILED) { - ds_log_errno(DS_ERR, "mmap failed"); - close(buffer->shm.fd); - free(buffer); - return NULL; - } - - ds_dbg("Shm buffer(%p) created: size(%dx%d)", buffer, width, height); - - return &buffer->base; -} - -static const struct ds_allocator_interface shm_allocator_iface = -{ - .destroy = shm_allocator_destroy, - .create_buffer = shm_allocator_create_buffer, -}; diff --git a/src/libds/backend.c b/src/libds/backend.c deleted file mode 100644 index dee97ca..0000000 --- a/src/libds/backend.c +++ /dev/null @@ -1,67 +0,0 @@ -#include - -#include - -#include "libds/interfaces/backend.h" - -WL_EXPORT bool -ds_backend_start(struct ds_backend *backend) -{ - if (backend->iface->start) - return backend->iface->start(backend); - - backend->started = true; - - return true; -} - -WL_EXPORT void -ds_backend_destroy(struct ds_backend *backend) -{ - if (!backend) - return; - - if (backend->iface && backend->iface->destroy) - backend->iface->destroy(backend); - else - free(backend); -} - -WL_EXPORT void -ds_backend_add_destroy_listener(struct ds_backend *backend, - struct wl_listener *listener) -{ - wl_signal_add(&backend->events.destroy, listener); -} - -WL_EXPORT void -ds_backend_add_new_output_listener(struct ds_backend *backend, - struct wl_listener *listener) -{ - wl_signal_add(&backend->events.new_output, listener); -} - -WL_EXPORT void -ds_backend_add_new_input_listener(struct ds_backend *backend, - struct wl_listener *listener) -{ - wl_signal_add(&backend->events.new_input, listener); -} - -void -ds_backend_init(struct ds_backend *backend, - struct wl_display *display, - const struct ds_backend_interface *iface) -{ - backend->iface = iface; - backend->display = display; - wl_signal_init(&backend->events.destroy); - wl_signal_init(&backend->events.new_output); - wl_signal_init(&backend->events.new_input); -} - -void -ds_backend_finish(struct ds_backend *backend) -{ - wl_signal_emit(&backend->events.destroy, backend); -} diff --git a/src/libds/backend/libinput/backend.c b/src/libds/backend/libinput/backend.c deleted file mode 100644 index b7e1bc4..0000000 --- a/src/libds/backend/libinput/backend.c +++ /dev/null @@ -1,229 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "libds/log.h" - -#include "backend.h" - -static const struct ds_backend_interface libinput_backend_interface; -static void libinput_backend_handle_display_destroy( - struct wl_listener *listener, void *data); - -WL_EXPORT struct ds_backend * -ds_libinput_backend_create(struct wl_display *display) -{ - struct ds_libinput_backend *libinput_backend; - - libinput_backend = calloc(1, sizeof *libinput_backend); - if (!libinput_backend) { - ds_log_errno(DS_ERR, "Could not allocate memory"); - return NULL; - } - - ds_backend_init(&libinput_backend->base, display, &libinput_backend_interface); - - libinput_backend->display = display; - wl_list_init(&libinput_backend->devices); - - libinput_backend->display_destroy.notify = - libinput_backend_handle_display_destroy; - wl_display_add_destroy_listener(display, - &libinput_backend->display_destroy); - - ds_inf("Libinput backend(%p) created", - libinput_backend); - - return &libinput_backend->base; -} - -WL_EXPORT struct ds_libinput_backend * -libinput_backend_from_backend(struct ds_backend *backend) -{ - assert(backend->iface == &libinput_backend_interface); - return (struct ds_libinput_backend *)backend; -} - -void -destroy_libinput_input_device(struct ds_libinput_input_device *dev) -{ - ds_input_device_destroy(&dev->base); - wl_list_remove(&dev->link); -} - -static void -libinput_backend_destroy(struct ds_libinput_backend *backend) -{ - struct ds_libinput_input_device *dev, *tmp_dev; - - wl_list_for_each_safe(dev, tmp_dev, &backend->devices, link) - destroy_libinput_input_device(dev); - - ds_backend_finish(&backend->base); - wl_list_remove(&backend->display_destroy.link); - wl_event_source_remove(backend->server_event_source); - udev_unref(backend->udev); - libinput_unref(backend->libinput_context); - - free(backend); -} - -static int -libinput_open_restricted(const char *path, int flags, void *_backend) -{ - int fd = -1; - struct stat s; - - fd = open(path, flags | O_CLOEXEC); - - if (fd < 0 || (fstat(fd, &s) == -1)) { - ds_log(DS_ERR, "Could not open device"); - close(fd); - return -1; - } - return fd; -} - -static void -libinput_close_restricted(int fd, void *_backend) -{ - if (fd >= 0) close(fd); -} - -static const struct libinput_interface libinput_impl = { - .open_restricted = libinput_open_restricted, - .close_restricted = libinput_close_restricted -}; - -static int -handle_libinput_readable(int fd, uint32_t mask, void *_backend) -{ - struct ds_libinput_backend *backend = _backend; - struct libinput_event *event; - int ret; - - ret = libinput_dispatch(backend->libinput_context); - if (ret != 0) { - ds_log(DS_ERR, "Failed to dispatch libinput: %s", strerror(-ret)); - wl_display_terminate(backend->display); - return 0; - } - - while ((event = libinput_get_event(backend->libinput_context))) { - handle_libinput_event(backend, event); - libinput_event_destroy(event); - } - return 0; -} - -static void -log_libinput(struct libinput *libinput_context, - enum libinput_log_priority priority, const char *fmt, va_list args) -{ - char buf[1024] = {0,}; - - vsnprintf(buf, 1024, fmt, args); - switch (priority) { - case LIBINPUT_LOG_PRIORITY_DEBUG: - ds_log(DS_DBG,"%s", buf); - break; - case LIBINPUT_LOG_PRIORITY_INFO: - ds_log(DS_INF, "%s", buf); - break; - case LIBINPUT_LOG_PRIORITY_ERROR: - ds_log(DS_ERR, "%s", buf); - break; - default: - break; - } -} - -static bool -libinput_backend_iface_start(struct ds_backend *ds_backend) -{ - struct ds_libinput_backend *backend; - struct wl_event_loop *event_loop; - int libinput_fd; - - backend = libinput_backend_from_backend(ds_backend); - ds_log(DS_DBG, "Starting libinput backend"); - - backend->udev = udev_new(); - backend->libinput_context = libinput_udev_create_context(&libinput_impl, - backend, backend->udev); - if (!backend->libinput_context) { - ds_log(DS_ERR, "Failed to create libinput context"); - return false; - } - - if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) { - ds_log(DS_ERR, "Failed to assign libinput seat"); - return false; - } - - libinput_log_set_handler(backend->libinput_context, log_libinput); - libinput_log_set_priority(backend->libinput_context, - LIBINPUT_LOG_PRIORITY_DEBUG); - - libinput_fd = libinput_get_fd(backend->libinput_context); - if (wl_list_empty(&backend->devices)) { - handle_libinput_readable(libinput_fd, WL_EVENT_READABLE, backend); - if (wl_list_empty(&backend->devices)) { - ds_log(DS_ERR, "libinput initialization failed, no input devices"); - return false; - } - } - - event_loop = wl_display_get_event_loop(backend->display); - if (backend->server_event_source) { - wl_event_source_remove(backend->server_event_source); - } - backend->server_event_source = - wl_event_loop_add_fd(event_loop, libinput_fd, WL_EVENT_READABLE, - handle_libinput_readable, backend); - if (!backend->server_event_source) { - ds_log(DS_ERR, "Failed to create input event on event loop"); - return false; - } - ds_log(DS_DBG, "libinput successfully initialized"); - - return true; -} - -static void -libinput_backend_iface_destroy(struct ds_backend *backend) -{ - struct ds_libinput_backend *libinput_backend; - - if (!backend) - return; - - libinput_backend = libinput_backend_from_backend(backend); - libinput_backend_destroy(libinput_backend); -} - -static const struct ds_backend_interface libinput_backend_interface = -{ - .start = libinput_backend_iface_start, - .destroy = libinput_backend_iface_destroy, - .get_drm_fd = NULL, -}; - -static void -libinput_backend_handle_display_destroy(struct wl_listener *listener, - void *data) -{ - struct ds_libinput_backend *libinput_backend; - - libinput_backend = - wl_container_of(listener, libinput_backend, display_destroy); - libinput_backend_destroy(libinput_backend); -} - -uint32_t usec_to_msec(uint64_t usec) { - return (uint32_t)(usec / 1000); -} \ No newline at end of file diff --git a/src/libds/backend/libinput/backend.h b/src/libds/backend/libinput/backend.h deleted file mode 100644 index 4d1c0ce..0000000 --- a/src/libds/backend/libinput/backend.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef DS_BACKEND_LIBINPUT_H -#define DS_BACKEND_LIBINPUT_H - -#include -#include - -#include "libds/interfaces/backend.h" -#include "libds/interfaces/input_device.h" -#include "libds/interfaces/pointer.h" -#include "libds/interfaces/keyboard.h" -#include "libds/interfaces/touch.h" - -struct ds_libinput_backend -{ - struct ds_backend base; - - struct wl_display *display; - struct wl_listener display_destroy; - - struct udev *udev; - struct libinput *libinput_context; - struct wl_list devices; // ds_libinput_input_device::link - - struct wl_event_source *server_event_source; -}; - -struct ds_libinput_input_device -{ - struct ds_input_device base; - - struct ds_libinput_backend *backend; - struct libinput_device *handle; - - struct wl_list link; //ds_libinput_backend.devices -}; - -uint32_t usec_to_msec(uint64_t usec); - -struct ds_libinput_backend * - libinput_backend_from_backend(struct ds_backend *backend); - -void handle_libinput_event(struct ds_libinput_backend *state, - struct libinput_event *event); - -void destroy_libinput_input_device(struct ds_libinput_input_device *dev); - -//keyboard -void handle_keyboard_key(struct libinput_event *event, - struct ds_keyboard *kbd); - -//pointer -void handle_pointer_motion(struct libinput_event *event, - struct ds_pointer *pointer); -void handle_pointer_motion_abs(struct libinput_event *event, - struct ds_pointer *pointer); -void handle_pointer_button(struct libinput_event *event, - struct ds_pointer *pointer); -void handle_pointer_axis(struct libinput_event *event, - struct ds_pointer *pointer); - -//touch -void handle_touch_down(struct libinput_event *event, - struct ds_touch *touch); -void handle_touch_up(struct libinput_event *event, - struct ds_touch *touch); -void handle_touch_motion(struct libinput_event *event, - struct ds_touch *touch); -void handle_touch_cancel(struct libinput_event *event, - struct ds_touch *touch); -void handle_touch_frame(struct libinput_event *event, - struct ds_touch *touch); - -#endif diff --git a/src/libds/backend/libinput/input.c b/src/libds/backend/libinput/input.c deleted file mode 100644 index b6e943f..0000000 --- a/src/libds/backend/libinput/input.c +++ /dev/null @@ -1,212 +0,0 @@ -#include - -#include "libds/log.h" -#include "backend.h" - -static const struct ds_input_device_interface input_device_iface; - -static bool -ds_input_device_is_libinput(struct ds_input_device *ds_dev) -{ - return ds_dev->iface == &input_device_iface; -} - -static struct ds_libinput_input_device * -get_libinput_input_device_from_input_device(struct ds_input_device *ds_dev) -{ - assert(ds_input_device_is_libinput(ds_dev)); - return (struct ds_libinput_input_device *)ds_dev; -} - -static void -input_device_iface_destroy(struct ds_input_device *ds_dev) -{ - struct ds_libinput_input_device *dev; - - dev = get_libinput_input_device_from_input_device(ds_dev); - - libinput_device_unref(dev->handle); - - free(dev); -} - -static const struct ds_input_device_interface input_device_iface = -{ - .destroy = input_device_iface_destroy, -}; - -static struct ds_keyboard * -create_ds_keyboard() -{ - struct ds_keyboard *kbd; - kbd = calloc(1, sizeof *kbd); - if (!kbd) { - ds_err("Could not allocate memory"); - return NULL; - } - ds_keyboard_init(kbd, NULL); - - return kbd; -} - -static struct ds_pointer * -create_ds_pointer() -{ - struct ds_pointer *pointer; - pointer = calloc(1, sizeof *pointer); - if (!pointer) { - ds_err("Could not allocate memory"); - return NULL; - } - ds_pointer_init(pointer, NULL); - - return pointer; -} - -static struct ds_touch * -create_ds_touch() -{ - struct ds_touch *touch; - touch = calloc(1, sizeof *touch); - if (!touch) { - ds_err("Could not allocate memory"); - return NULL; - } - ds_touch_init(touch, NULL); - - return touch; -} - -static void -handle_device_added(struct ds_libinput_backend *backend, - struct libinput_device *libinput_dev) -{ - int vendor, product; - const char *name; - struct ds_libinput_input_device *dev; - - vendor = libinput_device_get_id_vendor(libinput_dev); - product = libinput_device_get_id_product(libinput_dev); - name = libinput_device_get_name(libinput_dev); - ds_log(DS_DBG, "Adding %s [%d:%d]", name, vendor, product); - - dev = calloc(1, sizeof(struct ds_libinput_input_device)); - if (dev == NULL) { - ds_log(DS_ERR, "failed to allocate ds_libinput_input_device"); - return; - } - - dev->handle = libinput_dev; - dev->backend = backend; - libinput_device_ref(libinput_dev); - libinput_device_set_user_data(libinput_dev, dev); - - wl_list_insert(&backend->devices, &dev->link); - - if (libinput_device_has_capability( - libinput_dev, LIBINPUT_DEVICE_CAP_KEYBOARD)) { - ds_input_device_init(&dev->base, DS_INPUT_DEVICE_KEYBOARD, - &input_device_iface, name, vendor, product); - dev->base.keyboard = create_ds_keyboard(); - - wl_signal_emit(&backend->base.events.new_input, - &dev->base); - } - - if (libinput_device_has_capability( - libinput_dev, LIBINPUT_DEVICE_CAP_POINTER)) { - ds_input_device_init(&dev->base, DS_INPUT_DEVICE_POINTER, - &input_device_iface, name, vendor, product); - dev->base.pointer = create_ds_pointer(); - - wl_signal_emit(&backend->base.events.new_input, - &dev->base); - } - - if (libinput_device_has_capability( - libinput_dev, LIBINPUT_DEVICE_CAP_TOUCH)) { - ds_input_device_init(&dev->base, DS_INPUT_DEVICE_TOUCH, - &input_device_iface, name, vendor, product); - dev->base.touch = create_ds_touch(); - - wl_signal_emit(&backend->base.events.new_input, - &dev->base); - } -} - -static void -handle_device_removed(struct ds_libinput_backend *backend, - struct libinput_device *libinput_dev) -{ - int vendor, product; - const char *name; - struct ds_libinput_input_device *dev; - - vendor = libinput_device_get_id_vendor(libinput_dev); - product = libinput_device_get_id_product(libinput_dev); - name = libinput_device_get_name(libinput_dev); - ds_log(DS_DBG, "Removing %s [%d:%d]", name, vendor, product); - - dev = libinput_device_get_user_data(libinput_dev); - if (dev == NULL) { - ds_log(DS_ERR, "libinput_device has no ds_libinput_input_device"); - return; - } - - destroy_libinput_input_device(dev); -} - -void -handle_libinput_event(struct ds_libinput_backend *backend, - struct libinput_event *event) -{ - struct libinput_device *libinput_dev; - struct ds_libinput_input_device *dev; - enum libinput_event_type event_type; - - libinput_dev = libinput_event_get_device(event); - event_type = libinput_event_get_type(event); - dev = libinput_device_get_user_data(libinput_dev); - - switch (event_type) { - case LIBINPUT_EVENT_DEVICE_ADDED: - handle_device_added(backend, libinput_dev); - break; - case LIBINPUT_EVENT_DEVICE_REMOVED: - handle_device_removed(backend, libinput_dev); - break; - case LIBINPUT_EVENT_KEYBOARD_KEY: - handle_keyboard_key(event, dev->base.keyboard); - break; - case LIBINPUT_EVENT_POINTER_MOTION: - handle_pointer_motion(event, dev->base.pointer); - break; - case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: - handle_pointer_motion_abs(event, dev->base.pointer); - break; - case LIBINPUT_EVENT_POINTER_BUTTON: - handle_pointer_button(event, dev->base.pointer); - break; - case LIBINPUT_EVENT_POINTER_AXIS: - handle_pointer_axis(event, dev->base.pointer); - break; - case LIBINPUT_EVENT_TOUCH_DOWN: - handle_touch_down(event, dev->base.touch); - break; - case LIBINPUT_EVENT_TOUCH_UP: - handle_touch_up(event, dev->base.touch); - break; - case LIBINPUT_EVENT_TOUCH_MOTION: - handle_touch_motion(event, dev->base.touch); - break; - case LIBINPUT_EVENT_TOUCH_CANCEL: - handle_touch_cancel(event, dev->base.touch); - break; - case LIBINPUT_EVENT_TOUCH_FRAME: - handle_touch_frame(event, dev->base.touch); - break; - default: - ds_log(DS_DBG, "Unknown libinput event %d", event_type); - break; - } -} diff --git a/src/libds/backend/libinput/keyboard.c b/src/libds/backend/libinput/keyboard.c deleted file mode 100644 index 9376f11..0000000 --- a/src/libds/backend/libinput/keyboard.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "libds/log.h" -#include "backend.h" - -void -handle_keyboard_key(struct libinput_event *event, - struct ds_keyboard *kbd) -{ - struct libinput_event_keyboard *kbevent; - uint32_t key; - enum libinput_key_state li_state; - enum wl_keyboard_key_state state = WL_KEYBOARD_KEY_STATE_PRESSED; - struct ds_event_keyboard_key ds_event = {0}; - - kbevent = libinput_event_get_keyboard_event(event); - - key = libinput_event_keyboard_get_key(kbevent); - li_state = libinput_event_keyboard_get_key_state(kbevent); - if (li_state == LIBINPUT_KEY_STATE_PRESSED) { - state = WL_KEYBOARD_KEY_STATE_PRESSED; - } - else { - state = WL_KEYBOARD_KEY_STATE_RELEASED; - } - - ds_log(DS_DBG, "Keyboard(%p) key event key:%d, state:%s", kbd, key, - (state == WL_KEYBOARD_KEY_STATE_PRESSED) ? "PRESSED":"RELEASED"); - - ds_event.keycode = key; - ds_event.state = state; - ds_event.time_msec = usec_to_msec( - libinput_event_keyboard_get_time_usec(kbevent)); - ds_event.update_state = false; - - ds_keyboard_notify_key(kbd, &ds_event); -} diff --git a/src/libds/backend/libinput/meson.build b/src/libds/backend/libinput/meson.build deleted file mode 100644 index be85808..0000000 --- a/src/libds/backend/libinput/meson.build +++ /dev/null @@ -1,15 +0,0 @@ -libds_files += files( - 'backend.c', - 'input.c', - 'keyboard.c', - 'pointer.c', - 'touch.c', -) - -libinput = dependency('libinput', required: true) -libudev = dependency('libudev', required: true) - -libds_deps += [ - libinput, - libudev, -] diff --git a/src/libds/backend/libinput/pointer.c b/src/libds/backend/libinput/pointer.c deleted file mode 100644 index efdbaa7..0000000 --- a/src/libds/backend/libinput/pointer.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "libds/log.h" -#include "backend.h" - -void -handle_pointer_motion(struct libinput_event *event, - struct ds_pointer *pointer) -{ - struct libinput_event_pointer *pevent; - double delta_x, delta_y; - struct ds_event_pointer_motion ds_event = { 0 }; - - pevent = libinput_event_get_pointer_event(event); - - delta_x = libinput_event_pointer_get_dx(pevent); - delta_y = libinput_event_pointer_get_dy(pevent); - - ds_log(DS_DBG, "pointer motion event delta_x:%f, delta_y:%f", delta_x, delta_y); - - ds_event.device = NULL; - ds_event.time_msec = usec_to_msec( - libinput_event_pointer_get_time_usec(pevent)); - ds_event.delta_x = delta_x; - ds_event.delta_y = delta_y; - - wl_signal_emit(&pointer->events.motion, &ds_event); -} - -void -handle_pointer_motion_abs(struct libinput_event *event, - struct ds_pointer *pointer) -{ - struct libinput_event_pointer *pevent; - double x, y; - struct ds_event_pointer_motion_absolute ds_event = { 0 }; - - pevent = libinput_event_get_pointer_event(event); - - x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1); - y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1); - - ds_log(DS_DBG, "Pointer(%p) motion abs event x:%f, y:%f", pointer, x, y); - - ds_event.device = NULL; - ds_event.time_msec = usec_to_msec( - libinput_event_pointer_get_time_usec(pevent)); - ds_event.x = x; - ds_event.y = y; - - wl_signal_emit(&pointer->events.motion_absolute, &ds_event); -} -void -handle_pointer_button(struct libinput_event *event, - struct ds_pointer *pointer) -{ - struct libinput_event_pointer *pevent; - uint32_t button; - enum libinput_button_state li_state = LIBINPUT_BUTTON_STATE_PRESSED; - enum ds_button_state state = DS_BUTTON_PRESSED; - struct ds_event_pointer_button ds_event = { 0 }; - - pevent = libinput_event_get_pointer_event(event); - - button = libinput_event_pointer_get_button(pevent); - button = ((button & 0x00F) + 1); - if (button == 3) button = 2; - else if (button == 2) button = 3; - - li_state = libinput_event_pointer_get_button_state(pevent); - if (li_state == LIBINPUT_BUTTON_STATE_PRESSED) { - state = DS_BUTTON_PRESSED; - } - else { - state = DS_BUTTON_RELEASED; - } - ds_log(DS_DBG, "Pointer(%p) button event button:%d state:%s", - pointer, button, - (state == DS_BUTTON_PRESSED) ? "PRESSED" : "RELEASED"); - - ds_event.device = NULL; - ds_event.time_msec = usec_to_msec( - libinput_event_pointer_get_time_usec(pevent)); - ds_event.button = button; - ds_event.state = state; - - wl_signal_emit(&pointer->events.button, &ds_event); -} - -void -handle_pointer_axis(struct libinput_event *event, - struct ds_pointer *pointer) -{ - ds_log(DS_DBG, "pointer(%p) axis event", pointer); - /* TODO: wl_signal_emit() */ -} diff --git a/src/libds/backend/libinput/touch.c b/src/libds/backend/libinput/touch.c deleted file mode 100644 index fd94c0b..0000000 --- a/src/libds/backend/libinput/touch.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "libds/log.h" -#include "backend.h" - -void -handle_touch_down(struct libinput_event *event, - struct ds_touch *touch) -{ - struct libinput_event_touch *tevent; - uint32_t touch_id; - double x, y; - struct ds_event_touch_down ds_event = { 0 }; - - tevent = libinput_event_get_touch_event(event); - - touch_id = libinput_event_touch_get_seat_slot(tevent); - x = libinput_event_touch_get_x_transformed(tevent, 1); - y = libinput_event_touch_get_y_transformed(tevent, 1); - - ds_log(DS_DBG, "touch down event id:%d, x:%f, y:%f", touch_id, x, y); - - ds_event.device = NULL; - ds_event.time_msec = usec_to_msec( - libinput_event_touch_get_time_usec(tevent)); - ds_event.id = touch_id; - ds_event.x = x; - ds_event.y = y; - - wl_signal_emit(&touch->events.down, &ds_event); -} - -void -handle_touch_up(struct libinput_event *event, - struct ds_touch *touch) -{ - struct libinput_event_touch *tevent; - uint32_t touch_id; - struct ds_event_touch_up ds_event = { 0 }; - - tevent = libinput_event_get_touch_event(event); - - touch_id = libinput_event_touch_get_seat_slot(tevent); - - ds_log(DS_DBG, "touch up event id:%d", touch_id); - - ds_event.device = NULL; - ds_event.time_msec = usec_to_msec( - libinput_event_touch_get_time_usec(tevent)); - ds_event.id = touch_id; - - wl_signal_emit(&touch->events.up, &ds_event); -} - -void -handle_touch_motion(struct libinput_event *event, - struct ds_touch *touch) -{ - struct libinput_event_touch *tevent; - uint32_t touch_id; - double x, y; - struct ds_event_touch_motion ds_event = { 0 }; - - tevent = libinput_event_get_touch_event(event); - - touch_id = libinput_event_touch_get_seat_slot(tevent); - x = libinput_event_touch_get_x_transformed(tevent, 1); - y = libinput_event_touch_get_y_transformed(tevent, 1); - - ds_log(DS_DBG, "touch motion event id:%d, x:%f, y:%f", touch_id, x, y); - - ds_event.device = NULL; - ds_event.time_msec = usec_to_msec( - libinput_event_touch_get_time_usec(tevent)); - ds_event.id = touch_id; - ds_event.x = x; - ds_event.y = y; - - wl_signal_emit(&touch->events.motion, &ds_event); -} - -void -handle_touch_cancel(struct libinput_event *event, - struct ds_touch *touch) -{ - struct libinput_event_touch *tevent; - uint32_t touch_id; - - tevent = libinput_event_get_touch_event(event); - - touch_id = libinput_event_touch_get_seat_slot(tevent); - - ds_log(DS_DBG, "touch cancel event id:%d", touch_id); - /* TODO: wl_signal_emit() */ -} - -void -handle_touch_frame(struct libinput_event *event, - struct ds_touch *touch) -{ - ds_log(DS_DBG, "touch frame event"); - /* TODO: wl_signal_emit() */ -} diff --git a/src/libds/backend/meson.build b/src/libds/backend/meson.build deleted file mode 100644 index 97e8087..0000000 --- a/src/libds/backend/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -subdir('wayland') -subdir('libinput') diff --git a/src/libds/backend/wayland/backend.c b/src/libds/backend/wayland/backend.c deleted file mode 100644 index fd663f4..0000000 --- a/src/libds/backend/wayland/backend.c +++ /dev/null @@ -1,315 +0,0 @@ -#include -#include -#include - -#include -#include - -#include "libds/log.h" -#include "libds/output.h" -#include "xdg-shell-client-protocol.h" - -#include "backend.h" - -static const struct ds_backend_interface wl_backend_interface; -static void wl_backend_handle_display_destroy(struct wl_listener *listener, - void *data); -static bool wl_backend_server_init(struct ds_wl_backend *wl_backend, - struct ds_wl_backend_server *server, const char *name); -static void wl_backend_server_finish(struct ds_wl_backend_server *server); -static int wl_backend_handle_dispatch_events(int fd, uint32_t mask, - void *data); - -WL_EXPORT struct ds_backend * -ds_wl_backend_create(struct wl_display *display, const char *server_name) -{ - struct ds_wl_backend *wl_backend; - struct wl_event_loop *loop; - int fd; - - wl_backend = calloc(1, sizeof *wl_backend); - if (!wl_backend) { - ds_log_errno(DS_ERR, "Could not allocate memory"); - return NULL; - } - - ds_backend_init(&wl_backend->base, display, &wl_backend_interface); - - wl_backend->display = display; - wl_list_init(&wl_backend->buffers); - wl_list_init(&wl_backend->outputs); - wl_list_init(&wl_backend->seats); - - if (!wl_backend_server_init(wl_backend, &wl_backend->server, server_name)) { - ds_err("Failed to initialize Wayland Server"); - goto err_server; - } - - loop = wl_display_get_event_loop(wl_backend->display); - fd = wl_display_get_fd(wl_backend->server.display); - - wl_backend->server_event_source = - wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, - wl_backend_handle_dispatch_events, wl_backend); - if (!wl_backend->server_event_source) { - ds_err("Failed to create event source"); - goto err_src; - } - wl_event_source_check(wl_backend->server_event_source); - - wl_backend->display_destroy.notify = wl_backend_handle_display_destroy; - wl_display_add_destroy_listener(display, &wl_backend->display_destroy); - - ds_inf("Wayland backend(%p) created: server name \"%s\"", - wl_backend, server_name); - - return &wl_backend->base; - -err_src: - wl_backend_server_finish(&wl_backend->server); -err_server: - ds_backend_finish(&wl_backend->base); - free(wl_backend); - - return NULL; -} - -struct ds_wl_backend * -wl_backend_from_backend(struct ds_backend *backend) -{ - assert(backend->iface == &wl_backend_interface); - return (struct ds_wl_backend *)backend; -} - -static bool -wl_backend_iface_start(struct ds_backend *ds_backend) -{ - struct ds_wl_backend *backend; - - backend = wl_backend_from_backend(ds_backend); - - ds_inf("Starting wayland backend"); - - for (size_t i = 0; i < backend->requested_outputs; i++) - create_wl_output(backend); - - return true; -} - -static void -wl_backend_destroy(struct ds_wl_backend *backend) -{ - struct ds_wl_output *output, *tmp_output; - struct ds_wl_buffer *buffer, *tmp_buffer; - struct ds_wl_seat *seat, *tmp_seat; - - ds_dbg("Destroy wayland backend(%p)", backend); - - wl_list_for_each_safe(output, tmp_output, &backend->outputs, link) - ds_output_destroy(&output->base); - - wl_list_for_each_safe(buffer, tmp_buffer, &backend->buffers, link) - destroy_wl_buffer(buffer); - - wl_list_for_each_safe(seat, tmp_seat, &backend->seats, link) - destroy_wl_seat(seat); - - ds_backend_finish(&backend->base); - - wl_list_remove(&backend->display_destroy.link); - - wl_event_source_remove(backend->server_event_source); - - wl_backend_server_finish(&backend->server); - - free(backend); -} - -static void -wl_backend_iface_destroy(struct ds_backend *backend) -{ - struct ds_wl_backend *wl_backend; - - if (!backend) - return; - - wl_backend = wl_backend_from_backend(backend); - - wl_backend_destroy(wl_backend); -} - -static const struct ds_backend_interface wl_backend_interface = -{ - .start = wl_backend_iface_start, - .destroy = wl_backend_iface_destroy, - .get_drm_fd = NULL, -}; - -static void -wl_backend_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_wl_backend *wl_backend; - - wl_backend = wl_container_of(listener, wl_backend, display_destroy); - wl_backend_destroy(wl_backend); -} - -static void -shm_handle_format(void *data, struct wl_shm *shm, uint32_t shm_format) -{ -} - -static const struct wl_shm_listener shm_listener = -{ - .format = shm_handle_format, -}; - -static void -xdg_wm_base_handle_ping(void *data, struct xdg_wm_base *base, uint32_t serial) -{ - xdg_wm_base_pong(base, serial); -} - -static const struct xdg_wm_base_listener xdg_wm_base_listener = -{ - .ping = xdg_wm_base_handle_ping, -}; - -static void -registry_handle_global(void *data, struct wl_registry *registry, - uint32_t name, const char *iface, uint32_t version) -{ - struct ds_wl_backend_server *server = data; - struct ds_wl_seat *seat; - - ds_log(DS_DBG, "Wayland global: %s v%d", iface, version); - - if (strcmp(iface, wl_compositor_interface.name) == 0) { - server->compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 4); - } - else if (strcmp(iface, xdg_wm_base_interface.name) == 0) { - server->xdg_wm_base = wl_registry_bind(registry, name, - &xdg_wm_base_interface, 1); - xdg_wm_base_add_listener(server->xdg_wm_base, - &xdg_wm_base_listener, NULL); - } - else if (strcmp(iface, wl_shm_interface.name) == 0) { - server->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); - wl_shm_add_listener(server->shm, &shm_listener, server); - } - else if (strcmp(iface, wl_seat_interface.name) == 0) { - seat = create_wl_seat(server->backend, name, version); - if (!seat) { - ds_err("Could not create ds_wl_seat"); - return; - } - - wl_list_insert(&server->backend->seats, &seat->link); - } -} - -static void -registry_handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) -{ - // TODO -} - -static const struct wl_registry_listener registry_listener = -{ - .global = registry_handle_global, - .global_remove = registry_handle_global_remove, -}; - -static bool -wl_backend_server_init(struct ds_wl_backend *wl_backend, struct ds_wl_backend_server *server, const char *name) -{ - server->backend = wl_backend; - - server->display = wl_display_connect(name); - if (!server->display) { - ds_log_errno(DS_ERR, "Could not connect to display: name \"%s\"", name); - return false; - } - - server->registry = wl_display_get_registry(server->display); - if (!server->registry) { - ds_log_errno(DS_ERR, "Could not get wl_registry"); - goto err_reg; - } - - wl_registry_add_listener(server->registry, ®istry_listener, server); - - wl_display_roundtrip(server->display); - - if (!server->compositor) { - ds_err("Wayland Server does not support wl_compositor"); - goto err_bind; - } - - if (!server->xdg_wm_base) { - ds_err("Wayland Server does not support xdg_wm_base"); - goto err_bind; - } - - return true; - -err_bind: - if (server->compositor) - wl_compositor_destroy(server->compositor); - - if (server->xdg_wm_base) - xdg_wm_base_destroy(server->xdg_wm_base); - - wl_registry_destroy(server->registry); -err_reg: - wl_display_disconnect(server->display); - - return false; -} - -static void -wl_backend_server_finish(struct ds_wl_backend_server *server) -{ - xdg_wm_base_destroy(server->xdg_wm_base); - wl_compositor_destroy(server->compositor); - wl_registry_destroy(server->registry); - wl_display_disconnect(server->display); -} - -static int -wl_backend_handle_dispatch_events(int fd, uint32_t mask, void *data) -{ - struct ds_wl_backend *wl_backend = data; - struct ds_wl_backend_server *server = &wl_backend->server; - int count = 0; - - if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) { - if (mask & WL_EVENT_ERROR) { - ds_err("Failed to read from Wayland Server"); - } - wl_display_terminate(wl_backend->display); - return 0; - } - - count = 0; - if (mask & WL_EVENT_READABLE) - count = wl_display_dispatch(server->display); - - if (mask & WL_EVENT_WRITABLE) - wl_display_flush(server->display); - - if (mask == 0) { - count = wl_display_dispatch_pending(server->display); - wl_display_flush(server->display); - } - - if (count < 0) { - ds_err("Failed to dispatch Wayland Server"); - wl_display_terminate(wl_backend->display); - return 0; - } - - return count; -} diff --git a/src/libds/backend/wayland/backend.h b/src/libds/backend/wayland/backend.h deleted file mode 100644 index 12c8a27..0000000 --- a/src/libds/backend/wayland/backend.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef DS_BACKEND_WAYLAND_H -#define DS_BACKEND_WAYLAND_H - -#include "libds/interfaces/backend.h" -#include "libds/interfaces/output.h" -#include "libds/interfaces/input_device.h" -#include "libds/interfaces/pointer.h" -#include "libds/interfaces/keyboard.h" -#include "libds/interfaces/touch.h" - -struct ds_wl_backend_server -{ - struct ds_wl_backend *backend; - struct wl_display *display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct xdg_wm_base *xdg_wm_base; - struct wl_event_source *event_source; - struct wl_shm *shm; -}; - -struct ds_wl_backend -{ - struct ds_backend base; - - struct wl_display *display; - struct wl_listener display_destroy; - - struct wl_list outputs; // ds_wl_output.link - struct wl_list buffers; // ds_wl_buffer.link - struct wl_list seats; // ds_wl_seat.link - - struct wl_event_source *server_event_source; - struct ds_wl_backend_server server; - - size_t requested_outputs; -}; - -struct ds_wl_buffer -{ - struct ds_buffer *buffer; - struct wl_buffer *wl_buffer; - struct wl_list link; // ds_wl_backend.buffers - struct wl_listener buffer_destroy; - - bool released; -}; - -struct ds_wl_output -{ - struct ds_output base; - - struct ds_wl_backend *backend; - - struct wl_surface *surface; - struct xdg_surface *xdg_surface; - struct xdg_toplevel *xdg_toplevel; - struct wl_callback *frame_callback; - - struct wl_list link; - - struct { - struct ds_wl_pointer *pointer; - struct wl_surface *surface; - int32_t hotspot_x, hotspot_y; - uint32_t enter_serial; - } cursor; -}; - -struct ds_wl_seat -{ - struct ds_wl_backend *backend; - struct ds_wl_output *output; - - struct wl_seat *wl_seat; - char *name; - - struct ds_input_device *pointer_dev; - struct ds_input_device *keyboard_dev; - struct ds_input_device *touch_dev; - - struct wl_callback *initial_info_cb; - - struct wl_list link; // ds_wl_backend.seats - - enum wl_seat_capability caps; - - int version; - uint32_t enter_serial; - - bool initialized; -}; - -struct ds_wl_input_device -{ - struct ds_input_device base; - - struct ds_wl_backend *backend; - struct ds_wl_seat *seat; -}; - -struct ds_wl_pointer -{ - struct ds_pointer base; - - struct ds_wl_input_device *input_device; - struct wl_pointer *wl_pointer; -}; - -struct ds_wl_keyboard -{ - struct ds_keyboard base; - - struct wl_keyboard *wl_keyboard; -}; - -struct ds_wl_touch -{ - struct ds_touch base; - - struct wl_touch *wl_touch; -}; - -struct ds_wl_backend * -wl_backend_from_backend(struct ds_backend *backend); - -struct ds_wl_output *create_wl_output(struct ds_wl_backend *backend); - -void -destroy_wl_buffer(struct ds_wl_buffer *buffer); - -struct ds_wl_seat *create_wl_seat(struct ds_wl_backend *backend, uint32_t id, - uint32_t available_version); - -void destroy_wl_seat(struct ds_wl_seat *seat); - -void output_enter_pointer(struct ds_wl_output *output, - struct ds_wl_pointer *pointer, uint32_t serial); - -void output_leave_pointer(struct ds_wl_output *output); - -#endif diff --git a/src/libds/backend/wayland/meson.build b/src/libds/backend/wayland/meson.build deleted file mode 100644 index 88574a4..0000000 --- a/src/libds/backend/wayland/meson.build +++ /dev/null @@ -1,27 +0,0 @@ -libds_files += files( - 'backend.c', - 'output.c', - 'seat.c', -) - -protocols = { - 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', -} - -protocols_code = {} -protocols_client_header = {} - -foreach name, path : protocols - client_header = custom_target( - name.underscorify() + '_client_h', - input: path, - output: '@BASENAME@-client-protocol.h', - command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'], - build_by_default: false, - ) - libds_files += client_header -endforeach - -libds_deps += [ - dependency('wayland-client', required: true), -] diff --git a/src/libds/backend/wayland/output.c b/src/libds/backend/wayland/output.c deleted file mode 100644 index 7728abf..0000000 --- a/src/libds/backend/wayland/output.c +++ /dev/null @@ -1,376 +0,0 @@ -#include -#include - -#include - -#include "libds/log.h" -#include "libds/output.h" -#include "xdg-shell-client-protocol.h" - -#include "output.h" -#include "backend.h" - -const struct ds_output_interface wl_output_iface; -static const struct xdg_surface_listener wl_output_xdg_surface_listener; -static const struct xdg_toplevel_listener wl_output_xdg_toplevel_listener; - -static void output_update_cursor(struct ds_wl_output *output); -static bool output_set_custom_mode(struct ds_output *ds_output, - int32_t width, int32_t height, int32_t refresh); - -struct ds_output * -ds_wl_backend_create_output(struct ds_backend *ds_backend) -{ - struct ds_wl_backend *backend; - struct ds_wl_output *output; - - backend = wl_backend_from_backend(ds_backend); - - if (!ds_backend->started) { - backend->requested_outputs++; - return NULL; - } - - output = create_wl_output(backend); - if (!output) { - ds_err("Could not create ds_wl_output"); - return NULL; - } - - return &output->base; -} - -struct ds_wl_output * -create_wl_output(struct ds_wl_backend *backend) -{ - struct ds_wl_output *output; - - output = calloc(1, sizeof *output); - if (!output) { - ds_log_errno(DS_ERR, "Could not allocate ds_wl_output"); - return NULL; - } - - ds_output_init(&output->base, &backend->base, &wl_output_iface, - backend->display); - - output->backend = backend; - - output->surface = wl_compositor_create_surface(backend->server.compositor); - if (!output->surface) { - ds_log_errno(DS_ERR, "Could not create output surface"); - goto err; - } - wl_surface_set_user_data(output->surface, output); - - output->xdg_surface = - xdg_wm_base_get_xdg_surface(backend->server.xdg_wm_base, - output->surface); - if (!output->xdg_surface) { - ds_log_errno(DS_ERR, "Could not get xdg_surface"); - goto err; - } - xdg_surface_add_listener(output->xdg_surface, - &wl_output_xdg_surface_listener, output); - - output->xdg_toplevel = - xdg_surface_get_toplevel(output->xdg_surface); - if (!output->xdg_toplevel) { - ds_log_errno(DS_ERR, "Could not get xdg_toplevel"); - goto err; - } - xdg_toplevel_add_listener(output->xdg_toplevel, - &wl_output_xdg_toplevel_listener, output); - - xdg_toplevel_set_app_id(output->xdg_toplevel, "libds"); - - wl_surface_commit(output->surface); - - wl_display_roundtrip(backend->server.display); - - wl_list_insert(&backend->outputs, &output->link); - - wl_signal_emit(&backend->base.events.new_output, &output->base); - - ds_dbg("Wayland output(%p) created", output); - - return output; - -err: - ds_output_destroy(&output->base); - - return NULL; -} - -void -destroy_wl_buffer(struct ds_wl_buffer *buffer) -{ - if (buffer == NULL) - return; - - wl_list_remove(&buffer->buffer_destroy.link); - wl_list_remove(&buffer->link); - wl_buffer_destroy(buffer->wl_buffer); - free(buffer); -} - -void -output_enter_pointer(struct ds_wl_output *output, - struct ds_wl_pointer *pointer, uint32_t serial) -{ - output->cursor.pointer = pointer; - output->cursor.enter_serial = serial; - - output_update_cursor(output); -} - -void -output_leave_pointer(struct ds_wl_output *output) -{ - output->cursor.pointer = NULL; - output->cursor.enter_serial = 0; -} - -static void output_update_cursor(struct ds_wl_output *output) -{ - struct ds_wl_pointer *pointer = output->cursor.pointer; - - wl_pointer_set_cursor(pointer->wl_pointer, output->cursor.enter_serial, - output->cursor.surface, output->cursor.hotspot_x, - output->cursor.hotspot_y); -} - -static struct ds_wl_output * -wl_output_from_output(struct ds_output *ds_output) -{ - assert(ds_output->iface == &wl_output_iface); - return (struct ds_wl_output *)ds_output; -} - -static void -wl_output_iface_destroy(struct ds_output *ds_output) -{ - struct ds_wl_output *output; - - output = wl_output_from_output(ds_output); - - ds_dbg("Destroy wayland output(%p)", output); - - wl_list_remove(&output->link); - - if (output->frame_callback) - wl_callback_destroy(output->frame_callback); - - if (output->xdg_toplevel) - xdg_toplevel_destroy(output->xdg_toplevel); - - if (output->xdg_surface) - xdg_surface_destroy(output->xdg_surface); - - if (output->surface) - wl_surface_destroy(output->surface); - - wl_display_flush(output->backend->server.display); - - free(output); -} - -static struct wl_buffer * -import_shm(struct ds_wl_backend *backend, struct ds_shm_attributes *shm) -{ - enum wl_shm_format wl_shm_format = WL_SHM_FORMAT_XRGB8888; - struct wl_shm_pool *pool; - struct wl_buffer *wl_buffer; - uint32_t size; - - size = shm->stride * shm->height; - pool = wl_shm_create_pool(backend->server.shm, shm->fd, size); - if (!pool) - return NULL; - - wl_buffer = wl_shm_pool_create_buffer(pool, shm->offset, - shm->width, shm->height, shm->stride, wl_shm_format); - wl_shm_pool_destroy(pool); - - return wl_buffer; -} - -static void -buffer_handle_release(void *data, struct wl_buffer *wl_buffer) -{ - struct ds_wl_buffer *buffer = data; - - ds_dbg("Wayland output: Buffer(%p) released.", buffer->buffer); - buffer->released = true; - ds_buffer_unlock(buffer->buffer); -} - -static const struct wl_buffer_listener buffer_listener = -{ - .release = buffer_handle_release, -}; - -static void -buffer_handle_buffer_destroy(struct wl_listener *listener, void *data) -{ - struct ds_wl_buffer *buffer; - - buffer = wl_container_of(listener, buffer, buffer_destroy); - destroy_wl_buffer(buffer); -} - -static struct ds_wl_buffer * -create_wl_buffer(struct ds_wl_backend *backend, struct ds_buffer *ds_buffer) -{ - struct ds_shm_attributes shm; - struct ds_wl_buffer *buffer; - struct wl_buffer *wl_buffer; - - if (ds_buffer_get_shm(ds_buffer, &shm)) { - wl_buffer = import_shm(backend, &shm); - } - - buffer = calloc(1, sizeof *buffer); - if (!buffer) { - wl_buffer_destroy(wl_buffer); - return NULL; - } - - buffer->wl_buffer = wl_buffer; - buffer->buffer = ds_buffer_lock(ds_buffer); - wl_list_insert(&backend->buffers, &buffer->link); - - wl_buffer_add_listener(wl_buffer, &buffer_listener, buffer); - - buffer->buffer_destroy.notify = buffer_handle_buffer_destroy; - ds_buffer_add_destroy_listener(ds_buffer, &buffer->buffer_destroy); - - return buffer; -} - -static struct ds_wl_buffer * -get_or_create_wl_buffer(struct ds_wl_backend *backend, struct ds_buffer *ds_buffer) -{ - struct ds_wl_buffer *buffer; - - wl_list_for_each(buffer, &backend->buffers, link) { - if (buffer->buffer == ds_buffer && buffer->released) { - buffer->released = false; - ds_buffer_lock(buffer->buffer); - return buffer; - } - } - - return create_wl_buffer(backend, ds_buffer); -} - -static void -surface_frame_callback(void *data, struct wl_callback *cb, uint32_t time) -{ - struct ds_wl_output *output = data; - - wl_callback_destroy(cb); - output->frame_callback = NULL; - - wl_signal_emit(&output->base.events.frame, &output->base); -} - -static const struct wl_callback_listener frame_listener = -{ - .done = surface_frame_callback -}; - -static bool -wl_output_iface_commit(struct ds_output *ds_output) -{ - struct ds_wl_output *output; - struct ds_wl_buffer *buffer; - struct ds_buffer *ds_buffer; - - output = wl_output_from_output(ds_output); - - if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) { - if (!output_set_custom_mode(ds_output, - ds_output->pending.custom_mode.width, - ds_output->pending.custom_mode.height, - ds_output->pending.custom_mode.refresh)) - return false; - } - - ds_buffer = ds_output->pending.buffer; - buffer = get_or_create_wl_buffer(output->backend, ds_buffer); - if (!buffer) - return NULL; - - if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) { - - if (output->frame_callback != NULL) { - ds_err("Skipping buffer swap"); - return false; - } - - output->frame_callback = wl_surface_frame(output->surface); - wl_callback_add_listener(output->frame_callback, &frame_listener, - output); - wl_surface_attach(output->surface, buffer->wl_buffer, 0, 0); - wl_surface_damage_buffer(output->surface, 0, 0, INT32_MAX, INT32_MAX); - wl_surface_commit(output->surface); - } - - wl_display_flush(output->backend->server.display); - - return true; -} - -const struct ds_output_interface wl_output_iface = -{ - .destroy = wl_output_iface_destroy, - .commit = wl_output_iface_commit, -}; - -static void -wl_output_xdg_surface_handle_configure(void *data, - struct xdg_surface *xdg_surface, uint32_t serial) -{ - xdg_surface_ack_configure(xdg_surface, serial); -} - -static const struct xdg_surface_listener wl_output_xdg_surface_listener = -{ - .configure = wl_output_xdg_surface_handle_configure, -}; - -static void -wl_output_xdg_toplevel_handle_configure(void *data, - struct xdg_toplevel *xdg_toplevel, - int32_t width, int32_t height, struct wl_array *states) -{ - // TODO - // struct ds_wl_output *output = data; - - if (width == 0 || height == 0) - return; -} - -static void -wl_output_xdg_toplevel_handle_close(void *data, - struct xdg_toplevel *xdg_toplevel) -{ - struct ds_wl_output *output = data; - - ds_output_destroy(&output->base); -} - -static const struct xdg_toplevel_listener wl_output_xdg_toplevel_listener = -{ - .configure = wl_output_xdg_toplevel_handle_configure, - .close = wl_output_xdg_toplevel_handle_close, -}; - -static bool output_set_custom_mode(struct ds_output *ds_output, - int32_t width, int32_t height, int32_t refresh) -{ - ds_output_update_custom_mode(ds_output, width, height, 0); - - return true; -} diff --git a/src/libds/backend/wayland/seat.c b/src/libds/backend/wayland/seat.c deleted file mode 100644 index bec12ad..0000000 --- a/src/libds/backend/wayland/seat.c +++ /dev/null @@ -1,719 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libds/log.h" -#include "libds/pointer.h" -#include "libds/touch.h" - -#include "util.h" -#include "backend.h" - -#ifdef MIN -# undef MIN -#endif - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -static const struct wl_seat_listener seat_listener; -static const struct wl_callback_listener seat_callback_listener; - -static void seat_update_capabilities(struct ds_wl_seat *seat, - enum wl_seat_capability caps); -static struct ds_input_device * -create_wl_input_device(struct ds_wl_seat *seat, - enum ds_input_device_type type); -static struct ds_pointer *create_wl_pointer(struct ds_wl_seat *seat); -static struct ds_keyboard *create_wl_keyboard(struct ds_wl_seat *seat); -static struct ds_touch *create_wl_touch(struct ds_wl_seat *seat); - -struct ds_wl_seat * -create_wl_seat(struct ds_wl_backend *backend, uint32_t id, - uint32_t available_version) -{ - struct ds_wl_seat *seat; - - seat = calloc(1, sizeof *seat); - if (!seat) - return NULL; - - seat->backend = backend; - seat->version = MIN(available_version, 5); - seat->wl_seat = wl_registry_bind(backend->server.registry, id, - &wl_seat_interface, seat->version); - - wl_seat_add_listener(seat->wl_seat, &seat_listener, seat); - - seat->initial_info_cb = wl_display_sync(backend->server.display); - wl_callback_add_listener(seat->initial_info_cb, &seat_callback_listener, - seat); - - ds_dbg("wl_backend: Seat(%p) created", seat); - - return seat; -} - -void -destroy_wl_seat(struct ds_wl_seat *seat) -{ - ds_dbg("wl_backend: Seat(%p) destroy", seat); - - if (seat->pointer_dev) - ds_input_device_destroy(seat->pointer_dev); - - if (seat->keyboard_dev) - ds_input_device_destroy(seat->keyboard_dev); - - if (seat->touch_dev) - ds_input_device_destroy(seat->touch_dev); - - if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION) - wl_seat_release(seat->wl_seat); - else - wl_seat_destroy(seat->wl_seat); - - wl_list_remove(&seat->link); - - free(seat->name); - free(seat); -} - -static void -seat_handle_capabilities(void *data, struct wl_seat *wl_seat, - enum wl_seat_capability caps) -{ - struct ds_wl_seat *seat = data; - - if (seat->initialized) - seat_update_capabilities(seat, caps); - else - seat->caps = caps; - - ds_dbg("wl_backend: Seat(%p) capabilities(%d)", seat, caps); -} - -static void -seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) -{ - struct ds_wl_seat *seat = data; - - if (seat->name) - free(seat->name); - - ds_dbg("wl_backend: Seat(%p) name(%s)", seat, name); - - seat->name = strdup(name); -} - -static const struct wl_seat_listener seat_listener = { - .capabilities = seat_handle_capabilities, - .name = seat_handle_name, -}; - -static void -seat_add_callback_handle_done(void *data, struct wl_callback *callback, - uint32_t callback_data) -{ - struct ds_wl_seat *seat = data; - - wl_callback_destroy(seat->initial_info_cb); - seat->initial_info_cb = NULL; - seat->initialized = true; - - seat_update_capabilities(seat, seat->caps); -} - -static const struct wl_callback_listener seat_callback_listener = { - .done = seat_add_callback_handle_done, -}; - -static void -seat_update_capabilities(struct ds_wl_seat *seat, enum wl_seat_capability caps) -{ - if ((caps & WL_SEAT_CAPABILITY_POINTER) && seat->pointer_dev == NULL) { - ds_dbg("wl_backend: Seat(%p) offered pointer", seat); - - seat->pointer_dev = create_wl_input_device(seat, - DS_INPUT_DEVICE_POINTER); - seat->pointer_dev->pointer = create_wl_pointer(seat); - - wl_signal_emit(&seat->backend->base.events.new_input, - seat->pointer_dev); - } - else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && - seat->pointer_dev != NULL) { - ds_dbg("wl_backend: Seat(%p) dropped pointer", seat); - ds_input_device_destroy(seat->pointer_dev); - seat->pointer_dev = NULL; - } - - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && seat->keyboard_dev == NULL) { - ds_dbg("wl_backend: Seat(%p) offered keyboard", seat); - - seat->keyboard_dev = create_wl_input_device(seat, - DS_INPUT_DEVICE_KEYBOARD); - seat->keyboard_dev->keyboard = create_wl_keyboard(seat); - - wl_signal_emit(&seat->backend->base.events.new_input, - seat->keyboard_dev); - } - else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && - seat->keyboard_dev != NULL) { - ds_dbg("wl_backend: Seat(%p) dropped keyboard", seat); - ds_input_device_destroy(seat->keyboard_dev); - seat->keyboard_dev = NULL; - } - - if ((caps & WL_SEAT_CAPABILITY_TOUCH) && seat->touch_dev == NULL) { - ds_dbg("wl_backend: Seat(%p) offered touch", seat); - seat->touch_dev = create_wl_input_device(seat, - DS_INPUT_DEVICE_TOUCH); - seat->touch_dev->touch = create_wl_touch(seat); - wl_signal_emit(&seat->backend->base.events.new_input, - seat->touch_dev); - } - else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && - seat->touch_dev != NULL) { - ds_dbg("wl_backend: Seat(%p) dropped touch", seat); - ds_input_device_destroy(seat->touch_dev); - seat->touch_dev = NULL; - } -} - -static const struct ds_input_device_interface input_device_iface; - -static bool -ds_input_device_is_wl(struct ds_input_device *ds_dev) -{ - return ds_dev->iface == &input_device_iface; -} - -static struct ds_wl_input_device * -get_wl_input_device_from_input_device(struct ds_input_device *ds_dev) -{ - assert(ds_input_device_is_wl(ds_dev)); - return (struct ds_wl_input_device *)ds_dev; -} - -static void -input_device_iface_destroy(struct ds_input_device *ds_dev) -{ - struct ds_wl_input_device *dev; - - dev = get_wl_input_device_from_input_device(ds_dev); - - free(dev); -} - -static const struct ds_input_device_interface input_device_iface = -{ - .destroy = input_device_iface_destroy, -}; - -static struct ds_input_device * -create_wl_input_device(struct ds_wl_seat *seat, - enum ds_input_device_type type) -{ - struct ds_wl_input_device *dev; - unsigned int vendor = 0, product = 0; - size_t name_size; - char *name; - - dev = calloc(1, sizeof *dev); - if (!dev) - return NULL; - - dev->backend = seat->backend; - dev->seat = seat; - - name_size = 8 + strlen(seat->name) + 1; - name = alloca(name_size); - (void) snprintf(name, name_size, "wayland-%s", seat->name); - - ds_input_device_init(&dev->base, type, &input_device_iface, name, vendor, - product); - - return &dev->base; -} - -static const struct ds_pointer_interface pointer_iface; - -static struct ds_wl_pointer * -get_wl_pointer_from_pointer(struct ds_pointer *ds_pointer) -{ - assert(ds_pointer->iface == &pointer_iface); - return (struct ds_wl_pointer *)ds_pointer; -} - -static void -pointer_iface_destroy(struct ds_pointer *ds_pointer) -{ - struct ds_wl_pointer *pointer; - - pointer = get_wl_pointer_from_pointer(ds_pointer); - - wl_pointer_release(pointer->wl_pointer); - - free(pointer); -} - -static const struct ds_pointer_interface pointer_iface = { - .destroy = pointer_iface_destroy, -}; - -static void -pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy) -{ - struct ds_wl_seat *seat = data; - struct ds_wl_pointer *pointer; - - if (!surface) - return; - - ds_dbg("Enter pointer"); - - seat->output = wl_surface_get_user_data(surface); - seat->enter_serial = serial; - - pointer = get_wl_pointer_from_pointer(seat->pointer_dev->pointer); - output_enter_pointer(seat->output, pointer, seat->enter_serial); -} - -static void -pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) -{ - struct ds_wl_seat *seat = data; - struct ds_wl_output *output; - - if (!seat->output) - return; - - output = wl_surface_get_user_data(surface); - if (seat->output != output) - return; - - ds_dbg("Leave pointer"); - - output_leave_pointer(seat->output); - - seat->output = NULL; - seat->enter_serial = 0; -} - -static void -pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t sx, wl_fixed_t sy) -{ - struct ds_wl_seat *seat = data; - struct ds_output *ds_output; - - if (!seat->output) - return; - - ds_output = &seat->output->base; - - // FIXME take size size of a output into account - struct ds_event_pointer_motion_absolute event = { - .device = seat->pointer_dev, - .time_msec = time, - .x = wl_fixed_to_double(sx) / ds_output->width, - .y = wl_fixed_to_double(sy) / ds_output->height, - }; - - wl_signal_emit(&seat->pointer_dev->pointer->events.motion_absolute, - &event); -} - -static void -pointer_handle_button(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, uint32_t time, uint32_t button, uint32_t state) -{ - struct ds_wl_seat *seat = data; - - if (!seat->output) - return; - - struct ds_event_pointer_button event = { - .device = seat->pointer_dev, - .button = button, - .state = state, - .time_msec = time, - }; - - wl_signal_emit(&seat->pointer_dev->pointer->events.button, &event); -} - -static void -pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) -{ - // TODO -} - -static void -pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) -{ - struct ds_wl_seat *seat = data; - - if (!seat->output) - return; - - wl_signal_emit(&seat->pointer_dev->pointer->events.frame, - seat->pointer_dev); -} - -static void -pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer, - uint32_t axis_source) -{ - // TODO -} - -static void -pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer, - uint32_t time, uint32_t axis) -{ - // TODO -} - -static void -pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer, - uint32_t axis, int32_t discrete) -{ - // TODO -} - -static const struct wl_pointer_listener wl_pointer_listener = { - .enter = pointer_handle_enter, - .leave = pointer_handle_leave, - .motion = pointer_handle_motion, - .button = pointer_handle_button, - .axis = pointer_handle_axis, - .frame = pointer_handle_frame, - .axis_source = pointer_handle_axis_source, - .axis_stop = pointer_handle_axis_stop, - .axis_discrete = pointer_handle_axis_discrete, -}; - -static struct ds_pointer * -create_wl_pointer(struct ds_wl_seat *seat) -{ - struct ds_wl_pointer *pointer; - - pointer = calloc(1, sizeof *pointer); - if (!pointer) { - ds_err("Could not allocate memory"); - return NULL; - } - - ds_pointer_init(&pointer->base, &pointer_iface); - - pointer->wl_pointer = wl_seat_get_pointer(seat->wl_seat); - wl_pointer_add_listener(pointer->wl_pointer, &wl_pointer_listener, seat); - - return &pointer->base; -} - -static const struct ds_keyboard_interface keyboard_iface; - -static struct ds_wl_keyboard * -get_wl_keyboard_from_keyboard(struct ds_keyboard *ds_keyboard) -{ - assert(ds_keyboard->iface == &keyboard_iface); - return (struct ds_wl_keyboard *)ds_keyboard; -} - -static void -keyboard_iface_destroy(struct ds_keyboard *ds_keyboard) -{ - struct ds_wl_keyboard *keyboard; - - keyboard = get_wl_keyboard_from_keyboard(ds_keyboard); - - wl_keyboard_release(keyboard->wl_keyboard); - - free(keyboard); -} - -static const struct ds_keyboard_interface keyboard_iface = { - .destroy = keyboard_iface_destroy, -}; - -static void -keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, - uint32_t format, int fd, uint32_t size) -{ - struct ds_wl_seat *seat = data; - struct xkb_context *context; - struct xkb_keymap *keymap; - char *map_str; - - ds_dbg("wl_keyboard: keymap"); - - if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { - map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - if (map_str == MAP_FAILED) { - ds_log_errno(DS_ERR, "mmap failed"); - goto end; - } - - context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - keymap = xkb_keymap_new_from_string(context, map_str, - XKB_KEYMAP_FORMAT_TEXT_V1, 0); - munmap(map_str, size); - - if (!keymap) { - ds_err("Failed to compile keymap"); - goto end; - } - - ds_keyboard_set_keymap(seat->keyboard_dev->keyboard, keymap); - - xkb_keymap_unref(keymap); - xkb_context_unref(context); - } - - // TODO More case? - -end: - close(fd); -} - -static void -keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface, struct wl_array *keys) -{ - struct ds_wl_seat *seat = data; - uint32_t *keycode_ptr; - uint32_t time; - - ds_dbg("wl_keyboard: enter"); - - time = get_current_time_msec(); - - wl_array_for_each(keycode_ptr, keys) { - struct ds_event_keyboard_key event = { - .keycode = *keycode_ptr, - .state = WL_KEYBOARD_KEY_STATE_PRESSED, - .time_msec = time, - .update_state = false, - }; - - ds_keyboard_notify_key(seat->keyboard_dev->keyboard, &event); - } -} - -static void -keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface) -{ - struct ds_wl_seat *seat = data; - struct ds_keyboard *keyboard = seat->keyboard_dev->keyboard; - uint32_t *pressed; - uint32_t time, keycode; - size_t num_keycodes; - - ds_dbg("wl_keyboard: leave"); - - time = get_current_time_msec(); - - num_keycodes = keyboard->num_keycodes; - pressed = alloca(num_keycodes + 1); - memcpy(pressed, keyboard->keycodes, num_keycodes * sizeof(uint32_t)); - - for (size_t i = 0; i < num_keycodes; i++) { - keycode = pressed[i]; - - struct ds_event_keyboard_key event = { - .keycode = keycode, - .state = WL_KEYBOARD_KEY_STATE_RELEASED, - .time_msec = time, - .update_state = false, - }; - - ds_keyboard_notify_key(keyboard, &event); - } -} - -static void -keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - struct ds_wl_seat *seat = data; - - ds_dbg("wl_keyboard: key"); - - struct ds_event_keyboard_key event = { - .keycode = key, - .state = state, - .time_msec = time, - .update_state = false, - }; - - ds_keyboard_notify_key(seat->keyboard_dev->keyboard, &event); -} - -static void -keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial_in, uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) -{ - struct ds_wl_seat *seat = data; - - ds_dbg("wl_keyboard: modifiers"); - - ds_keyboard_notify_modifiers(seat->keyboard_dev->keyboard, - mods_depressed, mods_latched, mods_locked, group); -} - -static void -keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, - int32_t rate, int32_t delay) -{ - ds_dbg("wl_keyboard: repeat_info"); - - // This space is intentionally left blank -} - -static const struct wl_keyboard_listener wl_keyboard_listener = { - .keymap = keyboard_handle_keymap, - .enter = keyboard_handle_enter, - .leave = keyboard_handle_leave, - .key = keyboard_handle_key, - .modifiers = keyboard_handle_modifiers, - .repeat_info = keyboard_handle_repeat_info, -}; - -static struct ds_keyboard * -create_wl_keyboard(struct ds_wl_seat *seat) -{ - struct ds_wl_keyboard *keyboard; - - keyboard = calloc(1, sizeof *keyboard); - if (!keyboard) - return NULL; - - ds_keyboard_init(&keyboard->base, &keyboard_iface); - - keyboard->wl_keyboard = wl_seat_get_keyboard(seat->wl_seat); - wl_keyboard_add_listener(keyboard->wl_keyboard, - &wl_keyboard_listener, seat); - - return &keyboard->base; -} - -static const struct ds_touch_interface touch_iface; - -static struct ds_wl_touch * -get_wl_touch_from_touch(struct ds_touch *ds_touch) -{ - assert(ds_touch->iface == &touch_iface); - return (struct ds_wl_touch *)ds_touch; -} - -static void -touch_iface_destroy(struct ds_touch *ds_touch) -{ - struct ds_wl_touch *touch; - - touch = get_wl_touch_from_touch(ds_touch); - - wl_touch_release(touch->wl_touch); - - free(touch); -} - -static const struct ds_touch_interface touch_iface = { - .destroy = touch_iface_destroy, -}; - -static void -touch_handle_down(void *data, struct wl_touch *wl_touch, - uint32_t serial, uint32_t time, - struct wl_surface *surface, int32_t id, - wl_fixed_t fixed_x, wl_fixed_t fixed_y) -{ - struct ds_wl_seat *seat = data; - - ds_dbg("wl_touch: down"); - - struct ds_event_touch_down event = { - .device = seat->touch_dev, - .id = id, - .x = fixed_x, - .y = fixed_y, - }; - - wl_signal_emit(&seat->touch_dev->touch->events.down, &event); -} - -static void -touch_handle_up(void *data, struct wl_touch *wl_touch, - uint32_t serial, uint32_t time, int32_t id) -{ - struct ds_wl_seat *seat = data; - - ds_dbg("wl_touch: up"); - - struct ds_event_touch_up event = { - .device = seat->touch_dev, - .id = id, - }; - - wl_signal_emit(&seat->touch_dev->touch->events.up, &event); -} - -static void -touch_handle_motion(void *data, struct wl_touch *wl_touch, - uint32_t time, int32_t id, - wl_fixed_t fixed_x, wl_fixed_t fixed_y) -{ - ds_dbg("wl_touch: motion"); -} - -static void -touch_handle_frame(void *data, struct wl_touch *wl_touch) -{ - ds_dbg("wl_touch: frame"); -} - -static void -touch_handle_cancel(void *data, struct wl_touch *wl_touch) -{ - ds_dbg("wl_touch: cancel"); -} - -static const struct wl_touch_listener wl_touch_listener = { - .down = touch_handle_down, - .up = touch_handle_up, - .motion = touch_handle_motion, - .frame = touch_handle_frame, - .cancel = touch_handle_cancel, -}; - -static struct ds_touch * -create_wl_touch(struct ds_wl_seat *seat) -{ - struct ds_wl_touch *touch; - - touch = calloc(1, sizeof *touch); - if (!touch) { - ds_err("Could not allocate memory"); - return NULL; - } - - ds_touch_init(&touch->base, &touch_iface); - - touch->wl_touch = wl_seat_get_touch(seat->wl_seat); - wl_touch_add_listener(touch->wl_touch, &wl_touch_listener, seat); - - return &touch->base; -} diff --git a/src/libds/buffer.c b/src/libds/buffer.c deleted file mode 100644 index 60b9925..0000000 --- a/src/libds/buffer.c +++ /dev/null @@ -1,203 +0,0 @@ -#include -#include - -#include "libds/log.h" -#include "libds/interfaces/buffer.h" - -#include "buffer.h" -#include "client_buffer.h" - -static struct wl_array buffer_resource_interfaces = {0}; - -static void buffer_consider_destroy(struct ds_buffer *buffer); -static bool ds_resource_is_buffer(struct wl_resource *resource); -static const struct ds_buffer_resource_interface * -get_buffer_resource_iface(struct wl_resource *resource); - -WL_EXPORT void -ds_buffer_init(struct ds_buffer *buffer, - const struct ds_buffer_interface *iface, int width, int height) -{ - buffer->iface = iface; - buffer->width = width; - buffer->height = height; - - wl_signal_init(&buffer->events.destroy); - wl_signal_init(&buffer->events.release); -} - -WL_EXPORT struct ds_buffer * -ds_buffer_from_resource(struct wl_resource *resource) -{ - struct ds_buffer *buffer; - const struct ds_buffer_resource_interface *iface; - - assert(resource && ds_resource_is_buffer(resource)); - - if (wl_shm_buffer_get(resource) != NULL) { - struct ds_shm_client_buffer *shm_client_buffer = - ds_shm_client_buffer_get_or_create(resource); - if (!shm_client_buffer) { - ds_err("Failed to create shm client buffer"); - return NULL; - } - - buffer = ds_buffer_lock(&shm_client_buffer->base); - } - else { - iface = get_buffer_resource_iface(resource); - if (!iface) { - ds_err("Unknown buffer type"); - return NULL; - } - - buffer = iface->from_resource(resource); - if (!buffer) { - ds_err("Failed to create %s buffer", iface->name); - return NULL; - } - - buffer = ds_buffer_lock(buffer); - } - - return buffer; -} - -WL_EXPORT void -ds_buffer_drop(struct ds_buffer *buffer) -{ - assert(!buffer->dropped); - buffer->dropped = true; - ds_dbg("Buffer(%p) dropped: n_locks(%zu)", buffer, buffer->n_locks); - buffer_consider_destroy(buffer); -} - -WL_EXPORT struct ds_buffer * -ds_buffer_lock(struct ds_buffer *buffer) -{ - buffer->n_locks++; - ds_dbg("Buffer(%p) n_locks(%zu)", buffer, buffer->n_locks); - return buffer; -} - -WL_EXPORT void -ds_buffer_unlock(struct ds_buffer *buffer) -{ - assert(buffer->n_locks > 0); - buffer->n_locks--; - ds_dbg("Buffer(%p) n_locks(%zu)", buffer, buffer->n_locks); - - if (buffer->n_locks == 0) - wl_signal_emit(&buffer->events.release, NULL); - - buffer_consider_destroy(buffer); -} - -WL_EXPORT bool -ds_buffer_begin_data_ptr_access(struct ds_buffer *buffer, uint32_t flags, - void **data, uint32_t *format, size_t *stride) -{ - assert(!buffer->accessing_data_ptr); - if (!buffer->iface->begin_data_ptr_access) - return false; - if (!buffer->iface->begin_data_ptr_access(buffer, - flags, data, format, stride)) - return false; - buffer->accessing_data_ptr = true; - return true; -} - -WL_EXPORT void -ds_buffer_end_data_ptr_access(struct ds_buffer *buffer) -{ - assert(buffer->accessing_data_ptr); - buffer->iface->end_data_ptr_access(buffer); - buffer->accessing_data_ptr = false; -} - -WL_EXPORT void -ds_buffer_add_destroy_listener(struct ds_buffer *buffer, - struct wl_listener *listener) -{ - wl_signal_add(&buffer->events.destroy, listener); -} - -void -ds_buffer_add_release_listener(struct ds_buffer *buffer, - struct wl_listener *listener) -{ - wl_signal_add(&buffer->events.release, listener); -} - -WL_EXPORT bool -ds_buffer_get_shm(struct ds_buffer *buffer, struct ds_shm_attributes *attribs) -{ - if (!buffer->iface->get_shm) - return false; - - return buffer->iface->get_shm(buffer, attribs); -} - -WL_EXPORT void -ds_buffer_get_size(struct ds_buffer *buffer, int *out_width, int *out_height) -{ - if (out_width) - *out_width = buffer->width; - if (out_height) - *out_height = buffer->height; -} - -WL_EXPORT void -ds_buffer_register_resource_interface( - const struct ds_buffer_resource_interface *iface) -{ - const struct ds_buffer_resource_interface **iface_ptr; - - assert(iface); - assert(iface->is_instance); - assert(iface->from_resource); - - wl_array_for_each(iface_ptr, &buffer_resource_interfaces) { - if (*iface_ptr == iface) { - ds_dbg("ds_buffer_resource_interface %s has already " - "been registered", iface->name); - return; - } - } - - iface_ptr = wl_array_add(&buffer_resource_interfaces, sizeof(iface)); - *iface_ptr = iface; -} - -static void -buffer_consider_destroy(struct ds_buffer *buffer) -{ - if (!buffer->dropped || buffer->n_locks > 0) - return; - - assert(!buffer->accessing_data_ptr); - - wl_signal_emit(&buffer->events.destroy, NULL); - buffer->iface->destroy(buffer); -} - -static bool -ds_resource_is_buffer(struct wl_resource *resource) -{ - return strcmp(wl_resource_get_class(resource), - wl_buffer_interface.name) == 0; -} - -static const struct ds_buffer_resource_interface * -get_buffer_resource_iface(struct wl_resource *resource) -{ - struct ds_buffer_resource_interface **iface_ptr; - - wl_array_for_each(iface_ptr, &buffer_resource_interfaces) { - if ((*iface_ptr)->is_instance(resource)) { - return *iface_ptr; - } - } - - return NULL; -} diff --git a/src/libds/buffer.h b/src/libds/buffer.h deleted file mode 100644 index 08b4784..0000000 --- a/src/libds/buffer.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DS_BUFFER_H -#define DS_BUFFER_H - -#include - -#include "libds/buffer.h" - -#endif diff --git a/src/libds/client_buffer.h b/src/libds/client_buffer.h deleted file mode 100644 index a2aef6a..0000000 --- a/src/libds/client_buffer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef DS_CLIENT_BUFFER_H -#define DS_CLIENT_BUFFER_H - -#include - -#include "libds/buffer.h" -#include "libds/interfaces/buffer.h" - -#include "util.h" - -struct ds_shm_client_buffer -{ - struct ds_buffer base; - - uint32_t format; - size_t stride; - - struct wl_resource *resource; - struct wl_shm_buffer *shm_buffer; - - struct { - struct wl_listener buffer_release; - struct wl_listener resource_destroy; - } listener; -}; - -struct ds_shm_client_buffer * -ds_shm_client_buffer_get_or_create(struct wl_resource *resource); - -#endif diff --git a/src/libds/client_buffer/shm_client_buffer.c b/src/libds/client_buffer/shm_client_buffer.c deleted file mode 100644 index 6d52fb9..0000000 --- a/src/libds/client_buffer/shm_client_buffer.c +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include - -#include - -#include "libds/log.h" - -#include "pixel_format.h" -#include "buffer.h" -#include "client_buffer.h" - -static void -shm_client_buffer_resource_handle_destroy(struct wl_listener *listener, - void *data); -static struct ds_shm_client_buffer * -shm_client_buffer_create(struct wl_resource *resource); - -struct ds_shm_client_buffer * -ds_shm_client_buffer_get_or_create(struct wl_resource *resource) -{ - struct ds_shm_client_buffer *buffer; - struct wl_listener *resource_destroy_listener; - - resource_destroy_listener = wl_resource_get_destroy_listener(resource, - shm_client_buffer_resource_handle_destroy); - if (resource_destroy_listener) { - buffer = wl_container_of(resource_destroy_listener, - buffer, listener.resource_destroy); - return buffer; - } - - return shm_client_buffer_create(resource); -} - -static void -shm_client_buffer_resource_handle_destroy(struct wl_listener *listener, - void *data) -{ - struct ds_shm_client_buffer *buffer; - - buffer = wl_container_of(listener, buffer, listener.resource_destroy); - buffer->resource = NULL; - buffer->shm_buffer = NULL; - wl_list_remove(&buffer->listener.resource_destroy.link); - wl_list_init(&buffer->listener.resource_destroy.link); - - ds_buffer_drop(&buffer->base); -} - -static const struct ds_buffer_interface shm_client_buffer_iface; - -static struct ds_shm_client_buffer * -shm_client_buffer_from_buffer(struct ds_buffer *buffer) -{ - assert(buffer->iface == &shm_client_buffer_iface); - return (struct ds_shm_client_buffer *)buffer; -} - -static void -shm_client_buffer_destroy(struct ds_buffer *ds_buffer) -{ - struct ds_shm_client_buffer *buffer; - - buffer = shm_client_buffer_from_buffer(ds_buffer); - - ds_dbg("Destroy shm client buffer(%p)", buffer); - - wl_list_remove(&buffer->listener.resource_destroy.link); - wl_list_remove(&buffer->listener.buffer_release.link); - free(buffer); -} - -static bool -shm_client_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, - enum ds_buffer_data_ptr_access_flag flags, void **data, - uint32_t *format, size_t *stride) -{ - struct ds_shm_client_buffer *buffer; - - buffer = shm_client_buffer_from_buffer(ds_buffer); - *format = buffer->format; - *stride = buffer->stride; - if (buffer->shm_buffer) { - *data = wl_shm_buffer_get_data(buffer->shm_buffer); - wl_shm_buffer_begin_access(buffer->shm_buffer); - } - else { - return false; - } - - return true; -} - -static void -shm_client_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer) -{ - struct ds_shm_client_buffer *buffer; - - buffer = shm_client_buffer_from_buffer(ds_buffer); - if (buffer->shm_buffer) - wl_shm_buffer_end_access(buffer->shm_buffer); -} - -static const struct ds_buffer_interface shm_client_buffer_iface = -{ - .destroy = shm_client_buffer_destroy, - .begin_data_ptr_access = shm_client_buffer_begin_data_ptr_access, - .end_data_ptr_access = shm_client_buffer_end_data_ptr_access, -}; - -static void -shm_client_buffer_handle_release(struct wl_listener *listener, void *data) -{ - struct ds_shm_client_buffer *buffer; - - buffer = wl_container_of(listener, buffer, listener.buffer_release); - if (buffer->resource) - wl_buffer_send_release(buffer->resource); -} - -static struct ds_shm_client_buffer * -shm_client_buffer_create(struct wl_resource *resource) -{ - struct ds_shm_client_buffer *buffer; - struct wl_shm_buffer *shm_buffer; - enum wl_shm_format wl_shm_format; - int32_t width; - int32_t height; - - shm_buffer = wl_shm_buffer_get(resource); - width = wl_shm_buffer_get_width(shm_buffer); - height = wl_shm_buffer_get_height(shm_buffer); - - buffer = calloc(1, sizeof(*buffer)); - if (!buffer) - return NULL; - - ds_buffer_init(&buffer->base, &shm_client_buffer_iface, width, height); - - buffer->resource = resource; - buffer->shm_buffer = shm_buffer; - - wl_shm_format = wl_shm_buffer_get_format(shm_buffer); - buffer->format = convert_wl_shm_format_to_drm(wl_shm_format); - buffer->stride = wl_shm_buffer_get_stride(shm_buffer); - - buffer->listener.buffer_release.notify = - shm_client_buffer_handle_release; - ds_buffer_add_release_listener(&buffer->base, - &buffer->listener.buffer_release); - - buffer->listener.resource_destroy.notify = - shm_client_buffer_resource_handle_destroy; - wl_resource_add_destroy_listener(resource, - &buffer->listener.resource_destroy); - - ds_dbg("Shm client buffer(%p) created", buffer); - - return buffer; -} diff --git a/src/libds/compositor.c b/src/libds/compositor.c deleted file mode 100644 index 64b9a99..0000000 --- a/src/libds/compositor.c +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include - -#include "libds/log.h" - -#include "subcompositor.h" -#include "surface.h" -#include "region.h" - -#define COMPOSITOR_VERSION 4 - -struct ds_compositor -{ - struct wl_global *global; - struct ds_subcompositor subcompositor; - - struct { - struct wl_signal new_surface; - struct wl_signal destroy; - } events; - - struct wl_listener display_destroy; -}; - -static void compositor_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id); -static void compositor_handle_display_destroy(struct wl_listener *listener, - void *data); - -WL_EXPORT struct ds_compositor * -ds_compositor_create(struct wl_display *display) -{ - struct ds_compositor *compositor; - - compositor = calloc(1, sizeof *compositor); - if (!compositor) { - ds_log_errno(DS_ERR, "Could not allocate memory"); - return NULL; - } - - compositor->global = wl_global_create(display, &wl_compositor_interface, - COMPOSITOR_VERSION, compositor, compositor_bind); - if (!compositor->global) { - ds_log_errno(DS_ERR, "Could not create global"); - goto err_global; - } - - if (!ds_subcompositor_init(&compositor->subcompositor, display)) { - ds_err("Could not initialize subcompositor"); - goto err_subcomp; - } - - wl_signal_init(&compositor->events.new_surface); - wl_signal_init(&compositor->events.destroy); - - compositor->display_destroy.notify = compositor_handle_display_destroy; - wl_display_add_destroy_listener(display, &compositor->display_destroy); - - ds_inf("Compositor(%p) created", compositor); - - return compositor; - -err_subcomp: - wl_global_destroy(compositor->global); -err_global: - free(compositor); - - return NULL; -} - -WL_EXPORT void -ds_compositor_add_new_surface_listener(struct ds_compositor *compositor, - struct wl_listener *listener) -{ - wl_signal_add(&compositor->events.new_surface, listener); -} - -WL_EXPORT void -ds_compositor_add_destroy_listener(struct ds_compositor *compositor, - struct wl_listener *listener) -{ - wl_signal_add(&compositor->events.destroy, listener); -} - -static void -compositor_handle_create_surface(struct wl_client *client, - struct wl_resource *resource, uint32_t id) -{ - struct ds_compositor *compositor; - struct ds_surface *surface; - - compositor = wl_resource_get_user_data(resource); - surface = ds_surface_create(client, - wl_resource_get_version(resource), id); - if (!surface) { - ds_err("Could not create ds_surface"); - return; - } - - wl_signal_emit(&compositor->events.new_surface, surface); -} - -static void -compositor_handle_create_region(struct wl_client *client, - struct wl_resource *resource, uint32_t id) -{ - ds_region_add(client, wl_resource_get_version(resource), id); -} - -static const struct wl_compositor_interface compositor_impl = -{ - .create_surface = compositor_handle_create_surface, - .create_region = compositor_handle_create_region, -}; - -static void compositor_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - struct ds_compositor *compositor = data; - struct wl_resource *resource; - - resource = wl_resource_create(client, &wl_compositor_interface, - version, id); - if (resource == NULL) { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(resource, &compositor_impl, - compositor, NULL); -} - -static void -compositor_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_compositor *compositor; - - compositor = wl_container_of(listener, compositor, display_destroy); - - ds_dbg("Destroy compositor(%p)", compositor); - - wl_signal_emit(&compositor->events.destroy, compositor); - - wl_list_remove(&compositor->display_destroy.link); - ds_subcompositor_finish(&compositor->subcompositor); - free(compositor); -} diff --git a/src/libds/input_device.c b/src/libds/input_device.c deleted file mode 100644 index 534bced..0000000 --- a/src/libds/input_device.c +++ /dev/null @@ -1,105 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include -#include -#include - -#include "libds/log.h" -#include "libds/interfaces/input_device.h" -#include "libds/interfaces/pointer.h" -#include "libds/interfaces/keyboard.h" -#include "libds/interfaces/touch.h" - -WL_EXPORT enum ds_input_device_type -ds_input_device_get_type(struct ds_input_device *dev) -{ - return dev->type; -} - -WL_EXPORT const char * -ds_input_device_get_name(struct ds_input_device *dev) -{ - return dev->name; -} - -WL_EXPORT struct ds_pointer * -ds_input_device_get_pointer(struct ds_input_device *dev) -{ - if (dev->type != DS_INPUT_DEVICE_POINTER) { - ds_err("Given ds_input_device is not a pointer device"); - return NULL; - } - - return dev->pointer; -} - -WL_EXPORT struct ds_keyboard * -ds_input_device_get_keyboard(struct ds_input_device *dev) -{ - if (dev->type != DS_INPUT_DEVICE_KEYBOARD) { - ds_err("Given ds_input_device is not a keyboard device"); - return NULL; - } - - return dev->keyboard; -} - -WL_EXPORT struct ds_touch * -ds_input_device_get_touch(struct ds_input_device *dev) -{ - if (dev->type != DS_INPUT_DEVICE_TOUCH) { - ds_err("Given ds_input_device is not a touch device"); - return NULL; - } - - return dev->touch; -} - -WL_EXPORT void -ds_input_device_add_destroy_listener(struct ds_input_device *dev, - struct wl_listener *listener) -{ - wl_signal_add(&dev->events.destroy, listener); -} - -void -ds_input_device_init(struct ds_input_device *dev, - enum ds_input_device_type type, - const struct ds_input_device_interface *iface, - const char *name, int vendor, int product) -{ - dev->type = type; - dev->iface = iface; - dev->name = strdup(name); - - wl_signal_init(&dev->events.destroy); -} - -void -ds_input_device_destroy(struct ds_input_device *dev) -{ - wl_signal_emit(&dev->events.destroy, dev); - - if (dev->_device) { - switch (dev->type) { - case DS_INPUT_DEVICE_POINTER: - ds_pointer_destroy(dev->pointer); - break; - case DS_INPUT_DEVICE_KEYBOARD: - ds_keyboard_destroy(dev->keyboard); - break; - case DS_INPUT_DEVICE_TOUCH: - ds_touch_destroy(dev->touch); - break; - default: - ds_err("Warning: leaking memory %p %p %d", - dev->_device, dev, dev->type); - break; - } - } - - free(dev->name); - if (dev->iface && dev->iface->destroy) - dev->iface->destroy(dev); - else - free(dev); -} diff --git a/src/libds/keyboard.c b/src/libds/keyboard.c deleted file mode 100644 index d122e81..0000000 --- a/src/libds/keyboard.c +++ /dev/null @@ -1,304 +0,0 @@ -#include -#include -#include -#include - -#include - -#include "libds/log.h" -#include "libds/interfaces/keyboard.h" -#include "util.h" - -static bool keyboard_modifier_update(struct ds_keyboard *keyboard); -static void keyboard_key_update(struct ds_keyboard *keyboard, - struct ds_event_keyboard_key *event); -static void keyboard_led_update(struct ds_keyboard *keyboard); - -WL_EXPORT bool -ds_keyboard_set_keymap(struct ds_keyboard *keyboard, struct xkb_keymap *keymap) -{ - char *tmp_keymap_string; - void *dst; - int rw_fd, ro_fd; - xkb_keycode_t keycode; - const char *led_names[DS_LED_COUNT] = { - XKB_LED_NAME_NUM, - XKB_LED_NAME_CAPS, - XKB_LED_NAME_SCROLL, - }; - const char *mod_names[DS_MODIFIER_COUNT] = { - XKB_MOD_NAME_SHIFT, - XKB_MOD_NAME_CAPS, - XKB_MOD_NAME_CTRL, - XKB_MOD_NAME_ALT, - XKB_MOD_NAME_NUM, - "Mod3", - XKB_MOD_NAME_LOGO, - "Mod5", - }; - - if (keyboard->keymap) - xkb_keymap_unref(keyboard->keymap); - - keyboard->keymap = xkb_keymap_ref(keymap); - - if (keyboard->xkb_state) - xkb_state_unref(keyboard->xkb_state); - - keyboard->xkb_state = xkb_state_new(keyboard->keymap); - if (!keyboard->xkb_state) { - ds_err("Failed to create XKB state"); - goto err_state; - } - - for (size_t i = 0; i < DS_LED_COUNT; i++) { - keyboard->led_indexes[i] = - xkb_map_led_get_index(keyboard->keymap, led_names[i]); - } - - for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) { - keyboard->mod_indexes[i] = - xkb_map_mod_get_index(keyboard->keymap, mod_names[i]); - } - - tmp_keymap_string = xkb_keymap_get_as_string(keyboard->keymap, - XKB_KEYMAP_FORMAT_TEXT_V1); - if (!tmp_keymap_string) { - ds_err("Failed to get string version of keymap"); - goto err_keymap_string; - } - - if (keyboard->keymap_string) - free(keyboard->keymap_string); - keyboard->keymap_string = tmp_keymap_string; - keyboard->keymap_size = strlen(keyboard->keymap_string) + 1; - - if (!allocate_shm_file_pair(keyboard->keymap_size, &rw_fd, &ro_fd)) { - ds_err("Failed to allocate shm_file for keymap"); - goto err_shm_file; - } - - dst = mmap(NULL, keyboard->keymap_size, PROT_READ | PROT_WRITE, - MAP_SHARED, rw_fd, 0); - if (dst == MAP_FAILED) { - ds_log_errno(DS_ERR, "mmap failed"); - goto err_mmap; - } - - memcpy(dst, keyboard->keymap_string, keyboard->keymap_size); - munmap(dst, keyboard->keymap_size); - close(rw_fd); - - if (keyboard->keymap_fd >= 0) - close(keyboard->keymap_fd); - keyboard->keymap_fd = ro_fd; - - for (size_t i = 0; i < keyboard->num_keycodes; i++) { - keycode = keyboard->keycodes[i] + 8; - xkb_state_update_key(keyboard->xkb_state, keycode, XKB_KEY_DOWN); - } - - keyboard_modifier_update(keyboard); - - wl_signal_emit(&keyboard->events.keymap, keyboard); - - return true; - -err_mmap: - close(rw_fd); - close(ro_fd); -err_shm_file: - free(keyboard->keymap_string); - keyboard->keymap_string = NULL; -err_keymap_string: - xkb_state_unref(keyboard->xkb_state); - keyboard->xkb_state = NULL; -err_state: - xkb_keymap_unref(keymap); - keyboard->keymap = NULL; - - return false; -} - -WL_EXPORT void -ds_keyboard_set_repeat_info(struct ds_keyboard *keyboard, - int32_t rate, int32_t delay) -{ - if (keyboard->repeat_info.rate == rate && - keyboard->repeat_info.delay == delay) - return; - keyboard->repeat_info.rate = rate; - keyboard->repeat_info.delay = delay; - - wl_signal_emit(&keyboard->events.repeat_info, keyboard); -} - -WL_EXPORT uint32_t -ds_keyboard_get_modifiers(struct ds_keyboard *keyboard) -{ - xkb_mod_mask_t mask; - uint32_t modifiers = 0; - - mask = keyboard->modifiers.depressed | keyboard->modifiers.latched; - for (size_t i = 0; i < DS_MODIFIER_COUNT; i++) { - if (keyboard->mod_indexes[i] != XKB_MOD_INVALID && - (mask & (1 << keyboard->mod_indexes[i]))) - modifiers |= (1 << i); - } - - return modifiers; -} - -WL_EXPORT struct xkb_state * -ds_keyboard_get_xkb_state(struct ds_keyboard *keyboard) -{ - return keyboard->xkb_state; -} - -WL_EXPORT void -ds_keyboard_notify_key(struct ds_keyboard *keyboard, - struct ds_event_keyboard_key *event) -{ - uint32_t keycode; - enum xkb_key_direction dir; - bool updated; - - keyboard_key_update(keyboard, event); - - wl_signal_emit(&keyboard->events.key, event); - - if (!keyboard->xkb_state) - return; - - if (event->update_state) { - keycode = event->keycode + 8; - dir = (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) ? - XKB_KEY_DOWN : XKB_KEY_UP; - xkb_state_update_key(keyboard->xkb_state, keycode, dir); - } - - updated = keyboard_modifier_update(keyboard); - if (updated) - wl_signal_emit(&keyboard->events.modifiers, keyboard); - - keyboard_led_update(keyboard); -} - -WL_EXPORT void -ds_keyboard_notify_modifiers(struct ds_keyboard *keyboard, - uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, - uint32_t group) -{ - bool updated; - - if (!keyboard->xkb_state) - return; - - xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, - mods_locked, 0, 0, group); - - updated = keyboard_modifier_update(keyboard); - if (updated) - wl_signal_emit(&keyboard->events.modifiers, keyboard); - - keyboard_led_update(keyboard); -} - -WL_EXPORT void -ds_keyboard_add_destroy_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener) -{ - wl_signal_add(&keyboard->events.destroy, listener); -} - -WL_EXPORT void -ds_keyboard_add_key_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener) -{ - wl_signal_add(&keyboard->events.key, listener); -} - -WL_EXPORT void -ds_keyboard_add_modifiers_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener) -{ - wl_signal_add(&keyboard->events.modifiers, listener); -} - -WL_EXPORT void -ds_keyboard_add_keymap_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener) -{ - wl_signal_add(&keyboard->events.keymap, listener); -} - -WL_EXPORT void -ds_keyboard_add_repeat_info_listener(struct ds_keyboard *keyboard, - struct wl_listener *listener) -{ - wl_signal_add(&keyboard->events.repeat_info, listener); -} - -void -ds_keyboard_init(struct ds_keyboard *keyboard, - const struct ds_keyboard_interface *iface) -{ - keyboard->iface = iface; - keyboard->keymap_fd = -1; - - wl_signal_init(&keyboard->events.destroy); - wl_signal_init(&keyboard->events.key); - wl_signal_init(&keyboard->events.modifiers); - wl_signal_init(&keyboard->events.keymap); - wl_signal_init(&keyboard->events.repeat_info); -} - -void -ds_keyboard_destroy(struct ds_keyboard *keyboard) -{ - if (keyboard->iface && keyboard->iface->destroy) - keyboard->iface->destroy(keyboard); - else - free(keyboard); -} - -static bool -keyboard_modifier_update(struct ds_keyboard *keyboard) -{ - xkb_mod_mask_t depressed, latched, locked, group; - - if (!keyboard->xkb_state) - return false; - - depressed = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_DEPRESSED); - latched = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_LATCHED); - locked = xkb_state_serialize_mods(keyboard->xkb_state, - XKB_STATE_MODS_LOCKED); - group = xkb_state_serialize_layout(keyboard->xkb_state, - XKB_STATE_LAYOUT_EFFECTIVE); - if (depressed == keyboard->modifiers.depressed && - latched == keyboard->modifiers.latched && - locked == keyboard->modifiers.locked && - group == keyboard->modifiers.group) - return false; - - keyboard->modifiers.depressed = depressed; - keyboard->modifiers.latched = latched; - keyboard->modifiers.locked = locked; - keyboard->modifiers.group = group; - - return true; -} - -static void keyboard_key_update(struct ds_keyboard *keyboard, - struct ds_event_keyboard_key *event) -{ - // TODO -} - -static void keyboard_led_update(struct ds_keyboard *keyboard) -{ - // TODO -} diff --git a/src/libds/log.c b/src/libds/log.c deleted file mode 100644 index 67386af..0000000 --- a/src/libds/log.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include "libds/log.h" - -static bool colored = true; -static enum ds_log_level log_level = DS_ERR; - -static const char *level_colors[] = { - [DS_SILENT] = "", - [DS_ERR] = "\x1B[1;31m", - [DS_INF] = "\x1B[1;34m", - [DS_DBG] = "\x1B[1;90m", -}; - -static const char *level_headers[] = { - [DS_SILENT] = "", - [DS_ERR] = "[ERROR]", - [DS_INF] = "[INFO]", - [DS_DBG] = "[DEBUG]", -}; - -static void log_stderr(enum ds_log_level level, const char *fmt, va_list args); -static void log_wl(const char *fmt, va_list args); - -static ds_log_func_t log_callback = log_stderr; - -WL_EXPORT void -ds_log_init(enum ds_log_level level, ds_log_func_t callback) -{ - if (level < DS_LOG_LEVEL_LAST) - log_level = level; - if (callback) - log_callback = callback; - - wl_log_set_handler_server(log_wl); -} - -WL_EXPORT void -_ds_vlog(enum ds_log_level level, const char *fmt, va_list args) -{ - log_callback(level, fmt, args); -} - -WL_EXPORT void -_ds_log(enum ds_log_level level, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - log_callback(level, fmt, args); - va_end(args); -} - -enum ds_log_level -ds_log_get_level(void) -{ - return log_level; -} - -static void -log_stderr(enum ds_log_level level, const char *fmt, va_list args) -{ - bool colored_tty = false; - unsigned c; - - if (level > log_level) - return; - - c = (level < DS_LOG_LEVEL_LAST) ? level : DS_LOG_LEVEL_LAST - 1; - - colored_tty = colored && isatty(STDERR_FILENO); - if (colored_tty) - fprintf(stderr, "%s", level_colors[c]); - else - fprintf(stderr, "%s ", level_headers[c]); - - vfprintf(stderr, fmt, args); - - if (colored_tty) - fprintf(stderr, "\x1B[0m"); - fprintf(stderr, "\n"); -} - -static void -log_wl(const char *fmt, va_list args) -{ - static char ds_fmt[1024]; - int n; - - n = snprintf(ds_fmt, sizeof(ds_fmt), "[wayland] %s", fmt); - if (n > 0 && ds_fmt[n - 1] == '\n') - ds_fmt[n - 1] = '\0'; - _ds_vlog(DS_INF, ds_fmt, args); -} diff --git a/src/libds/meson.build b/src/libds/meson.build deleted file mode 100644 index b59fda2..0000000 --- a/src/libds/meson.build +++ /dev/null @@ -1,101 +0,0 @@ -libds_files = [ - 'log.c', - 'addon.c', - 'buffer.c', - 'allocator.c', - 'swapchain.c', - 'output.c', - 'compositor.c', - 'subcompositor.c', - 'region.c', - 'util/time.c', - 'util/shm.c', - 'surface/surface.c', - 'surface/subsurface.c', - 'client_buffer/shm_client_buffer.c', - 'xdg_shell/xdg_shell.c', - 'xdg_shell/xdg_surface.c', - 'xdg_shell/xdg_toplevel.c', - 'pixel_format.c', - 'backend.c', - 'input_device.c', - 'pointer.c', - 'keyboard.c', - 'touch.c', - 'seat/seat.c', - 'seat/seat_pointer.c', - 'seat/seat_keyboard.c', - 'seat/seat_touch.c', - 'shell.c', - 'shell_surface.c', -] - -protocols = { - 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', -} - -protocols_code = {} -protocols_server_header = {} - -foreach name, path : protocols - code = custom_target( - name.underscorify() + '_c', - input: path, - output: '@BASENAME@-protocol.c', - command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'], - ) - libds_files += code - - server_header = custom_target( - name.underscorify() + '_server_h', - input: path, - output: '@BASENAME@-server-protocol.h', - command: [wayland_scanner, 'server-header', '@INPUT@', '@OUTPUT@'], - build_by_default: false, - ) - libds_files += server_header -endforeach - -math = meson.get_compiler('c').find_library('m') -wayland_server = dependency('wayland-server', required: true) -pixman = dependency('pixman-1', required: true) -libdrm = dependency('libdrm', required: true) -xkbcommon = dependency('xkbcommon', required: true) -rt = meson.get_compiler('c').find_library('rt') - -if wayland_server.version().version_compare('>= 1.19') - cdata.set('HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY', '1') -endif - -libds_deps = [ - math, - wayland_server, - pixman, - libdrm, - xkbcommon, - rt, -] - -subdir('backend') -subdir('allocator') - -lib_libds = shared_library('ds', libds_files, - dependencies: libds_deps, - include_directories: [ common_inc, include_directories('.') ], - version: meson.project_version(), - install: true -) - -dep_libds = declare_dependency( - link_with: lib_libds, - dependencies: libds_deps, - include_directories: [ common_inc, include_directories('.') ], -) - -pkgconfig = import('pkgconfig') -pkgconfig.generate(lib_libds, - version: meson.project_version(), - filebase: meson.project_name(), - name: meson.project_name(), - description: 'Wayland compositor library', -) diff --git a/src/libds/output.c b/src/libds/output.c deleted file mode 100644 index d5af56e..0000000 --- a/src/libds/output.c +++ /dev/null @@ -1,215 +0,0 @@ -#include -#include - -#include "libds/log.h" -#include "libds/output.h" -#include "libds/interfaces/output.h" - -static void output_handle_display_destroy(struct wl_listener *listener, - void *data); -static void output_enable(struct ds_output *output, bool enable); -static void output_state_clear(struct ds_output_state *state); -static void output_state_clear_buffer(struct ds_output_state *state); -static void output_state_clear_mode(struct ds_output_state *state); - -WL_EXPORT void -ds_output_init(struct ds_output *output, struct ds_backend *backend, - const struct ds_output_interface *iface, struct wl_display *display) -{ - assert(iface->commit); - - output->backend = backend; - output->iface = iface; - output->display = display; - - wl_list_init(&output->modes); - - wl_signal_init(&output->events.destroy); - wl_signal_init(&output->events.frame); - wl_signal_init(&output->events.commit); - - output->display_destroy.notify = output_handle_display_destroy; - wl_display_add_destroy_listener(display, &output->display_destroy); -} - -WL_EXPORT void -ds_output_destroy(struct ds_output *output) -{ - wl_list_remove(&output->display_destroy.link); - - wl_signal_emit(&output->events.destroy, output); - - if (output->iface && output->iface->destroy) - output->iface->destroy(output); - else - free(output); -} - -void -ds_output_enable(struct ds_output *output) -{ - output_enable(output, true); -} - -void -ds_output_disable(struct ds_output *output) -{ - output_enable(output, false); -} - -WL_EXPORT bool -ds_output_commit(struct ds_output *output) -{ - // TODO signal precommit - - if (!output->iface->commit(output)) { - return false; - } - - output_state_clear(&output->pending); - - // TODO signal commit - - return true; -} - -WL_EXPORT void -ds_output_attach_buffer(struct ds_output *output, struct ds_buffer *buffer) -{ - output_state_clear_buffer(&output->pending); - output->pending.committed |= DS_OUTPUT_STATE_BUFFER; - output->pending.buffer = ds_buffer_lock(buffer); -} - -WL_EXPORT const struct ds_output_mode * -ds_output_get_preferred_mode(struct ds_output *output) -{ - struct ds_output_mode *mode; - - if (wl_list_empty(&output->modes)) - return NULL; - - wl_list_for_each(mode, &output->modes, link) { - if (mode->preferred) - return mode; - } - - // No preferred mode, choose the first one - return wl_container_of(output->modes.next, mode, link); -} - -WL_EXPORT void -ds_output_set_mode(struct ds_output *output, const struct ds_output_mode *mode) -{ - output_state_clear_mode(&output->pending); - - if (output->current_mode == mode) { - return; - } - - output->pending.committed |= DS_OUTPUT_STATE_MODE; - output->pending.mode_type = DS_OUTPUT_STATE_MODE_FIXED; - output->pending.mode = mode; -} - -WL_EXPORT void -ds_output_set_custom_mode(struct ds_output *output, - int32_t width, int32_t height, int32_t refresh) -{ - output_state_clear_mode(&output->pending); - - if (output->width == width && output->height == height && - output->refresh == refresh) - return; - - output->pending.committed |= DS_OUTPUT_STATE_MODE; - output->pending.mode_type = DS_OUTPUT_STATE_MODE_CUSTOM; - output->pending.custom_mode.width = width; - output->pending.custom_mode.height = height; - output->pending.custom_mode.refresh = refresh; -} - -WL_EXPORT void -ds_output_add_destroy_listener(struct ds_output *output, - struct wl_listener *listener) -{ - wl_signal_add(&output->events.destroy, listener); -} - -WL_EXPORT void -ds_output_add_frame_listener(struct ds_output *output, - struct wl_listener *listener) -{ - wl_signal_add(&output->events.frame, listener); -} - -WL_EXPORT void -ds_output_add_commit_listener(struct ds_output *output, - struct wl_listener *listener) -{ - wl_signal_add(&output->events.commit, listener); -} - -void -ds_output_update_custom_mode(struct ds_output *output, - int32_t width, int32_t height, int32_t refresh) -{ - if (output->width == width && output->height == height && - output->refresh == refresh) - return; - - output->width = width; - output->height = height; - output->refresh = refresh; -} - -static void -output_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_output *output; - - output = wl_container_of(listener, output, display_destroy); - // TODO - // destroy wl_global -} - -static void -output_state_clear(struct ds_output_state *state) -{ - output_state_clear_buffer(state); - state->committed = 0; -} - -static void -output_state_clear_buffer(struct ds_output_state *state) -{ - if (!(state->committed & DS_OUTPUT_STATE_BUFFER)) - return; - - ds_buffer_unlock(state->buffer); - state->buffer = NULL; - - state->committed &= ~DS_OUTPUT_STATE_BUFFER; -} - -static void -output_enable(struct ds_output *output, bool enable) -{ - if (output->enabled == enable) { - output->pending.committed &= ~DS_OUTPUT_STATE_ENABLED; - return; - } - - output->pending.committed |= DS_OUTPUT_STATE_ENABLED; - output->pending.enabled = enable; -} - -static void -output_state_clear_mode(struct ds_output_state *state) -{ - if (!(state->committed & DS_OUTPUT_STATE_MODE)) - return; - - state->mode = NULL; - state->committed &= ~DS_OUTPUT_STATE_MODE; -} diff --git a/src/libds/output.h b/src/libds/output.h deleted file mode 100644 index edf4560..0000000 --- a/src/libds/output.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef DS_OUTPUT_H -#define DS_OUTPUT_H - -#include - -#include "libds/output.h" - -void ds_output_update_custom_mode(struct ds_output *output, - int32_t width, int32_t height, int32_t refresh); - -#endif diff --git a/src/libds/pixel_format.c b/src/libds/pixel_format.c deleted file mode 100644 index 8676bec..0000000 --- a/src/libds/pixel_format.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#include "pixel_format.h" - -uint32_t -convert_wl_shm_format_to_drm(enum wl_shm_format fmt) -{ - switch (fmt) { - case WL_SHM_FORMAT_XRGB8888: - return DRM_FORMAT_XRGB8888; - case WL_SHM_FORMAT_ARGB8888: - return DRM_FORMAT_ARGB8888; - default: - return (uint32_t)fmt; - } -} diff --git a/src/libds/pixel_format.h b/src/libds/pixel_format.h deleted file mode 100644 index 21eb0a6..0000000 --- a/src/libds/pixel_format.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef DS_PIXEL_FORMAT_H -#define DS_PIXEL_FORMAT_H - -#include -#include - -uint32_t convert_wl_shm_format_to_drm(enum wl_shm_format fmt); - -#endif diff --git a/src/libds/pointer.c b/src/libds/pointer.c deleted file mode 100644 index 5c5cbda..0000000 --- a/src/libds/pointer.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include "libds/interfaces/pointer.h" - -void -ds_pointer_init(struct ds_pointer *pointer, - const struct ds_pointer_interface *iface) -{ - pointer->iface = iface; - - wl_signal_init(&pointer->events.motion); - wl_signal_init(&pointer->events.motion_absolute); - wl_signal_init(&pointer->events.button); - wl_signal_init(&pointer->events.frame); -} - -void -ds_pointer_destroy(struct ds_pointer *pointer) -{ - if (!pointer) - return; - - if (pointer->iface && pointer->iface->destroy) - pointer->iface->destroy(pointer); - else - free(pointer); -} - -WL_EXPORT void -ds_pointer_add_motion_listener(struct ds_pointer *pointer, - struct wl_listener *listener) -{ - wl_signal_add(&pointer->events.motion, listener); -} - -WL_EXPORT void -ds_pointer_add_motion_absolute_listener(struct ds_pointer *pointer, - struct wl_listener *listener) -{ - wl_signal_add(&pointer->events.motion_absolute, listener); -} - -WL_EXPORT void -ds_pointer_add_button_listener(struct ds_pointer *pointer, - struct wl_listener *listener) -{ - wl_signal_add(&pointer->events.button, listener); -} - -WL_EXPORT void -ds_pointer_add_frame_listener(struct ds_pointer *pointer, - struct wl_listener *listener) -{ - wl_signal_add(&pointer->events.frame, listener); -} diff --git a/src/libds/presentation.c b/src/libds/presentation.c deleted file mode 100644 index 54d10d9..0000000 --- a/src/libds/presentation.c +++ /dev/null @@ -1,115 +0,0 @@ -// TODO - -#include "libds-private.h" -#include "presentation-time-protocol.h" - -#define PRESENTATION_VERSION 1 - -struct ds_presentation -{ - struct wl_global *global; - - struct { - struct wl_signal destroy; - } events; -}; - -struct ds_presentation_feedback -{ - struct wl_list resources; - -} - -struct ds_presentation_surface_state -{ -}; - -struct ds_presentation_feedback -{ - struct wl_resource *resource; - struct wl_list link; - uint32_t psf_flags; -}; - -static void presentation_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id); -static void handle_display_destroy(struct wl_listener *listener, void *data); - -struct ds_presentation * -ds_presentation_create(struct wl_display *display, clockid_t clk_id) -{ - struct ds_presentation *presentation; - - presentation = calloc(1, sizeof *presentation); - if (!presentation) - return NULL; - - presentation->global = wl_global_create(display, &wp_presentation_interface, - PRESENTATION_VERSION, presentation, presentation_bind); - if (!presentation->global) { - free(presentation); - return NULL; - } - - presentation->clock = clk_id; - - wl_signal_init(&presentation->events.destroy); - - presentation->display_destroy.notify = handle_display_destroy; - wl_display_add_destroy_listener(display, &presentation->display_destroy); -} - -static void -presentation_handle_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -presentation_handle_feedback(struct wl_client *client, - struct wl_resource *presentation_resource, - struct wl_resource *surface_resource, uint32_t id) -{ - struct ds_presentation *presentation; - struct ds_surface *surface; - - presentation = wl_resource_get_user_data(presentation_resource); - surface = ds_surface_from_resource(surface_resource); -} - -static const struct wp_presentation_interface presentation_impl = -{ - .destroy = presentation_handle_destroy, - .feedback = presentation_handle_feedback, -}; - -static void -presentation_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - struct ds_presentation *presentation = data; - struct wl_resource *resource; - - resource = wl_resource_create(client, &wp_presentation_interface, - version, id); - if (!resource) { - wl_client_post_no_memory(client); - return; - } - wl_resource_set_implementation(resource, &presentation_impl, - presentation, NULL); - - wp_presentation_send_clock_id(resource, (uint32_t)presentation->clock); -} - -static void -handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_presentation *presentation; - - presentation = wl_container_of(listener, presentation, display_destroy); - wl_signal_emit(&presentation->events.destroy, presentation); - wl_list_remove(&presentation->display_destroy.link); - wl_global_destroy(presentation->global); - free(presentation); -} diff --git a/src/libds/region.c b/src/libds/region.c deleted file mode 100644 index 92fe003..0000000 --- a/src/libds/region.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include -#include -#include - -#include "libds/log.h" - -#include "region.h" - -static const struct wl_region_interface region_impl; - -static void region_handle_resource_destroy(struct wl_resource *resource); - -void -ds_region_add(struct wl_client *client, uint32_t version, uint32_t id) -{ - struct wl_resource *resource; - pixman_region32_t *region; - - region = calloc(1, sizeof *region); - if (!region) { - wl_client_post_no_memory(client); - return; - } - - pixman_region32_init(region); - - resource = wl_resource_create(client, &wl_region_interface, version, id); - if (!resource) { - free(region); - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(resource, ®ion_impl, region, - region_handle_resource_destroy); -} - -pixman_region32_t * -ds_region_from_resource(struct wl_resource *resource) -{ - assert(wl_resource_instance_of(resource, &wl_region_interface, - ®ion_impl)); - return wl_resource_get_user_data(resource); -} - -void -ds_region_transform(pixman_region32_t *dst, pixman_region32_t *src, - enum wl_output_transform transform, int width, int height) -{ - pixman_box32_t *src_rects, *dst_rects; - int nrects, i; - - if (transform == WL_OUTPUT_TRANSFORM_NORMAL) { - pixman_region32_copy(dst, src); - return; - } - - src_rects = pixman_region32_rectangles(src, &nrects); - dst_rects = malloc(nrects * sizeof *dst_rects); - if (!dst_rects) - return; - - for (i = 0; i < nrects; i++) { - switch (transform) { - default: - ds_err("Unkown transform value(%d)", transform); - case WL_OUTPUT_TRANSFORM_NORMAL: - dst_rects[i].x1 = src_rects[i].x1; - dst_rects[i].y1 = src_rects[i].y1; - dst_rects[i].x2 = src_rects[i].x2; - dst_rects[i].y2 = src_rects[i].y2; - break; - case WL_OUTPUT_TRANSFORM_90: - dst_rects[i].x1 = height - src_rects[i].y2; - dst_rects[i].y1 = src_rects[i].x1; - dst_rects[i].x2 = height - src_rects[i].y1; - dst_rects[i].y2 = src_rects[i].x2; - break; - case WL_OUTPUT_TRANSFORM_180: - dst_rects[i].x1 = width - src_rects[i].x2; - dst_rects[i].y1 = height - src_rects[i].y2; - dst_rects[i].x2 = width - src_rects[i].x1; - dst_rects[i].y2 = height - src_rects[i].y1; - break; - case WL_OUTPUT_TRANSFORM_270: - dst_rects[i].x1 = src_rects[i].y1; - dst_rects[i].y1 = width - src_rects[i].x2; - dst_rects[i].x2 = src_rects[i].y2; - dst_rects[i].y2 = width - src_rects[i].x1; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED: - dst_rects[i].x1 = width - src_rects[i].x2; - dst_rects[i].y1 = src_rects[i].y1; - dst_rects[i].x2 = width - src_rects[i].x1; - dst_rects[i].y2 = src_rects[i].y2; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - dst_rects[i].x1 = src_rects[i].y1; - dst_rects[i].y1 = src_rects[i].x1; - dst_rects[i].x2 = src_rects[i].y2; - dst_rects[i].y2 = src_rects[i].x2; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - dst_rects[i].x1 = src_rects[i].x1; - dst_rects[i].y1 = height - src_rects[i].y2; - dst_rects[i].x2 = src_rects[i].x2; - dst_rects[i].y2 = height - src_rects[i].y1; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - dst_rects[i].x1 = height - src_rects[i].y2; - dst_rects[i].y1 = width - src_rects[i].x2; - dst_rects[i].x2 = height - src_rects[i].y1; - dst_rects[i].y2 = width - src_rects[i].x1; - break; - } - } - - pixman_region32_fini(dst); - pixman_region32_init_rects(dst, dst_rects, nrects); - free(dst_rects); -} - -void -ds_region_scale_xy(pixman_region32_t *dst, pixman_region32_t *src, - float scale_x, float scale_y) -{ - pixman_box32_t *src_rects, *dst_rects; - int nrects, i; - - if (scale_x == 1.0 && scale_y == 1.0) - pixman_region32_copy(dst, src); - - src_rects = pixman_region32_rectangles(src, &nrects); - dst_rects = malloc(nrects * sizeof *dst_rects); - if (!dst_rects) - return; - - for (i = 0; i < nrects; i++) { - dst_rects[i].x1 = floor(src_rects[i].x1 * scale_x); - dst_rects[i].x2 = ceil(src_rects[i].x2 * scale_x); - dst_rects[i].y1 = floor(src_rects[i].y1 * scale_y); - dst_rects[i].y2 = ceil(src_rects[i].y2 * scale_y); - } - - pixman_region32_fini(dst); - pixman_region32_init_rects(dst, dst_rects, nrects); - free(dst_rects); -} - -void -ds_region_scale(pixman_region32_t *dst, pixman_region32_t *src, float scale) -{ - ds_region_scale_xy(dst, src, scale, scale); -} - -static void -region_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -region_add(struct wl_client *client, struct wl_resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - pixman_region32_t *region = wl_resource_get_user_data(resource); - pixman_region32_union_rect(region, region, x, y, width, height); -} - -static void -region_subtract(struct wl_client *client, struct wl_resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - pixman_region32_t *region = wl_resource_get_user_data(resource); - pixman_region32_t rect; - - pixman_region32_union_rect(region, region, x, y, width, height); - pixman_region32_init_rect(&rect, x, y, width, height); - pixman_region32_subtract(region, region, &rect); - pixman_region32_fini(&rect); -} - -static const struct wl_region_interface region_impl = -{ - .destroy = region_destroy, - .add = region_add, - .subtract = region_subtract, -}; - -static void -region_handle_resource_destroy(struct wl_resource *resource) -{ - pixman_region32_t *region = wl_resource_get_user_data(resource); - pixman_region32_fini(region); - free(region); -} diff --git a/src/libds/region.h b/src/libds/region.h deleted file mode 100644 index b27963c..0000000 --- a/src/libds/region.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef DS_REGION_H -#define DS_REGION_H - -#include -#include - -void -ds_region_add(struct wl_client *client, uint32_t version, uint32_t id); - -pixman_region32_t * -ds_region_from_resource(struct wl_resource *resource); - -void -ds_region_transform(pixman_region32_t *dst, pixman_region32_t *src, - enum wl_output_transform transform, int width, int height); - -void -ds_region_scale_xy(pixman_region32_t *dst, pixman_region32_t *src, - float scale_x, float scale_y); - -void -ds_region_scale(pixman_region32_t *dst, pixman_region32_t *src, float scale); - -#endif diff --git a/src/libds/seat.h b/src/libds/seat.h deleted file mode 100644 index 6295647..0000000 --- a/src/libds/seat.h +++ /dev/null @@ -1,135 +0,0 @@ -#ifndef DS_SEAT_H -#define DS_SEAT_H - -#include "libds/keyboard.h" -#include "libds/seat.h" - -struct ds_seat_pointer_grab; - -struct ds_pointer_grab_interface -{ - void (*enter)(struct ds_seat_pointer_grab *grab, - struct ds_surface *surface, double sx, double sy); - void (*clear_focus)(struct ds_seat_pointer_grab *grab); - void (*motion)(struct ds_seat_pointer_grab *grab, uint32_t time_msec, - double sx, double sy); - uint32_t (*button)(struct ds_seat_pointer_grab *grab, uint32_t time_msec, - uint32_t button, enum ds_button_state state); - void (*axis)(struct ds_seat_pointer_grab *grab, uint32_t time_msec, - enum ds_axis_orientation orientation, double value, - int32_t value_discrete, enum ds_axis_source source); - void (*frame)(struct ds_seat_pointer_grab *grab); - void (*cancel)(struct ds_seat_pointer_grab *grab); -}; - -struct ds_seat_keyboard_grab; - -struct ds_keyboard_grab_interface -{ - void (*enter)(struct ds_seat_keyboard_grab *grab, - struct ds_surface *surface, uint32_t keycodes[], - size_t num_keycodes, struct ds_keyboard_modifiers *modifiers); - void (*clear_focus)(struct ds_seat_keyboard_grab *grab); - void (*key)(struct ds_seat_keyboard_grab *grab, uint32_t time_msec, - uint32_t key, uint32_t state); - void (*modifiers)(struct ds_seat_keyboard_grab *grab, - struct ds_keyboard_modifiers *modifiers); - void (*cancel)(struct ds_seat_keyboard_grab *grab); -}; - -struct ds_touch_point; - -struct ds_seat_touch_grab; - -struct ds_touch_grab_interface -{ - uint32_t (*down)(struct ds_seat_touch_grab *grab, uint32_t time_msec, - struct ds_touch_point *point); - void (*up)(struct ds_seat_touch_grab *grab, uint32_t time_msec, - struct ds_touch_point *point); - void (*motion)(struct ds_seat_touch_grab *grab, uint32_t time_msec, - struct ds_touch_point *point); - void (*enter)(struct ds_seat_touch_grab *grab, uint32_t time_msec, - struct ds_touch_point *point); - void (*frame)(struct ds_seat_touch_grab *grab); - void (*cancel)(struct ds_seat_touch_grab *grab); -}; - -struct ds_seat_pointer_grab -{ - const struct ds_pointer_grab_interface *iface; - struct ds_seat *seat; - void *data; -}; - -struct ds_seat_keyboard_grab -{ - const struct ds_keyboard_grab_interface *iface; - struct ds_seat *seat; - void *data; -}; - -struct ds_seat_touch_grab -{ - const struct ds_touch_grab_interface *iface; - struct ds_seat *seat; - void *data; -}; - -void ds_seat_pointer_start_grab(struct ds_seat *seat, - struct ds_seat_pointer_grab *grab); - -void ds_seat_pointer_end_grab(struct ds_seat *seat); - -void ds_seat_pointer_enter(struct ds_seat *seat, struct ds_surface *surface, - double sx, double sy); - -void ds_seat_pointer_clear_focus(struct ds_seat *seat); - -void ds_seat_pointer_send_motion(struct ds_seat *seat, uint32_t time_msec, - double sx, double sy); - -uint32_t ds_seat_pointer_send_button(struct ds_seat *seat, uint32_t time_msec, - uint32_t button, enum ds_button_state state); - -void ds_seat_pointer_send_axis(struct ds_seat *seat, uint32_t time_msec, - enum ds_axis_orientation orientation, double value, - int32_t value_discrete, enum ds_axis_source source); - -void ds_seat_pointer_send_frame(struct ds_seat *seat); - -void ds_seat_keyboard_start_grab(struct ds_seat *seat, - struct ds_seat_keyboard_grab *grab); - -void ds_seat_keyboard_end_grab(struct ds_seat *seat); - -void ds_seat_keyboard_enter(struct ds_seat *seat, struct ds_surface *surface, - uint32_t keycodes[], size_t num_keycodes, - struct ds_keyboard_modifiers *modifiers); - -void ds_seat_keyboard_clear_focus(struct ds_seat *seat); - -void ds_seat_keyboard_send_key(struct ds_seat *seat, uint32_t time_msec, - uint32_t key, uint32_t state); - -void ds_seat_keyboard_send_modifiers(struct ds_seat *seat, - struct ds_keyboard_modifiers *modifiers); - -void ds_seat_touch_start_grab(struct ds_seat *seat, - struct ds_seat_touch_grab *grab); - -void ds_seat_touch_end_grab(struct ds_seat *seat); - -uint32_t ds_seat_touch_send_down(struct ds_seat *seat, - struct ds_surface *surface, uint32_t time_msec, int32_t touch_id, - double sx, double sy); - -void ds_seat_touch_send_up(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id); - -void ds_seat_touch_send_motion(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id, double sx, double sy); - -void ds_seat_touch_send_frame(struct ds_seat *seat); - -#endif diff --git a/src/libds/seat/seat.c b/src/libds/seat/seat.c deleted file mode 100644 index 51d5c23..0000000 --- a/src/libds/seat/seat.c +++ /dev/null @@ -1,390 +0,0 @@ -#include "config.h" - -#define _POSIX_C_SOURCE 200809L -#include -#include -#include - -#include "libds/log.h" -#include "seat_private.h" - -#define SEAT_VERSION 7 - -static void seat_handle_bind(struct wl_client *wl_client, void *data, - uint32_t version, uint32_t id); -static void seat_handle_display_destroy(struct wl_listener *listener, - void *data); -static void seat_destroy(struct ds_seat *seat); -static struct ds_seat_client *seat_client_create(struct ds_seat *seat, - struct wl_client *wl_client); -static void seat_client_destroy(struct ds_seat_client *seat_client); -static void -seat_client_send_capabilities(struct ds_seat_client *seat_client); -static void seat_client_send_name(struct ds_seat_client *seat_client); - -WL_EXPORT struct ds_seat * -ds_seat_create(struct wl_display *display, const char *name) -{ - struct ds_seat *seat; - - seat = calloc(1, sizeof *seat); - if (!seat) - return NULL; - - if (!seat_pointer_init(seat)) { - ds_err("Failed to initialize pointer for seat(%s)", name); - goto err_ptr; - } - - if (!seat_keyboard_init(seat)) { - ds_err("Failed to initialize keyboard for seat(%s)", name); - goto err_kbd; - } - - if (!seat_touch_init(seat)) { - ds_err("Failed to initialize touch for seat(%s)", name); - goto err_touch; - } - - seat->global = wl_global_create(display, &wl_seat_interface, - SEAT_VERSION, seat, seat_handle_bind); - if (!seat->global) { - ds_err("Failed to create wl_global for seat(%s)", name); - goto err_global; - } - - seat->display = display; - seat->name = strdup(name); - - wl_list_init(&seat->clients); - - wl_signal_init(&seat->events.destroy); - wl_signal_init(&seat->events.pointer_grab_begin); - wl_signal_init(&seat->events.pointer_grab_end); - wl_signal_init(&seat->events.keyboard_grab_begin); - wl_signal_init(&seat->events.keyboard_grab_end); - wl_signal_init(&seat->events.touch_grab_begin); - wl_signal_init(&seat->events.touch_grab_end); - - seat->display_destroy.notify = seat_handle_display_destroy; - wl_display_add_destroy_listener(display, &seat->display_destroy); - - return seat; - -err_global: - seat_touch_finish(seat); -err_touch: - seat_keyboard_finish(seat); -err_kbd: - seat_pointer_finish(seat); -err_ptr: - free(seat); - - return NULL; -} - -WL_EXPORT void -ds_seat_destroy(struct ds_seat *seat) -{ - seat_destroy(seat); -} - -WL_EXPORT void -ds_seat_set_capabilities(struct ds_seat *seat, - enum wl_seat_capability capabilities) -{ - struct ds_seat_client *seat_client; - - if (capabilities == seat->capabilities) - return; - - seat->capabilities = capabilities; - seat->accumulated_capabilities |= capabilities; - - wl_list_for_each(seat_client, &seat->clients, link) { - if (!(capabilities & WL_SEAT_CAPABILITY_POINTER)) { - seat_client_remove_all_pointer_resources(seat_client); - } - if (!(capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) { - seat_client_remove_all_keyboard_resources(seat_client); - } - if (!(capabilities & WL_SEAT_CAPABILITY_TOUCH)) { - seat_client_remove_all_touch_resources(seat_client); - } - - seat_client_send_capabilities(seat_client); - } -} - -WL_EXPORT void -ds_seat_set_name(struct ds_seat *seat, const char *name) -{ - struct ds_seat_client *seat_client; - - free(seat->name); - seat->name = strdup(name); - - wl_list_for_each(seat_client, &seat->clients, link) { - seat_client_send_name(seat_client); - } -} - -WL_EXPORT void -ds_seat_add_destroy_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->events.destroy, listener); -} - -struct ds_seat_client * -seat_client_for_wl_client(struct ds_seat *seat, struct wl_client *wl_client) -{ - struct ds_seat_client *seat_client; - - wl_list_for_each(seat_client, &seat->clients, link) { - if (seat_client->wl_client == wl_client) - return seat_client; - } - - return NULL; -} - -static struct ds_seat_client * -ds_seat_client_get_or_create(struct ds_seat *seat, struct wl_client *wl_client) -{ - struct ds_seat_client *seat_client; - - seat_client = seat_client_for_wl_client(seat, wl_client); - if (!seat_client) { - seat_client = seat_client_create(seat, wl_client); - if (!seat_client) - return NULL; - - wl_list_insert(&seat->clients, &seat_client->link); - } - - return seat_client; -} - -static void -seat_handle_get_pointer(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t id) -{ - struct ds_seat_client *seat_client; - - seat_client = wl_resource_get_user_data(resource); - if (!seat_client) - return; - - if (!(seat_client->seat->accumulated_capabilities & - WL_SEAT_CAPABILITY_POINTER)) { -#ifdef HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY - wl_resource_post_error(resource, WL_SEAT_ERROR_MISSING_CAPABILITY, - "wl_seat.get_pointer called when no " - "pointer capability has existed"); -#endif - return; - } - - seat_client_add_pointer_resource(seat_client, - wl_resource_get_version(resource), id); -} - -static void -seat_handle_get_keyboard(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t id) -{ - struct ds_seat_client *seat_client; - - seat_client = wl_resource_get_user_data(resource); - if (!seat_client) - return; - - if (!(seat_client->seat->accumulated_capabilities & - WL_SEAT_CAPABILITY_KEYBOARD)) { -#ifdef HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY - wl_resource_post_error(resource, WL_SEAT_ERROR_MISSING_CAPABILITY, - "wl_seat.get_keyboard called when no " - "keyboard capability has existed"); -#endif - return; - } - - seat_client_add_keyboard_resource(seat_client, - wl_resource_get_version(resource), id); -} - -static void -seat_handle_get_touch(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t id) -{ - struct ds_seat_client *seat_client; - - seat_client = wl_resource_get_user_data(resource); - if (!seat_client) - return; - - if (!(seat_client->seat->accumulated_capabilities & - WL_SEAT_CAPABILITY_TOUCH)) { -#ifdef HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY - wl_resource_post_error(resource, WL_SEAT_ERROR_MISSING_CAPABILITY, - "wl_seat.get_touch called when no " - "touch capability has existed"); -#endif - return; - } - - seat_client_add_touch_resource(seat_client, - wl_resource_get_version(resource), id); -} - -static void -seat_handle_release(struct wl_client *wl_client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct wl_seat_interface seat_impl = -{ - .get_pointer = seat_handle_get_pointer, - .get_keyboard = seat_handle_get_keyboard, - .get_touch = seat_handle_get_touch, - .release = seat_handle_release, -}; - -static void -seat_client_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_seat_client *seat_client; - - seat_client = wl_resource_get_user_data(resource); - if (!seat_client) - return; - - wl_list_remove(wl_resource_get_link(resource)); - if (!wl_list_empty(&seat_client->resources)) - return; - - seat_client_destroy(seat_client); -} - -static void -seat_handle_bind(struct wl_client *wl_client, void *data, uint32_t version, - uint32_t id) -{ - struct ds_seat *seat = data; - struct ds_seat_client *seat_client; - struct wl_resource *resource; - - resource = wl_resource_create(wl_client, &wl_seat_interface, version, id); - if (!resource) { - wl_client_post_no_memory(wl_client); - return; - } - - seat_client = ds_seat_client_get_or_create(seat, wl_client); - if (!seat_client) { - wl_resource_destroy(resource); - wl_client_post_no_memory(wl_client); - return; - } - - wl_resource_set_implementation(resource, &seat_impl, - seat_client, seat_client_handle_resource_destroy); - - wl_list_insert(&seat_client->resources, wl_resource_get_link(resource)); - - wl_seat_send_capabilities(resource, seat->capabilities); - - if (version >= WL_SEAT_NAME_SINCE_VERSION) - wl_seat_send_name(resource, seat->name); -} - -static void -seat_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_seat *seat; - - seat = wl_container_of(listener, seat, display_destroy); - seat_destroy(seat); -} - -static void -seat_destroy(struct ds_seat *seat) -{ - struct ds_seat_client *seat_client, *tmp; - struct wl_resource *resource, *next; - - wl_signal_emit(&seat->events.destroy, seat); - - wl_list_remove(&seat->display_destroy.link); - - wl_list_for_each_safe(seat_client, tmp, &seat->clients, link) { - wl_resource_for_each_safe(resource, next, &seat_client->resources) { - wl_list_remove(wl_resource_get_link(resource)); - wl_resource_set_user_data(resource, NULL); - } - seat_client_destroy(seat_client); - } - - seat_pointer_finish(seat); - seat_keyboard_finish(seat); - seat_touch_finish(seat); - - wl_global_destroy(seat->global); - free(seat->name); - free(seat); -} - -static struct ds_seat_client * -seat_client_create(struct ds_seat *seat, struct wl_client *wl_client) -{ - struct ds_seat_client *seat_client; - - seat_client = calloc(1, sizeof *seat_client); - seat_client->seat = seat; - seat_client->wl_client = wl_client; - - wl_list_init(&seat_client->resources); - wl_list_init(&seat_client->pointers); - wl_list_init(&seat_client->keyboards); - wl_list_init(&seat_client->touches); - - wl_signal_init(&seat_client->events.destroy); - - return seat_client; -} - -static void -seat_client_destroy(struct ds_seat_client *seat_client) -{ - wl_signal_emit(&seat_client->events.destroy, seat_client); - - seat_client_remove_all_pointer_resources(seat_client); - seat_client_remove_all_keyboard_resources(seat_client); - seat_client_remove_all_touch_resources(seat_client); - - wl_list_remove(&seat_client->link); - - free(seat_client); -} - -static void -seat_client_send_capabilities(struct ds_seat_client *seat_client) -{ - struct wl_resource *resource; - - wl_resource_for_each(resource, &seat_client->resources) { - wl_seat_send_capabilities(resource, seat_client->seat->capabilities); - } -} - -static void -seat_client_send_name(struct ds_seat_client *seat_client) -{ - struct wl_resource *resource; - - wl_resource_for_each(resource, &seat_client->resources) { - wl_seat_send_name(resource, seat_client->seat->name); - } -} diff --git a/src/libds/seat/seat_keyboard.c b/src/libds/seat/seat_keyboard.c deleted file mode 100644 index 8931a5c..0000000 --- a/src/libds/seat/seat_keyboard.c +++ /dev/null @@ -1,383 +0,0 @@ -#include -#include -#include -#include - -#include "libds/log.h" -#include "seat_private.h" - -static const struct ds_keyboard_grab_interface default_keyboard_grab_iface; -static const struct wl_keyboard_interface keyboard_impl; - -static void -seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client, - struct ds_surface *surface); -static void -seat_keyboard_handle_surface_destroy(struct wl_listener *listener, - void *data); -static void keyboard_handle_resource_destroy(struct wl_resource *resource); - -WL_EXPORT void -ds_seat_keyboard_notify_enter(struct ds_seat *seat, - struct ds_surface *surface, uint32_t keycodes[], size_t num_keycodes, - struct ds_keyboard_modifiers *modifiers) -{ - struct ds_seat_keyboard_grab *grab = seat->keyboard.grab; - - grab->iface->enter(grab, surface, keycodes, num_keycodes, modifiers); -} - -WL_EXPORT void -ds_seat_keyboard_notify_clear_focus(struct ds_seat *seat) -{ - struct ds_seat_keyboard_grab *grab = seat->keyboard.grab; - - grab->iface->clear_focus(grab); -} - -WL_EXPORT void -ds_seat_keyboard_notify_modifiers(struct ds_seat *seat, - struct ds_keyboard_modifiers *modifiers) -{ - struct ds_seat_keyboard_grab *grab = seat->keyboard.grab; - - clock_gettime(CLOCK_MONOTONIC, &seat->last_event); - grab->iface->modifiers(grab, modifiers); -} - -WL_EXPORT void -ds_seat_keyboard_notify_key(struct ds_seat *seat, uint32_t time_msec, - uint32_t key, uint32_t state) -{ - struct ds_seat_keyboard_grab *grab = seat->keyboard.grab; - - clock_gettime(CLOCK_MONOTONIC, &seat->last_event); - grab->iface->key(grab, time_msec, key, state); -} - -WL_EXPORT void -ds_seat_keyboard_add_grab_begin_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->events.keyboard_grab_begin, listener); -} - -WL_EXPORT void -ds_seat_keyboard_add_grab_end_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->events.keyboard_grab_end, listener); -} - -WL_EXPORT void -ds_seat_keyboard_add_focus_change_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->keyboard.events.focus_change, listener); -} - -void -ds_seat_keyboard_start_grab(struct ds_seat *seat, - struct ds_seat_keyboard_grab *grab) -{ - grab->seat = seat; - seat->keyboard.grab = grab; - - wl_signal_emit(&seat->events.keyboard_grab_begin, grab); -} - -void -ds_seat_keyboard_end_grab(struct ds_seat *seat) -{ - struct ds_seat_keyboard *keyboard = &seat->keyboard; - struct ds_seat_keyboard_grab *grab = keyboard->grab; - - if (grab != keyboard->default_grab) { - keyboard->grab = keyboard->default_grab; - wl_signal_emit(&seat->events.keyboard_grab_end, grab); - if (grab->iface->cancel) - grab->iface->cancel(grab); - } -} - -void -ds_seat_keyboard_enter(struct ds_seat *seat, struct ds_surface *surface, - uint32_t keycodes[], size_t num_keycodes, - struct ds_keyboard_modifiers *modifiers) -{ - struct ds_seat_keyboard *keyboard = &seat->keyboard; - struct ds_seat_client *seat_client = NULL, *focused_client; - struct ds_surface *focused_surface; - struct wl_client *wl_client; - struct wl_array keys; - struct wl_resource *resource; - uint32_t *p; - uint32_t serial; - - if (keyboard->focused_surface == surface) - return; - - if (surface) { - wl_client = - wl_resource_get_client(ds_surface_get_wl_resource(surface)); - seat_client = seat_client_for_wl_client(seat, wl_client); - } - - focused_client = keyboard->focused_client; - focused_surface = keyboard->focused_surface; - - if (focused_client != NULL && focused_surface != NULL) - seat_client_send_keyboard_leave_raw(focused_client, focused_surface); - - if (seat_client) { - wl_array_init(&keys); - - for (size_t i = 0; i < num_keycodes; i++) { - p = wl_array_add(&keys, sizeof(uint32_t)); - if (!p) { - ds_err("Cannot allocate memory, skipping keycode: %" PRIu32 - "\n", keycodes[i]); - continue; - } - *p = keycodes[i]; - } - - serial = wl_display_next_serial(seat->display); - - wl_resource_for_each(resource, &seat_client->keyboards) { - wl_keyboard_send_enter(resource, serial, - ds_surface_get_wl_resource(surface), &keys); - } - wl_array_release(&keys); - } - - wl_list_remove(&keyboard->surface_destroy.link); - wl_list_init(&keyboard->surface_destroy.link); - - if (surface) { - keyboard->surface_destroy.notify = - seat_keyboard_handle_surface_destroy; - ds_surface_add_destroy_listener(surface, &keyboard->surface_destroy); - } - - keyboard->focused_client = seat_client; - keyboard->focused_surface = surface; - - if (seat_client) { - ds_seat_keyboard_send_modifiers(seat, modifiers); - - // TODO handle selection - } - - struct ds_event_seat_keyboard_focus_change event = { - .seat = seat, - .old_surface = focused_surface, - .new_surface = surface, - }; - wl_signal_emit(&keyboard->events.focus_change, &event); -} - -void -ds_seat_keyboard_clear_focus(struct ds_seat *seat) -{ - ds_seat_keyboard_enter(seat, NULL, NULL, 0, NULL); -} - -void -ds_seat_keyboard_send_key(struct ds_seat *seat, uint32_t time_msec, - uint32_t key, uint32_t state) -{ - struct ds_seat_client *seat_client; - struct wl_resource *resource; - uint32_t serial; - - seat_client = seat->keyboard.focused_client; - if (!seat_client) - return; - - serial = wl_display_next_serial(seat->display); - wl_resource_for_each(resource, &seat_client->keyboards) - wl_keyboard_send_key(resource, serial, time_msec, key, state); -} - -void -ds_seat_keyboard_send_modifiers(struct ds_seat *seat, - struct ds_keyboard_modifiers *modifiers) -{ - struct ds_seat_keyboard *keyboard = &seat->keyboard; - struct ds_seat_client *seat_client = keyboard->focused_client; - struct wl_resource *resource; - uint32_t serial; - - if (!seat_client) - return; - - serial = wl_display_next_serial(seat->display); - wl_resource_for_each(resource, &seat_client->keyboards) { - if (!modifiers) { - wl_keyboard_send_modifiers(resource, serial, 0, 0, 0, 0); - } - else { - wl_keyboard_send_modifiers(resource, serial, - modifiers->depressed, modifiers->latched, - modifiers->locked, modifiers->group); - } - } -} - -bool -seat_keyboard_init(struct ds_seat *seat) -{ - struct ds_seat_keyboard *keyboard = &seat->keyboard; - struct ds_seat_keyboard_grab *grab; - - grab = calloc(1, sizeof *grab); - if (!grab) - return false; - - grab->iface = &default_keyboard_grab_iface; - grab->seat = seat; - - keyboard->default_grab = grab; - keyboard->grab = grab; - keyboard->seat = seat; - - wl_list_init(&keyboard->surface_destroy.link); - - wl_signal_init(&keyboard->events.focus_change); - - return true; -} - -void seat_keyboard_finish(struct ds_seat *seat) -{ - struct ds_seat_keyboard *keyboard = &seat->keyboard; - - wl_list_remove(&keyboard->surface_destroy.link); - free(keyboard->default_grab); -} - -void -seat_client_add_keyboard_resource(struct ds_seat_client *seat_client, - uint32_t version, uint32_t id) -{ - struct wl_resource *resource; - - resource = wl_resource_create(seat_client->wl_client, - &wl_keyboard_interface, version, id); - if (!resource) { - wl_client_post_no_memory(seat_client->wl_client); - return; - } - - wl_resource_set_implementation(resource, &keyboard_impl, seat_client, - keyboard_handle_resource_destroy); - - wl_list_insert(&seat_client->keyboards, wl_resource_get_link(resource)); - - if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)) { - wl_resource_set_user_data(resource, NULL); - return; - } -} - -void -seat_client_remove_all_keyboard_resources(struct ds_seat_client *seat_client) -{ - struct wl_resource *resource, *tmp; - - wl_resource_for_each_safe(resource, tmp, &seat_client->keyboards) { - wl_list_remove(wl_resource_get_link(resource)); - wl_resource_set_user_data(resource, NULL); - } -} - -static void -keyboard_handle_release(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct wl_keyboard_interface keyboard_impl = -{ - .release = keyboard_handle_release, -}; - -static void -keyboard_handle_resource_destroy(struct wl_resource *resource) -{ - if (!wl_resource_get_user_data(resource)) - return; - - wl_list_remove(wl_resource_get_link(resource)); -} - -static void -default_keyboard_grab_iface_enter(struct ds_seat_keyboard_grab *grab, - struct ds_surface *surface, uint32_t keycodes[], - size_t num_keycodes, struct ds_keyboard_modifiers *modifiers) -{ - ds_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes, - modifiers); -} - -static void -default_keyboard_grab_iface_clear_focus(struct ds_seat_keyboard_grab *grab) -{ - ds_seat_keyboard_clear_focus(grab->seat); -} - -static void -default_keyboard_grab_iface_key(struct ds_seat_keyboard_grab *grab, - uint32_t time_msec, uint32_t key, uint32_t state) -{ - ds_seat_keyboard_send_key(grab->seat, time_msec, key, state); -} - -static void -default_modifiers_grab_iface_key(struct ds_seat_keyboard_grab *grab, - struct ds_keyboard_modifiers *modifiers) -{ - ds_seat_keyboard_send_modifiers(grab->seat, modifiers); -} - -static void -default_cancel_grab_iface_key(struct ds_seat_keyboard_grab *grab) -{ - // cannot be cancelled -} - -static const struct ds_keyboard_grab_interface default_keyboard_grab_iface = { - .enter = default_keyboard_grab_iface_enter, - .clear_focus = default_keyboard_grab_iface_clear_focus, - .key = default_keyboard_grab_iface_key, - .modifiers = default_modifiers_grab_iface_key, - .cancel = default_cancel_grab_iface_key, -}; - -static void -seat_client_send_keyboard_leave_raw(struct ds_seat_client *seat_client, - struct ds_surface *surface) -{ - struct wl_resource *resource; - uint32_t serial; - - serial = wl_display_next_serial(wl_client_get_display(seat_client->wl_client)); - wl_resource_for_each(resource, &seat_client->keyboards) { - wl_keyboard_send_leave(resource, serial, - ds_surface_get_wl_resource(surface)); - } -} - -static void -seat_keyboard_handle_surface_destroy(struct wl_listener *listener, - void *data) -{ - struct ds_seat_keyboard *keyboard; - - keyboard = wl_container_of(listener, keyboard, surface_destroy); - - wl_list_remove(&keyboard->surface_destroy.link); - wl_list_init(&keyboard->surface_destroy.link); - ds_seat_keyboard_clear_focus(keyboard->seat); -} diff --git a/src/libds/seat/seat_pointer.c b/src/libds/seat/seat_pointer.c deleted file mode 100644 index 2616756..0000000 --- a/src/libds/seat/seat_pointer.c +++ /dev/null @@ -1,512 +0,0 @@ -#include -#include -#include -#include - -#include "seat_private.h" - -static const struct ds_pointer_grab_interface default_pointer_grab_iface; -static const struct wl_pointer_interface pointer_impl; - -static void seat_pointer_warp(struct ds_seat *seat, double sx, double sy); -static void -seat_client_send_pointer_leave_raw(struct ds_seat_client *seat_client, - struct ds_surface *surface); -static void -seat_pointer_handle_surface_destroy(struct wl_listener *listener, - void *data); -static void pointer_handle_resource_destroy(struct wl_resource *resource); -static void pointer_send_frame(struct wl_resource *resource); - -WL_EXPORT void -ds_seat_pointer_notify_enter(struct ds_seat *seat, struct ds_surface *surface, - double sx, double sy) -{ - struct ds_seat_pointer_grab *grab = seat->pointer.grab; - - assert(surface); - grab->iface->enter(grab, surface, sx, sy); -} - -WL_EXPORT void -ds_seat_pointer_notify_clear_focus(struct ds_seat *seat) -{ - struct ds_seat_pointer_grab *grab = seat->pointer.grab; - - grab->iface->clear_focus(grab); -} - -WL_EXPORT void -ds_seat_pointer_notify_motion(struct ds_seat *seat, uint32_t time_msec, - double sx, double sy) -{ - struct ds_seat_pointer_grab *grab = seat->pointer.grab; - - grab->iface->motion(grab, time_msec, sx, sy); -} - -WL_EXPORT uint32_t -ds_seat_pointer_notify_button(struct ds_seat *seat, uint32_t time_msec, - uint32_t button, enum ds_button_state state) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - struct ds_seat_pointer_grab *grab = pointer->grab; - uint32_t serial; - - if (state == DS_BUTTON_PRESSED) { - if (pointer->button_count == 0) { - pointer->grab_button = button; - pointer->grab_time = time_msec; - } - // TODO need a set struct for assigning pointer->buttons - } - else { - // TODO - } - - serial = grab->iface->button(grab, time_msec, button, state); - if (serial && pointer->button_count == 1 && - state == DS_BUTTON_PRESSED) - pointer->grab_serial = serial; - - return serial; -} - -WL_EXPORT void -ds_seat_pointer_notify_axis(struct ds_seat *seat, uint32_t time_msec, - enum ds_axis_orientation orientation, double value, - int32_t value_discrete, enum ds_axis_source source) -{ - struct ds_seat_pointer_grab *grab = seat->pointer.grab; - - clock_gettime(CLOCK_MONOTONIC, &seat->last_event); - grab->iface->axis(grab, time_msec, orientation, value, value_discrete, source); -} - -WL_EXPORT void -ds_seat_pointer_notify_frame(struct ds_seat *seat) -{ - struct ds_seat_pointer_grab *grab = seat->pointer.grab; - - clock_gettime(CLOCK_MONOTONIC, &seat->last_event); - if (grab->iface->frame) - grab->iface->frame(grab); -} - -WL_EXPORT void -ds_seat_pointer_add_grab_begin_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->events.pointer_grab_begin, listener); -} - -WL_EXPORT void -ds_seat_pointer_add_grab_end_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->events.pointer_grab_end, listener); -} - -WL_EXPORT void -ds_seat_pointer_add_focus_change_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->pointer.events.focus_change, listener); -} - -void -ds_seat_pointer_start_grab(struct ds_seat *seat, - struct ds_seat_pointer_grab *grab) -{ - grab->seat = seat; - seat->pointer.grab = grab; - wl_signal_emit(&seat->events.pointer_grab_begin, grab); -} - -void -ds_seat_pointer_end_grab(struct ds_seat *seat) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - struct ds_seat_pointer_grab *grab = pointer->grab; - - if (grab != pointer->default_grab) { - pointer->grab = pointer->default_grab; - wl_signal_emit(&seat->events.pointer_grab_end, grab); - if (grab->iface->cancel) - grab->iface->cancel(grab); - } -} - -void -ds_seat_pointer_enter(struct ds_seat *seat, struct ds_surface *surface, - double sx, double sy) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - struct ds_seat_client *seat_client = NULL, *focused_client; - struct ds_surface *focused_surface; - struct wl_client *wl_client; - struct wl_resource *resource; - uint32_t serial; - - if (pointer->focused_surface == surface) { - // this surface already got an enter notify - return; - } - - focused_client = pointer->focused_client; - focused_surface = pointer->focused_surface; - - if (focused_client != NULL && focused_surface != NULL) - seat_client_send_pointer_leave_raw(focused_client, focused_surface); - - if (surface) { - wl_client = - wl_resource_get_client(ds_surface_get_wl_resource(surface)); - seat_client = seat_client_for_wl_client(seat, wl_client); - } - - if (seat_client) { - serial = wl_display_next_serial(seat->display); - wl_resource_for_each(resource, &seat_client->pointers) { - wl_pointer_send_enter(resource, serial, - ds_surface_get_wl_resource(surface), - wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - pointer_send_frame(resource); - } - } - - wl_list_remove(&pointer->surface_destroy.link); - wl_list_init(&pointer->surface_destroy.link); - - if (surface) { - pointer->surface_destroy.notify = - seat_pointer_handle_surface_destroy; - ds_surface_add_destroy_listener(surface, &pointer->surface_destroy); - } - - pointer->focused_client = seat_client; - pointer->focused_surface = surface; - if (surface) - seat_pointer_warp(seat, sx, sy); - else - seat_pointer_warp(seat, NAN, NAN); - - struct ds_event_seat_pointer_focus_change event = { - .seat = seat, - .new_surface = surface, - .old_surface = focused_surface, - .sx = sx, - .sy = sy, - }; - wl_signal_emit(&pointer->events.focus_change, &event); -} - -void -ds_seat_pointer_clear_focus(struct ds_seat *seat) -{ - ds_seat_pointer_enter(seat, NULL, 0, 0); -} - -void -ds_seat_pointer_send_motion(struct ds_seat *seat, uint32_t time_msec, - double sx, double sy) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - struct ds_seat_client *seat_client = pointer->focused_client; - struct wl_resource *resource; - wl_fixed_t sx_fixed, sy_fixed; - - if (!seat_client) - return; - - sx_fixed = wl_fixed_from_double(sx); - sy_fixed = wl_fixed_from_double(sy); - if (wl_fixed_from_double(pointer->sx) != sx_fixed || - wl_fixed_from_double(pointer->sy) != sy_fixed) { - wl_resource_for_each(resource, &seat_client->pointers) - wl_pointer_send_motion(resource, time_msec, sx_fixed, sy_fixed); - } - - seat_pointer_warp(seat, sx, sy); -} - -uint32_t -ds_seat_pointer_send_button(struct ds_seat *seat, uint32_t time_msec, - uint32_t button, enum ds_button_state state) -{ - struct ds_seat_client *seat_client = seat->pointer.focused_client; - struct wl_resource *resource; - uint32_t serial; - - if (!seat_client) - return 0; - - serial = wl_display_next_serial(seat->display); - wl_resource_for_each(resource, &seat_client->pointers) - wl_pointer_send_button(resource, serial, time_msec, button, state); - - return serial; -} - -void -ds_seat_pointer_send_axis(struct ds_seat *seat, uint32_t time_msec, - enum ds_axis_orientation orientation, double value, - int32_t value_discrete, enum ds_axis_source source) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - struct ds_seat_client *seat_client = pointer->focused_client; - struct wl_resource *resource; - uint32_t version; - bool send_source = false; - - if (!seat_client) - return; - - if (pointer->sent_axis_source) { - assert(pointer->cached_axis_source == source); - } - else { - pointer->sent_axis_source = true; - pointer->cached_axis_source = source; - send_source = true; - } - - wl_resource_for_each(resource, &seat_client->pointers) { - version = wl_resource_get_version(resource); - - if (send_source && version >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) - wl_pointer_send_axis_source(resource, source); - - if (value) { - if (value_discrete && - version >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) { - wl_pointer_send_axis_discrete(resource, orientation, - value_discrete); - } - - wl_pointer_send_axis(resource, time_msec, orientation, - wl_fixed_from_double(value)); - } - else if (version >= WL_POINTER_AXIS_STOP_SINCE_VERSION) { - wl_pointer_send_axis_stop(resource, time_msec, orientation); - } - } -} - -void -ds_seat_pointer_send_frame(struct ds_seat *seat) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - struct ds_seat_client *seat_client = pointer->focused_client; - struct wl_resource *resource; - - if (!seat_client) - return; - - pointer->sent_axis_source = false; - - wl_resource_for_each(resource, &seat_client->pointers) - pointer_send_frame(resource); -} - -bool -seat_pointer_init(struct ds_seat *seat) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - struct ds_seat_pointer_grab *grab; - - grab = calloc(1, sizeof *grab); - if (!grab) - return false; - - grab->iface = &default_pointer_grab_iface; - grab->seat = seat; - - pointer->default_grab = grab; - pointer->grab = grab; - pointer->seat = seat; - - wl_list_init(&pointer->surface_destroy.link); - - wl_signal_init(&pointer->events.focus_change); - - return true; -} - -void -seat_pointer_finish(struct ds_seat *seat) -{ - struct ds_seat_pointer *pointer = &seat->pointer; - - wl_list_remove(&pointer->surface_destroy.link); - free(pointer->default_grab); -} - -void -seat_client_add_pointer_resource(struct ds_seat_client *seat_client, - uint32_t version, uint32_t id) -{ - struct wl_resource *resource; - - resource = wl_resource_create(seat_client->wl_client, - &wl_pointer_interface, version, id); - if (!resource) { - wl_client_post_no_memory(seat_client->wl_client); - return; - } - - wl_resource_set_implementation(resource, &pointer_impl, seat_client, - &pointer_handle_resource_destroy); - - if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_POINTER)) { - wl_resource_set_user_data(resource, NULL); - return; - } - - wl_list_insert(&seat_client->pointers, wl_resource_get_link(resource)); -} - -void -seat_client_remove_all_pointer_resources(struct ds_seat_client *seat_client) -{ - struct wl_resource *resource, *tmp; - - wl_resource_for_each_safe(resource, tmp, &seat_client->pointers) { - wl_list_remove(wl_resource_get_link(resource)); - wl_resource_set_user_data(resource, NULL); - } -} - -static void -seat_pointer_warp(struct ds_seat *seat, double sx, double sy) -{ - seat->pointer.sx = sx; - seat->pointer.sy = sy; -} - -static void -seat_client_send_pointer_leave_raw(struct ds_seat_client *seat_client, - struct ds_surface *surface) -{ - struct wl_resource *resource; - uint32_t serial; - - serial = wl_display_next_serial(seat_client->seat->display); - wl_resource_for_each(resource, &seat_client->pointers) { - wl_pointer_send_leave(resource, serial, - ds_surface_get_wl_resource(surface)); - pointer_send_frame(resource); - } -} - -static void -seat_pointer_handle_surface_destroy(struct wl_listener *listener, void *data) -{ - struct ds_seat_pointer *pointer; - - pointer = wl_container_of(listener, pointer, surface_destroy); - wl_list_remove(&pointer->surface_destroy.link); - wl_list_init(&pointer->surface_destroy.link); - ds_seat_pointer_clear_focus(pointer->seat); -} - -static void -default_pointer_grab_iface_enter(struct ds_seat_pointer_grab *grab, - struct ds_surface *surface, double sx, double sy) -{ - ds_seat_pointer_enter(grab->seat, surface, sx, sy); -} - -static void -default_pointer_grab_iface_clear_focus(struct ds_seat_pointer_grab *grab) -{ - ds_seat_pointer_clear_focus(grab->seat); -} - -static void -default_pointer_grab_iface_motion(struct ds_seat_pointer_grab *grab, - uint32_t time_msec, double sx, double sy) -{ - ds_seat_pointer_send_motion(grab->seat, time_msec, sx, sy); -} - -static uint32_t -default_pointer_grab_iface_button(struct ds_seat_pointer_grab *grab, - uint32_t time_msec, uint32_t button, enum ds_button_state state) -{ - return ds_seat_pointer_send_button(grab->seat, time_msec, button, state); -} - -static void -default_pointer_grab_iface_axis(struct ds_seat_pointer_grab *grab, - uint32_t time_msec, enum ds_axis_orientation orientation, double value, - int32_t value_discrete, enum ds_axis_source source) -{ - ds_seat_pointer_send_axis(grab->seat, time_msec, orientation, value, - value_discrete, source); -} - -static void -default_pointer_grab_iface_frame(struct ds_seat_pointer_grab *grab) -{ - ds_seat_pointer_send_frame(grab->seat); -} - -static void -default_pointer_grab_iface_cancel(struct ds_seat_pointer_grab *grab) -{ - // cannot be cancelled -} - -static const struct ds_pointer_grab_interface default_pointer_grab_iface = { - .enter = default_pointer_grab_iface_enter, - .clear_focus = default_pointer_grab_iface_clear_focus, - .motion = default_pointer_grab_iface_motion, - .button = default_pointer_grab_iface_button, - .axis = default_pointer_grab_iface_axis, - .frame = default_pointer_grab_iface_frame, - .cancel = default_pointer_grab_iface_cancel, -}; - -static void -pointer_handle_set_cursor(struct wl_client *client, - struct wl_resource *pointer_resource, uint32_t serial, - struct wl_resource *surface_resource, - int32_t hotspot_x, int32_t hotspot_y) -{ - struct ds_seat_client *seat_client; - - seat_client = wl_resource_get_user_data(pointer_resource); - if (!seat_client) - return; - - // TODO -} - -static void -pointer_handle_release(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct wl_pointer_interface pointer_impl = -{ - .set_cursor = pointer_handle_set_cursor, - .release = pointer_handle_release, -}; - -static void pointer_handle_resource_destroy(struct wl_resource *resource) -{ - if (!wl_resource_get_user_data(resource)) - return; - - wl_list_remove(wl_resource_get_link(resource)); -} - -static void -pointer_send_frame(struct wl_resource *resource) -{ - if (wl_resource_get_version(resource) >= - WL_POINTER_FRAME_SINCE_VERSION) - wl_pointer_send_frame(resource); -} diff --git a/src/libds/seat/seat_private.h b/src/libds/seat/seat_private.h deleted file mode 100644 index 7a566bb..0000000 --- a/src/libds/seat/seat_private.h +++ /dev/null @@ -1,172 +0,0 @@ -#ifndef DS_SEAT_PRIVATE_H -#define DS_SEAT_PRIVATE_H - -#include -#include - -#include "libds/seat.h" -#include "seat.h" -#include "surface.h" - -struct ds_seat_client -{ - struct ds_seat *seat; - struct wl_client *wl_client; - struct wl_list link; - - struct wl_list resources; // wl_seat - struct wl_list pointers; // wl_pointer - struct wl_list keyboards; // wl_keyboard - struct wl_list touches; // wl_touch - - struct { - struct wl_signal destroy; - } events; - - bool needs_touch_frame; -}; - -#define DS_POINTER_BUTTONS_CAP 16 - -struct ds_seat_pointer -{ - struct ds_seat *seat; - struct ds_seat_client *focused_client; - struct ds_surface *focused_surface; - double sx, sy; - - struct ds_seat_pointer_grab *grab; - struct ds_seat_pointer_grab *default_grab; - - bool sent_axis_source; - enum ds_axis_source cached_axis_source; - - uint32_t buttons[DS_POINTER_BUTTONS_CAP]; - size_t button_count; - uint32_t grab_button; - uint32_t grab_serial; - uint32_t grab_time; - - struct wl_listener surface_destroy; - - struct { - struct wl_signal focus_change; - } events; -}; - -struct ds_seat_keyboard -{ - struct ds_seat *seat; - - struct ds_seat_client *focused_client; - struct ds_surface *focused_surface; - - struct wl_listener surface_destroy; - - struct ds_seat_keyboard_grab *grab; - struct ds_seat_keyboard_grab *default_grab; - - struct { - struct wl_signal focus_change; - } events; -}; - -struct ds_touch_point -{ - int32_t touch_id; - struct ds_surface *surface; - struct ds_seat_client *seat_client; - - struct ds_seat_client *focused_client; - struct ds_surface *focused_surface; - double sx, sy; - - struct wl_listener surface_destroy; - struct wl_listener focused_surface_destroy; - struct wl_listener client_destroy; - - struct { - struct wl_signal destroy; - } events; - - struct wl_list link; -}; - -struct ds_seat_touch -{ - struct ds_seat *seat; - struct wl_list touch_points; // ds_touch_point::link - - uint32_t grab_serial; - uint32_t grab_id; - - struct ds_seat_touch_grab *grab; - struct ds_seat_touch_grab *default_grab; -}; - -struct ds_seat -{ - char *name; - enum wl_seat_capability capabilities; - enum wl_seat_capability accumulated_capabilities; - struct timespec last_event; - - struct wl_display *display; - struct wl_global *global; - - struct wl_list clients; // ds_seat_client::link - - struct ds_seat_pointer pointer; - struct ds_seat_keyboard keyboard; - struct ds_seat_touch touch; - - struct wl_listener display_destroy; - - struct { - struct wl_signal destroy; - - struct wl_signal pointer_grab_begin; - struct wl_signal pointer_grab_end; - - struct wl_signal keyboard_grab_begin; - struct wl_signal keyboard_grab_end; - - struct wl_signal touch_grab_begin; - struct wl_signal touch_grab_end; - } events; -}; - -struct ds_seat_client * -seat_client_for_wl_client(struct ds_seat *seat, struct wl_client *wl_client); - -bool seat_pointer_init(struct ds_seat *seat); - -void seat_pointer_finish(struct ds_seat *seat); - -void seat_client_add_pointer_resource(struct ds_seat_client *seat_client, - uint32_t version, uint32_t id); - -void -seat_client_remove_all_pointer_resources(struct ds_seat_client *seat_client); - -bool seat_keyboard_init(struct ds_seat *seat); - -void seat_keyboard_finish(struct ds_seat *seat); - -void seat_client_add_keyboard_resource(struct ds_seat_client *seat_client, - uint32_t version, uint32_t id); - -void -seat_client_remove_all_keyboard_resources(struct ds_seat_client *seat_client); - -bool seat_touch_init(struct ds_seat *seat); - -void seat_touch_finish(struct ds_seat *seat); - -void seat_client_add_touch_resource(struct ds_seat_client *seat_client, - uint32_t version, uint32_t id); - -void -seat_client_remove_all_touch_resources(struct ds_seat_client *seat_client); - -#endif diff --git a/src/libds/seat/seat_touch.c b/src/libds/seat/seat_touch.c deleted file mode 100644 index 476c6a8..0000000 --- a/src/libds/seat/seat_touch.c +++ /dev/null @@ -1,432 +0,0 @@ -#include -#include -#include - -#include "libds/log.h" -#include "seat_private.h" - -static const struct ds_touch_grab_interface default_touch_grab_iface; -static const struct wl_touch_interface touch_impl; - -static void touch_handle_resource_destroy(struct wl_resource *resource); -static struct ds_touch_point *touch_point_create(struct ds_seat *seat, - int32_t touch_id, struct ds_surface *surface, double sx, double sy); -static void touch_point_destroy(struct ds_touch_point *point); -static void touch_point_clear_focus(struct ds_touch_point *point); -static struct ds_touch_point *seat_find_touch_point(struct ds_seat *seat, - int32_t touch_id); -static int seat_touch_num_points(struct ds_seat *seat); - -WL_EXPORT uint32_t -ds_seat_touch_notify_down(struct ds_seat *seat, struct ds_surface *surface, - uint32_t time_msec, int32_t touch_id, double sx, double sy) -{ - struct ds_seat_touch_grab *grab = seat->touch.grab; - struct ds_touch_point *point; - uint32_t serial; - - // FIXME - // What if ds_touch_point is already exist associated with given touch_id? - point = touch_point_create(seat, touch_id, surface, sx, sy); - if (!point) { - ds_err("Could not create touch point"); - return 0; - } - - serial = grab->iface->down(grab, time_msec, point); - if (!serial) { - touch_point_destroy(point); - return 0; - } - - if (serial && seat_touch_num_points(seat) == 1) { - seat->touch.grab_serial = serial; - seat->touch.grab_id = touch_id; - } - - return serial; -} - -WL_EXPORT void -ds_seat_touch_notify_up(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id) -{ - struct ds_seat_touch_grab *grab = seat->touch.grab; - struct ds_touch_point *point; - - clock_gettime(CLOCK_MONOTONIC, &seat->last_event); - - point = seat_find_touch_point(seat, touch_id); - if (!point) - return; - - grab->iface->up(grab, time_msec, point); - - touch_point_destroy(point); -} - -WL_EXPORT void -ds_seat_touch_notify_motion(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id, double sx, double sy) -{ - struct ds_seat_touch_grab *grab = seat->touch.grab; - struct ds_touch_point *point; - - clock_gettime(CLOCK_MONOTONIC, &seat->last_event); - - point = seat_find_touch_point(seat, touch_id); - if (!point) - return; - - point->sx = sx; - point->sy = sy; - - grab->iface->motion(grab, time_msec, point); -} - -WL_EXPORT void -ds_seat_touch_notify_frame(struct ds_seat *seat) -{ - struct ds_seat_touch_grab *grab = seat->touch.grab; - - if (grab->iface->frame) - grab->iface->frame(grab); -} - -WL_EXPORT void -ds_seat_touch_add_grab_start_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->events.touch_grab_begin, listener); -} - -WL_EXPORT void -ds_seat_touch_end_grab_start_listener(struct ds_seat *seat, - struct wl_listener *listener) -{ - wl_signal_add(&seat->events.touch_grab_end, listener); -} - -uint32_t -ds_seat_touch_send_down(struct ds_seat *seat, struct ds_surface *surface, - uint32_t time_msec, int32_t touch_id, double sx, double sy) -{ - struct ds_touch_point *point; - struct wl_resource *resource; - uint32_t serial; - - point = seat_find_touch_point(seat, touch_id); - if (!point) { - ds_err("Got touch down for unknown touch point"); - return 0; - } - - serial = wl_display_next_serial(seat->display); - wl_resource_for_each(resource, &point->seat_client->touches) { - wl_touch_send_down(resource, serial, time_msec, - ds_surface_get_wl_resource(surface), touch_id, - wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - } - - point->seat_client->needs_touch_frame = true; - - return serial; -} - -void -ds_seat_touch_send_up(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id) -{ - struct ds_touch_point *point; - struct wl_resource *resource; - uint32_t serial; - - point = seat_find_touch_point(seat, touch_id); - if (!point) { - ds_err("Got touch up for unknown touch point"); - return; - } - - serial = wl_display_next_serial(seat->display); - wl_resource_for_each(resource, &point->seat_client->touches) - wl_touch_send_up(resource, serial, time_msec, touch_id); - - point->seat_client->needs_touch_frame = true; -} - -void -ds_seat_touch_send_motion(struct ds_seat *seat, uint32_t time_msec, - int32_t touch_id, double sx, double sy) -{ - struct ds_touch_point *point; - struct wl_resource *resource; - - point = seat_find_touch_point(seat, touch_id); - if (!point) { - ds_err("Got touch motion for unknown touch point"); - return; - } - - wl_resource_for_each(resource, &point->seat_client->touches) { - wl_touch_send_motion(resource, time_msec, touch_id, - wl_fixed_from_double(sx), wl_fixed_from_double(sy)); - } - - point->seat_client->needs_touch_frame = true; -} - -void -ds_seat_touch_send_frame(struct ds_seat *seat) -{ - struct ds_seat_client *seat_client; - struct wl_resource *resource; - - wl_list_for_each(seat_client, &seat->clients, link) { - if (!seat_client->needs_touch_frame) - continue; - - wl_resource_for_each(resource, &seat_client->touches) - wl_touch_send_frame(resource); - - seat_client->needs_touch_frame = false; - } -} - -bool -seat_touch_init(struct ds_seat *seat) -{ - struct ds_seat_touch *touch = &seat->touch; - struct ds_seat_touch_grab *grab; - - grab = calloc(1, sizeof *grab); - if (!grab) - return false; - - grab->iface = &default_touch_grab_iface; - grab->seat = seat; - - touch->default_grab = grab; - touch->grab = grab; - touch->seat = seat; - - wl_list_init(&touch->touch_points); - - return true; -} - -void -seat_touch_finish(struct ds_seat *seat) -{ - struct ds_seat_touch *touch = &seat->touch; - struct ds_touch_point *point; - - wl_list_for_each(point, &touch->touch_points, link) - touch_point_clear_focus(point); - - free(touch->default_grab); -} - -void -seat_client_add_touch_resource(struct ds_seat_client *seat_client, - uint32_t version, uint32_t id) -{ - struct wl_resource *resource; - - resource = wl_resource_create(seat_client->wl_client, - &wl_touch_interface, version, id); - if (!resource) { - wl_client_post_no_memory(seat_client->wl_client); - return; - } - - wl_resource_set_implementation(resource, &touch_impl, seat_client, - touch_handle_resource_destroy); - - wl_list_insert(&seat_client->touches, wl_resource_get_link(resource)); - - if (!(seat_client->seat->capabilities & WL_SEAT_CAPABILITY_TOUCH)) - wl_resource_set_user_data(resource, NULL); -} - -void -seat_client_remove_all_touch_resources(struct ds_seat_client *seat_client) -{ - struct wl_resource *resource, *tmp; - - wl_resource_for_each_safe(resource, tmp, &seat_client->touches) { - wl_list_remove(wl_resource_get_link(resource)); - wl_resource_set_user_data(resource, NULL); - } -} - -static uint32_t -default_touch_grab_iface_down(struct ds_seat_touch_grab *grab, - uint32_t time_msec, struct ds_touch_point *point) -{ - return ds_seat_touch_send_down(grab->seat, point->surface, time_msec, - point->touch_id, point->sx, point->sy); -} - -static void -default_touch_grab_iface_up(struct ds_seat_touch_grab *grab, - uint32_t time_msec, struct ds_touch_point *point) -{ - ds_seat_touch_send_up(grab->seat, time_msec, point->touch_id); -} - -static void -default_touch_grab_iface_motion(struct ds_seat_touch_grab *grab, - uint32_t time_msec, struct ds_touch_point *point) -{ - if (!point->focused_surface || point->focused_surface == point->surface) { - ds_seat_touch_send_motion(grab->seat, time_msec, point->touch_id, - point->sx, point->sy); - } -} - -static void -default_touch_grab_iface_enter(struct ds_seat_touch_grab *grab, - uint32_t time_msec, struct ds_touch_point *point) -{ - // not handled by default -} - -static void -default_touch_grab_iface_frame(struct ds_seat_touch_grab *grab) -{ - ds_seat_touch_send_frame(grab->seat); -} - -static void -default_touch_grab_iface_cancel(struct ds_seat_touch_grab *grab) -{ - // cannot be cancelled -} - -static const struct ds_touch_grab_interface default_touch_grab_iface = { - .down = default_touch_grab_iface_down, - .up = default_touch_grab_iface_up, - .motion = default_touch_grab_iface_motion, - .enter = default_touch_grab_iface_enter, - .frame = default_touch_grab_iface_frame, - .cancel = default_touch_grab_iface_cancel, -}; - -static void -touch_handle_release(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct wl_touch_interface touch_impl = -{ - .release = touch_handle_release, -}; - -static void -touch_handle_resource_destroy(struct wl_resource *resource) -{ - if (!wl_resource_get_user_data(resource)) - return; - - wl_list_remove(wl_resource_get_link(resource)); -} - -static void -touch_point_handle_surface_destroy(struct wl_listener *listener, void *data) -{ - struct ds_touch_point *point; - - point = wl_container_of(listener, point, surface_destroy); - point->surface = NULL; - wl_list_remove(&point->surface_destroy.link); - wl_list_init(&point->surface_destroy.link); -} - -static void -touch_point_handle_client_destroy(struct wl_listener *listener, void *data) -{ - struct ds_touch_point *point; - - point = wl_container_of(listener, point, surface_destroy); - touch_point_destroy(point); -} - -static struct ds_touch_point * -touch_point_create(struct ds_seat *seat, int32_t touch_id, - struct ds_surface *surface, double sx, double sy) -{ - struct ds_touch_point *point; - struct ds_seat_client *seat_client; - struct wl_client *wl_client; - - wl_client = wl_resource_get_client(ds_surface_get_wl_resource(surface)); - seat_client = seat_client_for_wl_client(seat, wl_client); - if (!seat_client || wl_list_empty(&seat_client->touches)) - return NULL; - - point = calloc(1, sizeof *point); - if (!point) - return NULL; - - point->touch_id = touch_id; - point->surface = surface; - point->seat_client = seat_client; - point->sx = sx; - point->sy = sy; - - wl_signal_init(&point->events.destroy); - - point->surface_destroy.notify = touch_point_handle_surface_destroy; - ds_surface_add_destroy_listener(surface, &point->surface_destroy); - - point->client_destroy.notify = touch_point_handle_client_destroy; - wl_signal_add(&seat_client->events.destroy, &point->client_destroy); - - wl_list_insert(&seat->touch.touch_points, &point->link); - - return point; -} - -static void -touch_point_destroy(struct ds_touch_point *point) -{ - wl_signal_emit(&point->events.destroy, point); - - touch_point_clear_focus(point); - - wl_list_remove(&point->surface_destroy.link); - wl_list_remove(&point->client_destroy.link); - wl_list_remove(&point->link); - free(point); -} - -static void -touch_point_clear_focus(struct ds_touch_point *point) -{ - if (!point->focused_surface) - return; - - wl_list_remove(&point->focused_surface_destroy.link); - point->focused_client = NULL; - point->focused_surface = NULL; -} - -static struct ds_touch_point *seat_find_touch_point(struct ds_seat *seat, - int32_t touch_id) -{ - struct ds_touch_point *point; - - wl_list_for_each(point, &seat->touch.touch_points, link) { - if (point->touch_id == touch_id) - return point; - } - - return NULL; -} - -static int -seat_touch_num_points(struct ds_seat *seat) -{ - return wl_list_length(&seat->touch.touch_points); -} diff --git a/src/libds/shell.c b/src/libds/shell.c deleted file mode 100644 index 3adb519..0000000 --- a/src/libds/shell.c +++ /dev/null @@ -1,175 +0,0 @@ -#include -#include -#include - -#include "libds/log.h" -#include "libds/shell.h" - -#include "shell.h" - -#define WL_SHELL_VERSION 1 -#define SHELL_PING_TIMEOUT 10000 - -static void shell_handle_display_destroy(struct wl_listener *listener, - void *data); -static void shell_bind(struct wl_client *wl_client, void *data, - uint32_t verison, uint32_t id); - -WL_EXPORT struct ds_shell * -ds_shell_create(struct wl_display *display) -{ - struct ds_shell *shell; - - shell = calloc(1, sizeof *shell); - if (!shell) { - return NULL; - } - - shell->global = wl_global_create(display, &wl_shell_interface, - WL_SHELL_VERSION, shell, shell_bind); - if (!shell->global) { - free(shell); - return NULL; - } - - wl_list_init(&shell->clients); - - shell->display_destroy.notify = shell_handle_display_destroy; - wl_display_add_destroy_listener(display, &shell->display_destroy); - - wl_signal_init(&shell->events.destroy); - wl_signal_init(&shell->events.new_surface); - - shell->ping_timeout = SHELL_PING_TIMEOUT; - - ds_inf("Global created: xdg_wm_base shell(%p)", shell); - - return shell; -} - -WL_EXPORT void -ds_shell_add_destroy_listener(struct ds_shell *shell, - struct wl_listener *listener) -{ - wl_signal_add(&shell->events.destroy, listener); -} - -WL_EXPORT void -ds_shell_add_new_surface_listener(struct ds_shell *shell, - struct wl_listener *listener) -{ - wl_signal_add(&shell->events.new_surface, listener); -} - -static void -shell_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_shell *shell; - - shell = wl_container_of(listener, shell, display_destroy); - - ds_inf("Global destroy: xdg_wm_base shell(%p)", shell); - - wl_signal_emit(&shell->events.destroy, shell); - wl_list_remove(&shell->display_destroy.link); - wl_global_destroy(shell->global); - free(shell); -} - -static void -shell_handle_get_shell_surface(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t id, - struct wl_resource *surface_resource) -{ - struct ds_shell_client *client; - struct ds_surface *surface; - - client = wl_resource_get_user_data(resource); - surface = ds_surface_from_resource(surface_resource); - create_shell_surface(client, surface, id); -} - -static const struct wl_shell_interface shell_impl = -{ - .get_shell_surface = shell_handle_get_shell_surface, -}; - -static void -shell_client_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_shell_client *client; - struct ds_shell_surface *shell_surface, *tmp; - - client = wl_resource_get_user_data(resource); - - wl_list_for_each_safe(shell_surface, tmp, &client->shell_surfaces, link) - destroy_shell_surface(shell_surface); - - if (client->ping_timer != NULL) - wl_event_source_remove(client->ping_timer); - - wl_list_remove(&client->link); - free(client); -} - -static int -shell_client_handle_ping_timeout(void *user_data) -{ - struct ds_shell_client *client = user_data; - struct ds_shell_surface *surface; - - wl_list_for_each(surface, &client->shell_surfaces, link) - wl_signal_emit(&surface->events.ping_timeout, surface); - - client->ping_serial = 0; - - return 1; -} - -static void -shell_client_init_ping_timer(struct ds_shell_client *client) -{ - struct wl_display *display; - struct wl_event_loop *loop; - - display = wl_client_get_display(client->wl_client); - loop = wl_display_get_event_loop(display); - client->ping_timer = wl_event_loop_add_timer(loop, - shell_client_handle_ping_timeout, client); - if (client->ping_timer == NULL) - wl_client_post_no_memory(client->wl_client); -} - -static void -shell_bind(struct wl_client *wl_client, void *data, uint32_t version, - uint32_t id) -{ - struct ds_shell *shell = data; - struct ds_shell_client *client; - - client = calloc(1, sizeof *client); - if (client == NULL) { - wl_client_post_no_memory(wl_client); - return; - } - - client->wl_client = wl_client; - client->shell = shell; - - wl_list_init(&client->shell_surfaces); - - client->resource = - wl_resource_create(wl_client, &wl_shell_interface, version, id); - if (client->resource == NULL) { - free(client); - wl_client_post_no_memory(wl_client); - return; - } - - wl_resource_set_implementation(client->resource, &shell_impl, client, - shell_client_handle_resource_destroy); - - wl_list_insert(&shell->clients, &client->link); - - shell_client_init_ping_timer(client); -} diff --git a/src/libds/shell.h b/src/libds/shell.h deleted file mode 100644 index c2306af..0000000 --- a/src/libds/shell.h +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef DS_SHELL_H -#define DS_SHELL_H - -#include - -#include "libds/output.h" - -#include "surface.h" - -enum ds_shell_surface_role -{ - DS_SHELL_SURFACE_ROLE_NONE, - DS_SHELL_SURFACE_ROLE_TOPLEVEL, - DS_SHELL_SURFACE_ROLE_POPUP, -}; - -struct ds_shell -{ - struct wl_global *global; - - struct wl_list clients; - - struct wl_listener display_destroy; - - struct { - struct wl_signal destroy; - struct wl_signal new_surface; - } events; - - uint32_t ping_timeout; -}; - -struct ds_shell_client -{ - struct ds_shell *shell; - - struct wl_resource *resource; - struct wl_client *wl_client; - struct wl_event_source *ping_timer; - - struct wl_list shell_surfaces; - - struct wl_list link; // ds_shell::clients - - uint32_t ping_serial; -}; - -struct ds_shell_toplevel_state -{ - bool maximized, fullscreen, resizing, activated; - uint32_t tiled; - uint32_t width, height; - uint32_t max_width, max_height; - uint32_t min_width, min_height; -}; - -struct ds_shell_toplevel_requested -{ - bool maximized, minimized, fullscreen; - struct ds_output *fullscreen_output; - struct wl_listener fullscreen_output_destroy; -}; - -struct ds_shell_toplevel -{ - struct ds_shell_surface *base; - bool added; - - struct ds_shell_surface *parent; - struct wl_listener parent_unmap; - - struct ds_shell_toplevel_state current, pending; - struct ds_shell_toplevel_requested requested; - - char *title; - char *app_id; - - struct { - struct wl_signal request_maximize; - struct wl_signal request_fullscreen; - struct wl_signal request_minimize; - struct wl_signal request_move; - struct wl_signal request_resize; - struct wl_signal request_show_window_menu; - struct wl_signal set_parent; - struct wl_signal set_title; - struct wl_signal set_app_id; - } events; -}; - -struct ds_xdg_popup -{ - -}; - -struct ds_shell_surface_state -{ - uint32_t configure_serial; - struct { - int x, y; - int width, height; - } geometry; -}; - -struct ds_shell_surface -{ - struct ds_shell_client *client; - struct ds_surface *surface; - - enum ds_shell_surface_role role; - - union { - struct ds_shell_toplevel *toplevel; - struct ds_xdg_popup *popup; - }; - - struct wl_resource *resource; - - struct wl_event_source *configure_idle; - uint32_t scheduled_serial; - struct wl_list configure_list; - - struct ds_shell_surface_state current, pending; - - struct wl_list link; // ds_shell_client::surfaces - - struct { - struct wl_listener surface_destroy; - struct wl_listener surface_commit; - } listener; - - struct { - struct wl_signal destroy; - struct wl_signal ping_timeout; - struct wl_signal new_popup; - struct wl_signal map; - struct wl_signal unmap; - struct wl_signal configure; - } events; - - bool added, configured, mapped; -}; - -struct ds_shell_surface_configure -{ - struct ds_shell_surface *shell_surface; - struct wl_list link; - uint32_t serial; -}; - -struct ds_shell_surface * -create_shell_surface(struct ds_shell_client *client, struct ds_surface *surface, - uint32_t id); - -void destroy_shell_surface(struct ds_shell_surface *surface); - -#endif diff --git a/src/libds/shell_surface.c b/src/libds/shell_surface.c deleted file mode 100644 index 73c498b..0000000 --- a/src/libds/shell_surface.c +++ /dev/null @@ -1,540 +0,0 @@ -#include -#include -#include - -#include "libds/log.h" - -#include "shell.h" - -static const struct wl_shell_surface_interface shell_surface_impl; - -static void reset_shell_surface(struct ds_shell_surface *shell_surface); -static void shell_surface_handle_surface_destroy(struct wl_listener *listener, - void *data); -static void shell_surface_handle_surface_commit(struct wl_listener *listener, - void *data); -static void shell_surface_handle_resource_destroy(struct wl_resource *resource); -static void shell_surface_configure_destroy(struct ds_shell_surface_configure *configure); -static void surface_send_configure(void *user_data); -static void handle_shell_surface_commit(struct ds_surface *surface); - -WL_EXPORT void -ds_shell_surface_add_destroy_listener(struct ds_shell_surface *shell_surface, - struct wl_listener *listener) -{ - wl_signal_add(&shell_surface->events.destroy, listener); -} - -WL_EXPORT void -ds_shell_surface_add_map_listener(struct ds_shell_surface *shell_surface, - struct wl_listener *listener) -{ - wl_signal_add(&shell_surface->events.map, listener); -} - -WL_EXPORT void -ds_shell_surface_add_unmap_listener(struct ds_shell_surface *shell_surface, - struct wl_listener *listener) -{ - wl_signal_add(&shell_surface->events.unmap, listener); -} - -WL_EXPORT struct ds_surface * -ds_shell_surface_get_surface(struct ds_shell_surface *shell_surface) -{ - return shell_surface->surface; -} - -static const struct ds_surface_role shell_surface_role = -{ - .name = "shell_surface", - .commit = handle_shell_surface_commit, -}; - -struct ds_shell_surface * -create_shell_surface(struct ds_shell_client *client, struct ds_surface *surface, - uint32_t id) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = calloc(1, sizeof *shell_surface); - if (!shell_surface) { - wl_client_post_no_memory(client->wl_client); - return NULL; - } - - shell_surface->client = client; - shell_surface->role = DS_SHELL_SURFACE_ROLE_NONE; - shell_surface->surface = surface; - shell_surface->resource = wl_resource_create(client->wl_client, - &wl_shell_surface_interface, wl_resource_get_version(client->resource), - id); - if (!shell_surface->resource) { - free(shell_surface); - wl_client_post_no_memory(client->wl_client); - return NULL; - } - - if (!ds_surface_set_role(shell_surface->surface, &shell_surface_role, - shell_surface, shell_surface->resource, -1)) { - free(shell_surface); - return NULL; - } - - wl_list_init(&shell_surface->configure_list); - - wl_signal_init(&shell_surface->events.destroy); - wl_signal_init(&shell_surface->events.ping_timeout); - wl_signal_init(&shell_surface->events.new_popup); - wl_signal_init(&shell_surface->events.map); - wl_signal_init(&shell_surface->events.unmap); - wl_signal_init(&shell_surface->events.configure); - - shell_surface->listener.surface_destroy.notify = - shell_surface_handle_surface_destroy; - ds_surface_add_destroy_listener(surface, - &shell_surface->listener.surface_destroy); - - shell_surface->listener.surface_commit.notify = - shell_surface_handle_surface_commit; - ds_surface_add_commit_listener(surface, - &shell_surface->listener.surface_commit); - - wl_resource_set_implementation(shell_surface->resource, &shell_surface_impl, - shell_surface, shell_surface_handle_resource_destroy); - - wl_list_insert(&client->shell_surfaces, &shell_surface->link); - - ds_inf("New shell_surface %p (res %p)", shell_surface, shell_surface->resource); - - return shell_surface; -} - -void -destroy_shell_surface(struct ds_shell_surface *shell_surface) -{ - reset_shell_surface(shell_surface); - - wl_resource_set_user_data(shell_surface->resource, NULL); - - ds_surface_reset_role_data(shell_surface->surface); - - wl_list_remove(&shell_surface->link); - wl_list_remove(&shell_surface->listener.surface_destroy.link); - wl_list_remove(&shell_surface->listener.surface_commit.link); - - free(shell_surface); -} - -static void -unmap_shell_surface(struct ds_shell_surface *shell_surface) -{ - struct ds_shell_surface_configure *configure, *tmp; - - // TODO handle popup - - if (shell_surface->mapped) - wl_signal_emit(&shell_surface->events.unmap, shell_surface); - - switch (shell_surface->role) { - case DS_SHELL_SURFACE_ROLE_TOPLEVEL: - if (shell_surface->toplevel->parent) { - wl_list_remove(&shell_surface->toplevel->parent_unmap.link); - shell_surface->toplevel->parent = NULL; - } - free(shell_surface->toplevel->title); - shell_surface->toplevel->title = NULL; - free(shell_surface->toplevel->app_id); - shell_surface->toplevel->app_id = NULL; - break; - case DS_SHELL_SURFACE_ROLE_POPUP: - // TODO - break; - case DS_SHELL_SURFACE_ROLE_NONE: - assert(false && "not reached"); - } - - wl_list_for_each_safe(configure, tmp, &shell_surface->configure_list, link) - shell_surface_configure_destroy(configure); - - if (shell_surface->configure_idle) { - wl_event_source_remove(shell_surface->configure_idle); - shell_surface->configure_idle = NULL; - } - - shell_surface->configured = false; - shell_surface->mapped = false; -} - -static void -reset_shell_surface(struct ds_shell_surface *shell_surface) -{ - struct ds_shell_toplevel_requested *req; - - if (shell_surface->role != DS_SHELL_SURFACE_ROLE_NONE) - unmap_shell_surface(shell_surface); - - if (shell_surface->added) { - wl_signal_emit(&shell_surface->events.destroy, shell_surface); - shell_surface->added = false; - } - - switch (shell_surface->role) { - case DS_SHELL_SURFACE_ROLE_TOPLEVEL: - req = &shell_surface->toplevel->requested; - if (req->fullscreen_output) - wl_list_remove(&req->fullscreen_output_destroy.link); - free(shell_surface->toplevel); - shell_surface->toplevel = NULL; - break; - case DS_SHELL_SURFACE_ROLE_POPUP: - // TODO - break; - case DS_SHELL_SURFACE_ROLE_NONE: - // This space is intentionally left blank - break; - } - - shell_surface->role = DS_SHELL_SURFACE_ROLE_NONE; -} - -static uint32_t -ds_shell_surface_schedule_configure(struct ds_shell_surface *shell_surface) -{ - struct wl_display *display; - struct wl_event_loop *loop; - - display = wl_client_get_display(shell_surface->client->wl_client); - loop = wl_display_get_event_loop(display); - - if (!shell_surface->configure_idle) { - shell_surface->scheduled_serial = wl_display_next_serial(display); - shell_surface->configure_idle = wl_event_loop_add_idle(loop, - surface_send_configure, shell_surface); - if (!shell_surface->configure_idle) - wl_client_post_no_memory(shell_surface->client->wl_client); - } - - return shell_surface->scheduled_serial; -} - -static void -handle_shell_surface_commit(struct ds_surface *surface) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = ds_surface_get_role_data(surface); - shell_surface->current = shell_surface->pending; - - switch (shell_surface->role) { - case DS_SHELL_SURFACE_ROLE_NONE: - // inert toplevel or popup - break; - case DS_SHELL_SURFACE_ROLE_TOPLEVEL: - if (!shell_surface->toplevel->added) { - ds_shell_surface_schedule_configure(shell_surface); - shell_surface->toplevel->added = true; - } - // TODO - break; - case DS_SHELL_SURFACE_ROLE_POPUP: - // TODO - break; - } - - if (!shell_surface->added) { - shell_surface->added = true; - wl_signal_emit(&shell_surface->client->shell->events.new_surface, shell_surface); - } - - if (shell_surface->configured && - ds_surface_has_buffer(shell_surface->surface) && - !shell_surface->mapped) { - shell_surface->mapped = true; - wl_signal_emit(&shell_surface->events.map, shell_surface); - } -} - -void handle_shell_surface_precommit(struct ds_surface *surface) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = ds_surface_get_role_data(surface); - - // TODO - (void)shell_surface; -} - -void -ds_shell_surface_ping(struct ds_shell_surface *shell_surface) -{ -} - -static void -shell_surface_handle_surface_destroy(struct wl_listener *listener, void *data) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_container_of(listener, shell_surface, listener.surface_destroy); - destroy_shell_surface(shell_surface); -} - -static void -shell_surface_handle_surface_commit(struct wl_listener *listener, void *data) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_container_of(listener, shell_surface, listener.surface_commit); - - if (ds_surface_has_buffer(shell_surface->surface) && - !shell_surface->configured) { - wl_resource_post_error(shell_surface->resource, - -1, - "shell_surface has never been configured"); - return; - } - - if (!ds_surface_get_role(shell_surface->surface)) { - wl_resource_post_error(shell_surface->resource, - -1, - "shell_surface must have a role"); - return; - } -} - -static void -shell_surface_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - if (!shell_surface) - return; - - destroy_shell_surface(shell_surface); -} - -static void -shell_surface_configure_destroy(struct ds_shell_surface_configure *configure) -{ - wl_list_remove(&configure->link); - free(configure); -} - -static void -create_shell_surface_toplevel(struct ds_shell_surface *shell_surface) -{ - assert(shell_surface->toplevel == NULL); - - shell_surface->toplevel = calloc(1, sizeof *shell_surface->toplevel); - if (!shell_surface->toplevel) { - wl_resource_post_no_memory(shell_surface->resource); - return; - } - - shell_surface->toplevel->base = shell_surface; - - wl_signal_init(&shell_surface->toplevel->events.request_maximize); - wl_signal_init(&shell_surface->toplevel->events.request_fullscreen); - wl_signal_init(&shell_surface->toplevel->events.request_minimize); - wl_signal_init(&shell_surface->toplevel->events.request_move); - wl_signal_init(&shell_surface->toplevel->events.request_resize); - wl_signal_init(&shell_surface->toplevel->events.request_show_window_menu); - wl_signal_init(&shell_surface->toplevel->events.set_parent); - wl_signal_init(&shell_surface->toplevel->events.set_title); - wl_signal_init(&shell_surface->toplevel->events.set_app_id); - - shell_surface->role = DS_SHELL_SURFACE_ROLE_TOPLEVEL; -} - -static void -shell_surface_handle_pong(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t serial) -{ - struct ds_shell_surface *shell_surface; - struct ds_shell_client *client; - - shell_surface = wl_resource_get_user_data(resource); - - client = shell_surface->client; - if (client->ping_serial != serial) - return; - - wl_event_source_timer_update(client->ping_timer, 0); - client->ping_serial = 0; -} - -static void -shell_surface_handle_move(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - - // TODO - (void)shell_surface; -} - -static void -shell_surface_handle_resize(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial, uint32_t edges) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - - // TODO - (void)shell_surface; -} - -static void -shell_surface_handle_set_toplevel(struct wl_client *client, struct wl_resource *resource) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - create_shell_surface_toplevel(shell_surface); -} - -static void -shell_surface_handle_set_transient(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *parent_resource, - int32_t x, int32_t y, uint32_t flags) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - - // TODO - (void)shell_surface; - ds_err("Not implemented yet."); -} - -static void -shell_surface_handle_set_fullscreen(struct wl_client *client, - struct wl_resource *resource, uint32_t method, uint32_t framerate, - struct wl_resource *output_resource) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - - // TODO - (void)shell_surface; - ds_err("Not implemented yet."); -} - -static void -shell_surface_handle_set_popup(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial, struct wl_resource *parent_resource, - int32_t x, int32_t y, uint32_t flags) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - - // TODO - (void)shell_surface; - ds_err("Not implemented yet."); -} - -static void -shell_surface_handle_set_maximized(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *output_resource) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - - shell_surface->toplevel->requested.maximized = true; - wl_signal_emit(&shell_surface->toplevel->events.request_maximize, shell_surface); - ds_shell_surface_schedule_configure(shell_surface); -} - -static void -shell_surface_handle_set_title(struct wl_client *client, - struct wl_resource *resource, const char *title) -{ - struct ds_shell_surface *shell_surface; - char *tmp; - - shell_surface = wl_resource_get_user_data(resource); - tmp = strdup(title); - if (!tmp) { - wl_resource_post_no_memory(resource); - return; - } - - if (shell_surface->toplevel->title) - free(shell_surface->toplevel->title); - - shell_surface->toplevel->title = tmp; - wl_signal_emit(&shell_surface->toplevel->events.set_title, shell_surface); -} - -static void -shell_surface_handle_set_class(struct wl_client *client, - struct wl_resource *resource, const char *clas) -{ - struct ds_shell_surface *shell_surface; - - shell_surface = wl_resource_get_user_data(resource); - - // TODO - (void)shell_surface; - ds_err("Not implemented yet."); -} - -static const struct wl_shell_surface_interface shell_surface_impl = -{ - .pong = shell_surface_handle_pong, - .move = shell_surface_handle_move, - .resize = shell_surface_handle_resize, - .set_toplevel = shell_surface_handle_set_toplevel, - .set_transient = shell_surface_handle_set_transient, - .set_fullscreen = shell_surface_handle_set_fullscreen, - .set_popup = shell_surface_handle_set_popup, - .set_maximized = shell_surface_handle_set_maximized, - .set_title = shell_surface_handle_set_title, - .set_class = shell_surface_handle_set_class, -}; - -static void -surface_send_configure(void *user_data) -{ - struct ds_shell_surface *shell_surface; - struct ds_shell_surface_configure *configure; - uint32_t width, height; - uint32_t edges = 0; - - shell_surface = user_data; - shell_surface->configure_idle = NULL; - - // TDOO: Not sure if shell needs the struct ds_shell_surface_configure. - configure = calloc(1, sizeof *configure); - if (!configure) { - wl_client_post_no_memory(shell_surface->client->wl_client); - return; - } - - wl_list_insert(shell_surface->configure_list.prev, &configure->link); - configure->serial = shell_surface->scheduled_serial; - configure->shell_surface = shell_surface; - - wl_signal_emit(&shell_surface->events.configure, configure); - - edges = (WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_LEFT); // fixed default value - width = shell_surface->current.geometry.width; - height = shell_surface->current.geometry.height; - - wl_shell_surface_send_configure(shell_surface->resource, edges, width, height); - - shell_surface->configured = true; - - // TDOO: Not sure if shell needs the struct ds_shell_surface_configure. - shell_surface_configure_destroy(configure); -} diff --git a/src/libds/subcompositor.c b/src/libds/subcompositor.c deleted file mode 100644 index 9e821b3..0000000 --- a/src/libds/subcompositor.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "libds/log.h" - -#include "subcompositor.h" -#include "surface.h" - -#define SUBCOMPOSITOR_VERSION 1 - -static void subcompositor_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - -bool -ds_subcompositor_init(struct ds_subcompositor *subcomp, - struct wl_display *display) -{ - subcomp->global = wl_global_create(display, &wl_subcompositor_interface, - SUBCOMPOSITOR_VERSION, subcomp, subcompositor_bind); - if (!subcomp->global) { - ds_log_errno(DS_ERR, "Could not create global"); - return false; - } - - return true; -} - -void -ds_subcompositor_finish(struct ds_subcompositor *subcomp) -{ - wl_global_destroy(subcomp->global); -} - -static void -subcompositor_handle_destroy(struct wl_client *client, - struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -subcompositor_handle_get_subsurface(struct wl_client *client, - struct wl_resource *resource, uint32_t id, - struct wl_resource *surface_resource, - struct wl_resource *parent_resource) -{ - struct ds_surface *surface, *parent; - - surface = ds_surface_from_resource(surface_resource); - parent = ds_surface_from_resource(parent_resource); - if (surface == parent) { - ds_inf("ds_surface(%p) cannot be its own parent", surface); - wl_resource_post_error(resource, - WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, - "%d: wl_surface@%d cannot be its own parent", - id, wl_resource_get_id(surface_resource)); - return; - } - - if (ds_surface_is_subsurface(surface)) { - ds_inf("ds_surface(%p) is already a sub-surface", surface); - wl_resource_post_error(resource, - WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, - "%d: wl_surface@%d is already a sub-surface", - id, wl_resource_get_id(surface_resource)); - return; - } - - if (ds_surface_is_ancestor_of(surface, parent)) { - ds_inf("ds_surface(%p) is an ancestor of given parent(%p)", - surface, parent); - wl_resource_post_error(resource, - WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE, - "%d: wl_surface@%d is an ancestor of parent", - id, wl_resource_get_id(surface_resource)); - return; - } - - ds_subsurface_create(resource, surface, parent, - wl_resource_get_version(resource), id); -} - -static const struct wl_subcompositor_interface subcompositor_impl = -{ - .destroy = subcompositor_handle_destroy, - .get_subsurface = subcompositor_handle_get_subsurface, -}; - -static void -subcompositor_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) -{ - struct ds_subcompositor *subcomp = data; - struct wl_resource *resource; - - resource = wl_resource_create(client, &wl_subcompositor_interface, 1, id); - if (resource == NULL) { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(resource, &subcompositor_impl, - subcomp, NULL); -} diff --git a/src/libds/subcompositor.h b/src/libds/subcompositor.h deleted file mode 100644 index 71265d0..0000000 --- a/src/libds/subcompositor.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef DS_SUBCOMPOSITOR_H -#define DS_SUBCOMPOSITOR_H - -#include - -struct ds_subcompositor -{ - struct wl_global *global; -}; - -bool -ds_subcompositor_init(struct ds_subcompositor *subcomp, - struct wl_display *display); - -void -ds_subcompositor_finish(struct ds_subcompositor *subcomp); - -#endif diff --git a/src/libds/surface.h b/src/libds/surface.h deleted file mode 100644 index 008fb9c..0000000 --- a/src/libds/surface.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef DS_SURFACE_H -#define DS_SURFACE_H - -#include - -#include "libds/surface.h" - -struct ds_surface_role -{ - const char *name; - void (*commit)(struct ds_surface *surface); -}; - -struct ds_surface * -ds_surface_create(struct wl_client *client, uint32_t version, uint32_t id); - -struct ds_surface * -ds_surface_from_resource(struct wl_resource *resource); - -bool -ds_surface_set_role(struct ds_surface *surface, - const struct ds_surface_role *role, void *role_data, - struct wl_resource *error_resource, uint32_t error_code); - -const struct ds_surface_role * -ds_surface_get_role(struct ds_surface *surface); - -void * -ds_surface_get_role_data(struct ds_surface *surface); - -void -ds_surface_reset_role_data(struct ds_surface *surface); - -bool -ds_surface_has_buffer(struct ds_surface *surface); - -bool -ds_surface_is_ancestor_of(struct ds_surface *surface, - struct ds_surface *target_surface); - -bool -ds_surface_is_subsurface(struct ds_surface *surface); - -struct ds_subsurface * -ds_subsurface_create(struct wl_resource *subcomp_resource, - struct ds_surface *surface, struct ds_surface *parent, - uint32_t version, uint32_t id); - -struct wl_resource * -ds_surface_get_wl_resource(struct ds_surface *surface); - -#endif diff --git a/src/libds/surface/subsurface.c b/src/libds/surface/subsurface.c deleted file mode 100644 index 2ec0dae..0000000 --- a/src/libds/surface/subsurface.c +++ /dev/null @@ -1,336 +0,0 @@ -#include -#include - -#include "libds/log.h" -#include "libds/surface.h" - -#include "surface-private.h" - -static const struct wl_subsurface_interface subsurface_impl; -static const struct ds_surface_role subsurface_role; - -static void subsurface_handle_resource_destroy(struct wl_resource *resource); -static void subsurface_handle_surface_destroy(struct wl_listener *listener, - void *data); -static void subsurface_link_surface(struct ds_subsurface *subsurface, - struct ds_surface *surface); -static void subsurface_unlink_surface(struct ds_subsurface *subsurface); -static void subsurface_link_parent(struct ds_subsurface *subsurface, - struct ds_surface *parent); -static void subsurface_unlink_parent(struct ds_subsurface *subsurface); -static struct ds_subsurface *subsurface_find_sibling(struct ds_subsurface *subsurface, - struct ds_surface *surface); - -struct ds_subsurface * -ds_subsurface_create(struct wl_resource *subcomp_resource, - struct ds_surface *surface, struct ds_surface *parent, - uint32_t version, uint32_t id) -{ - struct wl_client *client; - struct ds_subsurface *subsurface; - - client = wl_resource_get_client(subcomp_resource); - - subsurface = calloc(1, sizeof *subsurface); - if (!subsurface) { - ds_log_errno(DS_ERR, "Could not allocate memory"); - wl_client_post_no_memory(client); - return NULL; - } - - if (!ds_surface_set_role(surface, &subsurface_role, subsurface, - subcomp_resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE)) { - free(subsurface); - return NULL; - } - - subsurface->resource = wl_resource_create(client, &wl_subsurface_interface, - version, id); - if (!subsurface->resource) { - ds_log_errno(DS_ERR, "Could not create resource"); - free(subsurface); - wl_client_post_no_memory(client); - return NULL; - } - wl_resource_set_implementation(subsurface->resource, &subsurface_impl, - subsurface, subsurface_handle_resource_destroy); - - subsurface->synchronized = true; - - wl_signal_init(&subsurface->events.destroy); - - subsurface_link_surface(subsurface, surface); - subsurface_link_parent(subsurface, parent); - - ds_inf("New ds_subsurface %p: surface %p, parent surface %p", - subsurface, surface, parent); - - wl_signal_emit(&parent->events.new_subsurface, subsurface); - - return subsurface; -} - -bool -ds_surface_is_subsurface(struct ds_surface *surface) -{ - return ds_surface_get_role(surface) == &subsurface_role; -} - -struct ds_subsurface * -ds_subsurface_from_ds_surface(struct ds_surface *surface) -{ - assert(ds_surface_is_subsurface(surface)); - return (struct ds_subsurface *)surface->role_data; -} - -struct ds_surface * -ds_subsurface_get_parent(struct ds_subsurface *subsurface) -{ - return subsurface->parent; -} - -static const struct ds_surface_role subsurface_role = -{ - .name = "wl_subsurface", -}; - -static void -subsurface_handle_destroy(struct wl_client *client, - struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -subsurface_handle_set_position(struct wl_client *client, - struct wl_resource *resource, int32_t x, int32_t y) -{ - struct ds_subsurface *subsurface; - - subsurface = wl_resource_get_user_data(resource); - if (!subsurface) - return; - - subsurface->pending.x = x; - subsurface->pending.y = y; -} - -static void -subsurface_handle_place_above(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *sibling_resource) -{ - struct ds_subsurface *subsurface, *sibling; - struct ds_surface *sibling_surface; - struct wl_list *node; - - subsurface = wl_resource_get_user_data(resource); - if (!subsurface) - return; - - sibling_surface = ds_surface_from_resource(sibling_resource); - if (sibling_surface == subsurface->parent) { - node = &subsurface->parent->pending.subsurfaces_above; - } - else { - sibling = subsurface_find_sibling(subsurface, sibling_surface); - if (!sibling) { - wl_resource_post_error(subsurface->resource, - WL_SUBSURFACE_ERROR_BAD_SURFACE, - "%s: wl_surface@%d is not a parent or sibling", - "place_above", wl_resource_get_id(sibling_resource)); - return; - } - node = &sibling->pending.link; - } - - wl_list_remove(&subsurface->pending.link); - wl_list_insert(node, &subsurface->pending.link); - - subsurface->reordered = true; -} - -static void -subsurface_handle_place_below(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *sibling_resource) -{ - struct ds_subsurface *subsurface, *sibling; - struct ds_surface *sibling_surface; - struct wl_list *node; - - subsurface = wl_resource_get_user_data(resource); - if (!subsurface) - return; - - sibling_surface = ds_surface_from_resource(sibling_resource); - if (sibling_surface == subsurface->parent) { - node = &subsurface->parent->pending.subsurfaces_below; - } - else { - sibling = subsurface_find_sibling(subsurface, sibling_surface); - if (!sibling) { - wl_resource_post_error(subsurface->resource, - WL_SUBSURFACE_ERROR_BAD_SURFACE, - "%s: wl_surface@%d is not a parent or sibling", - "place_below", wl_resource_get_id(sibling_resource)); - return; - } - node = &sibling->pending.link; - - } - - wl_list_remove(&subsurface->pending.link); - wl_list_insert(node->prev, &subsurface->pending.link); - - subsurface->reordered = true; -} - -static void -subsurface_handle_set_sync(struct wl_client *client, - struct wl_resource *resource) -{ - struct ds_subsurface *subsurface; - - subsurface = wl_resource_get_user_data(resource); - if (!subsurface) - return; - - subsurface->synchronized = true; -} - -static void -subsurface_handle_set_desync(struct wl_client *client, - struct wl_resource *resource) -{ - struct ds_subsurface *subsurface; - - subsurface = wl_resource_get_user_data(resource); - if (!subsurface) - return; - - if (subsurface->synchronized) { - subsurface->synchronized = false; - - // TODO: flush - } -} - -static const struct wl_subsurface_interface subsurface_impl = -{ - .destroy = subsurface_handle_destroy, - .set_position = subsurface_handle_set_position, - .place_above = subsurface_handle_place_above, - .place_below = subsurface_handle_place_below, - .set_sync = subsurface_handle_set_sync, - .set_desync = subsurface_handle_set_desync, -}; - -static void -subsurface_destroy(struct ds_subsurface *subsurface) -{ - wl_signal_emit(&subsurface->events.destroy, subsurface); - - if (subsurface->parent) - subsurface_unlink_parent(subsurface); - - if (subsurface->surface) - subsurface_unlink_surface(subsurface); - - wl_resource_set_user_data(subsurface->resource, NULL); - - free(subsurface); -} - -static void -subsurface_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_subsurface *subsurface; - - subsurface = wl_resource_get_user_data(resource); - if (!subsurface) - return; - - subsurface_destroy(subsurface); -} - -static -void subsurface_handle_surface_destroy(struct wl_listener *listener, - void *data) -{ - struct ds_subsurface *subsurface; - - subsurface = wl_container_of(listener, subsurface, - listener.surface_destroy); - subsurface_destroy(subsurface); -} - -static void -subsurface_handle_parent_destroy(struct wl_listener *listener, - void *data) -{ - struct ds_subsurface *subsurface; - - subsurface = wl_container_of(listener, subsurface, - listener.parent_destroy); - subsurface_unlink_parent(subsurface); -} - -static void -subsurface_link_surface(struct ds_subsurface *subsurface, struct ds_surface *surface) -{ - subsurface->surface = surface; - subsurface->listener.surface_destroy.notify = - subsurface_handle_surface_destroy; - ds_surface_add_destroy_listener(surface, - &subsurface->listener.surface_destroy); -} - -static void -subsurface_unlink_surface(struct ds_subsurface *subsurface) -{ - wl_list_remove(&subsurface->listener.surface_destroy.link); - subsurface->surface->role_data = NULL; - subsurface->surface = NULL; -} - -static void -subsurface_link_parent(struct ds_subsurface *subsurface, struct ds_surface *parent) -{ - subsurface->parent = parent; - subsurface->listener.parent_destroy.notify = - subsurface_handle_parent_destroy; - ds_surface_add_destroy_listener(parent, - &subsurface->listener.parent_destroy); - wl_list_insert(parent->current.subsurfaces_above.prev, - &subsurface->current.link); - wl_list_insert(parent->pending.subsurfaces_above.prev, - &subsurface->pending.link); -} - -static void -subsurface_unlink_parent(struct ds_subsurface *subsurface) -{ - wl_list_remove(&subsurface->current.link); - wl_list_remove(&subsurface->pending.link); - wl_list_remove(&subsurface->listener.parent_destroy.link); - subsurface->parent = NULL; -} - -static struct ds_subsurface * -subsurface_find_sibling(struct ds_subsurface *subsurface, struct ds_surface *surface) -{ - struct ds_surface *parent = subsurface->parent; - struct ds_subsurface *sibling; - - wl_list_for_each(sibling, &parent->pending.subsurfaces_below, pending.link) { - if (sibling->surface == surface && sibling != subsurface) - return sibling; - } - - wl_list_for_each(sibling, &parent->pending.subsurfaces_above, pending.link) { - if (sibling->surface == surface && sibling != subsurface) { - return sibling; - } - } - - return NULL; -} diff --git a/src/libds/surface/surface-private.h b/src/libds/surface/surface-private.h deleted file mode 100644 index aee9547..0000000 --- a/src/libds/surface/surface-private.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef DS_SURFACE_PRIVATE_H -#define DS_SURFACE_PRIVATE_H - -#include - -#include -#include - -#include "addon.h" -#include "buffer.h" -#include "surface.h" - -enum ds_surface_state_field -{ - DS_SURFACE_STATE_BUFFER = 1 << 0, - DS_SURFACE_STATE_SURFACE_DAMAGE = 1 << 1, - DS_SURFACE_STATE_BUFFER_DAMAGE = 1 << 2, - DS_SURFACE_STATE_OPAQUE_REGION = 1 << 3, - DS_SURFACE_STATE_INPUT_REGION = 1 << 4, - DS_SURFACE_STATE_TRANSFORM = 1 << 5, - DS_SURFACE_STATE_SCALE = 1 << 6, - DS_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7, - DS_SURFACE_STATE_VIEWPORT = 1 << 8, -}; - -struct ds_surface_state -{ - enum ds_surface_state_field committed; - - struct ds_buffer *buffer; - int32_t dx, dy; - pixman_region32_t surface_damage, buffer_damage; - pixman_region32_t opaque, input; - enum wl_output_transform transform; - int32_t scale; - struct wl_list frame_callback_list; - - int width, height; - int buffer_width, buffer_height; - - struct wl_list subsurfaces_below; - struct wl_list subsurfaces_above; - - // TODO viewport -}; - -struct ds_surface -{ - struct wl_resource *resource; - - struct ds_buffer *buffer; - - pixman_region32_t buffer_damage; - pixman_region32_t opaque_region; - pixman_region32_t input_region; - - struct ds_surface_state current, pending; - - const struct ds_surface_role *role; - void *role_data; - - int sx, sy; - - struct { - struct wl_signal commit; - struct wl_signal new_subsurface; - struct wl_signal destroy; - } events; - - struct ds_addon_set addons; -}; - -struct ds_subsurface_parent_state -{ - int32_t x, y; - struct wl_list link; -}; - -struct ds_subsurface -{ - struct wl_resource *resource; - struct ds_surface *surface; - struct ds_surface *parent; - - struct ds_subsurface_parent_state current, pending; - - struct { - struct wl_signal destroy; - } events; - - struct { - struct wl_listener surface_destroy; - struct wl_listener parent_destroy; - } listener; - - bool synchronized; - bool reordered; - bool mapped; -}; - -struct ds_surface * -ds_surface_get_root_surface(struct ds_surface *surface); - -struct ds_subsurface * -ds_subsurface_from_ds_surface(struct ds_surface *surface); - -struct ds_surface * -ds_subsurface_get_parent(struct ds_subsurface *subsurface); - -#endif diff --git a/src/libds/surface/surface.c b/src/libds/surface/surface.c deleted file mode 100644 index 78dc41c..0000000 --- a/src/libds/surface/surface.c +++ /dev/null @@ -1,757 +0,0 @@ -#include -#include - -#include "libds/log.h" -#include "libds/surface.h" - -#include "region.h" -#include "util.h" -#include "surface-private.h" - -#define CALLBACK_VERSION 1 - -static const struct wl_surface_interface surface_impl; - -static void surface_handle_resource_destroy(struct wl_resource *resource); -static void surface_state_init(struct ds_surface_state *state); -static void surface_state_finish(struct ds_surface_state *state); -static void surface_state_move(struct ds_surface_state *state, - struct ds_surface_state *next); -static void surface_finalize_pending(struct ds_surface *surface); -static void surface_commit_state(struct ds_surface *surface, - struct ds_surface_state *next); -static bool surface_for_each(struct ds_surface *surface, int x, int y, - ds_surface_for_each_func_t iterator, void *data); - -WL_EXPORT void -ds_surface_add_destroy_listener(struct ds_surface *surface, - struct wl_listener *listener) -{ - wl_signal_add(&surface->events.destroy, listener); -} - -WL_EXPORT void -ds_surface_add_commit_listener(struct ds_surface *surface, - struct wl_listener *listener) -{ - wl_signal_add(&surface->events.commit, listener); -} - -WL_EXPORT void -ds_surface_add_new_subsurface_listener(struct ds_surface *surface, - struct wl_listener *listener) -{ - wl_signal_add(&surface->events.new_subsurface, listener); -} - -WL_EXPORT struct ds_buffer * -ds_surface_get_buffer(struct ds_surface *surface) -{ - return surface->buffer; -} - -WL_EXPORT void -ds_surface_for_each(struct ds_surface *surface, - ds_surface_for_each_func_t iterator, void *data) -{ - surface_for_each(surface, 0, 0, iterator, data); -} - -WL_EXPORT void -ds_surface_send_frame_done(struct ds_surface *surface, - const struct timespec *when) -{ - struct wl_resource *resource, *tmp; - - wl_resource_for_each_safe(resource, tmp, - &surface->current.frame_callback_list) { - wl_callback_send_done(resource, timespec_to_msec(when)); - wl_resource_destroy(resource); - } -} - -struct ds_surface * -ds_surface_create(struct wl_client *client, uint32_t version, uint32_t id) -{ - struct ds_surface *surface; - - surface = calloc(1, sizeof *surface); - if (!surface) { - wl_client_post_no_memory(client); - return NULL; - } - - surface->resource = - wl_resource_create(client, &wl_surface_interface, version, id); - if (!surface->resource) { - free(surface); - wl_client_post_no_memory(client); - return NULL; - } - - wl_resource_set_implementation(surface->resource, &surface_impl, - surface, surface_handle_resource_destroy); - - surface_state_init(&surface->current); - surface_state_init(&surface->pending); - - wl_signal_init(&surface->events.commit); - wl_signal_init(&surface->events.destroy); - wl_signal_init(&surface->events.new_subsurface); - - pixman_region32_init(&surface->buffer_damage); - pixman_region32_init(&surface->opaque_region); - pixman_region32_init(&surface->input_region); - - ds_inf("New ds_surface %p (res %p)", surface, surface->resource); - - return surface; -} - -struct ds_surface * -ds_surface_from_resource(struct wl_resource *resource) -{ - assert(wl_resource_instance_of(resource, &wl_surface_interface, - &surface_impl)); - return wl_resource_get_user_data(resource); -} - -bool -ds_surface_set_role(struct ds_surface *surface, - const struct ds_surface_role *role, void *role_data, - struct wl_resource *error_resource, uint32_t error_code) -{ - assert(role != NULL); - - if (surface->role != NULL && surface->role != role) { - ds_err("Cannot assign role %s to ds_surface(%p) " - "already has role %s\n", - role->name, surface, surface->role->name); - if (error_resource != NULL) { - wl_resource_post_error(error_resource, error_code, - "Cannot assign role %s to wl_surface@%d " - "already has role %s\n", - role->name, wl_resource_get_id(surface->resource), - surface->role->name); - } - return false; - } - - if (surface->role_data != NULL && surface->role_data != role_data) { - ds_err("Cannot reassign role %s to ds_surface(%p), " - "role object still exists", role->name, surface); - wl_resource_post_error(error_resource, error_code, - "Cannot reassign role %s to wl_surface@%d, " - "role object still exists", role->name, - wl_resource_get_id(surface->resource)); - return false; - } - - surface->role = role; - surface->role_data = role_data; - - ds_inf("Set ds_surface(%p) role: %s", surface, role->name); - - return true; -} - -const struct ds_surface_role * -ds_surface_get_role(struct ds_surface *surface) -{ - return surface->role; -} - -void * -ds_surface_get_role_data(struct ds_surface *surface) -{ - return surface->role_data; -} - -void -ds_surface_reset_role_data(struct ds_surface *surface) -{ - surface->role_data = NULL; -} - -bool -ds_surface_is_ancestor_of(struct ds_surface *surface, - struct ds_surface *target_surface) -{ - struct ds_subsurface *target_subsurface; - struct ds_surface *parent_surface; - - while (target_surface && - ds_surface_is_subsurface(target_surface)) { - target_subsurface = ds_subsurface_from_ds_surface(target_surface); - if (!target_subsurface) - break; - - parent_surface = ds_subsurface_get_parent(target_subsurface); - if (surface == parent_surface) - return true; - - target_surface = parent_surface; - } - - return false; -} - -struct ds_surface * -ds_surface_get_root_surface(struct ds_surface *surface) -{ - struct ds_subsurface *subsurface; - - while (ds_surface_is_subsurface(surface)) { - subsurface = ds_subsurface_from_ds_surface(surface); - if (!subsurface) - break; - - surface = ds_subsurface_get_parent(subsurface); - if (!surface) - return NULL; - } - - return surface; -} - -bool -ds_surface_has_buffer(struct ds_surface *surface) -{ - return !!surface->buffer; -} - -struct wl_resource * -ds_surface_get_wl_resource(struct ds_surface *surface) -{ - return surface->resource; -} - -static void -surface_handle_destroy(struct wl_client *client, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -surface_handle_attach(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *buffer_resource, - int32_t dx, int32_t dy) -{ - struct ds_surface *surface; - struct ds_buffer *buffer = NULL; - - if (buffer_resource) { - buffer = ds_buffer_from_resource(buffer_resource); - if (!buffer) { - wl_resource_post_error(buffer_resource, 0, "unknown buffer type"); - return; - } - } - - surface = wl_resource_get_user_data(resource); - surface->pending.committed |= DS_SURFACE_STATE_BUFFER; - surface->pending.dx = dx; - surface->pending.dy = dy; - - if (surface->pending.buffer) - ds_buffer_unlock(surface->pending.buffer); - - surface->pending.buffer = buffer; - - ds_dbg("ds_surface(%p) attach buffer(%p)", surface, buffer); -} - -static void -surface_handle_damage(struct wl_client *client, - struct wl_resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - struct ds_surface *surface; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) damage: x %d y %d width %d height %d", - surface, x, y, width, height); - - if (width < 0 || height < 0) - return; - - surface->pending.committed |= DS_SURFACE_STATE_SURFACE_DAMAGE; - pixman_region32_union_rect(&surface->pending.surface_damage, - &surface->pending.surface_damage, - x, y, width, height); -} - -static void -callback_handle_resource_destroy(struct wl_resource *resource) -{ - wl_list_remove(wl_resource_get_link(resource)); -} - -static void -surface_handle_frame(struct wl_client *client, - struct wl_resource *resource, uint32_t callback) -{ - struct ds_surface *surface; - struct wl_resource *callback_resource; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) frame", surface); - - callback_resource = wl_resource_create(client, &wl_callback_interface, - CALLBACK_VERSION, callback); - if (!callback_resource) { - wl_resource_post_no_memory(resource); - return; - } - - wl_resource_set_implementation(callback_resource, NULL, NULL, - callback_handle_resource_destroy); - - wl_list_insert(surface->pending.frame_callback_list.prev, - wl_resource_get_link(callback_resource)); - - surface->pending.committed |= DS_SURFACE_STATE_FRAME_CALLBACK_LIST; -} - -static void -surface_handle_set_opaque_region(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *region_resource) -{ - struct ds_surface *surface; - pixman_region32_t *region; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) set opaque region", surface); - - surface->pending.committed |= DS_SURFACE_STATE_OPAQUE_REGION; - if (region_resource) { - region = ds_region_from_resource(region_resource); - pixman_region32_copy(&surface->pending.opaque, region); - } - else { - pixman_region32_clear(&surface->pending.opaque); - } -} - -static void -surface_handle_set_input_region(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *region_resource) -{ - struct ds_surface *surface; - pixman_region32_t *region; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) set input region", surface); - - surface->pending.committed |= DS_SURFACE_STATE_INPUT_REGION; - if (region_resource) { - region = ds_region_from_resource(region_resource); - pixman_region32_copy(&surface->pending.input, region); - } - else { - pixman_region32_fini(&surface->pending.input); - pixman_region32_init_rect(&surface->pending.input, - INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); - } -} - -static void -surface_handle_commit(struct wl_client *client, struct wl_resource *resource) -{ - struct ds_surface *surface; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) commit", surface); - - // TODO handle subsurface - - surface_finalize_pending(surface); - - surface_commit_state(surface, &surface->pending); - - // TODO handle subsurfaces of a given surface - - if (surface->role && surface->role->commit) - surface->role->commit(surface); - - wl_signal_emit(&surface->events.commit, surface); -} - -static void -surface_handle_set_buffer_transform(struct wl_client *client, - struct wl_resource *resource, int32_t transform) -{ - struct ds_surface *surface; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) set buffer transform(%d)", surface, transform); - - if (transform < WL_OUTPUT_TRANSFORM_NORMAL || - transform > WL_OUTPUT_TRANSFORM_FLIPPED_270) { - ds_err("Specified transform value(%d) is invalid. ds_surface(%p)", - transform, surface); - wl_resource_post_error(resource, WL_SURFACE_ERROR_INVALID_TRANSFORM, - "Specified transform value(%d) is invalid", transform); - return; - } - - surface->pending.committed |= DS_SURFACE_STATE_TRANSFORM; - surface->pending.transform = transform; -} - -static void -surface_handle_set_buffer_scale(struct wl_client *client, - struct wl_resource *resource, int32_t scale) -{ - struct ds_surface *surface; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) set buffer scale(%d)", surface, scale); - - if (scale <= 0) { - ds_err("Specified scale value(%d) is not positive. ds_surface(%p)", - scale, surface); - wl_resource_post_error(resource, WL_SURFACE_ERROR_INVALID_SCALE, - "Specified scale value(%d) is not positive", scale); - return; - } - - surface->pending.committed |= DS_SURFACE_STATE_SCALE; - surface->pending.scale = scale; -} - -static void -surface_handle_damage_buffer(struct wl_client *client, - struct wl_resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - struct ds_surface *surface; - - surface = wl_resource_get_user_data(resource); - - ds_dbg("ds_surface(%p) damage: x %d y %d width %d height %d", - surface, x, y, width, height); - - if (width < 0 || height < 0) { - ds_err("Size cannot be less than zero. ds_surface(%p) " - "width %d height %d", surface, width, height); - return; - } - - surface->pending.committed |= DS_SURFACE_STATE_BUFFER_DAMAGE; - pixman_region32_union_rect(&surface->pending.buffer_damage, - &surface->pending.buffer_damage, - x, y, width, height); -} - -static const struct wl_surface_interface surface_impl = -{ - .destroy = surface_handle_destroy, - .attach = surface_handle_attach, - .damage = surface_handle_damage, - .frame = surface_handle_frame, - .set_opaque_region = surface_handle_set_opaque_region, - .set_input_region = surface_handle_set_input_region, - .commit = surface_handle_commit, - .set_buffer_transform = surface_handle_set_buffer_transform, - .set_buffer_scale = surface_handle_set_buffer_scale, - .damage_buffer = surface_handle_damage_buffer, -}; - -static void -surface_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_surface *surface; - - surface = wl_resource_get_user_data(resource); - - ds_inf("Destroy ds_surface %p (res %p)", surface, surface->resource); - - wl_signal_emit(&surface->events.destroy, surface); - - if (surface->buffer) - ds_buffer_unlock(surface->buffer); - - surface_state_finish(&surface->pending); - surface_state_finish(&surface->current); - - pixman_region32_fini(&surface->buffer_damage); - pixman_region32_fini(&surface->opaque_region); - pixman_region32_fini(&surface->input_region); - - free(surface); -} - -static void -surface_state_init(struct ds_surface_state *state) -{ - state->scale = 1; - state->transform = WL_OUTPUT_TRANSFORM_NORMAL; - - wl_list_init(&state->subsurfaces_above); - wl_list_init(&state->subsurfaces_below); - - wl_list_init(&state->frame_callback_list); - - pixman_region32_init(&state->surface_damage); - pixman_region32_init(&state->buffer_damage); - pixman_region32_init(&state->opaque); - pixman_region32_init_rect(&state->input, - INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX); -} - -static void -surface_state_finish(struct ds_surface_state *state) -{ - struct wl_resource *resource, *tmp; - - if (state->buffer) - ds_buffer_unlock(state->buffer); - - wl_resource_for_each_safe(resource, tmp, &state->frame_callback_list) - wl_resource_destroy(resource); - - pixman_region32_fini(&state->surface_damage); - pixman_region32_fini(&state->buffer_damage); - pixman_region32_fini(&state->opaque); - pixman_region32_fini(&state->input); -} - -static void -surface_state_move(struct ds_surface_state *state, struct ds_surface_state *next) -{ - state->width = next->width; - state->height = next->height; - state->buffer_width = next->buffer_width; - state->buffer_height = next->buffer_height; - - if (next->committed & DS_SURFACE_STATE_SCALE) - state->scale = next->scale; - - if (next->committed & DS_SURFACE_STATE_TRANSFORM) - state->transform = next->transform; - - if (next->committed & DS_SURFACE_STATE_BUFFER) { - state->dx = next->dx; - state->dy = next->dy; - next->dx = next->dy = 0; - - if (state->buffer) { - ds_buffer_unlock(state->buffer); - state->buffer = NULL; - } - - if (next->buffer) { - state->buffer = ds_buffer_lock(next->buffer); - ds_buffer_unlock(next->buffer); - next->buffer = NULL; - } - } - else { - state->dx = state->dy = 0; - } - - if (next->committed & DS_SURFACE_STATE_SURFACE_DAMAGE) { - pixman_region32_copy(&state->surface_damage, &next->surface_damage); - pixman_region32_clear(&next->surface_damage); - } - else - pixman_region32_clear(&state->surface_damage); - - if (next->committed & DS_SURFACE_STATE_BUFFER_DAMAGE) { - pixman_region32_copy(&state->buffer_damage, &next->buffer_damage); - pixman_region32_clear(&next->buffer_damage); - } - else - pixman_region32_clear(&state->buffer_damage); - - if (next->committed & DS_SURFACE_STATE_OPAQUE_REGION) - pixman_region32_copy(&state->opaque, &next->opaque); - - if (next->committed & DS_SURFACE_STATE_INPUT_REGION) - pixman_region32_copy(&state->input, &next->input); - - if (next->committed & DS_SURFACE_STATE_FRAME_CALLBACK_LIST) { - wl_list_insert_list(&state->frame_callback_list, - &next->frame_callback_list); - wl_list_init(&next->frame_callback_list); - } - - // FIXME - // state->committed |= next->committed; ?? - state->committed = next->committed; - next->committed = 0; -} - -static void -surface_state_viewport_src_size(struct ds_surface_state *state, - int *out_width, int *out_height) -{ - int width, height, tmp; - - if (state->buffer_width == 0 && state->buffer_height == 0) { - *out_width = 0; - *out_height = 0; - return; - } - - width = state->buffer_width / state->scale; - height = state->buffer_height / state->scale; - if ((state->transform & WL_OUTPUT_TRANSFORM_90) != 0) { - tmp = width; - width = height; - height = tmp; - } - - *out_width = width; - *out_height = height; -} - -static void -surface_finalize_pending(struct ds_surface *surface) -{ - struct ds_surface_state *pending = &surface->pending; - - if ((pending->committed & DS_SURFACE_STATE_BUFFER)) { - if (pending->buffer) { - ds_buffer_get_size(pending->buffer, - &pending->buffer_width, &pending->buffer_height); - } - else { - pending->buffer_width = 0; - pending->buffer_height = 0; - } - } - - surface_state_viewport_src_size(pending, - &pending->width, &pending->height); - - pixman_region32_intersect_rect(&pending->surface_damage, - &pending->surface_damage, - 0, 0, pending->width, pending->height); - - pixman_region32_intersect_rect(&pending->buffer_damage, - &pending->buffer_damage, - 0, 0, pending->buffer_width, pending->buffer_height); -} - -// FIXME -static enum wl_output_transform -ds_output_transform_invert(enum wl_output_transform tr) -{ - if ((tr & WL_OUTPUT_TRANSFORM_90) && !(tr & WL_OUTPUT_TRANSFORM_FLIPPED)) { - tr ^= WL_OUTPUT_TRANSFORM_180; - } - return tr; -} - -static void -surface_update_damage(pixman_region32_t *buffer_damage, - struct ds_surface_state *current, struct ds_surface_state *pending) -{ - pixman_region32_clear(buffer_damage); - - if (pending->width != current->width || - pending->height != current->height) { - pixman_region32_union_rect(buffer_damage, buffer_damage, - 0, 0, pending->buffer_width, pending->buffer_height); - } - else { - pixman_region32_t surface_damage; - - pixman_region32_init(&surface_damage); - pixman_region32_copy(&surface_damage, &pending->surface_damage); - - // TODO viewport - - ds_region_transform(&surface_damage, &surface_damage, - ds_output_transform_invert(pending->transform), - pending->width, pending->height); - ds_region_scale(&surface_damage, &surface_damage, pending->scale); - - pixman_region32_union(buffer_damage, - &pending->buffer_damage, &surface_damage); - - pixman_region32_fini(&surface_damage); - } -} - -static void -surface_update_buffer(struct ds_surface *surface) -{ - if (!surface->current.buffer) { - if (surface->buffer) { - ds_buffer_unlock(surface->buffer); - surface->buffer = NULL; - } - return; - } - - if (surface->buffer) { - ds_buffer_unlock(surface->buffer); - surface->buffer = NULL; - } - - if (surface->current.buffer) { - surface->buffer = ds_buffer_lock(surface->current.buffer); - ds_buffer_unlock(surface->current.buffer); - surface->current.buffer = NULL; - } -} - -static void -surface_commit_state(struct ds_surface *surface, struct ds_surface_state *next) -{ - surface->sx += next->dx; - surface->sy += next->dy; - surface_update_damage(&surface->buffer_damage, &surface->current, next); - - surface_state_move(&surface->current, next); - - // FIXME no need? - if (surface->current.committed & DS_SURFACE_STATE_BUFFER) - surface_update_buffer(surface); - - wl_signal_emit(&surface->events.commit, surface); -} - -static bool -surface_for_each(struct ds_surface *surface, int x, int y, - ds_surface_for_each_func_t iterator, void *data) -{ - struct ds_subsurface *subsurface; - struct ds_subsurface_parent_state *state; - bool stop = false; - - wl_list_for_each(subsurface, - &surface->current.subsurfaces_below, current.link) { - state = &subsurface->current; - stop = surface_for_each(subsurface->surface, - x + state->x, y + state->y, iterator, data); - if (stop) - return true; - } - - stop = iterator(surface, x, y, data); - if (stop) - return true; - - wl_list_for_each(subsurface, - &surface->current.subsurfaces_above, current.link) { - state = &subsurface->current; - stop = surface_for_each(subsurface->surface, - x + state->x, y + state->y, iterator, data); - if (stop) - return true; - } - - return false; -} diff --git a/src/libds/swapchain.c b/src/libds/swapchain.c deleted file mode 100644 index 78a2ece..0000000 --- a/src/libds/swapchain.c +++ /dev/null @@ -1,202 +0,0 @@ -#include -#include -#include - -#include "libds/log.h" -#include "libds/allocator.h" - -#define DS_SWAPCHAIN_CAP 4 - -struct ds_swapchain_slot -{ - struct ds_buffer *buffer; - - struct wl_listener buffer_release; - - int age; - bool acquired; -}; - -struct ds_swapchain -{ - struct ds_allocator *allocator; - - struct ds_swapchain_slot slots[DS_SWAPCHAIN_CAP]; - - struct wl_listener allocator_destroy; - - int width, height; - uint32_t format; -}; - -static void swapchain_handle_allocator_destroy(struct wl_listener *listener, - void *data); -static bool swapchain_has_buffer(struct ds_swapchain *swapchain, - struct ds_buffer *buffer); -static struct ds_buffer *swapchain_slot_acquire(struct ds_swapchain *swapchain, - struct ds_swapchain_slot *slot, int *age); -static void swapchain_slot_reset(struct ds_swapchain_slot *slot); - -struct ds_swapchain * -ds_swapchain_create(struct ds_allocator *alloc, int width, int height, - uint32_t format) -{ - struct ds_swapchain *swapchain; - - swapchain = calloc(1, sizeof *swapchain); - if (!swapchain) - return NULL; - - swapchain->allocator = alloc; - swapchain->width = width; - swapchain->height = height; - swapchain->format = format; - - swapchain->allocator_destroy.notify = - swapchain_handle_allocator_destroy; - ds_allocator_add_destroy_listener(alloc, - &swapchain->allocator_destroy); - - ds_inf("Swapchain(%p) created", swapchain); - - return swapchain; -} - -void -ds_swapchain_destroy(struct ds_swapchain *swapchain) -{ - size_t i; - - ds_dbg("Destroy swapchain(%p)", swapchain); - - for (i = 0; i < DS_SWAPCHAIN_CAP; i++) - swapchain_slot_reset(&swapchain->slots[i]); - - wl_list_remove(&swapchain->allocator_destroy.link); - free(swapchain); -} - -struct ds_buffer * -ds_swapchain_acquire(struct ds_swapchain *swapchain, int *age) -{ - struct ds_swapchain_slot *slot, *free_slot = NULL; - size_t i; - - for (i = 0; i < DS_SWAPCHAIN_CAP; i++) { - slot = &swapchain->slots[i]; - if (slot->acquired) - continue; - - if (slot->buffer != NULL) - return swapchain_slot_acquire(swapchain, slot, age); - - free_slot = slot; - } - - if (free_slot == NULL) { - ds_err("No free output buffer slot"); - return NULL; - } - - if (!swapchain->allocator) - return NULL; - - free_slot->buffer = ds_allocator_create_buffer(swapchain->allocator, - swapchain->width, swapchain->height, swapchain->format); - if (!free_slot->buffer) { - ds_err("Failed to allocate buffer"); - return NULL; - } - - ds_dbg("Allocating new swapchain buffer(%p)", free_slot->buffer); - - return swapchain_slot_acquire(swapchain, free_slot, age); -} - -void -ds_swapchain_set_buffer_submitted(struct ds_swapchain *swapchain, - struct ds_buffer *buffer) -{ - struct ds_swapchain_slot *slot; - size_t i; - - assert(buffer); - - if (!swapchain_has_buffer(swapchain, buffer)) - return; - - for (i = 0; i < DS_SWAPCHAIN_CAP; i++) { - slot = &swapchain->slots[i]; - if (slot->buffer == buffer) - slot->age = 1; - else if (slot->age > 0) - slot->age++; - } -} - -static void -swapchain_handle_allocator_destroy(struct wl_listener *listener, void *data) -{ - struct ds_swapchain *swapchain; - - swapchain = wl_container_of(listener, swapchain, allocator_destroy); - swapchain->allocator = NULL; -} - -static bool swapchain_has_buffer(struct ds_swapchain *swapchain, - struct ds_buffer *buffer) -{ - struct ds_swapchain_slot *slot; - size_t i; - - for (i = 0; i < DS_SWAPCHAIN_CAP; i++) { - slot = &swapchain->slots[i]; - if (slot->buffer == buffer) - return true; - } - - return false; -} - -static void -swapchain_slot_handle_buffer_release(struct wl_listener *listener, void *data) -{ - struct ds_swapchain_slot *slot; - - slot = wl_container_of(listener, slot, buffer_release); - - ds_dbg("Buffer(%p) released.", slot->buffer); - - wl_list_remove(&slot->buffer_release.link); - slot->acquired = false; -} - -static struct ds_buffer * -swapchain_slot_acquire(struct ds_swapchain *swapchain, struct ds_swapchain_slot *slot, - int *age) -{ - assert(!slot->acquired); - assert(slot->buffer); - - slot->acquired = true; - - slot->buffer_release.notify = swapchain_slot_handle_buffer_release; - ds_buffer_add_release_listener(slot->buffer, &slot->buffer_release); - - if (age != NULL) - *age = slot->age; - - return ds_buffer_lock(slot->buffer); -} - -static void -swapchain_slot_reset(struct ds_swapchain_slot *slot) -{ - if (slot->acquired) - wl_list_remove(&slot->buffer_release.link); - - if (slot->buffer) - ds_buffer_drop(slot->buffer); - - memset(slot, 0, sizeof *slot); -} diff --git a/src/libds/touch.c b/src/libds/touch.c deleted file mode 100644 index 72a3660..0000000 --- a/src/libds/touch.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include "libds/interfaces/touch.h" - -void -ds_touch_init(struct ds_touch *touch, - const struct ds_touch_interface *iface) -{ - touch->iface = iface; - - wl_signal_init(&touch->events.down); - wl_signal_init(&touch->events.up); - wl_signal_init(&touch->events.motion); - wl_signal_init(&touch->events.frame); -} - -void -ds_touch_destroy(struct ds_touch *touch) -{ - if (!touch) - return; - - if (touch->iface && touch->iface->destroy) - touch->iface->destroy(touch); - else - free(touch); -} - -WL_EXPORT void -ds_touch_add_down_listener(struct ds_touch *touch, - struct wl_listener *listener) -{ - wl_signal_add(&touch->events.down, listener); -} - -WL_EXPORT void -ds_touch_add_up_listener(struct ds_touch *touch, - struct wl_listener *listener) -{ - wl_signal_add(&touch->events.up, listener); -} - -WL_EXPORT void -ds_touch_add_motion_listener(struct ds_touch *touch, - struct wl_listener *listener) -{ - wl_signal_add(&touch->events.motion, listener); -} - -WL_EXPORT void -ds_touch_add_frame_listener(struct ds_touch *touch, - struct wl_listener *listener) -{ - wl_signal_add(&touch->events.frame, listener); -} diff --git a/src/libds/util.h b/src/libds/util.h deleted file mode 100644 index 4603544..0000000 --- a/src/libds/util.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef DS_UTIL_H -#define DS_UTIL_H - -#include -#include - -int64_t -timespec_to_msec(const struct timespec *a); - -uint32_t -get_current_time_msec(void); - -int -allocate_shm_file(size_t size); - -bool -allocate_shm_file_pair(size_t size, int *rw_fd_ptr, int *ro_fd_ptr); - -#endif diff --git a/src/libds/util/shm.c b/src/libds/util/shm.c deleted file mode 100644 index 4abd229..0000000 --- a/src/libds/util/shm.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright © 2012 Collabora, Ltd. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define _POSIX_C_SOURCE 200809L -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define RANDNAME_PATTERN "/libds-XXXXXX" - -int -os_fd_set_cloexec(int fd) -{ - long flags; - - if (fd == -1) - return -1; - - flags = fcntl(fd, F_GETFD); - if (flags == -1) - return -1; - - if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) - return -1; - - return 0; -} - -static int -set_cloexec_or_close(int fd) -{ - if (os_fd_set_cloexec(fd) != 0) { - close(fd); - return -1; - } - return fd; -} - -static int -create_tmpfile_cloexec(char *tmpname) -{ - int fd; - -#ifdef HAVE_MKOSTEMP - fd = mkostemp(tmpname, O_CLOEXEC); - if (fd >= 0) - unlink(tmpname); -#else - fd = mkstemp(tmpname); - if (fd >= 0) { - fd = set_cloexec_or_close(fd); - unlink(tmpname); - } -#endif - - return fd; -} - -/* - * Create a new, unique, anonymous file of the given size, and - * return the file descriptor for it. The file descriptor is set - * CLOEXEC. The file is immediately suitable for mmap()'ing - * the given size at offset zero. - * - * The file should not have a permanent backing store like a disk, - * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. - * - * The file name is deleted from the file system. - * - * The file is suitable for buffer sharing between processes by - * transmitting the file descriptor over Unix sockets using the - * SCM_RIGHTS methods. - * - * If the C library implements posix_fallocate(), it is used to - * guarantee that disk space is available for the file at the - * given size. If disk space is insufficient, errno is set to ENOSPC. - * If posix_fallocate() is not supported, program may receive - * SIGBUS on accessing mmap()'ed file contents instead. - * - * If the C library implements memfd_create(), it is used to create the - * file purely in memory, without any backing file name on the file - * system, and then sealing off the possibility of shrinking it. This - * can then be checked before accessing mmap()'ed file contents, to - * make sure SIGBUS can't happen. It also avoids requiring - * XDG_RUNTIME_DIR. - */ -int -allocate_shm_file(off_t size) -{ - static const char template[] = "/weston-shared-XXXXXX"; - const char *path; - char *name; - int fd; - int ret; - -#ifdef HAVE_MEMFD_CREATE - fd = memfd_create("weston-shared", MFD_CLOEXEC | MFD_ALLOW_SEALING); - if (fd >= 0) { - /* We can add this seal before calling posix_fallocate(), as - * the file is currently zero-sized anyway. - * - * There is also no need to check for the return value, we - * couldn't do anything with it anyway. - */ - fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK); - } else -#endif - { - path = getenv("XDG_RUNTIME_DIR"); - if (!path) { - errno = ENOENT; - return -1; - } - - name = malloc(strlen(path) + sizeof(template)); - if (!name) - return -1; - - strcpy(name, path); - strcat(name, template); - - fd = create_tmpfile_cloexec(name); - - free(name); - - if (fd < 0) - return -1; - } - -#ifdef HAVE_POSIX_FALLOCATE - do { - ret = posix_fallocate(fd, 0, size); - } while (ret == EINTR); - if (ret != 0) { - close(fd); - errno = ret; - return -1; - } -#else - do { - ret = ftruncate(fd, size); - } while (ret < 0 && errno == EINTR); - if (ret < 0) { - close(fd); - return -1; - } -#endif - - return fd; -} - -static void -randname(char *buf) -{ - struct timespec ts; - long r; - - clock_gettime(CLOCK_REALTIME, &ts); - r = ts.tv_nsec; - for (int i = 0; i < 6; i++) { - buf[i] = 'A' + (r & 15) + (r & 16) * 2; - r >>= 5; - } -} - -static int -excl_shm_open(char *name) -{ - int retries = 100; - int fd; - - do { - randname(name + strlen(RANDNAME_PATTERN) - 6); - - --retries; - - fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd >= 0) - return fd; - } while (retries > 0 && errno == EEXIST); - - return -1; -} - -bool -allocate_shm_file_pair(size_t size, int *rw_fd_ptr, int *ro_fd_ptr) -{ - char name[] = RANDNAME_PATTERN; - int rw_fd, ro_fd; - int ret; - - rw_fd = excl_shm_open(name); - if (rw_fd < 0) - return false; - - ro_fd = shm_open(name, O_RDONLY, 0); - if (ro_fd < 0) { - shm_unlink(name); - close(rw_fd); - return false; - } - - shm_unlink(name); - - do { - ret = ftruncate(rw_fd, size); - } while (ret < 0 && errno == EINTR); - - if (ret < 0) { - close(rw_fd); - close(ro_fd); - return false; - } - - *rw_fd_ptr = rw_fd; - *ro_fd_ptr = ro_fd; - - return true; -} diff --git a/src/libds/util/time.c b/src/libds/util/time.c deleted file mode 100644 index 2461cb7..0000000 --- a/src/libds/util/time.c +++ /dev/null @@ -1,19 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include -#include - -int64_t -timespec_to_msec(const struct timespec *a) -{ - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; -} - -uint32_t -get_current_time_msec(void) -{ - struct timespec now; - - clock_gettime(CLOCK_MONOTONIC, &now); - return timespec_to_msec(&now); -} diff --git a/src/libds/xdg_shell/xdg_shell.c b/src/libds/xdg_shell/xdg_shell.c deleted file mode 100644 index 0b5252c..0000000 --- a/src/libds/xdg_shell/xdg_shell.c +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include -#include - -#include "libds/log.h" -#include "libds/xdg_shell.h" - -#include "xdg_shell.h" - -#define XDG_WM_BASE_VERSION 2 -#define XDG_SHELL_PING_TIMEOUT 10000 - -static void xdg_shell_handle_display_destroy(struct wl_listener *listener, - void *data); -static void xdg_shell_bind(struct wl_client *wl_client, void *data, - uint32_t verison, uint32_t id); - -WL_EXPORT struct ds_xdg_shell * -ds_xdg_shell_create(struct wl_display *display) -{ - struct ds_xdg_shell *shell; - - shell = calloc(1, sizeof *shell); - if (!shell) { - return NULL; - } - - shell->ping_timeout = XDG_SHELL_PING_TIMEOUT; - - wl_list_init(&shell->clients); - - shell->global = wl_global_create(display, &xdg_wm_base_interface, - XDG_WM_BASE_VERSION, shell, xdg_shell_bind); - if (!shell->global) { - free(shell); - return NULL; - } - - wl_signal_init(&shell->events.destroy); - wl_signal_init(&shell->events.new_surface); - - shell->display_destroy.notify = xdg_shell_handle_display_destroy; - wl_display_add_destroy_listener(display, &shell->display_destroy); - - ds_inf("Global created: xdg_wm_base shell(%p)", shell); - - return shell; -} - -WL_EXPORT void -ds_xdg_shell_add_destroy_listener(struct ds_xdg_shell *shell, - struct wl_listener *listener) -{ - wl_signal_add(&shell->events.destroy, listener); -} - -void -ds_xdg_shell_add_new_surface_listener(struct ds_xdg_shell *shell, - struct wl_listener *listener) -{ - wl_signal_add(&shell->events.new_surface, listener); -} - -static void -xdg_shell_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_xdg_shell *shell; - - shell = wl_container_of(listener, shell, display_destroy); - - ds_inf("Global destroy: xdg_wm_base shell(%p)", shell); - - wl_signal_emit(&shell->events.destroy, shell); - wl_list_remove(&shell->display_destroy.link); - wl_global_destroy(shell->global); - free(shell); -} - -static void -xdg_shell_handle_destroy(struct wl_client *wl_client, - struct wl_resource *resource) -{ - struct ds_xdg_client *client; - - client = wl_resource_get_user_data(resource); - - if (!wl_list_empty(&client->surfaces)) { - wl_resource_post_error(client->resource, - XDG_WM_BASE_ERROR_DEFUNCT_SURFACES, - "xdg_wm_base was destroyed before children"); - return; - } - - wl_resource_destroy(resource); -} - -static void -xdg_shell_handle_create_positioner(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t id) -{ - // TODO -} - -static void -xdg_shell_handle_get_xdg_surface(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t id, - struct wl_resource *surface_resource) -{ - struct ds_xdg_client *client; - struct ds_surface *surface; - - client = wl_resource_get_user_data(resource); - surface = ds_surface_from_resource(surface_resource); - create_xdg_surface(client, surface, id); -} - -static void -xdg_shell_handle_pong(struct wl_client *wl_client, - struct wl_resource *resource, uint32_t serial) -{ - struct ds_xdg_client *client; - - client = wl_resource_get_user_data(resource); - if (client->ping_serial != serial) - return; - - wl_event_source_timer_update(client->ping_timer, 0); - client->ping_serial = 0; -} - -static const struct xdg_wm_base_interface xdg_shell_impl = -{ - .destroy = xdg_shell_handle_destroy, - .create_positioner = xdg_shell_handle_create_positioner, - .get_xdg_surface = xdg_shell_handle_get_xdg_surface, - .pong = xdg_shell_handle_pong, -}; - -static void -xdg_client_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_xdg_client *client; - struct ds_xdg_surface *surface, *tmp; - - client = wl_resource_get_user_data(resource); - - wl_list_for_each_safe(surface, tmp, &client->surfaces, link) - destroy_xdg_surface(surface); - - if (client->ping_timer != NULL) - wl_event_source_remove(client->ping_timer); - - wl_list_remove(&client->link); - free(client); -} - -static int -xdg_client_handle_ping_timeout(void *user_data) -{ - struct ds_xdg_client *client = user_data; - struct ds_xdg_surface *surface; - - wl_list_for_each(surface, &client->surfaces, link) - wl_signal_emit(&surface->events.ping_timeout, surface); - - client->ping_serial = 0; - - return 1; -} - -static void -xdg_client_init_ping_timer(struct ds_xdg_client *client) -{ - struct wl_display *display; - struct wl_event_loop *loop; - - display = wl_client_get_display(client->wl_client); - loop = wl_display_get_event_loop(display); - client->ping_timer = wl_event_loop_add_timer(loop, - xdg_client_handle_ping_timeout, client); - if (client->ping_timer == NULL) - wl_client_post_no_memory(client->wl_client); -} - -static void -xdg_shell_bind(struct wl_client *wl_client, void *data, uint32_t version, - uint32_t id) -{ - struct ds_xdg_shell *shell = data; - struct ds_xdg_client *client; - - client = calloc(1, sizeof *client); - if (client == NULL) { - wl_client_post_no_memory(wl_client); - return; - } - - client->wl_client = wl_client; - client->shell = shell; - - wl_list_init(&client->surfaces); - - client->resource = - wl_resource_create(wl_client, &xdg_wm_base_interface, version, id); - if (client->resource == NULL) { - free(client); - wl_client_post_no_memory(wl_client); - return; - } - - wl_resource_set_implementation(client->resource, &xdg_shell_impl, client, - xdg_client_handle_resource_destroy); - - wl_list_insert(&shell->clients, &client->link); - - xdg_client_init_ping_timer(client); -} diff --git a/src/libds/xdg_shell/xdg_shell.h b/src/libds/xdg_shell/xdg_shell.h deleted file mode 100644 index dc50d37..0000000 --- a/src/libds/xdg_shell/xdg_shell.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef DS_XDG_SHELL_H -#define DS_XDG_SHELL_H - -#include - -#include "libds/output.h" -#include "xdg-shell-server-protocol.h" - -#include "surface.h" - -enum ds_xdg_surface_role -{ - DS_XDG_SURFACE_ROLE_NONE, - DS_XDG_SURFACE_ROLE_TOPLEVEL, - DS_XDG_SURFACE_ROLE_POPUP, -}; - -struct ds_xdg_shell -{ - struct wl_global *global; - - struct wl_list clients; - - struct wl_listener display_destroy; - - struct { - struct wl_signal destroy; - struct wl_signal new_surface; - } events; - - uint32_t ping_timeout; -}; - -struct ds_xdg_client -{ - struct ds_xdg_shell *shell; - - struct wl_resource *resource; - struct wl_client *wl_client; - struct wl_event_source *ping_timer; - - struct wl_list surfaces; - - struct wl_list link; // ds_xdg_shell::clients - - uint32_t ping_serial; -}; - -struct ds_xdg_toplevel_state -{ - bool maximized, fullscreen, resizing, activated; - uint32_t tiled; - uint32_t width, height; - uint32_t max_width, max_height; - uint32_t min_width, min_height; -}; - -struct ds_xdg_toplevel_configure -{ - bool maximized, fullscreen, resizing, activated; - uint32_t tiled; - uint32_t width, height; -}; - -struct ds_xdg_toplevel_requested -{ - bool maximized, minimized, fullscreen; - struct ds_output *fullscreen_output; - struct wl_listener fullscreen_output_destroy; -}; - -struct ds_xdg_toplevel -{ - struct wl_resource *resource; - struct ds_xdg_surface *base; - bool added; - - struct ds_xdg_surface *parent; - struct wl_listener parent_unmap; - - struct ds_xdg_toplevel_state current, pending; - struct ds_xdg_toplevel_configure scheduled; - struct ds_xdg_toplevel_requested requested; - - char *title; - char *app_id; - - struct { - struct wl_signal request_maximize; - struct wl_signal request_fullscreen; - struct wl_signal request_minimize; - struct wl_signal request_move; - struct wl_signal request_resize; - struct wl_signal request_show_window_menu; - struct wl_signal set_parent; - struct wl_signal set_title; - struct wl_signal set_app_id; - } events; -}; - -struct ds_xdg_popup -{ - -}; - -struct ds_xdg_surface_state -{ - uint32_t configure_serial; - struct { - int x, y; - int width, height; - } geometry; -}; - -struct ds_xdg_surface -{ - struct ds_xdg_client *client; - struct ds_surface *ds_surface; - - enum ds_xdg_surface_role role; - - union { - struct ds_xdg_toplevel *toplevel; - struct ds_xdg_popup *popup; - }; - - struct wl_resource *resource; - - struct wl_event_source *configure_idle; - uint32_t scheduled_serial; - struct wl_list configure_list; - - struct ds_xdg_surface_state current, pending; - - struct wl_list link; // ds_xdg_client::surfaces - - struct { - struct wl_listener surface_destroy; - struct wl_listener surface_commit; - } listener; - - struct { - struct wl_signal destroy; - struct wl_signal ping_timeout; - struct wl_signal new_popup; - struct wl_signal map; - struct wl_signal unmap; - struct wl_signal configure; - struct wl_signal ack_configure; - } events; - - bool added, configured, mapped; -}; - -struct ds_xdg_surface_configure -{ - struct ds_xdg_surface *surface; - struct wl_list link; - uint32_t serial; - - struct ds_xdg_toplevel_configure *toplevel_configure; -}; - -uint32_t -ds_xdg_surface_schedule_configure(struct ds_xdg_surface *surface); - -struct ds_xdg_surface * -create_xdg_surface(struct ds_xdg_client *client, struct ds_surface *surface, - uint32_t id); - -void destroy_xdg_surface(struct ds_xdg_surface *surface); - -void -reset_xdg_surface(struct ds_xdg_surface *surface); - -void -create_xdg_toplevel(struct ds_xdg_surface *surface, uint32_t id); - -void -handle_xdg_surface_commit(struct ds_surface *ds_surface); - -void -handle_xdg_surface_toplevel_committed(struct ds_xdg_surface *surface); - -void -send_xdg_toplevel_configure(struct ds_xdg_surface *surface, - struct ds_xdg_surface_configure *configure); - -#endif diff --git a/src/libds/xdg_shell/xdg_surface.c b/src/libds/xdg_shell/xdg_surface.c deleted file mode 100644 index 1e1654e..0000000 --- a/src/libds/xdg_shell/xdg_surface.c +++ /dev/null @@ -1,487 +0,0 @@ -#include -#include - -#include "libds/log.h" - -#include "xdg_shell.h" - -static const struct xdg_surface_interface xdg_surface_impl; - -static void xdg_surface_handle_surface_destroy(struct wl_listener *listener, - void *data); -static void xdg_surface_handle_surface_commit(struct wl_listener *listener, - void *data); -static void xdg_surface_handle_resource_destroy(struct wl_resource *resource); -static void xdg_surface_configure_destroy(struct ds_xdg_surface_configure *configure); -static void surface_send_configure(void *user_data); - -void -ds_xdg_surface_add_destroy_listener(struct ds_xdg_surface *surface, - struct wl_listener *listener) -{ - wl_signal_add(&surface->events.destroy, listener); -} - -WL_EXPORT void -ds_xdg_surface_add_map_listener(struct ds_xdg_surface *surface, - struct wl_listener *listener) -{ - wl_signal_add(&surface->events.map, listener); -} - -WL_EXPORT void -ds_xdg_surface_add_unmap_listener(struct ds_xdg_surface *surface, - struct wl_listener *listener) -{ - wl_signal_add(&surface->events.unmap, listener); -} - -struct ds_surface * -ds_xdg_surface_get_surface(struct ds_xdg_surface *surface) -{ - return surface->ds_surface; -} - -struct ds_xdg_surface * -create_xdg_surface(struct ds_xdg_client *client, struct ds_surface *ds_surface, - uint32_t id) -{ - struct ds_xdg_surface *surface; - - surface = calloc(1, sizeof *surface); - if (!surface) { - wl_client_post_no_memory(client->wl_client); - return NULL; - } - - surface->client = client; - surface->role = DS_XDG_SURFACE_ROLE_NONE; - surface->ds_surface = ds_surface; - surface->resource = wl_resource_create(client->wl_client, - &xdg_surface_interface, wl_resource_get_version(client->resource), - id); - if (!surface->resource) { - free(surface); - wl_client_post_no_memory(client->wl_client); - return NULL; - } - - if (ds_surface_has_buffer(surface->ds_surface)) { - wl_resource_destroy(surface->resource); - free(surface); - wl_resource_post_error(client->resource, - XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, - "xdg_surface must not have a buffer at creation"); - return NULL; - } - - wl_list_init(&surface->configure_list); - - wl_signal_init(&surface->events.destroy); - wl_signal_init(&surface->events.ping_timeout); - wl_signal_init(&surface->events.new_popup); - wl_signal_init(&surface->events.map); - wl_signal_init(&surface->events.unmap); - wl_signal_init(&surface->events.configure); - wl_signal_init(&surface->events.ack_configure); - - surface->listener.surface_destroy.notify = - xdg_surface_handle_surface_destroy; - ds_surface_add_destroy_listener(ds_surface, - &surface->listener.surface_destroy); - - surface->listener.surface_commit.notify = - xdg_surface_handle_surface_commit; - ds_surface_add_commit_listener(ds_surface, - &surface->listener.surface_commit); - - wl_resource_set_implementation(surface->resource, &xdg_surface_impl, - surface, xdg_surface_handle_resource_destroy); - - wl_list_insert(&client->surfaces, &surface->link); - - ds_inf("New xdg_surface %p (res %p)", surface, surface->resource); - - return surface; -} - -void -unmap_xdg_surface(struct ds_xdg_surface *surface) -{ - struct ds_xdg_surface_configure *configure, *tmp; - - // TODO handle popup - - if (surface->mapped) - wl_signal_emit(&surface->events.unmap, surface); - - switch (surface->role) { - case DS_XDG_SURFACE_ROLE_TOPLEVEL: - if (surface->toplevel->parent) { - wl_list_remove(&surface->toplevel->parent_unmap.link); - surface->toplevel->parent = NULL; - } - free(surface->toplevel->title); - surface->toplevel->title = NULL; - free(surface->toplevel->app_id); - surface->toplevel->app_id = NULL; - break; - case DS_XDG_SURFACE_ROLE_POPUP: - // TODO - break; - case DS_XDG_SURFACE_ROLE_NONE: - assert(false && "not reached"); - } - - wl_list_for_each_safe(configure, tmp, &surface->configure_list, link) - xdg_surface_configure_destroy(configure); - - if (surface->configure_idle) { - wl_event_source_remove(surface->configure_idle); - surface->configure_idle = NULL; - } - - surface->configured = false; - surface->mapped = false; -} - -void -reset_xdg_surface(struct ds_xdg_surface *surface) -{ - struct ds_xdg_toplevel_requested *req; - - if (surface->role != DS_XDG_SURFACE_ROLE_NONE) - unmap_xdg_surface(surface); - - if (surface->added) { - wl_signal_emit(&surface->events.destroy, surface); - surface->added = false; - } - - switch (surface->role) { - case DS_XDG_SURFACE_ROLE_TOPLEVEL: - wl_resource_set_user_data(surface->toplevel->resource, NULL); - surface->toplevel->resource = NULL; - req = &surface->toplevel->requested; - if (req->fullscreen_output) - wl_list_remove(&req->fullscreen_output_destroy.link); - free(surface->toplevel); - surface->toplevel = NULL; - break; - case DS_XDG_SURFACE_ROLE_POPUP: - // TODO - break; - case DS_XDG_SURFACE_ROLE_NONE: - // This space is intentionally left blank - break; - } - - surface->role = DS_XDG_SURFACE_ROLE_NONE; -} - -void -destroy_xdg_surface(struct ds_xdg_surface *surface) -{ - reset_xdg_surface(surface); - - wl_resource_set_user_data(surface->resource, NULL); - - ds_surface_reset_role_data(surface->ds_surface); - - wl_list_remove(&surface->link); - wl_list_remove(&surface->listener.surface_destroy.link); - wl_list_remove(&surface->listener.surface_commit.link); - - free(surface); -} - -void -handle_xdg_surface_commit(struct ds_surface *ds_surface) -{ - struct ds_xdg_surface *surface; - - surface = ds_surface_get_role_data(ds_surface); - surface->current = surface->pending; - - switch (surface->role) { - case DS_XDG_SURFACE_ROLE_NONE: - // inert toplevel or popup - break; - case DS_XDG_SURFACE_ROLE_TOPLEVEL: - handle_xdg_surface_toplevel_committed(surface); - // TODO - break; - case DS_XDG_SURFACE_ROLE_POPUP: - // TODO - break; - } - - if (!surface->added) { - surface->added = true; - wl_signal_emit(&surface->client->shell->events.new_surface, surface); - } - - if (surface->configured && - ds_surface_has_buffer(surface->ds_surface) && - !surface->mapped) { - surface->mapped = true; - wl_signal_emit(&surface->events.map, surface); - } -} - -void handle_xdg_surface_precommit(struct ds_surface *ds_surface) -{ - struct ds_xdg_surface *surface; - - surface = ds_surface_get_role_data(ds_surface); - - // TODO - (void)surface; -} - -uint32_t -ds_xdg_surface_schedule_configure(struct ds_xdg_surface *surface) -{ - struct wl_display *display; - struct wl_event_loop *loop; - - display = wl_client_get_display(surface->client->wl_client); - loop = wl_display_get_event_loop(display); - - if (!surface->configure_idle) { - surface->scheduled_serial = wl_display_next_serial(display); - surface->configure_idle = wl_event_loop_add_idle(loop, - surface_send_configure, surface); - if (!surface->configure_idle) - wl_client_post_no_memory(surface->client->wl_client); - } - - return surface->scheduled_serial; -} - -void -ds_xdg_surface_ping(struct ds_xdg_surface *surface) -{ -} - -static void -xdg_surface_handle_surface_destroy(struct wl_listener *listener, void *data) -{ - struct ds_xdg_surface *surface; - - surface = wl_container_of(listener, surface, listener.surface_destroy); - destroy_xdg_surface(surface); -} - -static void -xdg_surface_handle_surface_commit(struct wl_listener *listener, void *data) -{ - struct ds_xdg_surface *surface; - - surface = wl_container_of(listener, surface, listener.surface_commit); - - if (ds_surface_has_buffer(surface->ds_surface) && - !surface->configured) { - wl_resource_post_error(surface->resource, - XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, - "xdg_surface has never been configured"); - return; - } - - if (!ds_surface_get_role(surface->ds_surface)) { - wl_resource_post_error(surface->resource, - XDG_SURFACE_ERROR_NOT_CONSTRUCTED, - "xdg_surface must have a role"); - return; - } -} - -static void -xdg_surface_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - if (!surface) - return; - - destroy_xdg_surface(surface); -} - -static void -xdg_surface_configure_destroy(struct ds_xdg_surface_configure *configure) -{ - wl_list_remove(&configure->link); - free(configure->toplevel_configure); - free(configure); -} - -static void -xdg_surface_handle_destroy(struct wl_client *client, - struct wl_resource *resource) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - - if (surface->role != DS_XDG_SURFACE_ROLE_NONE) { - ds_err("Tried to destroy an xdg_surface before its role object"); - return; - } - - wl_resource_destroy(resource); -} - -static void -xdg_surface_handle_get_toplevel(struct wl_client *client, - struct wl_resource *resource, uint32_t id) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - create_xdg_toplevel(surface, id); -} - -static void -xdg_surface_handle_get_popup(struct wl_client *client, - struct wl_resource *resource, uint32_t id, - struct wl_resource *parent_resource, - struct wl_resource *positioner_resource) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - - // TODO - (void)surface; -} - -static void -xdg_surface_handle_ack_configure(struct wl_client *client, - struct wl_resource *resource, uint32_t serial) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - - if (surface->role == DS_XDG_SURFACE_ROLE_NONE) { - wl_resource_post_error(surface->resource, - XDG_SURFACE_ERROR_NOT_CONSTRUCTED, - "xdg_surface must have a role"); - return; - } - - bool found = false; - struct ds_xdg_surface_configure *configure, *tmp; - wl_list_for_each(configure, &surface->configure_list, link) { - if (configure->serial == serial) { - found = true; - break; - } - } - - if (!found) { - wl_resource_post_error(surface->client->resource, - XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE, - "wrong configure serial: %u", serial); - return; - } - - wl_list_for_each_safe(configure, tmp, &surface->configure_list, link) { - if (configure->serial == serial) - break; - - wl_signal_emit(&surface->events.ack_configure, configure); - xdg_surface_configure_destroy(configure); - } - - switch (surface->role) { - case DS_XDG_SURFACE_ROLE_NONE: - assert(0 && "not reached"); - break; - case DS_XDG_SURFACE_ROLE_TOPLEVEL: - // TODO - break; - case DS_XDG_SURFACE_ROLE_POPUP: - break; - } - - surface->configured = true; - surface->pending.configure_serial = serial; - - wl_signal_emit(&surface->events.ack_configure, configure); - xdg_surface_configure_destroy(configure); -} - -static void -xdg_surface_handle_set_window_geometry(struct wl_client *client, - struct wl_resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - - if (surface->role == DS_XDG_SURFACE_ROLE_NONE) { - wl_resource_post_error(surface->resource, - XDG_SURFACE_ERROR_NOT_CONSTRUCTED, - "xdg_surface must have a role"); - return; - } - - if (width <= 0 || height <= 0) { - ds_err("Client tried to set invalid geometry"); - wl_resource_post_error(resource, -1, - "Tried to set invalid xdg_surface geometry"); - return; - } - - surface->pending.geometry.x = x; - surface->pending.geometry.y = y; - surface->pending.geometry.width = width; - surface->pending.geometry.height = height; -} - -static const struct xdg_surface_interface xdg_surface_impl = -{ - .destroy = xdg_surface_handle_destroy, - .get_toplevel = xdg_surface_handle_get_toplevel, - .get_popup = xdg_surface_handle_get_popup, - .ack_configure = xdg_surface_handle_ack_configure, - .set_window_geometry = xdg_surface_handle_set_window_geometry, -}; - -static void -surface_send_configure(void *user_data) -{ - struct ds_xdg_surface *surface; - struct ds_xdg_surface_configure *configure; - - surface = user_data; - surface->configure_idle = NULL; - - configure = calloc(1, sizeof *configure); - if (!configure) { - wl_client_post_no_memory(surface->client->wl_client); - return; - } - - wl_list_insert(surface->configure_list.prev, &configure->link); - configure->serial = surface->scheduled_serial; - configure->surface = surface; - - switch (surface->role) { - case DS_XDG_SURFACE_ROLE_NONE: - assert(0 && "not reached"); - break; - case DS_XDG_SURFACE_ROLE_TOPLEVEL: - send_xdg_toplevel_configure(surface, configure); - break; - case DS_XDG_SURFACE_ROLE_POPUP: - break; - } - - wl_signal_emit(&surface->events.configure, configure); - - xdg_surface_send_configure(surface->resource, configure->serial); -} diff --git a/src/libds/xdg_shell/xdg_toplevel.c b/src/libds/xdg_shell/xdg_toplevel.c deleted file mode 100644 index 2a1e6d7..0000000 --- a/src/libds/xdg_shell/xdg_toplevel.c +++ /dev/null @@ -1,329 +0,0 @@ -#include -#include -#include - -#include "xdg_shell.h" - -static const struct ds_surface_role xdg_toplevel_surface_role = -{ - .name = "xdg_toplevel", - .commit = handle_xdg_surface_commit, -}; - -static const struct xdg_toplevel_interface xdg_toplevel_impl; - -static void xdg_toplevel_handle_resource_destroy(struct wl_resource *resource); - -void -create_xdg_toplevel(struct ds_xdg_surface *surface, uint32_t id) -{ - if (!ds_surface_set_role(surface->ds_surface, &xdg_toplevel_surface_role, - surface, surface->resource, XDG_WM_BASE_ERROR_ROLE)) - return; - - if (surface->role != DS_XDG_SURFACE_ROLE_NONE) { - wl_resource_post_error(surface->resource, - XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED, - "xdg_surface has already been constructed"); - return; - } - - assert(surface->toplevel == NULL); - - surface->toplevel = calloc(1, sizeof *surface->toplevel); - if (!surface->toplevel) { - wl_resource_post_no_memory(surface->resource); - return; - } - - surface->toplevel->base = surface; - - wl_signal_init(&surface->toplevel->events.request_maximize); - wl_signal_init(&surface->toplevel->events.request_fullscreen); - wl_signal_init(&surface->toplevel->events.request_minimize); - wl_signal_init(&surface->toplevel->events.request_move); - wl_signal_init(&surface->toplevel->events.request_resize); - wl_signal_init(&surface->toplevel->events.request_show_window_menu); - wl_signal_init(&surface->toplevel->events.set_parent); - wl_signal_init(&surface->toplevel->events.set_title); - wl_signal_init(&surface->toplevel->events.set_app_id); - - surface->toplevel->resource = wl_resource_create( - surface->client->wl_client, &xdg_toplevel_interface, - wl_resource_get_version(surface->resource), id); - if (!surface->toplevel->resource) { - free(surface->toplevel); - wl_resource_post_no_memory(surface->resource); - return; - } - - wl_resource_set_implementation(surface->toplevel->resource, - &xdg_toplevel_impl, surface, - xdg_toplevel_handle_resource_destroy); - - surface->role = DS_XDG_SURFACE_ROLE_TOPLEVEL; -} - -void -handle_xdg_surface_toplevel_committed(struct ds_xdg_surface *surface) -{ - if (!surface->toplevel->added) { - ds_xdg_surface_schedule_configure(surface); - surface->toplevel->added = true; - return; - } - - surface->toplevel->current = surface->toplevel->pending; -} - -void -send_xdg_toplevel_configure(struct ds_xdg_surface *surface, - struct ds_xdg_surface_configure *configure) -{ - struct wl_array states; - uint32_t width, height; - - configure->toplevel_configure = - malloc(sizeof *configure->toplevel_configure); - if (!configure->toplevel_configure) { - wl_resource_post_no_memory(surface->toplevel->resource); - return; - } - - *configure->toplevel_configure = surface->toplevel->scheduled; - - wl_array_init(&states); - if (surface->toplevel->scheduled.maximized) { - uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); - if (!s) - goto error_out; - *s = XDG_TOPLEVEL_STATE_MAXIMIZED; - } - - if (surface->toplevel->scheduled.fullscreen) { - uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); - if (!s) - goto error_out; - *s = XDG_TOPLEVEL_STATE_FULLSCREEN; - } - - if (surface->toplevel->scheduled.resizing) { - uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); - if (!s) - goto error_out; - *s = XDG_TOPLEVEL_STATE_RESIZING; - } - - if (surface->toplevel->scheduled.activated) { - uint32_t *s = wl_array_add(&states, sizeof(uint32_t)); - if (!s) - goto error_out; - *s = XDG_TOPLEVEL_STATE_ACTIVATED; - } - - if (surface->toplevel->scheduled.tiled) { - ;;; - // TODO - } - - width = surface->toplevel->scheduled.width; - height = surface->toplevel->scheduled.height; - - xdg_toplevel_send_configure(surface->toplevel->resource, width, height, - &states); - wl_array_release(&states); - - return; - -error_out: - wl_array_release(&states); - wl_resource_post_no_memory(surface->toplevel->resource); -} - -void -destroy_xdg_toplevel(struct ds_xdg_surface *xdg_surface) -{ - reset_xdg_surface(xdg_surface); -} - -static void -xdg_toplevel_handle_destroy(struct wl_client *client, - struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -xdg_toplevel_handle_set_parent(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *parent_resource) -{ - // TODO -} - -static void -xdg_toplevel_handle_set_title(struct wl_client *client, - struct wl_resource *resource, const char *title) -{ - struct ds_xdg_surface *surface; - char *tmp; - - surface = wl_resource_get_user_data(resource); - tmp = strdup(title); - if (!tmp) { - wl_resource_post_no_memory(resource); - return; - } - - if (surface->toplevel->title) - free(surface->toplevel->title); - - surface->toplevel->title = tmp; - wl_signal_emit(&surface->toplevel->events.set_title, surface); -} - -static void -xdg_toplevel_handle_set_app_id(struct wl_client *client, - struct wl_resource *resource, const char *app_id) -{ - struct ds_xdg_surface *surface; - char *tmp; - - surface = wl_resource_get_user_data(resource); - tmp = strdup(app_id); - if (!tmp) { - wl_resource_post_no_memory(resource); - return; - } - - if (surface->toplevel->app_id) - free(surface->toplevel->app_id); - - surface->toplevel->app_id= tmp; - wl_signal_emit(&surface->toplevel->events.set_app_id, surface); - -} - -static void -xdg_toplevel_handle_show_window_menu(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial, int32_t x, int32_t y) -{ - // TODO -} - -static void -xdg_toplevel_handle_move(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial) -{ - // TODO -} - -static void -xdg_toplevel_handle_resize(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *seat_resource, - uint32_t serial, uint32_t edges) -{ - // TODO -} - -static void -xdg_toplevel_handle_set_max_size(struct wl_client *client, - struct wl_resource *resource, int32_t width, int32_t height) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - surface->toplevel->pending.max_width = width; - surface->toplevel->pending.max_height = height; -} - -static void -xdg_toplevel_handle_set_min_size(struct wl_client *client, - struct wl_resource *resource, int32_t width, int32_t height) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - surface->toplevel->pending.min_width = width; - surface->toplevel->pending.min_height = height; -} - -static void -xdg_toplevel_handle_set_maximized(struct wl_client *client, - struct wl_resource *resource) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - surface->toplevel->requested.maximized = true; - wl_signal_emit(&surface->toplevel->events.request_maximize, surface); - ds_xdg_surface_schedule_configure(surface); -} - -static void -xdg_toplevel_handle_unset_maximized(struct wl_client *client, - struct wl_resource *resource) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - surface->toplevel->requested.maximized = false; - wl_signal_emit(&surface->toplevel->events.request_maximize, surface); - ds_xdg_surface_schedule_configure(surface); -} - -static void -xdg_toplevel_handle_set_fullscreen(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *output_resource) -{ - // TODO -} - -static void -xdg_toplevel_handle_unset_fullscreen(struct wl_client *client, - struct wl_resource *resource) -{ - // TODO -} - -static void -xdg_toplevel_handle_set_minimized(struct wl_client *client, - struct wl_resource *resource) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - surface->toplevel->requested.minimized = true; - wl_signal_emit(&surface->toplevel->events.request_maximize, surface); -} - -static const struct xdg_toplevel_interface xdg_toplevel_impl = -{ - xdg_toplevel_handle_destroy, - xdg_toplevel_handle_set_parent, - xdg_toplevel_handle_set_title, - xdg_toplevel_handle_set_app_id, - xdg_toplevel_handle_show_window_menu, - xdg_toplevel_handle_move, - xdg_toplevel_handle_resize, - xdg_toplevel_handle_set_max_size, - xdg_toplevel_handle_set_min_size, - xdg_toplevel_handle_set_maximized, - xdg_toplevel_handle_unset_maximized, - xdg_toplevel_handle_set_fullscreen, - xdg_toplevel_handle_unset_fullscreen, - xdg_toplevel_handle_set_minimized, -}; - -static void -xdg_toplevel_handle_resource_destroy(struct wl_resource *resource) -{ - struct ds_xdg_surface *surface; - - surface = wl_resource_get_user_data(resource); - if (!surface) - return; - - destroy_xdg_toplevel(surface); -} diff --git a/src/meson.build b/src/meson.build index d739bfe..d213f62 100644 --- a/src/meson.build +++ b/src/meson.build @@ -10,10 +10,7 @@ wayland_scanner = find_program( native: true, ) -subdir('libds') -if get_option('tizen') - subdir('libds-tizen') -endif -subdir('tests') +subdir('libds-tizen') +#subdir('tests') subdir('examples') subdir('clients') diff --git a/src/tests/meson.build b/src/tests/meson.build index dd52176..19f1e1d 100644 --- a/src/tests/meson.build +++ b/src/tests/meson.build @@ -1,7 +1,7 @@ tests = [ { 'name': 'test-compositor' }, { 'name': 'test-backend' }, - { + { 'name': 'test-surface', 'deps': [ dependency('wayland-client') ], }, @@ -12,11 +12,11 @@ tests = [ ] foreach t : tests - t_deps = [ dep_libds ] + t_deps = [ dep_libds_tizen ] t_deps += t.get('deps', []) - test('libds-' + t.get('name'), - executable('libds-' + t.get('name'), t.get('name') + '.c', + test('libds-tizen-' + t.get('name'), + executable('libds-tizen-' + t.get('name'), t.get('name') + '.c', dependencies: t_deps , include_directories: common_inc, install: false -- 2.7.4 From 042d6232f4fa4c05c7e0950609c3c5a2525f5b04 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 8 Jun 2022 10:33:48 +0900 Subject: [PATCH 10/16] rearrange the directories of git repository and fix some build break. Change-Id: I723cb9e5f13f05f5761d668737f6e2c9c84f9cac --- {src/clients => clients}/input-generator.c | 0 {src/clients => clients}/meson.build | 26 ++++---- {src/clients => clients}/simple-dpms.c | 0 {src/clients => clients}/simple-tbm.c | 0 {src/examples => examples}/meson.build | 22 +++---- {src/examples => examples}/pixman-helper.c | 0 {src/examples => examples}/pixman-helper.h | 0 {src/examples => examples}/pixman-tbm-helper.c | 0 {src/examples => examples}/pixman-tbm-helper.h | 0 {src/examples => examples}/tdm-backend.c | 0 {src/examples => examples}/tinyds-tdm-dpms.c | 0 {src/examples => examples}/tinyds-tdm-libinput.c | 0 {src/examples => examples}/tinyds-tdm-renderer.c | 0 {src/examples => examples}/tinyds-tdm-renderer.h | 0 {src/examples => examples}/tinyds-tdm.c | 0 meson.build | 15 +++++ packaging/libds-tizen.spec | 31 +++++----- src/{libds-tizen => }/allocator/meson.build | 0 src/{libds-tizen => }/allocator/tbm.c | 0 src/{libds-tizen => }/backend/meson.build | 0 src/{libds-tizen => }/backend/tdm/backend.c | 0 src/{libds-tizen => }/backend/tdm/meson.build | 0 src/{libds-tizen => }/backend/tdm/output.c | 0 src/{libds-tizen => }/backend/tdm/tdm.h | 0 .../backend/tdm/tdm_buffer_queue.c | 0 .../backend/tdm/tdm_buffer_queue.h | 0 src/{libds-tizen => }/dpms.c | 0 .../input-devicemgr/input-devicemgr.c | 0 .../input-devicemgr/input-devicemgr.h | 0 src/{libds-tizen => }/input-devicemgr/meson.build | 1 - src/{libds-tizen => }/keyrouter/keyrouter.c | 0 src/{libds-tizen => }/keyrouter/keyrouter.h | 0 src/{libds-tizen => }/keyrouter/keyrouter_grab.c | 0 src/{libds-tizen => }/keyrouter/meson.build | 0 src/libds-tizen/meson.build | 63 ------------------- src/meson.build | 71 ++++++++++++++++++---- src/{libds-tizen => }/pixel_format.c | 0 src/{libds-tizen => }/pixel_format.h | 0 src/{libds-tizen => }/tbm_server.c | 0 src/{libds-tizen => }/tbm_server.h | 0 src/{libds-tizen => }/util.h | 0 src/{libds-tizen => }/util/meson.build | 0 src/{libds-tizen => }/util/security.c | 0 {src/tests => tests}/meson.build | 0 {src/tests => tests}/test-backend.c | 0 {src/tests => tests}/test-compositor.c | 0 {src/tests => tests}/test-subsurface.c | 0 {src/tests => tests}/test-surface.c | 0 48 files changed, 114 insertions(+), 115 deletions(-) rename {src/clients => clients}/input-generator.c (100%) rename {src/clients => clients}/meson.build (80%) rename {src/clients => clients}/simple-dpms.c (100%) rename {src/clients => clients}/simple-tbm.c (100%) rename {src/examples => examples}/meson.build (79%) rename {src/examples => examples}/pixman-helper.c (100%) rename {src/examples => examples}/pixman-helper.h (100%) rename {src/examples => examples}/pixman-tbm-helper.c (100%) rename {src/examples => examples}/pixman-tbm-helper.h (100%) rename {src/examples => examples}/tdm-backend.c (100%) rename {src/examples => examples}/tinyds-tdm-dpms.c (100%) rename {src/examples => examples}/tinyds-tdm-libinput.c (100%) rename {src/examples => examples}/tinyds-tdm-renderer.c (100%) rename {src/examples => examples}/tinyds-tdm-renderer.h (100%) rename {src/examples => examples}/tinyds-tdm.c (100%) rename src/{libds-tizen => }/allocator/meson.build (100%) rename src/{libds-tizen => }/allocator/tbm.c (100%) rename src/{libds-tizen => }/backend/meson.build (100%) rename src/{libds-tizen => }/backend/tdm/backend.c (100%) rename src/{libds-tizen => }/backend/tdm/meson.build (100%) rename src/{libds-tizen => }/backend/tdm/output.c (100%) rename src/{libds-tizen => }/backend/tdm/tdm.h (100%) rename src/{libds-tizen => }/backend/tdm/tdm_buffer_queue.c (100%) rename src/{libds-tizen => }/backend/tdm/tdm_buffer_queue.h (100%) rename src/{libds-tizen => }/dpms.c (100%) rename src/{libds-tizen => }/input-devicemgr/input-devicemgr.c (100%) rename src/{libds-tizen => }/input-devicemgr/input-devicemgr.h (100%) rename src/{libds-tizen => }/input-devicemgr/meson.build (98%) rename src/{libds-tizen => }/keyrouter/keyrouter.c (100%) rename src/{libds-tizen => }/keyrouter/keyrouter.h (100%) rename src/{libds-tizen => }/keyrouter/keyrouter_grab.c (100%) rename src/{libds-tizen => }/keyrouter/meson.build (100%) delete mode 100644 src/libds-tizen/meson.build rename src/{libds-tizen => }/pixel_format.c (100%) rename src/{libds-tizen => }/pixel_format.h (100%) rename src/{libds-tizen => }/tbm_server.c (100%) rename src/{libds-tizen => }/tbm_server.h (100%) rename src/{libds-tizen => }/util.h (100%) rename src/{libds-tizen => }/util/meson.build (100%) rename src/{libds-tizen => }/util/security.c (100%) rename {src/tests => tests}/meson.build (100%) rename {src/tests => tests}/test-backend.c (100%) rename {src/tests => tests}/test-compositor.c (100%) rename {src/tests => tests}/test-subsurface.c (100%) rename {src/tests => tests}/test-surface.c (100%) diff --git a/src/clients/input-generator.c b/clients/input-generator.c similarity index 100% rename from src/clients/input-generator.c rename to clients/input-generator.c diff --git a/src/clients/meson.build b/clients/meson.build similarity index 80% rename from src/clients/meson.build rename to clients/meson.build index b22419b..5d80f18 100644 --- a/src/clients/meson.build +++ b/clients/meson.build @@ -52,19 +52,19 @@ executable('ds-simple-dpms', dependency('wayland-client', required: true), dependency('tizen-dpms-client', required: true), ], - install_dir: libds_bindir, + install_dir: libds_tizen_bindir, install: true, ) -input_generator_files = ['input-generator.c'] -input_generator_deps = [ - dependency('wayland-client', required: true), - tizen_extension_client, -] - -executable('input-generator', - input_generator_files, - dependencies: input_generator_deps, - install_dir: libds_bindir, - install: true, -) +# input_generator_files = ['input-generator.c'] +# input_generator_deps = [ +# dependency('wayland-client', required: true), +# tizen_extension_client, +# ] +# +# executable('input-generator', +# input_generator_files, +# dependencies: input_generator_deps, +# install_dir: libds_tizen_bindir, +# install: true, +# ) diff --git a/src/clients/simple-dpms.c b/clients/simple-dpms.c similarity index 100% rename from src/clients/simple-dpms.c rename to clients/simple-dpms.c diff --git a/src/clients/simple-tbm.c b/clients/simple-tbm.c similarity index 100% rename from src/clients/simple-tbm.c rename to clients/simple-tbm.c diff --git a/src/examples/meson.build b/examples/meson.build similarity index 79% rename from src/examples/meson.build rename to examples/meson.build index af04c50..5917f02 100644 --- a/src/examples/meson.build +++ b/examples/meson.build @@ -35,16 +35,16 @@ tinyds_tdm_libinput_files = [ 'tinyds-tdm-renderer.c', ] -executable('tinyds-tdm-libinput', - tinyds_tdm_libinput_files, - dependencies: [ - common_deps, - dependency('pixman-1', required: true), - dependency('threads', required: true), - ], - install_dir: libds_tizen_bindir, - install : true -) +#executable('tinyds-tdm-libinput', +# tinyds_tdm_libinput_files, +# dependencies: [ +# common_deps, +# dependency('pixman-1', required: true), +# dependency('threads', required: true), +# ], +# install_dir: libds_tizen_bindir, +# install : true +#) executable('tinyds-tdm-dpms', 'tinyds-tdm-dpms.c', @@ -56,6 +56,6 @@ executable('tinyds-tdm-dpms', dependency('pixman-1', required: true), dependency('threads', required: true), ], - install_dir: libds_bindir, + install_dir: libds_tizen_bindir, install : true ) diff --git a/src/examples/pixman-helper.c b/examples/pixman-helper.c similarity index 100% rename from src/examples/pixman-helper.c rename to examples/pixman-helper.c diff --git a/src/examples/pixman-helper.h b/examples/pixman-helper.h similarity index 100% rename from src/examples/pixman-helper.h rename to examples/pixman-helper.h diff --git a/src/examples/pixman-tbm-helper.c b/examples/pixman-tbm-helper.c similarity index 100% rename from src/examples/pixman-tbm-helper.c rename to examples/pixman-tbm-helper.c diff --git a/src/examples/pixman-tbm-helper.h b/examples/pixman-tbm-helper.h similarity index 100% rename from src/examples/pixman-tbm-helper.h rename to examples/pixman-tbm-helper.h diff --git a/src/examples/tdm-backend.c b/examples/tdm-backend.c similarity index 100% rename from src/examples/tdm-backend.c rename to examples/tdm-backend.c diff --git a/src/examples/tinyds-tdm-dpms.c b/examples/tinyds-tdm-dpms.c similarity index 100% rename from src/examples/tinyds-tdm-dpms.c rename to examples/tinyds-tdm-dpms.c diff --git a/src/examples/tinyds-tdm-libinput.c b/examples/tinyds-tdm-libinput.c similarity index 100% rename from src/examples/tinyds-tdm-libinput.c rename to examples/tinyds-tdm-libinput.c diff --git a/src/examples/tinyds-tdm-renderer.c b/examples/tinyds-tdm-renderer.c similarity index 100% rename from src/examples/tinyds-tdm-renderer.c rename to examples/tinyds-tdm-renderer.c diff --git a/src/examples/tinyds-tdm-renderer.h b/examples/tinyds-tdm-renderer.h similarity index 100% rename from src/examples/tinyds-tdm-renderer.h rename to examples/tinyds-tdm-renderer.h diff --git a/src/examples/tinyds-tdm.c b/examples/tinyds-tdm.c similarity index 100% rename from src/examples/tinyds-tdm.c rename to examples/tinyds-tdm.c diff --git a/meson.build b/meson.build index 410b271..dfe8129 100644 --- a/meson.build +++ b/meson.build @@ -25,7 +25,22 @@ cdata.set('LIBDS_VERSION_MAJOR', libds_tizen_version_major) cdata.set('LIBDS_VERSION_MINOR', libds_tizen_version_minor) cdata.set('LIBDS_VERSION_PATCH', libds_tizen_version_patch) +wayland_protos = dependency('wayland-protocols', + fallback: ['wayland-protocols', 'wayland_protocols'], + default_options: ['tests=false'], +) +wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') + +wayland_scanner_dep = dependency('wayland-scanner', native: true) +wayland_scanner = find_program( + wayland_scanner_dep.get_variable('wayland_scanner'), + native: true, +) + subdir('src') +subdir('tests') +subdir('examples') +subdir('clients') subdir('include') configure_file(output: 'config.h', install: false, configuration: cdata) diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index ceb7b50..5c8e2a9 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -100,9 +100,8 @@ ninja -C builddir install %{_bindir}/tdm-backend %{_bindir}/tinyds-tdm %{_bindir}/ds-simple-tbm -%{_bindir}/tinyds-tdm-libinput %{_bindir}/tinyds-tdm-dpms -%{_bindir}/input-generator +%{_bindir}/ds-simple-dpms %files keyrouter %manifest %{name}.manifest @@ -118,16 +117,18 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-keyrouter.pc %{_libdir}/libds-tizen-keyrouter.so -%files tizen-input-devicemgr -%manifest %{name}.manifest -%defattr(-,root,root,-) -%license LICENSE -%{_libdir}/libds-tizen-input-devicemgr.so.* - -%files tizen-input-devicemgr-devel -%manifest %{name}.manifest -%defattr(-,root,root,-) -%license LICENSE -%{_includedir}/libds-tizen/input-devicemgr.h -%{_libdir}/pkgconfig/libds-tizen-input-devicemgr.pc -%{_libdir}/libds-tizen-input-devicemgr.so +# %files input-devicemgr +# %manifest %{name}.manifest +# %defattr(-,root,root,-) +# %license LICENSE +# %{_libdir}/libds-tizen-input-devicemgr.so.* +# +# %files input-devicemgr-devel +# %manifest %{name}.manifest +# %defattr(-,root,root,-) +# %license LICENSE +# %{_includedir}/libds-tizen/input-devicemgr.h +# %{_libdir}/pkgconfig/libds-tizen-input-devicemgr.pc +# %{_libdir}/libds-tizen-input-devicemgr.so +# %{_bindir}/tinyds-tdm-libinput +# %{_bindir}/input-generator diff --git a/src/libds-tizen/allocator/meson.build b/src/allocator/meson.build similarity index 100% rename from src/libds-tizen/allocator/meson.build rename to src/allocator/meson.build diff --git a/src/libds-tizen/allocator/tbm.c b/src/allocator/tbm.c similarity index 100% rename from src/libds-tizen/allocator/tbm.c rename to src/allocator/tbm.c diff --git a/src/libds-tizen/backend/meson.build b/src/backend/meson.build similarity index 100% rename from src/libds-tizen/backend/meson.build rename to src/backend/meson.build diff --git a/src/libds-tizen/backend/tdm/backend.c b/src/backend/tdm/backend.c similarity index 100% rename from src/libds-tizen/backend/tdm/backend.c rename to src/backend/tdm/backend.c diff --git a/src/libds-tizen/backend/tdm/meson.build b/src/backend/tdm/meson.build similarity index 100% rename from src/libds-tizen/backend/tdm/meson.build rename to src/backend/tdm/meson.build diff --git a/src/libds-tizen/backend/tdm/output.c b/src/backend/tdm/output.c similarity index 100% rename from src/libds-tizen/backend/tdm/output.c rename to src/backend/tdm/output.c diff --git a/src/libds-tizen/backend/tdm/tdm.h b/src/backend/tdm/tdm.h similarity index 100% rename from src/libds-tizen/backend/tdm/tdm.h rename to src/backend/tdm/tdm.h diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.c b/src/backend/tdm/tdm_buffer_queue.c similarity index 100% rename from src/libds-tizen/backend/tdm/tdm_buffer_queue.c rename to src/backend/tdm/tdm_buffer_queue.c diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.h b/src/backend/tdm/tdm_buffer_queue.h similarity index 100% rename from src/libds-tizen/backend/tdm/tdm_buffer_queue.h rename to src/backend/tdm/tdm_buffer_queue.h diff --git a/src/libds-tizen/dpms.c b/src/dpms.c similarity index 100% rename from src/libds-tizen/dpms.c rename to src/dpms.c diff --git a/src/libds-tizen/input-devicemgr/input-devicemgr.c b/src/input-devicemgr/input-devicemgr.c similarity index 100% rename from src/libds-tizen/input-devicemgr/input-devicemgr.c rename to src/input-devicemgr/input-devicemgr.c diff --git a/src/libds-tizen/input-devicemgr/input-devicemgr.h b/src/input-devicemgr/input-devicemgr.h similarity index 100% rename from src/libds-tizen/input-devicemgr/input-devicemgr.h rename to src/input-devicemgr/input-devicemgr.h diff --git a/src/libds-tizen/input-devicemgr/meson.build b/src/input-devicemgr/meson.build similarity index 98% rename from src/libds-tizen/input-devicemgr/meson.build rename to src/input-devicemgr/meson.build index 30924a4..7006326 100644 --- a/src/libds-tizen/input-devicemgr/meson.build +++ b/src/input-devicemgr/meson.build @@ -3,7 +3,6 @@ libds_tizen_input_devicemgr_files = [ ] libds_tizen_input_devicemgr_deps = [ - dep_libds, dep_libds_tizen, dependency('tizen-extension-server', required: true), ] diff --git a/src/libds-tizen/keyrouter/keyrouter.c b/src/keyrouter/keyrouter.c similarity index 100% rename from src/libds-tizen/keyrouter/keyrouter.c rename to src/keyrouter/keyrouter.c diff --git a/src/libds-tizen/keyrouter/keyrouter.h b/src/keyrouter/keyrouter.h similarity index 100% rename from src/libds-tizen/keyrouter/keyrouter.h rename to src/keyrouter/keyrouter.h diff --git a/src/libds-tizen/keyrouter/keyrouter_grab.c b/src/keyrouter/keyrouter_grab.c similarity index 100% rename from src/libds-tizen/keyrouter/keyrouter_grab.c rename to src/keyrouter/keyrouter_grab.c diff --git a/src/libds-tizen/keyrouter/meson.build b/src/keyrouter/meson.build similarity index 100% rename from src/libds-tizen/keyrouter/meson.build rename to src/keyrouter/meson.build diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build deleted file mode 100644 index 1ee9b99..0000000 --- a/src/libds-tizen/meson.build +++ /dev/null @@ -1,63 +0,0 @@ -libds_tizen_files = [ - 'pixel_format.c', - 'tbm_server.c', - 'dpms.c', -] - -math = meson.get_compiler('c').find_library('m') -wayland_server = dependency('wayland-server', required: true) -pixman = dependency('pixman-1', required: true) -libdrm = dependency('libdrm', required: true) -xkbcommon = dependency('xkbcommon', required: true) -rt = meson.get_compiler('c').find_library('rt') - -if wayland_server.version().version_compare('>= 1.19') - cdata.set('HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY', '1') -endif - -base_deps = [ - math, - wayland_server, - pixman, - libdrm, - xkbcommon, - rt, -] - -libds_tizen_deps = [ - base_deps, - dependency('libds', required: true), - dependency('libdrm', required: true), - dependency('libtbm', required: true), - dependency('wayland-tbm-server', required: true), - dependency('tizen-dpms-server', required: true), -] - -subdir('allocator') -subdir('backend') -subdir('util') - -lib_libds_tizen = shared_library('ds-tizen', libds_tizen_files, - dependencies: libds_tizen_deps, - include_directories: [ common_inc, include_directories('.') ], - version: meson.project_version(), - install: true -) - -dep_libds_tizen = declare_dependency( - link_with: lib_libds_tizen, - dependencies: libds_tizen_deps, - include_directories: [ common_inc, include_directories('.') ], -) - -pkgconfig = import('pkgconfig') -pkgconfig.generate(lib_libds_tizen, - version: meson.project_version(), - filebase: 'libds-tizen', - name: 'libds-tizen', - description: 'extension of libds for tizen platform', -) - -subdir('keyrouter') -subdir('input-devicemgr') - diff --git a/src/meson.build b/src/meson.build index d213f62..28ec46e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,16 +1,63 @@ -wayland_protos = dependency('wayland-protocols', - fallback: ['wayland-protocols', 'wayland_protocols'], - default_options: ['tests=false'], +libds_tizen_files = [ + 'pixel_format.c', + 'tbm_server.c', + 'dpms.c', +] + +math = meson.get_compiler('c').find_library('m') +wayland_server = dependency('wayland-server', required: true) +pixman = dependency('pixman-1', required: true) +libdrm = dependency('libdrm', required: true) +xkbcommon = dependency('xkbcommon', required: true) +rt = meson.get_compiler('c').find_library('rt') + +if wayland_server.version().version_compare('>= 1.19') + cdata.set('HAVE_WL_SEAT_ERROR_MISSING_CAPABILITY', '1') +endif + +base_deps = [ + math, + wayland_server, + pixman, + libdrm, + xkbcommon, + rt, +] + +libds_tizen_deps = [ + base_deps, + dependency('libds', required: true), + dependency('libdrm', required: true), + dependency('libtbm', required: true), + dependency('wayland-tbm-server', required: true), + dependency('tizen-dpms-server', required: true), +] + +subdir('allocator') +subdir('backend') +subdir('util') + +lib_libds_tizen = shared_library('ds-tizen', libds_tizen_files, + dependencies: libds_tizen_deps, + include_directories: [ common_inc, include_directories('.') ], + version: meson.project_version(), + install: true +) + +dep_libds_tizen = declare_dependency( + link_with: lib_libds_tizen, + dependencies: libds_tizen_deps, + include_directories: [ common_inc, include_directories('.') ], ) -wl_protocol_dir = wayland_protos.get_variable('pkgdatadir') -wayland_scanner_dep = dependency('wayland-scanner', native: true) -wayland_scanner = find_program( - wayland_scanner_dep.get_variable('wayland_scanner'), - native: true, +pkgconfig = import('pkgconfig') +pkgconfig.generate(lib_libds_tizen, + version: meson.project_version(), + filebase: 'libds-tizen', + name: 'libds-tizen', + description: 'extension of libds for tizen platform', ) -subdir('libds-tizen') -#subdir('tests') -subdir('examples') -subdir('clients') +subdir('keyrouter') +#subdir('input-devicemgr') + diff --git a/src/libds-tizen/pixel_format.c b/src/pixel_format.c similarity index 100% rename from src/libds-tizen/pixel_format.c rename to src/pixel_format.c diff --git a/src/libds-tizen/pixel_format.h b/src/pixel_format.h similarity index 100% rename from src/libds-tizen/pixel_format.h rename to src/pixel_format.h diff --git a/src/libds-tizen/tbm_server.c b/src/tbm_server.c similarity index 100% rename from src/libds-tizen/tbm_server.c rename to src/tbm_server.c diff --git a/src/libds-tizen/tbm_server.h b/src/tbm_server.h similarity index 100% rename from src/libds-tizen/tbm_server.h rename to src/tbm_server.h diff --git a/src/libds-tizen/util.h b/src/util.h similarity index 100% rename from src/libds-tizen/util.h rename to src/util.h diff --git a/src/libds-tizen/util/meson.build b/src/util/meson.build similarity index 100% rename from src/libds-tizen/util/meson.build rename to src/util/meson.build diff --git a/src/libds-tizen/util/security.c b/src/util/security.c similarity index 100% rename from src/libds-tizen/util/security.c rename to src/util/security.c diff --git a/src/tests/meson.build b/tests/meson.build similarity index 100% rename from src/tests/meson.build rename to tests/meson.build diff --git a/src/tests/test-backend.c b/tests/test-backend.c similarity index 100% rename from src/tests/test-backend.c rename to tests/test-backend.c diff --git a/src/tests/test-compositor.c b/tests/test-compositor.c similarity index 100% rename from src/tests/test-compositor.c rename to tests/test-compositor.c diff --git a/src/tests/test-subsurface.c b/tests/test-subsurface.c similarity index 100% rename from src/tests/test-subsurface.c rename to tests/test-subsurface.c diff --git a/src/tests/test-surface.c b/tests/test-surface.c similarity index 100% rename from src/tests/test-surface.c rename to tests/test-surface.c -- 2.7.4 From 5af8f0152be3f2aaf5543e8c3098d1e6014c2638 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 8 Jun 2022 16:25:42 +0900 Subject: [PATCH 11/16] keyrouter: Properly test for allocation failure Instead of testing the return of the function just called, it was testing something already checked earlier. Change-Id: Ibaa7884360afaa195d843bc90588e3af85caf0d0 --- src/keyrouter/keyrouter_grab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keyrouter/keyrouter_grab.c b/src/keyrouter/keyrouter_grab.c index 5009985..6af0c85 100644 --- a/src/keyrouter/keyrouter_grab.c +++ b/src/keyrouter/keyrouter_grab.c @@ -300,7 +300,7 @@ keyrouter_grab_create(void) /* FIXME: Who defined max keycode? */ keyrouter_grab->hard_keys = calloc(KEYROUTER_MAX_KEYS, sizeof(struct ds_tizen_keyrouter_grabbed)); - if (keyrouter_grab == NULL) { + if (keyrouter_grab->hard_keys == NULL) { ds_err("Failed to allocate memory."); free(keyrouter_grab); return NULL; -- 2.7.4 From 7861c6486a134b77b0a5000dcc42f6b6e5c373a9 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 8 Jun 2022 16:43:12 +0900 Subject: [PATCH 12/16] keyrouter: Fix illegally finishing tizen_security Do not finish tizen_security if the initialization's been failed. Change-Id: Iee1a6eb973a8513c97aaf27a5b40e2d60c8f1f32 --- src/keyrouter/keyrouter.c | 9 ++++++--- src/keyrouter/keyrouter.h | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/keyrouter/keyrouter.c b/src/keyrouter/keyrouter.c index cba286e..991c1f3 100644 --- a/src/keyrouter/keyrouter.c +++ b/src/keyrouter/keyrouter.c @@ -32,7 +32,8 @@ keyrouter_handle_display_destroy(struct wl_listener *listener, void *data) wl_signal_emit(&keyrouter->events.destroy, keyrouter); - tizen_security_finish(); + if (keyrouter->security_initialized) + tizen_security_finish(); free(keyrouter->opts); @@ -79,8 +80,10 @@ ds_tizen_keyrouter_create(struct wl_display *display) keyrouter_options_set(keyrouter); - if (!tizen_security_init()) { - ds_inf("tizen_security_init() is not sucessful. keyrouter works without security."); + keyrouter->security_initialized = tizen_security_init(); + if (!keyrouter->security_initialized) { + ds_inf("tizen_security_init() is not sucessful. " + "keyrouter works without security."); } ds_inf("Global created: ds_tizen_keyrouter(%p)", keyrouter); diff --git a/src/keyrouter/keyrouter.h b/src/keyrouter/keyrouter.h index ffbb3cd..3d88346 100644 --- a/src/keyrouter/keyrouter.h +++ b/src/keyrouter/keyrouter.h @@ -56,6 +56,8 @@ struct ds_tizen_keyrouter struct ds_tizen_keyrouter_key_options *opts; struct ds_tizen_keyrouter_grab *keyrouter_grab; + + bool security_initialized; }; struct ds_tizen_keyrouter_client -- 2.7.4 From 1a9fb7038826375139cc3574926f407058b40d1c Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 8 Jun 2022 16:53:16 +0900 Subject: [PATCH 13/16] keyrouter: Add missing assignment The member variable 'keyrouter' of ds_tizen_keyrouter_client is referred throughout the file, but it's never been assigned. Change-Id: I7db736c88c89026433da5c1621f249593b402125 --- src/keyrouter/keyrouter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/keyrouter/keyrouter.c b/src/keyrouter/keyrouter.c index 991c1f3..2e95e48 100644 --- a/src/keyrouter/keyrouter.c +++ b/src/keyrouter/keyrouter.c @@ -344,6 +344,7 @@ keyrouter_bind(struct wl_client *client, void *data, uint32_t version, return; } + keyrouter_client->keyrouter = keyrouter; keyrouter_client->resource = wl_resource_create(client, &tizen_keyrouter_interface, MIN(version, 2), id); if (keyrouter_client->resource == NULL) { -- 2.7.4 From 72a88cda5d0ab7eceae7eaebf66fa1bfb9c52372 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Wed, 8 Jun 2022 17:07:24 +0900 Subject: [PATCH 14/16] input-devicemgr: add input-devicemgr in build scripts Change-Id: I5fde58ecbf1187b561349f593521a25961535b7e --- clients/meson.build | 24 ++++++++++----------- examples/meson.build | 21 +++++++++--------- packaging/libds-tizen.spec | 40 ++++++++++++++++++----------------- src/input-devicemgr/input-devicemgr.c | 21 ++++++++---------- src/input-devicemgr/input-devicemgr.h | 2 +- src/meson.build | 2 +- 6 files changed, 55 insertions(+), 55 deletions(-) diff --git a/clients/meson.build b/clients/meson.build index 5d80f18..c97e3ad 100644 --- a/clients/meson.build +++ b/clients/meson.build @@ -56,15 +56,15 @@ executable('ds-simple-dpms', install: true, ) -# input_generator_files = ['input-generator.c'] -# input_generator_deps = [ -# dependency('wayland-client', required: true), -# tizen_extension_client, -# ] -# -# executable('input-generator', -# input_generator_files, -# dependencies: input_generator_deps, -# install_dir: libds_tizen_bindir, -# install: true, -# ) +input_generator_files = ['input-generator.c'] +input_generator_deps = [ + dependency('wayland-client', required: true), + tizen_extension_client, +] + +executable('input-generator', + input_generator_files, + dependencies: input_generator_deps, + install_dir: libds_tizen_bindir, + install: true, +) diff --git a/examples/meson.build b/examples/meson.build index 5917f02..d9233fb 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -35,16 +35,17 @@ tinyds_tdm_libinput_files = [ 'tinyds-tdm-renderer.c', ] -#executable('tinyds-tdm-libinput', -# tinyds_tdm_libinput_files, -# dependencies: [ -# common_deps, -# dependency('pixman-1', required: true), -# dependency('threads', required: true), -# ], -# install_dir: libds_tizen_bindir, -# install : true -#) +executable('tinyds-tdm-libinput', + tinyds_tdm_libinput_files, + dependencies: [ + common_deps, + dep_libds_tizen_input_devicemgr, + dependency('pixman-1', required: true), + dependency('threads', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) executable('tinyds-tdm-dpms', 'tinyds-tdm-dpms.c', diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index 5c8e2a9..c2e0180 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -53,18 +53,18 @@ Group: Development/Libraries %description keyrouter-devel Keyrouter Development package for Wayland Compositor Library -%package tizen-input-devicemgr +%package input-devicemgr Summary: Library for tizen input devicemgr Group: Development/Libraries -%description tizen-input-devicemgr +%description input-devicemgr Library for tizen input devicemgr -%package tizen-input-devicemgr-devel +%package input-devicemgr-devel Summary: Development package for tizen input devicemgr Group: Development/Libraries -%description tizen-input-devicemgr-devel +%description input-devicemgr-devel Development package for tizen input devicemgr %prep @@ -102,6 +102,8 @@ ninja -C builddir install %{_bindir}/ds-simple-tbm %{_bindir}/tinyds-tdm-dpms %{_bindir}/ds-simple-dpms +%{_bindir}/tinyds-tdm-libinput +%{_bindir}/input-generator %files keyrouter %manifest %{name}.manifest @@ -117,18 +119,18 @@ ninja -C builddir install %{_libdir}/pkgconfig/libds-tizen-keyrouter.pc %{_libdir}/libds-tizen-keyrouter.so -# %files input-devicemgr -# %manifest %{name}.manifest -# %defattr(-,root,root,-) -# %license LICENSE -# %{_libdir}/libds-tizen-input-devicemgr.so.* -# -# %files input-devicemgr-devel -# %manifest %{name}.manifest -# %defattr(-,root,root,-) -# %license LICENSE -# %{_includedir}/libds-tizen/input-devicemgr.h -# %{_libdir}/pkgconfig/libds-tizen-input-devicemgr.pc -# %{_libdir}/libds-tizen-input-devicemgr.so -# %{_bindir}/tinyds-tdm-libinput -# %{_bindir}/input-generator +%files input-devicemgr +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_libdir}/libds-tizen-input-devicemgr.so.* + +%files input-devicemgr-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE +%{_includedir}/libds-tizen/input-devicemgr.h +%{_libdir}/pkgconfig/libds-tizen-input-devicemgr.pc +%{_libdir}/libds-tizen-input-devicemgr.so +%{_bindir}/tinyds-tdm-libinput +%{_bindir}/input-generator diff --git a/src/input-devicemgr/input-devicemgr.c b/src/input-devicemgr/input-devicemgr.c index 84700d7..3e69d0e 100644 --- a/src/input-devicemgr/input-devicemgr.c +++ b/src/input-devicemgr/input-devicemgr.c @@ -5,11 +5,9 @@ #include #include #include -#include #include "util.h" #include "input-devicemgr.h" -#include "src/libds/seat.h" #define TIZEN_INPUT_DEVICEMGR_VERSION 4 #define TIZEN_PRIV_INPUT_GENERATOR "http://tizen.org/privilege/inputgenerator" @@ -128,16 +126,12 @@ ds_tizen_input_devicemgr_create(struct ds_backend *backend, goto err_kbd; } - tz_devicemgr->grab = calloc(1, sizeof(struct ds_seat_keyboard_grab)); - if (!tz_devicemgr->grab) - { + tz_devicemgr->grab = ds_seat_create_keyboard_grab( + tz_devicemgr->seat, &devicemgr_keyboard_grab_iface, tz_devicemgr); + if (!tz_devicemgr->grab) { goto err_grab; } - tz_devicemgr->grab->iface = &devicemgr_keyboard_grab_iface; - tz_devicemgr->grab->seat = tz_devicemgr->seat; - tz_devicemgr->grab->data = tz_devicemgr; - wl_signal_init(&tz_devicemgr->events.destroy); wl_list_init(&tz_devicemgr->clients); wl_list_init(&tz_devicemgr->pressed_keys); @@ -150,6 +144,7 @@ ds_tizen_input_devicemgr_create(struct ds_backend *backend, ds_inf("Global created: ds_tizen_input_devicemgr(%p) ", tz_devicemgr); return tz_devicemgr; + err_grab: free(tz_devicemgr->devices.kbd); err_kbd: @@ -207,6 +202,7 @@ tz_devicemgr_destroy(struct ds_tizen_input_devicemgr *tz_devicemgr) tz_devicemgr_keymap_list_cleanup(tz_devicemgr); tz_devicemgr_blocked_keys_cleanup(tz_devicemgr); tz_devicemgr_ungrab_keyboard(tz_devicemgr); + ds_seat_keyboard_destroy_grab(tz_devicemgr->grab); wl_signal_emit(&tz_devicemgr->events.destroy, tz_devicemgr); wl_list_remove(&tz_devicemgr->backend_destroy.link); @@ -224,7 +220,6 @@ tz_devicemgr_destroy(struct ds_tizen_input_devicemgr *tz_devicemgr) } free(tz_devicemgr->devices.kbd); - free(tz_devicemgr->grab); free(tz_devicemgr); } @@ -846,12 +841,13 @@ static void devicemgr_keyboard_grab_iface_key(struct ds_seat_keyboard_grab *grab, uint32_t time_msec, uint32_t key, uint32_t state) { - struct ds_tizen_input_devicemgr *devicemgr = grab->data; + struct ds_tizen_input_devicemgr *devicemgr; struct ds_tizen_input_devicemgr_key_info *keydata, *tmp; bool key_blocked = false; ds_inf("devicemgr. keyboard_grab_iface_key"); + devicemgr = ds_seat_keyboard_grab_get_data(grab); if (!devicemgr->block_resource) { if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { goto finish; @@ -1060,4 +1056,5 @@ device_manager_handle_unblock_events(struct wl_client *client, finish: tizen_input_device_manager_send_error(resource, ret); -} \ No newline at end of file +} + diff --git a/src/input-devicemgr/input-devicemgr.h b/src/input-devicemgr/input-devicemgr.h index 8418b16..52bd2ef 100644 --- a/src/input-devicemgr/input-devicemgr.h +++ b/src/input-devicemgr/input-devicemgr.h @@ -5,7 +5,7 @@ #include #include #include -#include "libds/interfaces/input_device.h" +#include #include struct ds_tizen_input_devicemgr_device { diff --git a/src/meson.build b/src/meson.build index 28ec46e..1ee9b99 100644 --- a/src/meson.build +++ b/src/meson.build @@ -59,5 +59,5 @@ pkgconfig.generate(lib_libds_tizen, ) subdir('keyrouter') -#subdir('input-devicemgr') +subdir('input-devicemgr') -- 2.7.4 From d4128c591749fba92d718853ef403f214fb6e421 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Thu, 16 Jun 2022 11:52:13 +0900 Subject: [PATCH 15/16] backend/tdm: Add ds_tdm_output_hwc ds_tdm_output_hwc composites surface or buffer if hardware layer of output can use direct scan-out(bypass compositing at output buffer). ds_tdm_output_hwc has is consists of ds_tdm_output_hwc_window. for using hardware compositing, display-server should set compositing infomation of ds_tdm_output_hwc_window it would be nice to ds_tdm_output_hwc can display all ds_tdm_output_hwc_window by direct scan-out but it has restrictions. output has limited number of hardware layer and hardware layer has hw restrictions(buffer size, transform, format, etc). if ds_tdm_output_hwc_window can not be display by direct scan-out, display-server should composite it at output buffer. ds_tdm_output_hwc_window is updated at output when ds_output_hwc_validate and ds_output_commit is called because ds_tdm_output_hwc is component of ds_output. Change-Id: If78e862e4acbcc1ae465fe8315fc478f888657b3 --- include/libds-tizen/backend/tdm.h | 11 + include/libds-tizen/backend/tdm_output_hwc.h | 74 ++++ include/libds-tizen/tbm_server.h | 1 + src/backend/tdm/meson.build | 1 + src/backend/tdm/output.c | 68 ++- src/backend/tdm/tdm.h | 3 + src/backend/tdm/tdm_output_hwc.c | 636 +++++++++++++++++++++++++++ src/backend/tdm/tdm_output_hwc.h | 83 ++++ 8 files changed, 842 insertions(+), 35 deletions(-) create mode 100644 include/libds-tizen/backend/tdm_output_hwc.h create mode 100644 src/backend/tdm/tdm_output_hwc.c create mode 100644 src/backend/tdm/tdm_output_hwc.h diff --git a/include/libds-tizen/backend/tdm.h b/include/libds-tizen/backend/tdm.h index 8c5c605..33422ba 100644 --- a/include/libds-tizen/backend/tdm.h +++ b/include/libds-tizen/backend/tdm.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -10,8 +11,15 @@ extern "C" { struct ds_tdm_output; +struct ds_tdm_output_hwc; + struct ds_tdm_buffer_queue; +struct ds_tdm_box { + int x, y; + int width, height; +}; + struct ds_backend * ds_tdm_backend_create(struct wl_display *display); @@ -31,6 +39,9 @@ void ds_tdm_buffer_queue_add_acquirable_listener(struct ds_tdm_buffer_queue *queue, struct wl_listener *listener); +struct ds_tdm_output_hwc * +ds_tdm_output_get_hwc(struct ds_tdm_output *output); + #ifdef __cplusplus } #endif diff --git a/include/libds-tizen/backend/tdm_output_hwc.h b/include/libds-tizen/backend/tdm_output_hwc.h new file mode 100644 index 0000000..abde223 --- /dev/null +++ b/include/libds-tizen/backend/tdm_output_hwc.h @@ -0,0 +1,74 @@ +#ifndef LIBDS_TIZEN_BACKEND_TDM_OUTPUT_HWC_H +#define LIBDS_TIZEN_BACKEND_TDM_OUTPUT_HWC_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ds_tdm_output_hwc; + +struct ds_tdm_output_hwc_window; + +enum ds_tdm_output_hwc_window_composition { + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO, +}; + +WL_EXPORT void +ds_tdm_output_hwc_set_enabled(struct ds_tdm_output_hwc *hwc, bool enabled); + +WL_EXPORT bool +ds_tdm_output_hwc_validate(struct ds_tdm_output_hwc *hwc, + struct ds_tdm_output_hwc_window **composited_windows, uint32_t num_windows, uint32_t *num_changed); + +WL_EXPORT bool +ds_tdm_output_hwc_get_changed_composition(struct ds_tdm_output_hwc *hwc, uint32_t *num_changed, + struct ds_tdm_output_hwc_window **changed_windows); + +WL_EXPORT bool +ds_tdm_output_hwc_accept_validation(struct ds_tdm_output_hwc *hwc); + +WL_EXPORT struct ds_tdm_output_hwc_window * +ds_tdm_output_hwc_window_create(struct ds_tdm_output_hwc *hwc); + +WL_EXPORT void +ds_tdm_output_hwc_window_destroy(struct ds_tdm_output_hwc_window *hwc_window); + +WL_EXPORT bool +ds_tdm_output_hwc_window_set_buffer(struct ds_tdm_output_hwc_window *hwc_window, + struct ds_buffer *buffer); + +WL_EXPORT void +ds_tdm_output_hwc_window_set_src_box(struct ds_tdm_output_hwc_window *hwc_window, + const struct ds_tdm_box *src_box); + +WL_EXPORT void +ds_tdm_output_hwc_window_set_transform(struct ds_tdm_output_hwc_window *hwc_window, + enum wl_output_transform transform); + +WL_EXPORT void +ds_tdm_output_hwc_window_set_position(struct ds_tdm_output_hwc_window *hwc_window, + int x, int y); + +WL_EXPORT void +ds_tdm_output_hwc_window_set_dest_size(struct ds_tdm_output_hwc_window *hwc_window, + int width, int height); + +WL_EXPORT void +ds_tdm_output_hwc_window_set_composition(struct ds_tdm_output_hwc_window *hwc_window, + enum ds_tdm_output_hwc_window_composition composition); + +WL_EXPORT enum ds_tdm_output_hwc_window_composition +ds_tdm_output_hwc_window_get_composition(struct ds_tdm_output_hwc_window *hwc_window); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libds-tizen/tbm_server.h b/include/libds-tizen/tbm_server.h index f1cc97d..6e3b148 100644 --- a/include/libds-tizen/tbm_server.h +++ b/include/libds-tizen/tbm_server.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/src/backend/tdm/meson.build b/src/backend/tdm/meson.build index 932559f..7a7c25f 100644 --- a/src/backend/tdm/meson.build +++ b/src/backend/tdm/meson.build @@ -2,6 +2,7 @@ libds_tizen_files += files( 'backend.c', 'output.c', 'tdm_buffer_queue.c', + 'tdm_output_hwc.c', ) libtdm = dependency('libtdm', required: true) diff --git a/src/backend/tdm/output.c b/src/backend/tdm/output.c index 089c067..5e874df 100644 --- a/src/backend/tdm/output.c +++ b/src/backend/tdm/output.c @@ -7,6 +7,7 @@ #include "libds-tizen/allocator/tbm.h" #include "tdm.h" +#include "tdm_output_hwc.h" #include "tdm_buffer_queue.h" static const struct ds_output_interface tdm_output_iface; @@ -44,6 +45,12 @@ ds_tdm_output_get_buffer_queue(struct ds_tdm_output *output) return output->queue; } +WL_EXPORT struct ds_tdm_output_hwc * +ds_tdm_output_get_hwc(struct ds_tdm_output *output) +{ + return output->hwc; +} + struct ds_tdm_output * create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) { @@ -265,6 +272,9 @@ output_destroy(struct ds_tdm_output *output) if (output->queue) buffer_queue_destroy(output->queue); + if (output->hwc) + ds_tdm_output_hwc_destroy(output->hwc); + free(output); } @@ -316,6 +326,18 @@ output_init_modes(struct ds_tdm_output *output) } static void +output_hwc_commit_handler(struct wl_listener *listener, void *data) +{ + struct ds_tdm_output *output; + + output = wl_container_of(listener, output, hwc_commit_handler_listener); + + output_update_front_buffer(output); + + wl_signal_emit(&output->base.events.frame, &output->base); +} + +static void output_init_hwc(struct ds_tdm_output *output) { tdm_error err; @@ -325,6 +347,15 @@ output_init_hwc(struct ds_tdm_output *output) ds_err("Could not get tdm_hwc: output(%p)", output); return; } + + output->hwc = ds_tdm_output_hwc_create(output->tdm.hwc); + if (!output->hwc) { + ds_err("Could not create ds_dm_hwc: output(%p)", output); + return; + } + + output->hwc_commit_handler_listener.notify = output_hwc_commit_handler; + ds_tdm_output_hwc_add_commit_handler_listener(output->hwc, &output->hwc_commit_handler_listener); } static bool @@ -352,8 +383,6 @@ output_set_pending_fb(struct ds_tdm_output *output, struct ds_tdm_queue_buffer *queue_buffer; struct ds_tdm_buffer *buffer; tbm_surface_h surface = NULL; - tdm_region fb_damage; - tdm_error err; if (output->queue) { queue_buffer = buffer_queue_find_buffer(output->queue, ds_buffer); @@ -371,10 +400,7 @@ output_set_pending_fb(struct ds_tdm_output *output, surface = buffer->surface; } - memset(&fb_damage, 0, sizeof(fb_damage)); - err = tdm_hwc_set_client_target_buffer(output->tdm.hwc, - surface, fb_damage); - if (err != TDM_ERROR_NONE) { + if (!ds_tdm_output_hwc_set_client_target_buffer(output->hwc, surface)) { ds_err("Could not set hwc client target buffer"); ds_buffer_unlock(ds_buffer); return false; @@ -385,38 +411,10 @@ output_set_pending_fb(struct ds_tdm_output *output, return true; } -static void -output_hwc_commit_handler(tdm_hwc *hwc, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data) -{ - struct ds_tdm_output *output = user_data; - - output_update_front_buffer(output); - - wl_signal_emit(&output->base.events.frame, &output->base); -} - static bool output_hwc_commit(struct ds_tdm_output *output) { - tdm_error err; - uint32_t num_changes; - - err = tdm_hwc_validate(output->tdm.hwc, NULL, 0, &num_changes); - if (err != TDM_ERROR_NONE) { - ds_err("Could not hwc validate"); - return false; - } - - err = tdm_hwc_accept_validation(output->tdm.hwc); - if (err != TDM_ERROR_NONE) { - ds_err("Could not hwc accept validation"); - return false; - } - - err = tdm_hwc_commit(output->tdm.hwc, 0, output_hwc_commit_handler, - output); - if (err != TDM_ERROR_NONE) { + if (!ds_tdm_output_hwc_commit(output->hwc)) { ds_err("Could not hwc commit"); return false; } diff --git a/src/backend/tdm/tdm.h b/src/backend/tdm/tdm.h index a151f01..7c00202 100644 --- a/src/backend/tdm/tdm.h +++ b/src/backend/tdm/tdm.h @@ -48,6 +48,9 @@ struct ds_tdm_output tdm_hwc *hwc; } tdm; + struct ds_tdm_output_hwc *hwc; + struct wl_listener hwc_commit_handler_listener; + struct wl_list link; enum ds_tdm_output_status status; diff --git a/src/backend/tdm/tdm_output_hwc.c b/src/backend/tdm/tdm_output_hwc.c new file mode 100644 index 0000000..8db2984 --- /dev/null +++ b/src/backend/tdm/tdm_output_hwc.c @@ -0,0 +1,636 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include "tdm_output_hwc.h" + +static void +hwc_window_update_front_buffer(struct ds_tdm_output_hwc_window *hwc_window) +{ + if (hwc_window->front_buffer == hwc_window->back_buffer) { + if (hwc_window->back_buffer) { + ds_buffer_unlock(hwc_window->back_buffer); + hwc_window->back_buffer = NULL; + } + + return; + } + + ds_tdm_output_hwc_window_lock(hwc_window); + + if (hwc_window->front_buffer) { + ds_buffer_unlock(hwc_window->front_buffer); + hwc_window->front_buffer = NULL; + ds_tdm_output_hwc_window_unlock(hwc_window); + } + + hwc_window->front_buffer = hwc_window->back_buffer; + hwc_window->back_buffer = NULL; + + if (hwc_window->front_buffer) + ds_tdm_output_hwc_window_lock(hwc_window); + + ds_tdm_output_hwc_window_unlock(hwc_window); +} + +static void +hwc_window_attach_back_buffer(struct ds_tdm_output_hwc_window *hwc_window, + struct ds_buffer *buffer) +{ + if (hwc_window->back_buffer) { + ds_buffer_unlock(hwc_window->back_buffer); + hwc_window->back_buffer = NULL; + } + + if (buffer) + hwc_window->back_buffer = ds_buffer_lock(buffer); +} + +static unsigned int +get_horizontal_get(tbm_surface_h tsurface) +{ + unsigned int horizontal = 0; + tbm_surface_info_s surf_info; + + tbm_surface_get_info(tsurface, &surf_info); + + switch (surf_info.format) { + case TBM_FORMAT_YUV420: + case TBM_FORMAT_YVU420: + case TBM_FORMAT_YUV422: + case TBM_FORMAT_YVU422: + case TBM_FORMAT_NV12: + case TBM_FORMAT_NV21: + horizontal = surf_info.planes[0].stride; + break; + case TBM_FORMAT_YUYV: + case TBM_FORMAT_UYVY: + horizontal = surf_info.planes[0].stride >> 1; + break; + case TBM_FORMAT_XRGB8888: + case TBM_FORMAT_XBGR8888: + case TBM_FORMAT_RGBX8888: + case TBM_FORMAT_BGRX8888: + case TBM_FORMAT_ARGB8888: + case TBM_FORMAT_ABGR8888: + case TBM_FORMAT_RGBA8888: + case TBM_FORMAT_BGRA8888: + case TBM_FORMAT_XRGB2101010: + case TBM_FORMAT_XBGR2101010: + case TBM_FORMAT_RGBX1010102: + case TBM_FORMAT_BGRX1010102: + case TBM_FORMAT_ARGB2101010: + case TBM_FORMAT_ABGR2101010: + case TBM_FORMAT_RGBA1010102: + case TBM_FORMAT_BGRA1010102: + horizontal = surf_info.planes[0].stride >> 2; + break; + default: + ds_err("not supported format"); + } + + return horizontal; +} + +static tdm_transform +get_tdm_transform(enum wl_output_transform output_transform) +{ + switch (output_transform) { + case WL_OUTPUT_TRANSFORM_90: + return TDM_TRANSFORM_90; + case WL_OUTPUT_TRANSFORM_180: + return TDM_TRANSFORM_180; + case WL_OUTPUT_TRANSFORM_270: + return TDM_TRANSFORM_270; + case WL_OUTPUT_TRANSFORM_FLIPPED: + return TDM_TRANSFORM_FLIPPED; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + return TDM_TRANSFORM_FLIPPED_90; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + return TDM_TRANSFORM_FLIPPED_180; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + return TDM_TRANSFORM_FLIPPED_270; + case WL_OUTPUT_TRANSFORM_NORMAL: + default: + return TDM_TRANSFORM_NORMAL; + } +} + +static tdm_hwc_window_composition +get_tdm_composition(enum ds_tdm_output_hwc_window_composition composition) +{ + switch (composition) { + case DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT: + return TDM_HWC_WIN_COMPOSITION_CLIENT; + case DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR: + return TDM_HWC_WIN_COMPOSITION_CURSOR; + case DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE: + return TDM_HWC_WIN_COMPOSITION_DEVICE; + case DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO: + return TDM_HWC_WIN_COMPOSITION_VIDEO; + case DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE: + default: + return TDM_HWC_WIN_COMPOSITION_NONE; + } +} + +static enum ds_tdm_output_hwc_window_composition +get_composition(tdm_hwc_window_composition composition) +{ + switch (composition) { + case TDM_HWC_WIN_COMPOSITION_CLIENT: + return DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT; + case TDM_HWC_WIN_COMPOSITION_CURSOR: + return DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR; + case TDM_HWC_WIN_COMPOSITION_DEVICE: + return DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE; + case TDM_HWC_WIN_COMPOSITION_VIDEO: + return DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO; + case TDM_HWC_WIN_COMPOSITION_NONE: + default: + return DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE; + } +} + +struct ds_tdm_output_hwc * +ds_tdm_output_hwc_create(tdm_hwc *thwc) +{ + struct ds_tdm_output_hwc *hwc; + + hwc = calloc(1, sizeof *hwc); + if (!hwc) + return NULL; + + hwc->thwc = thwc; + + wl_list_init(&hwc->hwc_windows); + wl_signal_init(&hwc->events.commit_handler); + wl_signal_init(&hwc->events.destroy); + + return hwc; +} + +void +ds_tdm_output_hwc_destroy(struct ds_tdm_output_hwc *hwc) +{ + wl_signal_emit(&hwc->events.destroy, hwc); + + free(hwc); +} + +bool +ds_tdm_output_hwc_set_client_target_buffer(struct ds_tdm_output_hwc *hwc, tbm_surface_h tsurface) +{ + tdm_error terr; + tdm_region fb_damage; + + memset(&fb_damage, 0, sizeof(fb_damage)); + + hwc->target_buffer_info.src_config.pos.x = 0; + hwc->target_buffer_info.src_config.pos.y = 0; + hwc->target_buffer_info.src_config.pos.w = tbm_surface_get_width(tsurface); + hwc->target_buffer_info.src_config.pos.h = tbm_surface_get_height(tsurface); + hwc->target_buffer_info.src_config.size.h = get_horizontal_get(tsurface); + hwc->target_buffer_info.src_config.size.v = tbm_surface_get_height(tsurface); + hwc->target_buffer_info.src_config.format = tbm_surface_get_format(tsurface); + + hwc->target_buffer_info.dst_pos.x = 0; + hwc->target_buffer_info.dst_pos.y = 0; + hwc->target_buffer_info.dst_pos.w = tbm_surface_get_width(tsurface); + hwc->target_buffer_info.dst_pos.h = tbm_surface_get_height(tsurface); + + hwc->target_buffer_info.transform = TDM_TRANSFORM_NORMAL; + + tdm_hwc_set_client_target_buffer_info(hwc->thwc, &hwc->target_buffer_info); + + terr = tdm_hwc_set_client_target_buffer(hwc->thwc, tsurface, fb_damage); + if (terr != TDM_ERROR_NONE) { + ds_err("Could not set hwc client target buffer"); + return false; + } + + return true; +} + +void +ds_tdm_output_hwc_window_set_accepted_composition(struct ds_tdm_output_hwc_window *hwc_window, + enum ds_tdm_output_hwc_window_composition composition) +{ + if (hwc_window->accepted_composition == composition) + return; + + hwc_window->accepted_composition = composition; +} + +static void +hwc_window_free(struct ds_tdm_output_hwc_window *hwc_window) +{ + if (hwc_window->buffer) + ds_buffer_unlock(hwc_window->buffer); + + if (hwc_window->set_buffer) + ds_buffer_unlock(hwc_window->set_buffer); + + if (hwc_window->front_buffer) + ds_buffer_unlock(hwc_window->front_buffer); + + if (hwc_window->back_buffer) + ds_buffer_unlock(hwc_window->back_buffer); + + wl_list_remove(&hwc_window->link); + + tdm_hwc_window_destroy(hwc_window->twindow); + + free(hwc_window); +} + +static void +hwc_window_consider_destroy(struct ds_tdm_output_hwc_window *hwc_window) +{ + if (!hwc_window->dropped || hwc_window->n_locks > 0) + return; + + hwc_window_free(hwc_window); +} + +struct ds_tdm_output_hwc_window * +ds_tdm_output_hwc_window_lock(struct ds_tdm_output_hwc_window *hwc_window) +{ + hwc_window->n_locks++; + ds_dbg("hwc_window(%p) n_locks(%zu)", hwc_window, hwc_window->n_locks); + return hwc_window; +} + +void +ds_tdm_output_hwc_window_unlock(struct ds_tdm_output_hwc_window *hwc_window) +{ + hwc_window->n_locks--; + ds_dbg("hwc_window(%p) n_locks(%zu)", hwc_window, hwc_window->n_locks); + + hwc_window_consider_destroy(hwc_window); +} + +WL_EXPORT void +ds_tdm_output_hwc_set_enabled(struct ds_tdm_output_hwc *hwc, bool enabled) +{ + if (hwc->enabled == enabled) + return; + + hwc->enabled = enabled; +} + +WL_EXPORT struct ds_tdm_output_hwc_window * +ds_tdm_output_hwc_window_create(struct ds_tdm_output_hwc *hwc) +{ + tdm_error terr; + tdm_hwc_window *thwc_window; + struct ds_tdm_output_hwc_window *hwc_window; + + hwc_window = calloc(1, sizeof *hwc_window); + if (!hwc_window) + return NULL; + + thwc_window = tdm_hwc_create_window(hwc->thwc, &terr); + if (terr != TDM_ERROR_NONE) { + ds_err("Could not create tdm_hwc_window error:%d", terr); + free(hwc_window); + return NULL; + } + + hwc_window->twindow = thwc_window; + + wl_list_insert(hwc->hwc_windows.prev, &hwc_window->link); + + return hwc_window; +} + +WL_EXPORT void +ds_tdm_output_hwc_window_destroy(struct ds_tdm_output_hwc_window *hwc_window) +{ + hwc_window->dropped = true; + ds_dbg("hwc_window(%p) dropped: n_locks(%zu)", hwc_window, hwc_window->n_locks); + hwc_window_consider_destroy(hwc_window); +} + +WL_EXPORT bool +ds_tdm_output_hwc_window_set_buffer(struct ds_tdm_output_hwc_window *hwc_window, + struct ds_buffer *buffer) +{ + if (hwc_window->buffer == buffer) + return true; + + if (hwc_window->buffer) { + ds_buffer_unlock(hwc_window->set_buffer); + hwc_window->buffer = NULL; + } + + if (buffer) + hwc_window->buffer = ds_buffer_lock(buffer); + + return true; +} + +WL_EXPORT void +ds_tdm_output_hwc_window_set_src_box(struct ds_tdm_output_hwc_window *hwc_window, + const struct ds_tdm_box *src_box) +{ + if (src_box != NULL && !memcmp(&hwc_window->src_box, src_box, sizeof(*src_box))) + return; + + if (src_box != NULL) { + memcpy(&hwc_window->src_box, src_box, sizeof(*src_box)); + } else { + memset(&hwc_window->src_box, 0, sizeof(hwc_window->src_box)); + } +} + +WL_EXPORT void +ds_tdm_output_hwc_window_set_transform(struct ds_tdm_output_hwc_window *hwc_window, + enum wl_output_transform transform) +{ + if (hwc_window->transform == transform) + return; + + hwc_window->transform = transform; +} + +WL_EXPORT void +ds_tdm_output_hwc_window_set_position(struct ds_tdm_output_hwc_window *hwc_window, + int x, int y) +{ + if ((hwc_window->x == x) && (hwc_window->y == y)) + return; + + hwc_window->x = x; + hwc_window->y = y; +} + +WL_EXPORT void +ds_tdm_output_hwc_window_set_dest_size(struct ds_tdm_output_hwc_window *hwc_window, + int width, int height) +{ + if ((hwc_window->dest_width == width) && (hwc_window->dest_height == height)) + return; + + hwc_window->dest_width = width; + hwc_window->dest_height = height; +} + +WL_EXPORT void +ds_tdm_output_hwc_window_set_composition(struct ds_tdm_output_hwc_window *hwc_window, + enum ds_tdm_output_hwc_window_composition composition) +{ + if (hwc_window->composition == composition) + return; + + hwc_window->composition = composition; +} + +WL_EXPORT enum ds_tdm_output_hwc_window_composition +ds_tdm_output_hwc_window_get_composition(struct ds_tdm_output_hwc_window *hwc_window) +{ + return hwc_window->composition; +} + +static void +hwc_window_update(struct ds_tdm_output_hwc_window *hwc_window) +{ + tdm_error terr; + tbm_surface_h tsurface = NULL; + tdm_hwc_window_info tinfo = {0, }; + struct ds_tbm_client_buffer *client_buffer; + + if (hwc_window->buffer) { + client_buffer = ds_tbm_client_buffer_from_buffer(hwc_window->buffer); + if (client_buffer) + tsurface = ds_tbm_client_buffer_get_tbm_surface(client_buffer); + } + + if (hwc_window->set_buffer != hwc_window->buffer) { + if (hwc_window->set_buffer) { + ds_buffer_unlock(hwc_window->set_buffer); + hwc_window->set_buffer = NULL; + } + + if (hwc_window->buffer) + hwc_window->set_buffer = ds_buffer_lock(hwc_window->buffer); + + terr = tdm_hwc_window_set_buffer(hwc_window->twindow, tsurface); + if (terr != TDM_ERROR_NONE) + ds_err("Could not set buffer hwc_window:%p tdm_error:%d", hwc_window, terr); + } + + if (tsurface) { + tinfo.src_config.pos.x = 0; + tinfo.src_config.pos.y = 0; + tinfo.src_config.pos.w = tbm_surface_get_width(tsurface); + tinfo.src_config.pos.h = tbm_surface_get_height(tsurface); + tinfo.src_config.size.h = get_horizontal_get(tsurface); + tinfo.src_config.size.v = tbm_surface_get_height(tsurface); + tinfo.src_config.format = tbm_surface_get_format(tsurface); + tinfo.dst_pos.x = hwc_window->x; + tinfo.dst_pos.y = hwc_window->y; + tinfo.dst_pos.w = hwc_window->dest_width; + tinfo.dst_pos.h = hwc_window->dest_height; + tinfo.transform = get_tdm_transform(hwc_window->transform); + } + + if (memcmp(&hwc_window->tinfo, &tinfo, sizeof tinfo)) { + memcpy(&hwc_window->tinfo, &tinfo, sizeof tinfo); + + terr = tdm_hwc_window_set_info(hwc_window->twindow, &hwc_window->tinfo); + if (terr != TDM_ERROR_NONE) + ds_err("Could not set info hwc_window:%p tdm_error:%d", hwc_window, terr); + } + + terr = tdm_hwc_window_set_composition_type(hwc_window->twindow, + get_tdm_composition(hwc_window->composition)); + if (terr != TDM_ERROR_NONE) + ds_err("Could not set composition type hwc_window:%p tdm_error:%d", hwc_window, terr); +} + +WL_EXPORT bool +ds_tdm_output_hwc_validate(struct ds_tdm_output_hwc *hwc, + struct ds_tdm_output_hwc_window **composited_windows, uint32_t num_windows, uint32_t *num_changed) +{ + tdm_error terr; + tdm_hwc_window **compositied_hwc_windows = NULL; + struct ds_tdm_output_hwc_window *hwc_window; + int i; + + wl_list_for_each(hwc_window, &hwc->hwc_windows, link) + hwc_window_update(hwc_window); + + if (num_windows > 0) { + compositied_hwc_windows = calloc(num_windows, sizeof(tdm_hwc_window *)); + if (!compositied_hwc_windows) + return false; + + for (i = 0; i < num_windows; i++) + compositied_hwc_windows[i] = composited_windows[i]->twindow; + } + + terr = tdm_hwc_validate(hwc->thwc, compositied_hwc_windows, num_windows, num_changed); + if (terr != TDM_ERROR_NONE) { + if (compositied_hwc_windows) + free(compositied_hwc_windows); + ds_err("Could not hwc validate"); + return false; + } + + if (compositied_hwc_windows) + free(compositied_hwc_windows); + + hwc->validate_num_changed = *num_changed; + + return true; +} + +static struct ds_tdm_output_hwc_window * +hwc_get_hwc_window_from_tdm_hwc_window(struct ds_tdm_output_hwc *hwc, tdm_hwc_window *thwc_window) +{ + struct ds_tdm_output_hwc_window *hwc_window; + + wl_list_for_each(hwc_window, &hwc->hwc_windows, link) { + if (hwc_window->twindow == thwc_window) + return hwc_window; + } + + return NULL; +} + +WL_EXPORT bool +ds_tdm_output_hwc_get_changed_composition(struct ds_tdm_output_hwc *hwc, uint32_t *num_changed, + struct ds_tdm_output_hwc_window **changed_windows) +{ + tdm_hwc_window **changed_thwc_windows = NULL; + tdm_hwc_window_composition *compositions = NULL; + struct ds_tdm_output_hwc_window *hwc_window; + tdm_error terr; + int i; + + if (!hwc->validate_num_changed) { + *num_changed = 0; + return true; + } + + changed_thwc_windows = calloc(hwc->validate_num_changed, sizeof *changed_thwc_windows); + if (!changed_thwc_windows) + return false; + + compositions = calloc(hwc->validate_num_changed, sizeof *compositions); + if (!compositions) { + free(changed_thwc_windows); + return false; + } + + terr = tdm_hwc_get_changed_composition_types(hwc->thwc, &hwc->validate_num_changed, + changed_thwc_windows, compositions); + if (terr != TDM_ERROR_NONE) { + ds_err("Could not hwc get changed composition types"); + free(changed_thwc_windows); + free(compositions); + return false; + } + + for (i = 0; i < hwc->validate_num_changed; i++) { + if (i >= *num_changed) + break; + + hwc_window = hwc_get_hwc_window_from_tdm_hwc_window(hwc, changed_thwc_windows[i]); + if (!hwc_window) + continue; + + ds_tdm_output_hwc_window_set_composition(hwc_window, get_composition(compositions[i])); + changed_windows[i] = hwc_window; + } + + free(changed_thwc_windows); + free(compositions); + + *num_changed = i; + + return true; +} + +WL_EXPORT bool +ds_tdm_output_hwc_accept_validation(struct ds_tdm_output_hwc *hwc) +{ + tdm_error terr; + struct ds_tdm_output_hwc_window *hwc_window; + enum ds_tdm_output_hwc_window_composition composition; + + terr = tdm_hwc_accept_validation(hwc->thwc); + if (terr != TDM_ERROR_NONE) { + ds_err("Could not hwc accept validation"); + return false; + } + + wl_list_for_each(hwc_window, &hwc->hwc_windows, link) { + composition = ds_tdm_output_hwc_window_get_composition(hwc_window); + ds_tdm_output_hwc_window_set_accepted_composition(hwc_window, + composition); + if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO)) { + hwc_window_attach_back_buffer(hwc_window, hwc_window->set_buffer); + } else { + hwc_window_attach_back_buffer(hwc_window, NULL); + } + } + + return true; +} + +static void +ds_tdm_output_hwc_commit_handler(tdm_hwc *thwc, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + struct ds_tdm_output_hwc *hwc = user_data; + struct ds_tdm_output_hwc_window *hwc_window, *tmp; + + wl_list_for_each_safe(hwc_window, tmp, &hwc->hwc_windows, link) + hwc_window_update_front_buffer(hwc_window); + + wl_signal_emit(&hwc->events.commit_handler, hwc); +} + +bool +ds_tdm_output_hwc_commit(struct ds_tdm_output_hwc *hwc) +{ + tdm_error terr; + uint32_t num_changes; + + if (!hwc->enabled) { + terr = tdm_hwc_validate(hwc->thwc, NULL, 0, &num_changes); + if (terr != TDM_ERROR_NONE) { + ds_err("Could not hwc validate"); + return false; + } + + terr = tdm_hwc_accept_validation(hwc->thwc); + if (terr != TDM_ERROR_NONE) { + ds_err("Could not hwc accept validation"); + return false; + } + } + + terr = tdm_hwc_commit(hwc->thwc, 0, ds_tdm_output_hwc_commit_handler, hwc); + if (terr != TDM_ERROR_NONE) { + ds_err("Could not hwc commit"); + return false; + } + + return true; +} + +void +ds_tdm_output_hwc_add_commit_handler_listener(struct ds_tdm_output_hwc *hwc, + struct wl_listener *listener) +{ + wl_signal_add(&hwc->events.commit_handler, listener); +} diff --git a/src/backend/tdm/tdm_output_hwc.h b/src/backend/tdm/tdm_output_hwc.h new file mode 100644 index 0000000..07b3699 --- /dev/null +++ b/src/backend/tdm/tdm_output_hwc.h @@ -0,0 +1,83 @@ +#ifndef DS_TIZEN_BACKEND_TDM_OUTPUT_HWC_H +#define DS_TIZEN_BACKEND_TDM_OUTPUT_HWC_H + +#include +#include +#include + +#include +#include + +struct ds_tdm_output_hwc_window { + struct wl_list link; + + tdm_hwc *hwc; + + size_t n_locks; + bool dropped; + + tdm_hwc_window *twindow; + tdm_hwc_window_info tinfo; + + enum ds_tdm_output_hwc_window_composition composition; + enum ds_tdm_output_hwc_window_composition accepted_composition; + + struct ds_tdm_box src_box; + int x, y; + int dest_width, dest_height; + enum wl_output_transform transform; + struct ds_buffer *buffer; + + struct ds_buffer *set_buffer; + struct ds_buffer *back_buffer, *front_buffer; +}; + +struct ds_tdm_output_hwc { + struct ds_tdm_output *tdm_output; + + tdm_hwc *thwc; + tdm_hwc_window_info target_buffer_info; + bool enabled; + + struct { + struct wl_signal destroy; + struct wl_signal commit_handler; + } events; + + uint32_t validate_num_changed; + + struct wl_list hwc_windows; +}; + +struct ds_tdm_output_hwc * +ds_tdm_output_hwc_create(tdm_hwc *thwc); + +void +ds_tdm_output_hwc_destroy(struct ds_tdm_output_hwc *hwc); + +bool +ds_tdm_output_hwc_set_client_target_buffer(struct ds_tdm_output_hwc *hwc, + tbm_surface_h tsurface); + +bool +ds_tdm_output_hwc_commit(struct ds_tdm_output_hwc *hwc); + +void +ds_tdm_output_hwc_add_commit_handler_listener(struct ds_tdm_output_hwc *hwc, + struct wl_listener *listener); + +void +ds_tdm_output_hwc_window_set_accepted_composition(struct ds_tdm_output_hwc_window *hwc_window, + enum ds_tdm_output_hwc_window_composition composition); + +void +ds_tdm_output_hwc_window_set_changed_composition(struct ds_tdm_output_hwc_window *hwc_window, + enum ds_tdm_output_hwc_window_composition composition); + +struct ds_tdm_output_hwc_window * +ds_tdm_output_hwc_window_lock(struct ds_tdm_output_hwc_window *hwc_window); + +void +ds_tdm_output_hwc_window_unlock(struct ds_tdm_output_hwc_window *hwc_window); + +#endif -- 2.7.4 From 7b9fd87d6e8fd123f5fbd1351f1601de93229eeb Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Thu, 16 Jun 2022 11:53:26 +0900 Subject: [PATCH 16/16] example: Add tinyds-tdm-hwc example ds_tdm_output_hwc Change-Id: I5a6f9f0a6055eaf52f0d6456896d5e65c4a746ee --- examples/meson.build | 17 + examples/tinyds-tdm-hwc.c | 768 +++++++++++++++++++++++++++++++++++++++++++++ packaging/libds-tizen.spec | 1 + 3 files changed, 786 insertions(+) create mode 100644 examples/tinyds-tdm-hwc.c diff --git a/examples/meson.build b/examples/meson.build index d9233fb..b7500a1 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -60,3 +60,20 @@ executable('tinyds-tdm-dpms', install_dir: libds_tizen_bindir, install : true ) + +tinyds_tdm_hwc_files = [ + 'tinyds-tdm-hwc.c', + 'pixman-helper.c', + 'pixman-tbm-helper.c', + 'tinyds-tdm-renderer.c', +] +executable('tinyds-tdm-hwc', + tinyds_tdm_hwc_files, + dependencies: [ + common_deps, + dependency('pixman-1', required: true), + dependency('threads', required: true), + ], + install_dir: libds_tizen_bindir, + install : true +) diff --git a/examples/tinyds-tdm-hwc.c b/examples/tinyds-tdm-hwc.c new file mode 100644 index 0000000..46925f1 --- /dev/null +++ b/examples/tinyds-tdm-hwc.c @@ -0,0 +1,768 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USE_TDM_BUFFER_QUEUE + +#ifdef USE_TDM_BUFFER_QUEUE +#include "pixman-tbm-helper.h" +#include "tinyds-tdm-renderer.h" +#else +#include +#endif + +#include "pixman-helper.h" + +#define TINYDS_UNUSED __attribute__((unused)) + +struct tinyds_output +{ + struct tinyds_server *server; + struct ds_output *ds_output; + struct ds_allocator *allocator; +#ifdef USE_TDM_BUFFER_QUEUE + struct tinyds_renderer renderer; + struct ds_tdm_buffer_queue *buffer_queue; + struct wl_listener buffer_queue_acquirable; +#else + struct ds_swapchain *swapchain; +#endif + struct ds_buffer *front_buffer; + + struct wl_listener output_destroy; + struct wl_listener output_frame; + + int width, height; + + struct wl_event_source *idle_commit; + bool commitable; + bool damaged; + + struct ds_tdm_output_hwc *hwc; +}; + +struct tinyds_server +{ + struct ds_tbm_server *tbm_server; + + struct wl_display *display; + + struct ds_backend *backend; + struct ds_compositor *compositor; + struct ds_xdg_shell *xdg_shell; + + struct tinyds_output *output; + struct wl_event_source *stdin_source; + + struct wl_list views; + + struct wl_listener new_output; + struct wl_listener new_xdg_surface; +}; + +struct tinyds_view +{ + struct tinyds_server *server; + + struct tinyds_texture *texture; + struct ds_xdg_surface *xdg_surface; + + struct wl_listener xdg_surface_map; + struct wl_listener xdg_surface_unmap; + struct wl_listener xdg_surface_destroy; + struct wl_listener surface_commit; + struct wl_list link; // tinyds_server::views + + struct ds_tdm_output_hwc_window *hwc_window; + + int x, y; + bool mapped; +}; + +struct tinyds_server tinyds; + +static bool init_server(struct tinyds_server *server, struct wl_display *display); +static int server_dispatch_stdin(int fd, uint32_t mask, void *data); +static void output_handle_destroy(struct wl_listener *listener, void *data); +static void output_handle_frame(struct wl_listener *listener, void *data); +static void draw_server_with_damage(struct tinyds_server *server); +static void draw_output(struct tinyds_output *output); +static void output_swap_buffer(struct tinyds_output *output, + struct ds_buffer *buffer); +static void view_send_frame_done(struct tinyds_view *view); +static void output_hwc_init(struct tinyds_output *output); +static void output_schedule_commit(struct tinyds_output *output); +static void output_commit(struct tinyds_output *output); +#ifdef USE_TDM_BUFFER_QUEUE +static void output_buffer_queue_init(struct tinyds_output *output); +static void output_renderer_init(struct tinyds_output *output); +static void output_draw_with_renderer(struct tinyds_output *output); +#else +static void output_swapchain_init(struct tinyds_output *output, + int width, int height, uint32_t format); +static void output_draw_with_swapchain(struct tinyds_output *output); +static void draw_view(struct tinyds_view *view, pixman_image_t *dst_image); +#endif + +int +main(void) +{ + struct tinyds_server *server = &tinyds; + struct wl_display *display; + struct wl_event_loop *loop; + const char *socket; + bool res; + + ds_log_init(DS_INF, NULL); + + display = wl_display_create(); + assert(display); + + res = init_server(server, display); + assert(res); + + socket = wl_display_add_socket_auto(display); + assert(socket); + + ds_backend_start(server->backend); + + setenv("WAYLAND_DISPLAY", socket, true); + + ds_inf("Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); + + loop = wl_display_get_event_loop(display); + server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO, + WL_EVENT_READABLE, server_dispatch_stdin, server); + + wl_display_run(display); + + wl_display_destroy_clients(display); + wl_display_destroy(display); + + return 0; +} + +static void +view_handle_xdg_surface_map(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + + view = wl_container_of(listener, view, xdg_surface_map); + view->mapped = true; +} + +static void +view_handle_xdg_surface_unmap(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + + view = wl_container_of(listener, view, xdg_surface_unmap); + view->mapped = false; +} + +static void +view_handle_xdg_surface_destroy(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + + view = wl_container_of(listener, view, xdg_surface_destroy); + + draw_server_with_damage(view->server); + + ds_tdm_output_hwc_window_destroy(view->hwc_window); + + wl_list_remove(&view->xdg_surface_destroy.link); + wl_list_remove(&view->xdg_surface_map.link); + wl_list_remove(&view->xdg_surface_unmap.link); + wl_list_remove(&view->surface_commit.link); + wl_list_remove(&view->link); + free(view); +} + +static void +view_handle_surface_commit(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_view *view; + + view = wl_container_of(listener, view, surface_commit); + + draw_server_with_damage(view->server); +} + +static void +server_new_xdg_surface(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct tinyds_view *view; + struct ds_xdg_surface *xdg_surface; + + server = wl_container_of(listener, server, new_xdg_surface); + xdg_surface = data; + + ds_inf("New xdg_surface(%p)", (void *)xdg_surface); + + view = calloc(1, sizeof *view); + assert(view); + + view->server = server; + view->xdg_surface = xdg_surface; + + view->xdg_surface_map.notify = view_handle_xdg_surface_map; + ds_xdg_surface_add_map_listener(xdg_surface, + &view->xdg_surface_map); + + view->xdg_surface_unmap.notify = view_handle_xdg_surface_unmap; + ds_xdg_surface_add_unmap_listener(xdg_surface, + &view->xdg_surface_unmap); + + view->xdg_surface_destroy.notify = view_handle_xdg_surface_destroy; + ds_xdg_surface_add_destroy_listener(xdg_surface, + &view->xdg_surface_destroy); + + view->surface_commit.notify = view_handle_surface_commit; + ds_surface_add_commit_listener( + ds_xdg_surface_get_surface(xdg_surface), + &view->surface_commit); + + view->hwc_window = ds_tdm_output_hwc_window_create(server->output->hwc); + + wl_list_insert(server->views.prev, &view->link); +} + +static void +backend_handle_new_output(struct wl_listener *listener, void *data) +{ + struct tinyds_server *server; + struct tinyds_output *output; + struct ds_output *ds_output; + const struct ds_output_mode *mode; + + server = wl_container_of(listener, server, new_output); + ds_output = data; + + ds_inf("New output(%p)", ds_output); + + if (server->output) + return; + + mode = ds_output_get_preferred_mode(ds_output); + ds_output_set_mode(ds_output, mode); + + output = calloc(1, sizeof *output); + if (!output) + return; + + output->server = server; + output->ds_output = ds_output; + output->width = mode->width; + output->height = mode->height; + output->damaged = true; + output->commitable = true; + +#ifdef USE_TDM_BUFFER_QUEUE + output_buffer_queue_init(output); + output_renderer_init(output); +#else + output_swapchain_init(output, mode->width, mode->height, + DRM_FORMAT_XRGB8888); +#endif + + output_hwc_init(output); + + output->output_destroy.notify = output_handle_destroy; + ds_output_add_destroy_listener(ds_output, &output->output_destroy); + + output->output_frame.notify = output_handle_frame; + ds_output_add_frame_listener(ds_output, &output->output_frame); + + server->output = output; + + output_schedule_commit(output); +} + +static bool +init_server(struct tinyds_server *server, struct wl_display *display) +{ + server->display = display; + + wl_list_init(&server->views); + + if (wl_display_init_shm(display) != 0) + return false; + + server->backend = ds_tdm_backend_create(display); + if (!server->backend) + return false; + + server->new_output.notify = backend_handle_new_output; + ds_backend_add_new_output_listener(server->backend, + &server->new_output); + + server->compositor = ds_compositor_create(display); + if (!server->compositor) { + ds_backend_destroy(server->backend); + return false; + } + + server->tbm_server = ds_tbm_server_create(display); + if (!server->tbm_server) { + ds_backend_destroy(server->backend); + return false; + } + + server->xdg_shell = ds_xdg_shell_create(display); + if (!server->xdg_shell) { + ds_backend_destroy(server->backend); + return false; + } + + server->new_xdg_surface.notify = server_new_xdg_surface; + ds_xdg_shell_add_new_surface_listener(server->xdg_shell, + &server->new_xdg_surface); + + return true; +} + +static void +output_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_output *output = + wl_container_of(listener, output, output_destroy); + + wl_list_remove(&output->output_destroy.link); + wl_list_remove(&output->output_frame.link); + + if (output->front_buffer) + ds_buffer_unlock(output->front_buffer); + +#ifdef USE_TDM_BUFFER_QUEUE + fini_renderer(&output->renderer); +#else + if (output->swapchain) + ds_swapchain_destroy(output->swapchain); + + if (output->allocator) + ds_allocator_destroy(output->allocator); +#endif + + wl_display_terminate(output->server->display); + + output->server->output = NULL; + + free(output); +} +static void +output_commit(struct tinyds_output *output) +{ + uint32_t num_changed = 0; + uint32_t num_windows = 0, current_num_windows = 0; + struct ds_tdm_output_hwc_window **composited_hwc_windows = NULL; + struct ds_tdm_output_hwc_window **changed_hwc_windows = NULL; + enum ds_tdm_output_hwc_window_composition composition; + struct tinyds_view *view; + int i; + bool need_target = false; + + if (!output->commitable || !output->damaged) + return; + + wl_list_for_each_reverse(view, &output->server->views, link) { + if (!view->hwc_window) + continue; + + if (view->mapped) + num_windows++; + } + + if (num_windows) { + composited_hwc_windows = calloc(num_windows, sizeof *composited_hwc_windows); + if (!composited_hwc_windows) + return; + } + + wl_list_for_each_reverse(view, &output->server->views, link) { + struct ds_buffer *ds_buffer; + struct ds_tdm_box src_box; + int w = 0, h = 0; + + if (!view->hwc_window) + continue; + + ds_buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + if (!ds_buffer) + continue; + + ds_tdm_output_hwc_window_set_buffer(view->hwc_window, ds_buffer); + + if (ds_buffer) + ds_buffer_get_size(ds_buffer, &w, &h); + + src_box.x = 0; + src_box.y = 0; + src_box.width = w; + src_box.height = h; + + ds_tdm_output_hwc_window_set_src_box(view->hwc_window, &src_box); + ds_tdm_output_hwc_window_set_position(view->hwc_window, view->x, view->y); + ds_tdm_output_hwc_window_set_dest_size(view->hwc_window, w, h); + ds_tdm_output_hwc_window_set_transform(view->hwc_window, WL_OUTPUT_TRANSFORM_NORMAL); + + if (view->mapped) { + ds_tdm_output_hwc_window_set_composition(view->hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE); + + composited_hwc_windows[current_num_windows] = view->hwc_window; + current_num_windows++; + } else { + ds_tdm_output_hwc_window_set_composition(view->hwc_window, + DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_NONE); + } + } + + if (!ds_tdm_output_hwc_validate(output->hwc, composited_hwc_windows, + num_windows, &num_changed)) { + free(composited_hwc_windows); + ds_err("Could not hwc validate"); + return; + } + + if (composited_hwc_windows) + free(composited_hwc_windows); + + if (num_changed > 0) { + changed_hwc_windows = calloc(num_windows, sizeof *changed_hwc_windows); + if (!changed_hwc_windows) + return; + + if (!ds_tdm_output_hwc_get_changed_composition(output->hwc, &num_changed, + changed_hwc_windows)) { + ds_err("Could not get chaged composition"); + return; + } + + for (i = 0; i < num_changed; i++) { + composition = ds_tdm_output_hwc_window_get_composition(changed_hwc_windows[i]); + if (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CLIENT) { + need_target = true; + break; + } + } + } + + if (changed_hwc_windows) + free(changed_hwc_windows); + + if (!ds_tdm_output_hwc_accept_validation(output->hwc)) { + ds_err("Could not hwc accept validateion"); + return; + } + + if (need_target) + draw_output(output); + +#ifdef USE_TDM_BUFFER_QUEUE + struct ds_buffer *buffer; + + buffer = ds_tdm_buffer_queue_acquire(output->buffer_queue); + if (buffer) + output_swap_buffer(output, buffer); +#endif + + ds_output_commit(output->ds_output); + + output->commitable = false; + output->damaged = false; + + wl_list_for_each(view, &output->server->views, link) { + enum ds_tdm_output_hwc_window_composition composition; + + if (!view->mapped) + continue; + + composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); + if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) + view_send_frame_done(view); + } + + ds_inf("output:%p commit", output); +} + +static void +output_handle_frame(struct wl_listener *listener, void *data TINYDS_UNUSED) +{ + struct tinyds_output *output = + wl_container_of(listener, output, output_frame); + + ds_inf("output:%p handle frame", output); + + output->commitable = true; + + output_commit(output); +} + +static void +draw_server_with_damage(struct tinyds_server *server) +{ + server->output->damaged = true; + output_schedule_commit(server->output); +} + +static void +output_hwc_init(struct tinyds_output *output) +{ + struct ds_tdm_output *tdm_output; + + tdm_output = ds_tdm_output_from_output(output->ds_output); + assert(tdm_output); + + output->hwc = ds_tdm_output_get_hwc(tdm_output); + assert(output->hwc); + + ds_tdm_output_hwc_set_enabled(output->hwc, true); +} + +#ifdef USE_TDM_BUFFER_QUEUE +static void +output_handle_buffer_queue_acquirable(struct wl_listener *listener, + void *data TINYDS_UNUSED) +{ + struct tinyds_output *output; + + output = wl_container_of(listener, output, buffer_queue_acquirable); + + draw_server_with_damage(output->server); +} + +static void +output_buffer_queue_init(struct tinyds_output *output) +{ + struct ds_tdm_output *tdm_output; + + tdm_output = ds_tdm_output_from_output(output->ds_output); + assert(tdm_output); + + output->buffer_queue = ds_tdm_output_get_buffer_queue(tdm_output); + assert(output->buffer_queue); + + output->buffer_queue_acquirable.notify = + output_handle_buffer_queue_acquirable; + ds_tdm_buffer_queue_add_acquirable_listener(output->buffer_queue, + &output->buffer_queue_acquirable); +} + +static void +output_renderer_init(struct tinyds_output *output) +{ + init_renderer(&output->renderer); + + renderer_set_surface_queue(&output->renderer, + ds_tdm_buffer_queue_get_native_queue(output->buffer_queue)); + + renderer_set_bg_color(&output->renderer, 0, 0, 0); +} + +static void +output_draw_with_renderer(struct tinyds_output *output) +{ + struct tinyds_view *view; + + ds_dbg(">> BEGIN UPDATE TEXTURES"); + + wl_list_for_each(view, &output->server->views, link) { + struct ds_buffer *ds_buffer; + struct ds_tbm_client_buffer *tbm_buffer; + tbm_surface_h surface; + enum ds_tdm_output_hwc_window_composition composition; + + if (!view->mapped) + continue; + + composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); + if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) + continue; + + ds_buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + assert(ds_buffer); + + tbm_buffer = ds_tbm_client_buffer_from_buffer(ds_buffer); + assert(tbm_buffer); + + surface = ds_tbm_client_buffer_get_tbm_surface(tbm_buffer); + + renderer_add_texture(&output->renderer, surface, view->x, view->y); + + view_send_frame_done(view); + } + + ds_dbg("<< END UPDATE TEXTURES"); + + renderer_draw(&output->renderer); +} + +#else +static void +output_swapchain_init(struct tinyds_output *output, + int width, int height, uint32_t format) + +{ + output->allocator = ds_tbm_allocator_create(); + assert(output->allocator); + + output->swapchain = ds_swapchain_create(output->allocator, + width, height, format); + assert(output->swapchain); +} + +static void +output_draw_with_swapchain(struct tinyds_output *output) +{ + struct tinyds_view *view; + struct ds_buffer *output_buffer; + pixman_image_t *output_image; + enum ds_tdm_output_hwc_window_composition composition; + + output_buffer = ds_swapchain_acquire(output->swapchain, NULL); + if (!output_buffer) + return; + + output_image = pixman_image_from_buffer(output_buffer, + DS_BUFFER_DATA_PTR_ACCESS_WRITE); + if (!output_image) { + ds_buffer_unlock(output_buffer); + return; + } + + pixman_image_fill_color(output_image, 0, 0, 0); + + wl_list_for_each(view, &output->server->views, link) { + if (!view->mapped) + continue; + + composition = ds_tdm_output_hwc_window_get_composition(view->hwc_window); + if ((composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_DEVICE) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_VIDEO) || + (composition == DS_TDM_OUTPUT_HWC_WINDOW_COMPOSITION_CURSOR)) + continue; + + draw_view(view, output_image); + } + pixman_image_unref(output_image); + + output_swap_buffer(output, output_buffer); +} + +static void +draw_view(struct tinyds_view *view, pixman_image_t *dst_image) +{ + struct ds_buffer *buffer; + pixman_image_t *src_image; + + buffer = ds_surface_get_buffer( + ds_xdg_surface_get_surface(view->xdg_surface)); + if (!buffer) + return; + + src_image = pixman_image_from_buffer(buffer, + DS_BUFFER_DATA_PTR_ACCESS_READ); + pixman_image_composite32(PIXMAN_OP_OVER, + src_image, + NULL, + dst_image, + 0, 0, 0, 0, + view->x, view->y, + pixman_image_get_width(src_image), + pixman_image_get_height(src_image)); + pixman_image_unref(src_image); + + view_send_frame_done(view); +} +#endif + +static void +draw_output(struct tinyds_output *output) +{ +#ifdef USE_TDM_BUFFER_QUEUE + output_draw_with_renderer(output); +#else + output_draw_with_swapchain(output); +#endif + + ds_inf("output:%p draw", output); +} + +static void +output_swap_buffer(struct tinyds_output *output, struct ds_buffer *buffer) +{ + ds_output_attach_buffer(output->ds_output, buffer); + + if (output->front_buffer) + ds_buffer_unlock(output->front_buffer); + output->front_buffer = buffer; +} + +static void +view_send_frame_done(struct tinyds_view *view) +{ + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + ds_surface_send_frame_done(ds_xdg_surface_get_surface(view->xdg_surface), + &now); +} + +static void +output_schedule_commit_handle_idle_timer(void *data) +{ + struct tinyds_output *output = data; + output->idle_commit = NULL; + + output_commit(output); +} + +static void +output_schedule_commit(struct tinyds_output *output) +{ + if (output->idle_commit) + return; + + output->damaged = true; + + struct wl_event_loop *ev = wl_display_get_event_loop(output->server->display); + output->idle_commit = + wl_event_loop_add_idle(ev, output_schedule_commit_handle_idle_timer, output); +} + +static int +server_dispatch_stdin(int fd, uint32_t mask, void *data) +{ + struct tinyds_server *server = data; + + wl_display_terminate(server->display); + + return 1; +} diff --git a/packaging/libds-tizen.spec b/packaging/libds-tizen.spec index c2e0180..000f5a9 100644 --- a/packaging/libds-tizen.spec +++ b/packaging/libds-tizen.spec @@ -99,6 +99,7 @@ ninja -C builddir install %{_libdir}/libds-tizen.so %{_bindir}/tdm-backend %{_bindir}/tinyds-tdm +%{_bindir}/tinyds-tdm-hwc %{_bindir}/ds-simple-tbm %{_bindir}/tinyds-tdm-dpms %{_bindir}/ds-simple-dpms -- 2.7.4