From a002a9cf36b0c0e691d4f9aa5494a119a4d485ff Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 16 May 2022 17:39:29 +0900 Subject: [PATCH 01/16] shell: implement wl_shell_interface ds_shell and ds_shell_surface are resources which implement the wl_shell_interface and wl_shell_surface_interface. Change-Id: I1064d0b431bdf1fd734353b58bc7994d202e9c57 --- include/libds/shell.h | 50 +++++ src/libds/meson.build | 2 + src/libds/shell.c | 175 +++++++++++++++ src/libds/shell.h | 157 ++++++++++++++ src/libds/shell_surface.c | 540 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 924 insertions(+) create mode 100644 include/libds/shell.h create mode 100644 src/libds/shell.c create mode 100644 src/libds/shell.h create mode 100644 src/libds/shell_surface.c diff --git a/include/libds/shell.h b/include/libds/shell.h new file mode 100644 index 0000000..b4fa688 --- /dev/null +++ b/include/libds/shell.h @@ -0,0 +1,50 @@ +#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/src/libds/meson.build b/src/libds/meson.build index 43bdeae..b59fda2 100644 --- a/src/libds/meson.build +++ b/src/libds/meson.build @@ -26,6 +26,8 @@ libds_files = [ 'seat/seat_pointer.c', 'seat/seat_keyboard.c', 'seat/seat_touch.c', + 'shell.c', + 'shell_surface.c', ] protocols = { diff --git a/src/libds/shell.c b/src/libds/shell.c new file mode 100644 index 0000000..3adb519 --- /dev/null +++ b/src/libds/shell.c @@ -0,0 +1,175 @@ +#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 new file mode 100644 index 0000000..c2306af --- /dev/null +++ b/src/libds/shell.h @@ -0,0 +1,157 @@ +#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 new file mode 100644 index 0000000..73c498b --- /dev/null +++ b/src/libds/shell_surface.c @@ -0,0 +1,540 @@ +#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); +} -- 2.7.4 From 4cb5ea8865251643d44ac600a3a7701bb208f68e Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Thu, 19 May 2022 10:38:44 +0900 Subject: [PATCH 02/16] client: add simple-shm-shell sample This is a simple wayland-client which use wl_shm and wl_shell interface. Change-Id: I48cfeebde8e6a5e6621942c2f0f7c642f5372111 --- packaging/libds.spec | 1 + src/clients/meson.build | 12 ++ src/clients/simple-shm-shell.c | 339 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 352 insertions(+) create mode 100644 src/clients/simple-shm-shell.c diff --git a/packaging/libds.spec b/packaging/libds.spec index 2ffdca0..5258295 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -103,6 +103,7 @@ ninja -C builddir install %{_bindir}/tinyds-tdm %{_bindir}/ds-simple-tbm %{_bindir}/tinyds-tdm-libinput +%{_bindir}/ds-simple-shm-shell %files tizen-keyrouter %manifest %{name}.manifest diff --git a/src/clients/meson.build b/src/clients/meson.build index 360c425..009016c 100644 --- a/src/clients/meson.build +++ b/src/clients/meson.build @@ -1,3 +1,15 @@ +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) diff --git a/src/clients/simple-shm-shell.c b/src/clients/simple-shm-shell.c new file mode 100644 index 0000000..52d9ed2 --- /dev/null +++ b/src/clients/simple-shm-shell.c @@ -0,0 +1,339 @@ +/* +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; +} -- 2.7.4 From 3909f200f7443473f4810a00de45125ee1f67549 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 27 May 2022 11:39:45 +0900 Subject: [PATCH 03/16] add review-bot as a reviewer Change-Id: Ida05f30c7edcc66605593a600e27901ced3f71c6 --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index d52bfc2..06c492b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -5,5 +5,5 @@ # the repo. Unless a later match takes precedence, # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. -* @sc1-lim @shiin-lee @joonbum-ko @cyeon-lee @doyoun-kang @gl77-lee @duna-oh @jinbong-lee @jk0430-kim @juns-kim @TizenWS/ws_members +* @sc1-lim @shiin-lee @joonbum-ko @cyeon-lee @doyoun-kang @gl77-lee @duna-oh @jinbong-lee @jk0430-kim @juns-kim @TizenWS/ws_members @review-bot -- 2.7.4 From 7eac7a77a9cefbc6b6a82875ff89de69c3c78b04 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 2 Jun 2022 13:14:29 +0900 Subject: [PATCH 04/16] security: Remove meaningless double check In the function tizen_security_check_privilege(), it double-checks a g_cynara to see if it exists and then return different value if it doesn't exist which is contradictory. Let's just return false if initializing the cynara has been failed or not been initialized. Change-Id: If141f0e9bcc75ee0804cfa65bb136121d4d23fcc --- src/libds-tizen/util/security.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libds-tizen/util/security.c b/src/libds-tizen/util/security.c index ad19027..8544951 100644 --- a/src/libds-tizen/util/security.c +++ b/src/libds-tizen/util/security.c @@ -55,11 +55,6 @@ tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege) int len = -1; int ret = -1; - /* If cynara_initialize() has been (retried) and failed, we suppose that cynara is not available. */ - /* Then we return true as if there is no security check available. */ - if (!g_cynara) - return true; - if (!g_cynara) { ds_err("security has not been initialized.\n"); return false; -- 2.7.4 From 9825b7f921f4b093f81ab4ff657ca81875cc5fe8 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 2 Jun 2022 13:50:54 +0900 Subject: [PATCH 05/16] security: Refactor implementation for cynara No functional changes Change-Id: I8cfe200969f71ad761dae5c06bfa3227ca89ffd5 --- src/libds-tizen/util.h | 2 +- src/libds-tizen/util/security.c | 180 +++++++++++++++++++++++----------------- 2 files changed, 104 insertions(+), 78 deletions(-) diff --git a/src/libds-tizen/util.h b/src/libds-tizen/util.h index 18ad811..82e178b 100644 --- a/src/libds-tizen/util.h +++ b/src/libds-tizen/util.h @@ -5,7 +5,7 @@ #define MIN(a,b) ((a)<(b)?(a):(b)) -int +bool tizen_security_init(void); void diff --git a/src/libds-tizen/util/security.c b/src/libds-tizen/util/security.c index 8544951..9983e24 100644 --- a/src/libds-tizen/util/security.c +++ b/src/libds-tizen/util/security.c @@ -1,4 +1,3 @@ - #include #include #include @@ -8,20 +7,61 @@ #include "util.h" #ifdef HAVE_CYNARA +#include +#include + #include #include #include #include -#include -#include #define CYNARA_BUFSIZE 128 -static cynara *g_cynara = NULL; -static int g_cynara_refcount = 0; +struct ds_cynara +{ + cynara *handle; + int references; +}; + +static struct ds_cynara ds_cynara; + +static bool ds_cynara_init(void); +static void ds_cynara_finish(void); +static bool ds_cynara_check_privilege(pid_t pid, uid_t uid, + const char *privilege); +#endif + +bool +tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege) +{ +#ifdef HAVE_CYNARA + return ds_cynara_check_privilege(pid, uid, privilege); +#else + return true; +#endif +} + +bool +tizen_security_init(void) +{ +#ifdef HAVE_CYNARA + return ds_cynara_init(); +#else + return true; +#endif +} + +void +tizen_security_finish(void) +{ +#ifdef HAVE_CYNARA + ds_cynara_finish(); +#endif +} +#ifdef HAVE_CYNARA static void -__security_log_print(int err, const char *fmt, ...) +print_cynara_error(int err, const char *fmt, ...) { int ret; va_list args; @@ -42,12 +82,56 @@ __security_log_print(int err, const char *fmt, ...) ds_err("%s is failed. (%s)\n", tmp, buf); } -#endif -bool -tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege) +static bool +ds_cynara_init(void) +{ + int ret = CYNARA_API_SUCCESS; + int retry_cnt = 0; + + if (++ds_cynara.references != 1) + return true; + + for (retry_cnt = 0; retry_cnt < 5; retry_cnt++) { + ds_dbg("Retry cynara initialize: %d\n", retry_cnt + 1); + + ret = cynara_initialize(&ds_cynara.handle, NULL); + + if (CYNARA_API_SUCCESS == ret) { + ds_dbg("Succeed to initialize cynara !\n"); + return true; + } + + print_cynara_error(ret, "cynara_initialize"); + } + + ds_err("Failed to initialize cynara! (error:%d, retry_cnt=%d)\n", + ret, retry_cnt); + + --ds_cynara.references; + + return false; + +} + +static void +ds_cynara_finish(void) +{ + if (ds_cynara.references < 1) { + ds_err("%s called without ds_cynara_init\n", __FUNCTION__); + return; + } + + if (--ds_cynara.references != 0) + return; + + cynara_finish(ds_cynara.handle); + ds_cynara.handle = NULL; +} + +static bool +ds_cynara_check_privilege(pid_t pid, uid_t uid, const char *privilege) { -#ifdef HAVE_CYNARA bool res = false; char *client_smack = NULL; char *client_session = NULL; @@ -55,8 +139,8 @@ tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege) int len = -1; int ret = -1; - if (!g_cynara) { - ds_err("security has not been initialized.\n"); + if (!ds_cynara.handle) { + ds_err("ds_cynara has not been initialized.\n"); return false; } @@ -70,86 +154,28 @@ tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege) if (!client_session) goto finish; - ret = cynara_check(g_cynara, client_smack, client_session, - uid_str, privilege); + ret = cynara_check(ds_cynara.handle, client_smack, client_session, + uid_str, privilege); if (ret == CYNARA_API_ACCESS_ALLOWED) res = true; else - __security_log_print(ret, "privilege: %s, client_smack: %s, pid: %d", privilege, client_smack, pid); + print_cynara_error(ret, "privilege: %s, client_smack: %s, pid: %d", + privilege, client_smack, pid); finish: - ds_dbg("Privilege Check For '%s' %s pid:%u uid:%u client_smack:%s(len:%d) client_session:%s ret:%d", + ds_dbg("Privilege Check For '%s' %s pid:%u uid:%u client_smack:%s(len:%d) " + "client_session:%s ret:%d", privilege, res ? "SUCCESS" : "FAIL", pid, uid, client_smack ? client_smack : "N/A", len, client_session ? client_session: "N/A", ret); if (client_session) free(client_session); + if (client_smack) free(client_smack); return res; -#else - return true; -#endif } - -int -tizen_security_init(void) -{ -#ifdef HAVE_CYNARA - int ret = CYNARA_API_SUCCESS; - int retry_cnt = 0; - static bool retried = false; - - if (++g_cynara_refcount != 1) - return g_cynara_refcount; - - if (!g_cynara && false == retried) { - retried = true; - - for (retry_cnt = 0; retry_cnt < 5; retry_cnt++) { - ds_dbg("Retry cynara initialize: %d\n", retry_cnt + 1); - - ret = cynara_initialize(&g_cynara, NULL); - - if (CYNARA_API_SUCCESS == ret) { - ds_dbg("Succeed to initialize cynara !\n"); - return 1; - } - - __security_log_print(ret, "cynara_initialize"); - g_cynara = NULL; - } - } - - ds_err("Failed to initialize _security ! (error:%d, retry_cnt=%d)\n", - ret, retry_cnt); - --g_cynara_refcount; - - return 0; -#else - return 1; #endif -} - -void -tizen_security_finish(void) -{ -#ifdef HAVE_CYNARA - if (g_cynara_refcount < 1) { - ds_err("%s called without tizen_security_init\n", __FUNCTION__); - return; - } - - if (--g_cynara_refcount != 0) - return; - - if (g_cynara) { - cynara_finish(g_cynara); - g_cynara = NULL; - } -#endif -} - -- 2.7.4 From 8a30c383a95bbe32229ed178ee4b3d4d7aa661fc Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 2 Jun 2022 13:53:14 +0900 Subject: [PATCH 06/16] tizen-util: Include an appropriate header Change-Id: I3ee70dc2ed75a4ef04ac7d8c604d5be8521651d0 --- src/libds-tizen/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libds-tizen/util.h b/src/libds-tizen/util.h index 82e178b..126467c 100644 --- a/src/libds-tizen/util.h +++ b/src/libds-tizen/util.h @@ -1,7 +1,7 @@ #ifndef DS_UTIL_H #define DS_UTIL_H -#include +#include #define MIN(a,b) ((a)<(b)?(a):(b)) -- 2.7.4 From cb42d11df4a866350f457d729786ba8478b0a5f3 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Thu, 2 Jun 2022 14:22:55 +0900 Subject: [PATCH 07/16] security: Enable cynara to be built This patch also removes conditional compilation for cynara. This should be considered again if it gets needed. Change-Id: I0597b3914780c30ce2b1835dd7089b6bc8f47888 --- packaging/libds.spec | 3 +++ src/libds-tizen/util/meson.build | 5 +++++ src/libds-tizen/util/security.c | 26 +++++--------------------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/packaging/libds.spec b/packaging/libds.spec index 5258295..ed21c53 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -23,6 +23,9 @@ BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(wayland-tbm-server) BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(tizen-dpms-server) +BuildRequires: pkgconfig(cynara-client) +BuildRequires: pkgconfig(cynara-session) +BuildRequires: pkgconfig(libsmack) %description Wayland Compositor Library diff --git a/src/libds-tizen/util/meson.build b/src/libds-tizen/util/meson.build index 3d34ab8..0ec6a9d 100644 --- a/src/libds-tizen/util/meson.build +++ b/src/libds-tizen/util/meson.build @@ -1 +1,6 @@ libds_tizen_files += files('security.c') +libds_tizen_deps += [ + dependency('cynara-client', required: true), + dependency('cynara-session', required: true), + dependency('libsmack', required: true) +] diff --git a/src/libds-tizen/util/security.c b/src/libds-tizen/util/security.c index 9983e24..b592577 100644 --- a/src/libds-tizen/util/security.c +++ b/src/libds-tizen/util/security.c @@ -1,20 +1,17 @@ +#include +#include #include #include #include -#include "libds/log.h" - -#include "util.h" - -#ifdef HAVE_CYNARA -#include -#include - #include #include #include #include +#include "libds/log.h" +#include "util.h" + #define CYNARA_BUFSIZE 128 struct ds_cynara @@ -29,37 +26,25 @@ static bool ds_cynara_init(void); static void ds_cynara_finish(void); static bool ds_cynara_check_privilege(pid_t pid, uid_t uid, const char *privilege); -#endif bool tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege) { -#ifdef HAVE_CYNARA return ds_cynara_check_privilege(pid, uid, privilege); -#else - return true; -#endif } bool tizen_security_init(void) { -#ifdef HAVE_CYNARA return ds_cynara_init(); -#else - return true; -#endif } void tizen_security_finish(void) { -#ifdef HAVE_CYNARA ds_cynara_finish(); -#endif } -#ifdef HAVE_CYNARA static void print_cynara_error(int err, const char *fmt, ...) { @@ -178,4 +163,3 @@ finish: return res; } -#endif -- 2.7.4 From a13252f49dbe4abb56b6f957688189530b048c3f Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 3 Jun 2022 18:05:12 +0900 Subject: [PATCH 08/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: I18f3b133cb44e983d929da1c525c8bf878cdd5c6 --- 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 af0d265c90ca3824e2373b8c8c50b6d4b810b316 Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 3 Jun 2022 18:12:29 +0900 Subject: [PATCH 09/16] keyrouter: Return an appropriate value The return value of keyrouter_grab_check_grabbed() is boolean. So let's make it right. Change-Id: I27048b419ad8e5b13060b5d87f2948b6e3c15d80 --- 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 402b30f8013e1231d5032103fc1b3493cd5abf96 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:29:44 +0900 Subject: [PATCH 10/16] dpms: fix build error Change-Id: I06c768d97d26ccee3ca85825e653c6cc56538539 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 2d2ba4d16f5fcbaf9eb97f0905dbae4740076bf2 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:31:32 +0900 Subject: [PATCH 11/16] example: add tinyds-tdm-dpms Change-Id: Ic63b2893120fc46865559a49e0dc34c376f3a1ca 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 ae1d36fed10e73a03f3e80259e4b3a0012cdea7a Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:34:43 +0900 Subject: [PATCH 12/16] client: add simple-dpms Change-Id: Ibd038539152aaee0f8f6a78f9eee88d7a542afcc 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 01e84ec6aeafb34bd44eb0966f9547884df3ac51 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Tue, 7 Jun 2022 13:35:51 +0900 Subject: [PATCH 13/16] dpms: set ds_tizen_dpms enum value by tizen dpms protocol enum value Change-Id: I55c31d0be7d92f4c85ffcd9c712bc61e54058073 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 6352c4116e2746ea0bd1f1f18398bba225037863 Mon Sep 17 00:00:00 2001 From: "duna.oh" Date: Tue, 7 Jun 2022 19:38:39 +0900 Subject: [PATCH 14/16] devicemgr: implement libds-tizen-input-devicemgr Change-Id: I7b5d45cd96122bb4f5d7926bd6d3d830475f5696 --- 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 38582fcb7d2bf911cb2eda5a142d76a4df1d288a Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 8 Jun 2022 08:30:48 +0900 Subject: [PATCH 15/16] keyrouter: Fix wrong validity check Change-Id: I0f26218b5305565061f35a5cd7a1c1739190a94f --- 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 7900df693219a6f1890cafda16b61748f8c2c287 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Sat, 4 Jun 2022 08:59:17 +0900 Subject: [PATCH 16/16] remove libds-tizen stuffs all files of libds-tizen move to libds-tizen repository Change-Id: I4349558c36e45f2c4e2877e7a416d9ac9eaad5a9 --- include/libds-tizen/allocator/tbm.h | 20 - include/libds-tizen/backend/tdm.h | 38 - include/libds-tizen/dpms.h | 64 -- include/libds-tizen/input-devicemgr.h | 40 - include/libds-tizen/keyrouter.h | 23 - include/libds-tizen/tbm_server.h | 32 - include/meson.build | 6 - meson_options.txt | 2 - packaging/libds.spec | 94 +- src/clients/meson.build | 71 -- src/clients/simple-tbm.c | 746 -------------- src/examples/meson.build | 83 +- src/examples/tdm-backend.c | 247 ----- src/examples/tinyds-tdm-libinput.c | 1125 --------------------- src/examples/tinyds-tdm-renderer.c | 187 ---- src/examples/tinyds-tdm-renderer.h | 48 - src/examples/tinyds-tdm.c | 575 ----------- src/libds-tizen/allocator/meson.build | 2 - src/libds-tizen/allocator/tbm.c | 177 ---- src/libds-tizen/backend/meson.build | 1 - src/libds-tizen/backend/tdm/backend.c | 176 ---- src/libds-tizen/backend/tdm/meson.build | 13 - src/libds-tizen/backend/tdm/output.c | 425 -------- src/libds-tizen/backend/tdm/tdm.h | 76 -- src/libds-tizen/backend/tdm/tdm_buffer_queue.c | 311 ------ src/libds-tizen/backend/tdm/tdm_buffer_queue.h | 45 - src/libds-tizen/dpms.c | 204 ---- 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/keyrouter/keyrouter.c | 430 -------- src/libds-tizen/keyrouter/keyrouter.h | 108 -- src/libds-tizen/keyrouter/keyrouter_grab.c | 351 ------- src/libds-tizen/keyrouter/meson.build | 34 - src/libds-tizen/meson.build | 42 - src/libds-tizen/pixel_format.c | 61 -- src/libds-tizen/pixel_format.h | 10 - src/libds-tizen/tbm_server.c | 268 ----- src/libds-tizen/tbm_server.h | 34 - src/libds-tizen/util.h | 17 - src/libds-tizen/util/meson.build | 6 - src/libds-tizen/util/security.c | 165 --- src/meson.build | 3 - 43 files changed, 14 insertions(+), 7498 deletions(-) delete mode 100644 include/libds-tizen/allocator/tbm.h delete mode 100644 include/libds-tizen/backend/tdm.h delete mode 100644 include/libds-tizen/dpms.h delete mode 100644 include/libds-tizen/input-devicemgr.h delete mode 100644 include/libds-tizen/keyrouter.h delete mode 100644 include/libds-tizen/tbm_server.h delete mode 100644 src/clients/simple-tbm.c delete mode 100644 src/examples/tdm-backend.c delete mode 100644 src/examples/tinyds-tdm-libinput.c delete mode 100644 src/examples/tinyds-tdm-renderer.c delete mode 100644 src/examples/tinyds-tdm-renderer.h delete mode 100644 src/examples/tinyds-tdm.c delete mode 100644 src/libds-tizen/allocator/meson.build delete mode 100644 src/libds-tizen/allocator/tbm.c delete mode 100644 src/libds-tizen/backend/meson.build delete mode 100644 src/libds-tizen/backend/tdm/backend.c delete mode 100644 src/libds-tizen/backend/tdm/meson.build delete mode 100644 src/libds-tizen/backend/tdm/output.c delete mode 100644 src/libds-tizen/backend/tdm/tdm.h delete mode 100644 src/libds-tizen/backend/tdm/tdm_buffer_queue.c delete mode 100644 src/libds-tizen/backend/tdm/tdm_buffer_queue.h delete mode 100644 src/libds-tizen/dpms.c delete mode 100644 src/libds-tizen/input-devicemgr/input-devicemgr.c delete mode 100644 src/libds-tizen/input-devicemgr/input-devicemgr.h delete mode 100644 src/libds-tizen/input-devicemgr/meson.build delete mode 100644 src/libds-tizen/keyrouter/keyrouter.c delete mode 100644 src/libds-tizen/keyrouter/keyrouter.h delete mode 100644 src/libds-tizen/keyrouter/keyrouter_grab.c delete mode 100644 src/libds-tizen/keyrouter/meson.build delete mode 100644 src/libds-tizen/meson.build delete mode 100644 src/libds-tizen/pixel_format.c delete mode 100644 src/libds-tizen/pixel_format.h delete mode 100644 src/libds-tizen/tbm_server.c delete mode 100644 src/libds-tizen/tbm_server.h delete mode 100644 src/libds-tizen/util.h delete mode 100644 src/libds-tizen/util/meson.build delete mode 100644 src/libds-tizen/util/security.c diff --git a/include/libds-tizen/allocator/tbm.h b/include/libds-tizen/allocator/tbm.h deleted file mode 100644 index 3febb10..0000000 --- a/include/libds-tizen/allocator/tbm.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef LIBDS_TIZEN_ALLOCATOR_TBM_H -#define LIBDS_TIZEN_ALLOCATOR_TBM_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_allocator * -ds_tbm_allocator_create(void); - -WL_EXPORT void * -ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds-tizen/backend/tdm.h b/include/libds-tizen/backend/tdm.h deleted file mode 100644 index 8c5c605..0000000 --- a/include/libds-tizen/backend/tdm.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef LIBDS_TIZEN_BACKEND_TDM_H -#define LIBDS_TIZEN_BACKEND_TDM_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_tdm_output; - -struct ds_tdm_buffer_queue; - -struct ds_backend * -ds_tdm_backend_create(struct wl_display *display); - -struct ds_tdm_output * -ds_tdm_output_from_output(struct ds_output *ds_output); - -struct ds_tdm_buffer_queue * -ds_tdm_output_get_buffer_queue(struct ds_tdm_output *output); - -void * -ds_tdm_buffer_queue_get_native_queue(struct ds_tdm_buffer_queue *queue); - -struct ds_buffer * -ds_tdm_buffer_queue_acquire(struct ds_tdm_buffer_queue *queue); - -void -ds_tdm_buffer_queue_add_acquirable_listener(struct ds_tdm_buffer_queue *queue, - struct wl_listener *listener); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds-tizen/dpms.h b/include/libds-tizen/dpms.h deleted file mode 100644 index c614e66..0000000 --- a/include/libds-tizen/dpms.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef LIBDS_DPMS_H -#define LIBDS_DPMS_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_tizen_dpms; - -enum ds_tizen_dpms_mode -{ - 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 = 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 -{ - //struct ds_output *output; - enum ds_tizen_dpms_mode mode; -}; - -struct ds_tizen_dpms * -ds_tizen_dpms_create(struct wl_display *display); - -void -ds_tizen_dpms_add_destroy_listener(struct ds_tizen_dpms *dpms, - struct wl_listener *listener); - -void -ds_tizen_dpms_add_set_dpms_listener(struct ds_tizen_dpms *dpms, - struct wl_listener *listener); - -void -ds_tizen_dpms_add_get_dpms_listener(struct ds_tizen_dpms *dpms, - struct wl_listener *listener); - -void -ds_tizen_dpms_send_set_result(struct ds_tizen_dpms *dpms, - enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error); - -void -ds_tizen_dpms_send_get_result(struct ds_tizen_dpms *dpms, - enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds-tizen/input-devicemgr.h b/include/libds-tizen/input-devicemgr.h deleted file mode 100644 index a9ed808..0000000 --- a/include/libds-tizen/input-devicemgr.h +++ /dev/null @@ -1,40 +0,0 @@ -#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-tizen/keyrouter.h b/include/libds-tizen/keyrouter.h deleted file mode 100644 index a870003..0000000 --- a/include/libds-tizen/keyrouter.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef LIBDS_TIZEN_KEYROUTER_H -#define LIBDS_TIZEN_KEYROUTER_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_tizen_keyrouter; - -struct ds_tizen_keyrouter * -ds_tizen_keyrouter_create(struct wl_display *display); - -void -ds_tizen_keyrouter_add_destroy_listener(struct ds_tizen_keyrouter *keyrouter, - struct wl_listener *listener); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/libds-tizen/tbm_server.h b/include/libds-tizen/tbm_server.h deleted file mode 100644 index f1cc97d..0000000 --- a/include/libds-tizen/tbm_server.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef LIBDS_TIZEN_TBM_SERVER_H -#define LIBDS_TIZEN_TBM_SERVER_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct ds_tbm_server; - -struct ds_tbm_client_buffer; - -struct ds_tbm_server * -ds_tbm_server_create(struct wl_display *display); - -void -ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm, - struct wl_listener *listener); - -struct ds_tbm_client_buffer * -ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer); - -tbm_surface_h -ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/meson.build b/include/meson.build index 0975c5d..0c0b256 100644 --- a/include/meson.build +++ b/include/meson.build @@ -1,9 +1,3 @@ install_subdir('libds', install_dir: get_option('includedir'), ) - -if get_option('tizen') - install_subdir('libds-tizen', - install_dir: get_option('includedir'), - ) -endif diff --git a/meson_options.txt b/meson_options.txt index 1d6ff21..e69de29 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,2 +0,0 @@ -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.spec b/packaging/libds.spec index f53efa9..1a7951e 100644 --- a/packaging/libds.spec +++ b/packaging/libds.spec @@ -11,24 +11,12 @@ BuildRequires: meson 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) BuildRequires: pkgconfig(libinput) BuildRequires: pkgconfig(libudev) -BuildRequires: pkgconfig(libtdm) -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) - %description Wayland Compositor Library @@ -40,40 +28,6 @@ Requires: %{name} = %{version}-%{release} %description devel Development package of Wayland Compositor Library -%package tizen-devel -Summary: Wayland Compositor development package on Tizen - -%description tizen-devel -Wayland Compositor development library for Tizen platform - -%package tizen-keyrouter -Summary: Wayland Compositor Library for keyrouter -Group: Development/Libraries - -%description tizen-keyrouter -Wayland Compositor Library for tizen keyrouter - -%package tizen-keyrouter-devel -Summary: Keyrouter Development package for Wayland Compositor Library -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} . @@ -83,9 +37,7 @@ meson setup \ --prefix /usr \ --libdir %{_libdir} \ --bindir %{_bindir} \ - builddir \ - -Dtizen=true \ - -Dkeylayout_dir="%{TZ_SYS_RO_SHARE}/X11/xkb/tizen_key_layout.txt" + builddir ninja -C builddir all %install @@ -97,7 +49,6 @@ ninja -C builddir install %defattr(-,root,root,-) %license LICENSE %{_libdir}/libds.so.* -%{_libdir}/libds-tizen.so.* %files devel %manifest %{name}.manifest @@ -110,47 +61,4 @@ ninja -C builddir install %{_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 -%{_bindir}/tdm-backend -%{_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 -%manifest %{name}.manifest -%defattr(-,root,root,-) -%license LICENSE -%{_libdir}/libds-tizen-keyrouter.so.* - -%files tizen-keyrouter-devel -%manifest %{name}.manifest -%defattr(-,root,root,-) -%license LICENSE -%{_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/meson.build b/src/clients/meson.build index ba09b32..a09cf3e 100644 --- a/src/clients/meson.build +++ b/src/clients/meson.build @@ -9,74 +9,3 @@ executable('ds-simple-shm-shell', 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) - -if not wayland_tbm_client.found() or not libtbm.found() - subdir_done() -endif - -simple_tbm_files = ['simple-tbm.c'] -simple_tbm_deps = [ - dependency('wayland-client', required: true), - wayland_tbm_client, - libtbm, - tizen_extension_client, -] - -protocols = { - 'xdg-shell': wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml', -} - -protocols_code = {} -protocols_client_header = {} -foreach name, path : protocols - code = custom_target( - name.underscorify() + '_c', - input: path, - output: '@BASENAME@-protocol.c', - command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'], - ) - simple_tbm_files += code - - 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, - ) - simple_tbm_files += client_header -endforeach - -executable('ds-simple-tbm', - simple_tbm_files, - dependencies: simple_tbm_deps, - 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, -) - -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 deleted file mode 100644 index c82349f..0000000 --- a/src/clients/simple-tbm.c +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright © 2011 Benjamin Franzke - * Copyright © 2010 Intel Corporation - * - * 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 "xdg-shell-client-protocol.h" -#include - -static uint64_t buffer_info_key; -#define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key) - -struct display { - struct wl_display *display; - struct wl_registry *registry; - struct wl_compositor *compositor; - struct xdg_wm_base *wm_base; - struct wl_shm *shm; - 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 { - struct display *display; - int width, height; - struct wl_surface *surface; - struct xdg_surface *xdg_surface; - struct xdg_toplevel *xdg_toplevel; - struct wl_callback *callback; - tbm_surface_queue_h surface_queue; - bool wait_for_configure; -}; - -struct buffer_info { - struct window *window; - struct wl_buffer *wl_buffer; -}; - -static int running = 1; - -static void -redraw(void *data, struct wl_callback *callback, uint32_t time); - -static void -handle_xdg_surface_configure(void *data, struct xdg_surface *surface, - uint32_t serial) -{ - struct window *window = data; - - xdg_surface_ack_configure(surface, serial); - - if (window->wait_for_configure) { - redraw(window, NULL, 0); - window->wait_for_configure = false; - } -} - -static const struct xdg_surface_listener xdg_surface_listener = { - handle_xdg_surface_configure, -}; - -static void -handle_xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel, - int32_t width, int32_t height, - struct wl_array *state) -{ -} - -static void -handle_xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel) -{ - running = 0; -} - -static const struct xdg_toplevel_listener xdg_toplevel_listener = { - handle_xdg_toplevel_configure, - handle_xdg_toplevel_close, -}; - -static struct window * -create_window(struct display *display, int width, int height) -{ - struct window *window; - - window = calloc(1, sizeof *window); - if (!window) - return NULL; - - window->callback = NULL; - window->display = display; - window->width = width; - window->height = height; - window->surface = wl_compositor_create_surface(display->compositor); - - if (display->wm_base) { - window->xdg_surface = - xdg_wm_base_get_xdg_surface(display->wm_base, - window->surface); - assert(window->xdg_surface); - xdg_surface_add_listener(window->xdg_surface, - &xdg_surface_listener, window); - - window->xdg_toplevel = - xdg_surface_get_toplevel(window->xdg_surface); - assert(window->xdg_toplevel); - xdg_toplevel_add_listener(window->xdg_toplevel, - &xdg_toplevel_listener, window); - - xdg_toplevel_set_title(window->xdg_toplevel, "simple-tbm"); - wl_surface_commit(window->surface); - window->wait_for_configure = true; - } else { - assert(0); - } - - window->surface_queue = - wayland_tbm_client_create_surface_queue(display->wl_tbm, - window->surface, - 3, - width, - height, - TBM_FORMAT_XRGB8888); - assert(window->surface_queue); - - return window; -} - -static void -destroy_window(struct window *window) -{ - tbm_surface_queue_destroy(window->surface_queue); - - if (window->callback) - wl_callback_destroy(window->callback); - - if (window->xdg_toplevel) - xdg_toplevel_destroy(window->xdg_toplevel); - if (window->xdg_surface) - xdg_surface_destroy(window->xdg_surface); - wl_surface_destroy(window->surface); - free(window); -} - -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 void -buffer_info_free_cb(void *data) -{ - struct buffer_info *buffer_info = data; - - if (!buffer_info) - return; - - wayland_tbm_client_destroy_buffer(buffer_info->window->display->wl_tbm, - buffer_info->wl_buffer); - free(buffer_info); -} - -static void -buffer_handle_release(void *data, struct wl_buffer *wl_buffer) -{ - tbm_surface_h surface = data; - struct buffer_info *buffer_info; - - tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY, - (void **)&buffer_info); - if (buffer_info) - tbm_surface_queue_release(buffer_info->window->surface_queue, surface); -} - -static const struct wl_buffer_listener buffer_listener = { - .release = buffer_handle_release, -}; - -static const struct wl_callback_listener frame_listener; - -static void -redraw(void *data, struct wl_callback *callback, uint32_t time) -{ - struct window *window = data; - struct buffer_info *buffer_info = NULL; - tbm_surface_h surface = NULL; - tbm_surface_info_s surface_info; - - if (!tbm_surface_queue_can_dequeue(window->surface_queue, 0)) - return; - - tbm_surface_queue_dequeue(window->surface_queue, &surface); - assert(surface); - - tbm_surface_internal_get_user_data(surface, BUFFER_INFO_KEY, - (void **)&buffer_info); - if (!buffer_info) { - buffer_info = calloc(1, sizeof *buffer_info); - assert(buffer_info); - - tbm_surface_internal_add_user_data(surface, BUFFER_INFO_KEY, buffer_info_free_cb); - tbm_surface_internal_set_user_data(surface, BUFFER_INFO_KEY, buffer_info); - - buffer_info->wl_buffer = - wayland_tbm_client_create_buffer(window->display->wl_tbm, surface); - assert(buffer_info->wl_buffer); - - wl_buffer_add_listener(buffer_info->wl_buffer, &buffer_listener, - surface); - - buffer_info->window = window; - } - - tbm_surface_map(surface, TBM_SURF_OPTION_WRITE, &surface_info); - - paint_pixels(surface_info.planes[0].ptr, 20, - (surface_info.planes[0].stride/4), surface_info.height, time); - - tbm_surface_unmap(surface); - - wl_surface_attach(window->surface, buffer_info->wl_buffer, 0, 0); - wl_surface_damage(window->surface, - 20, 20, window->width - 40, window->height - 40); - - if (callback) - wl_callback_destroy(callback); - - window->callback = wl_surface_frame(window->surface); - wl_callback_add_listener(window->callback, &frame_listener, window); - wl_surface_commit(window->surface); -} - -static const struct wl_callback_listener frame_listener = { - redraw -}; - -static void -shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) -{ - struct display *d = data; - - if (format == WL_SHM_FORMAT_XRGB8888) - d->has_xrgb = true; -} - -struct wl_shm_listener shm_listener = { - shm_format -}; - -static void -xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial) -{ - xdg_wm_base_pong(shell, serial); -} - -static const struct xdg_wm_base_listener xdg_wm_base_listener = { - xdg_wm_base_ping, -}; - -static void pointer_handle_button(void *data, struct wl_pointer *pointer, - uint32_t serial, uint32_t time, uint32_t button, uint32_t state) -{ - if (state == WL_POINTER_BUTTON_STATE_PRESSED) { - fprintf(stderr, "pointer_handle_button: PRESSED\n"); - } - else { - fprintf(stderr, "pointer_handle_button: RELEASED\n"); - } -} - -static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t surface_x, wl_fixed_t surface_y) -{ - fprintf(stderr, "pointer_handle_enter surface_x:%d, surface_y:%d\n", - wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); -} - -static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, - uint32_t serial, struct wl_surface *surface) -{ - fprintf(stderr, "pointer_handle_leave\n"); -} - -static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, - uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) -{ - fprintf(stderr, "pointer_handle_motion surface_x:%d, surface_y:%d\n", - wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y)); -} - -static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) -{ - fprintf(stderr, "pointer_handle_frame\n"); -} - -static struct wl_pointer_listener pointer_listener = { - .enter = pointer_handle_enter, - .leave = pointer_handle_leave, - .motion = pointer_handle_motion, - .button = pointer_handle_button, - .axis = NULL, - .frame = pointer_handle_frame, - .axis_source = NULL, - .axis_stop = NULL, - .axis_discrete = NULL, -}; - -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 x, wl_fixed_t y) -{ - 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, - uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) -{ - fprintf(stderr, "touch_handle_motion id:%d, x:%d, y:%d\n", - id, wl_fixed_to_int(x), wl_fixed_to_int(y)); -} - -static void touch_handle_frame(void *data, struct wl_touch *wl_touch) -{ - fprintf(stderr, "touch_handle_frame\n"); -} - -static struct wl_touch_listener touch_listener = { - .down = touch_handle_down, - .up = touch_handle_up, - .motion = touch_handle_motion, - .frame = touch_handle_frame, - .cancel = NULL, - .shape = NULL, - .orientation = NULL, -}; - -static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, - uint32_t format, int32_t fd, uint32_t size) -{ - fprintf(stderr, "keyboard_handle_keymap\n"); -} -static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface, struct wl_array *keys) -{ - fprintf(stderr, "keyboard_handle_enter\n"); -} -static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, struct wl_surface *surface) -{ - fprintf(stderr, "keyboard_handle_leave\n"); -} -static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, - uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) -{ - fprintf(stderr, "keyboard_handle_modifiers\n"); -} -static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, - int32_t rate, int32_t delay) -{ - fprintf(stderr, "keyboard_handle_repeat_info\n"); -} - -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: key:%d, PRESSED\n", key); - } else { - fprintf(stderr, "keyboard_handle_key: key:%d, RELEASED\n", key); - } -} - -static struct wl_keyboard_listener 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 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); - fprintf(stderr, "seat_handle_capabilities: keyboard\n"); - } - if ((caps & WL_SEAT_CAPABILITY_POINTER)) { - struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat); - wl_pointer_add_listener(pointer, &pointer_listener, NULL); - fprintf(stderr, "seat_handle_capabilities: pointer\n"); - } - if ((caps & WL_SEAT_CAPABILITY_TOUCH)) { - struct wl_touch *touch = wl_seat_get_touch(wl_seat); - wl_touch_add_listener(touch, &touch_listener, d); - fprintf(stderr, "seat_handle_capabilities: touch\n"); - } -} - -static void seat_handle_name(void *data, struct wl_seat *wl_seat, - const char *name) -{ - fprintf(stderr, "seat_handle_name name:%s\n", name); -} - -const struct wl_seat_listener seat_listener = { - .capabilities = seat_handle_capabilities, - .name = seat_handle_name, -}; - -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) -{ - struct display *d = data; - - if (strcmp(interface, "wl_compositor") == 0) { - d->compositor = - wl_registry_bind(registry, - id, &wl_compositor_interface, 1); - } else if (strcmp(interface, "xdg_wm_base") == 0) { - d->wm_base = wl_registry_bind(registry, - id, &xdg_wm_base_interface, 1); - xdg_wm_base_add_listener(d->wm_base, &xdg_wm_base_listener, d); - } else if (strcmp(interface, "wl_shm") == 0) { - d->shm = wl_registry_bind(registry, - id, &wl_shm_interface, 1); - wl_shm_add_listener(d->shm, &shm_listener, d); - } else if (strcmp(interface, "wl_seat") == 0) { - d->seat = wl_registry_bind(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 -registry_handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) -{ -} - -static const struct wl_registry_listener registry_listener = { - registry_handle_global, - registry_handle_global_remove -}; - -static struct display * -create_display(void) -{ - struct display *display; - - display = calloc(1, sizeof *display); - if (display == NULL) { - fprintf(stderr, "out of memory\n"); - exit(1); - } - display->display = wl_display_connect(NULL); - assert(display->display); - - display->has_xrgb = false; - display->registry = wl_display_get_registry(display->display); - wl_registry_add_listener(display->registry, - ®istry_listener, display); - wl_display_roundtrip(display->display); - if (display->shm == NULL) { - fprintf(stderr, "No wl_shm global\n"); - exit(1); - } - - wl_display_roundtrip(display->display); - - /* - * Why do we need two roundtrips here? - * - * wl_display_get_registry() sends a request to the server, to which - * the server replies by emitting the wl_registry.global events. - * The first wl_display_roundtrip() sends wl_display.sync. The server - * first processes the wl_display.get_registry which includes sending - * the global events, and then processes the sync. Therefore when the - * sync (roundtrip) returns, we are guaranteed to have received and - * processed all the global events. - * - * While we are inside the first wl_display_roundtrip(), incoming - * events are dispatched, which causes registry_handle_global() to - * be called for each global. One of these globals is wl_shm. - * registry_handle_global() sends wl_registry.bind request for the - * wl_shm global. However, wl_registry.bind request is sent after - * the first wl_display.sync, so the reply to the sync comes before - * the initial events of the wl_shm object. - * - * The initial events that get sent as a reply to binding to wl_shm - * include wl_shm.format. These tell us which pixel formats are - * supported, and we need them before we can create buffers. They - * don't change at runtime, so we receive them as part of init. - * - * When the reply to the first sync comes, the server may or may not - * have sent the initial wl_shm events. Therefore we need the second - * wl_display_roundtrip() call here. - * - * The server processes the wl_registry.bind for wl_shm first, and - * the second wl_display.sync next. During our second call to - * wl_display_roundtrip() the initial wl_shm events are received and - * processed. Finally, when the reply to the second wl_display.sync - * arrives, it guarantees we have processed all wl_shm initial events. - * - * This sequence contains two examples on how wl_display_roundtrip() - * can be used to guarantee, that all reply events to a request - * have been received and processed. This is a general Wayland - * technique. - */ - - if (!display->has_xrgb) { - fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n"); - exit(1); - } - - display->wl_tbm = wayland_tbm_client_init(display->display); - if (!display->wl_tbm) { - fprintf(stderr, "failed wayland_tbm_client_init()\n"); - 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); - - if (display->wm_base) - xdg_wm_base_destroy(display->wm_base); - - if (display->compositor) - wl_compositor_destroy(display->compositor); - - wayland_tbm_client_deinit(display->wl_tbm); - wl_registry_destroy(display->registry); - wl_display_flush(display->display); - wl_display_disconnect(display->display); - free(display); -} - -static void -signal_int(int signum) -{ - running = 0; -} - -int -main(int argc, char **argv) -{ - struct sigaction sigint; - struct display *display; - struct window *window; - int ret = 0; - - display = create_display(); - window = create_window(display, 250, 250); - if (!window) - return 1; - - sigint.sa_handler = signal_int; - sigemptyset(&sigint.sa_mask); - sigint.sa_flags = SA_RESETHAND; - sigaction(SIGINT, &sigint, NULL); - - /* Initialise damage to full surface, so the padding gets painted */ - wl_surface_damage(window->surface, 0, 0, - window->width, window->height); - - if (!window->wait_for_configure) - redraw(window, NULL, 0); - - while (running && ret != -1) - ret = wl_display_dispatch(display->display); - - fprintf(stderr, "simple-shm exiting\n"); - - destroy_window(window); - destroy_display(display); - - return 0; -} diff --git a/src/examples/meson.build b/src/examples/meson.build index eb9ae29..87d8654 100644 --- a/src/examples/meson.build +++ b/src/examples/meson.build @@ -4,10 +4,11 @@ common_deps = [ ] executable('wl-backend', - 'wl-backend.c', - dependencies: common_deps, - install_dir: libds_bindir, - install : true) + 'wl-backend.c', + dependencies: common_deps, + install_dir: libds_bindir, + install : true +) executable('tinyds', [ @@ -30,70 +31,12 @@ executable('input-device-test', ], 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 - ) + 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 +executable('libinput-backend', + 'libinput-backend.c', + dependencies: common_deps, + install_dir: libds_bindir, + install : true +) diff --git a/src/examples/tdm-backend.c b/src/examples/tdm-backend.c deleted file mode 100644 index ba3fecb..0000000 --- a/src/examples/tdm-backend.c +++ /dev/null @@ -1,247 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define WIDTH 1280 -#define HEIGHT 720 - -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 wl_event_source *stdin_source; - - struct wl_listener new_output; - struct wl_listener output_destroy; - struct wl_listener output_frame; - - 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); -static int stdin_dispatch(int fd, uint32_t mask, void *data); - -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); - - ds_backend_start(server->backend); - - draw_output(server); - - struct wl_event_loop *loop = wl_display_get_event_loop(display); - server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO, - WL_EVENT_READABLE, stdin_dispatch, server); - - wl_display_run(display); - - fini_server(server); - wl_display_destroy(display); - return 0; -} - -static void -backend_handle_new_output(struct wl_listener *listener, void *data) -{ - struct server *server; - struct ds_output *output; - - server = wl_container_of(listener, server, new_output); - output = data; - ds_inf("New output(%p)", output); - - - if (server->output) - return; - - server->output = output; - - server->output_destroy.notify = output_handle_destroy; - ds_output_add_destroy_listener(server->output, - &server->output_destroy); - - server->output_frame.notify = output_handle_frame; - ds_output_add_frame_listener(server->output, - &server->output_frame); -} - -static void -init_server(struct server *server, struct wl_display *display) -{ - server->display = display; - server->front_buffer = NULL; - - server->backend = ds_tdm_backend_create(display); - assert(server->backend); - - server->new_output.notify = backend_handle_new_output; - ds_backend_add_new_output_listener(server->backend, - &server->new_output); - - server->allocator = ds_tbm_allocator_create(); - assert(server->allocator); - - server->swapchain = ds_swapchain_create(server->allocator, - server->width, server->height, WL_SHM_FORMAT_XRGB8888); - assert(server->swapchain); -} - -static void -fini_server(struct server *server) -{ - wl_list_remove(&server->new_output.link); - wl_list_remove(&server->output_destroy.link); - wl_list_remove(&server->output_frame.link); - if (server->front_buffer) - ds_buffer_unlock(server->front_buffer); - ds_swapchain_destroy(server->swapchain); - ds_allocator_destroy(server->allocator); -} - -static void -output_handle_destroy(struct wl_listener *listener, - void *data __attribute__((unused))) -{ - struct server *server = - wl_container_of(listener, server, output_destroy); - wl_display_terminate(server->display); -} - -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_frame(struct wl_listener *listener, - void *data __attribute__((unused))) -{ - struct server *server = - wl_container_of(listener, server, 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; -} - -static int -stdin_dispatch(int fd, uint32_t mask, void *data) -{ - struct server *server = data; - - wl_display_terminate(server->display); - - return 1; -} diff --git a/src/examples/tinyds-tdm-libinput.c b/src/examples/tinyds-tdm-libinput.c deleted file mode 100644 index 5634707..0000000 --- a/src/examples/tinyds-tdm-libinput.c +++ /dev/null @@ -1,1125 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#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_keyboard; - -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_server -{ - struct ds_tbm_server *tbm_server; - - struct wl_display *display; - - struct ds_backend *backend; - struct ds_backend *input_backend; - struct ds_compositor *compositor; - struct ds_xdg_shell *xdg_shell; - 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; - - struct wl_list views; - - struct wl_listener new_output; - struct wl_listener new_input; - struct wl_listener new_xdg_surface; - - struct tinyds_keyboard *keyboard; -}; - -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_pointer -{ - struct ds_input_device *dev; - struct tinyds_server *server; - - struct tinyds_view *focused_view; - - struct wl_listener destroy; - struct wl_listener motion; //relative - 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_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 server_add_keyboard(struct tinyds_server *server, - struct ds_input_device *dev); -static void server_add_pointer(struct tinyds_server *server, - struct ds_input_device *dev); -static void server_add_touch(struct tinyds_server *server, - struct ds_input_device *dev); - -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); - ds_backend_start(server->input_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; - 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 -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 void -backend_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); - server->seat_caps |= WL_SEAT_CAPABILITY_KEYBOARD; - break; - case DS_INPUT_DEVICE_TOUCH: - server_add_touch(server, dev); - server->seat_caps |= WL_SEAT_CAPABILITY_TOUCH; - break; - case DS_INPUT_DEVICE_POINTER: - server_add_pointer(server, dev); - server->seat_caps |= WL_SEAT_CAPABILITY_POINTER; - break; - default: - ds_err("Unknown type(%d) of ds_input_device", dev_type); - break; - } - - 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) -{ - 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->input_backend = ds_libinput_backend_create(display); - 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, - &server->new_output); - - server->new_input.notify = backend_handle_new_input; - ds_backend_add_new_input_listener(server->input_backend, &server->new_input); - - server->compositor = ds_compositor_create(display); - if (!server->compositor) - goto err; - - server->tbm_server = ds_tbm_server_create(display); - if (!server->tbm_server) - 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; - 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: - ds_backend_destroy(server->backend); - ds_backend_destroy(server->input_backend); - - return false; -} - -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 -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); - - 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); - - ds_inf("Keyboard(%p) event key: keycode(%d), state(%d), time_msec(%d), " - "update_state(%d)", kbd->dev, - event->keycode, event->state, event->time_msec, - event->update_state); - - 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); - - 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); -} - -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 <= x + w && ly >= y && ly <= y + h) { - *sx = lx - x; - *sy = ly - y; - - return view; - } - } - - return NULL; -} - -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) -{ - struct ds_event_touch_down *event = data; - struct tinyds_touch *touch; - struct tinyds_view *view; - struct tinyds_server *server; - double sx = 0.f, sy = 0.f; - - touch = wl_container_of(listener, touch, down); - - server = touch->server; - server->output_x = event->x * server->output->width; - server->output_y = event->y * server->output->height; - - ds_inf("Touch(%p) event down: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f", - touch->dev, event->id, event->x, event->y, server->output_x, server->output_y); - - view = server_view_at(server, server->output_x, server->output_y, &sx, &sy); - - if (view) { - ds_seat_touch_notify_down(touch->server->seat, ds_xdg_surface_get_surface(view->xdg_surface), - event->time_msec, event->id, sx, sy); - } -} - -static void -touch_handle_up(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_up *event = data; - struct tinyds_touch *touch; - - touch = wl_container_of(listener, touch, up); - - ds_inf("Touch(%p) event up: id(%d) time_msec(%d)", - touch->dev, event->id, event->time_msec); - - ds_seat_touch_notify_up(touch->server->seat, event->time_msec, event->id); -} - -static void -touch_handle_motion(struct wl_listener *listener, void *data) -{ - struct ds_event_touch_motion *event = data; - struct tinyds_touch *touch; - struct tinyds_view *view; - struct tinyds_server *server; - double sx = 0.f, sy = 0.f; - - touch = wl_container_of(listener, touch, motion); - - server = touch->server; - server->output_x = event->x * server->output->width; - server->output_y = event->y * server->output->height; - - ds_inf("Touch(%p) event motion: id(%d) x %.3f y %.3f output_x %.1f output_y %.1f", - touch->dev, event->id, event->x, event->y, server->output_x, server->output_y); - - view = server_view_at(server, server->output_x, server->output_y, &sx, &sy); - - if (view) { - ds_seat_touch_notify_motion(server->seat, event->time_msec, - event->id, sx, sy); - } -} - -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->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; - struct ds_event_pointer_motion *event = data; - struct tinyds_view *view; - struct tinyds_server *server; - int ow = 0, oh = 0; - double sx, sy; - - pointer = wl_container_of(listener, pointer, motion); - - server = pointer->server; - if (server->output) { - ow = server->output->width; - oh = server->output->height; - } - - if (server->output_x + event->delta_x >= ow) - server->output_x = ow; - else if(server->output_x + event->delta_x <= 0.f) - server->output_x = 0.f; - else - server->output_x = server->output_x + event->delta_x ; - if (server->output_y + event->delta_y >= oh) - server->output_y = oh; - else if(server->output_y + event->delta_y <= 0.f) - server->output_y = 0.f; - else - server->output_y = server->output_y + event->delta_y ; - - ds_inf("Pointer(%p) motion: (delta_x %.1f delta_y %.1f) output_x %.1f output_y %.1f", - pointer, event->delta_x, event->delta_y, server->output_x, server->output_y); - - view = server_view_at(pointer->server, server->output_x, server->output_y, &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); - - ds_seat_pointer_notify_button(pointer->server->seat, event->time_msec, event->button, event->state); -} - -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; - server->output_x = 200; - server->output_y = 200; - - 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->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); -} diff --git a/src/examples/tinyds-tdm-renderer.c b/src/examples/tinyds-tdm-renderer.c deleted file mode 100644 index 0074dc9..0000000 --- a/src/examples/tinyds-tdm-renderer.c +++ /dev/null @@ -1,187 +0,0 @@ -#include -#include - -#include - -#include "pixman-helper.h" -#include "pixman-tbm-helper.h" -#include "tinyds-tdm-renderer.h" - -static void renderer_setup_thread(struct tinyds_renderer *renderer); -static void *renderer_thread_func(void *data); -static void texture_destroy(struct tinyds_texture *texture); - -bool -init_renderer(struct tinyds_renderer *renderer) -{ - renderer->damaged = false; - - wl_list_init(&renderer->textures); - - renderer_setup_thread(renderer); - - return true; -} - -void -fini_renderer(struct tinyds_renderer *renderer) -{ - pthread_mutex_lock(&renderer->mutex); - - renderer->destroying = true; - pthread_cond_signal(&renderer->cond); - - pthread_mutex_unlock(&renderer->mutex); - - pthread_join(renderer->worker_thread, NULL); - - pthread_mutex_destroy(&renderer->mutex); - pthread_cond_destroy(&renderer->cond); -} - -void -renderer_set_surface_queue(struct tinyds_renderer *renderer, - void *surface_queue) -{ - pthread_mutex_lock(&renderer->mutex); - - renderer->surface_queue = (tbm_surface_queue_h)surface_queue; - - pthread_mutex_unlock(&renderer->mutex); -} - -void -renderer_set_bg_color(struct tinyds_renderer *renderer, - uint8_t r, uint8_t g, uint8_t b) -{ - pixman_color_t color; - - pthread_mutex_lock(&renderer->mutex); - - color_rgb888(&color, r, g, b); - - renderer->bg_image = pixman_image_create_solid_fill(&color); - assert(renderer->bg_image); - - renderer->damaged = true; - - pthread_mutex_unlock(&renderer->mutex); -} - -void -renderer_add_texture(struct tinyds_renderer *renderer, - tbm_surface_h tbm_surface, int x, int y) -{ - struct tinyds_texture *texture; - - pthread_mutex_lock(&renderer->mutex); - - texture = calloc(1, sizeof *texture); - - texture->x = x; - texture->y = y; - texture->renderer = renderer; - texture->surface = tbm_surface; - texture->image = pixman_image_from_tbm_surface(tbm_surface, - DS_BUFFER_DATA_PTR_ACCESS_READ); - - wl_list_insert(renderer->textures.prev, &texture->link); - - ds_dbg("Add texture(%p)", texture); - - pthread_mutex_unlock(&renderer->mutex); -} - -void -renderer_draw(struct tinyds_renderer *renderer) -{ - pthread_mutex_lock(&renderer->mutex); - - renderer->damaged = true; - pthread_cond_signal(&renderer->cond); - - pthread_mutex_unlock(&renderer->mutex); -} - -static void -renderer_setup_thread(struct tinyds_renderer *renderer) -{ - pthread_mutex_init(&renderer->mutex, NULL); - pthread_cond_init(&renderer->cond, NULL); - pthread_create(&renderer->worker_thread, NULL, - renderer_thread_func, renderer); -} - -static void * -renderer_thread_func(void *data) -{ - struct tinyds_renderer *renderer = data; - struct tinyds_texture *texture, *texture_tmp; - pixman_image_t *dst_image; - tbm_surface_h surface; - tbm_surface_queue_error_e err; - - pthread_mutex_lock(&renderer->mutex); - - while (!renderer->destroying) { - if (!renderer->damaged) - pthread_cond_wait(&renderer->cond, &renderer->mutex); - - if (!renderer->damaged) - continue; - - if (!tbm_surface_queue_can_dequeue(renderer->surface_queue, 0)) - continue; - - ds_dbg(">> BEGIN DRAW"); - - err = tbm_surface_queue_dequeue(renderer->surface_queue, &surface); - assert(err == TBM_SURFACE_QUEUE_ERROR_NONE); - - dst_image = pixman_image_from_tbm_surface(surface, - DS_BUFFER_DATA_PTR_ACCESS_WRITE); - - if (renderer->bg_image) { - pixman_image_composite32(PIXMAN_OP_SRC, - renderer->bg_image, - NULL, - dst_image, - 0, 0, 0, 0, 0, 0, - pixman_image_get_width(dst_image), - pixman_image_get_height(dst_image)); - } - - wl_list_for_each_safe(texture, texture_tmp, &renderer->textures, link) { - ds_dbg("Draw texture(%p)", texture); - pixman_image_composite32(PIXMAN_OP_OVER, - texture->image, - NULL, - dst_image, - 0, 0, 0, 0, - texture->x, texture->y, - pixman_image_get_width(texture->image), - pixman_image_get_height(texture->image)); - texture_destroy(texture); - } - pixman_image_unref(dst_image); - - err = tbm_surface_queue_enqueue(renderer->surface_queue, surface); - assert(err == TBM_SURFACE_QUEUE_ERROR_NONE); - - renderer->damaged = false; - - ds_dbg("<< END DRAW"); - } - - pthread_mutex_unlock(&renderer->mutex); - - return NULL; -} - -static void -texture_destroy(struct tinyds_texture *texture) -{ - pixman_image_unref(texture->image); - wl_list_remove(&texture->link); - free(texture); -} diff --git a/src/examples/tinyds-tdm-renderer.h b/src/examples/tinyds-tdm-renderer.h deleted file mode 100644 index 5f3e6fd..0000000 --- a/src/examples/tinyds-tdm-renderer.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef EXAMPLES_TINYDS_TDM_RENDERER_H -#define EXAMPLES_TINYDS_TDM_RENDERER_H - -#include -#include -#include -#include -#include - -struct tinyds_renderer -{ - tbm_surface_queue_h surface_queue; - - struct wl_list textures; - - pthread_t worker_thread; - pthread_mutex_t mutex; - pthread_cond_t cond; - - pixman_image_t *bg_image; - - bool damaged; - bool destroying; -}; - -struct tinyds_texture -{ - struct tinyds_renderer *renderer; - pixman_image_t *image; - tbm_surface_h surface; - - struct wl_list link; - struct wl_listener buffer_destroy; - - int x, y; -}; - -bool init_renderer(struct tinyds_renderer *renderer); -void fini_renderer(struct tinyds_renderer *renderer); -void renderer_set_surface_queue(struct tinyds_renderer *renderer, - void *surface_queue); -void renderer_set_bg_color(struct tinyds_renderer *renderer, - uint8_t r, uint8_t g, uint8_t b); -void renderer_add_texture(struct tinyds_renderer *renderer, - tbm_surface_h tbm_surface, int x, int y); -void renderer_draw(struct tinyds_renderer *renderer); - -#endif diff --git a/src/examples/tinyds-tdm.c b/src/examples/tinyds-tdm.c deleted file mode 100644 index 4bc08f1..0000000 --- a/src/examples/tinyds-tdm.c +++ /dev/null @@ -1,575 +0,0 @@ -#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_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 - - 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 - -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 -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_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; -} diff --git a/src/libds-tizen/allocator/meson.build b/src/libds-tizen/allocator/meson.build deleted file mode 100644 index fe869bd..0000000 --- a/src/libds-tizen/allocator/meson.build +++ /dev/null @@ -1,2 +0,0 @@ -libds_tizen_files += files('tbm.c') -libds_tizen_deps += dependency('libtbm', required: true) diff --git a/src/libds-tizen/allocator/tbm.c b/src/libds-tizen/allocator/tbm.c deleted file mode 100644 index dc3be42..0000000 --- a/src/libds-tizen/allocator/tbm.c +++ /dev/null @@ -1,177 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -#include "libds/interfaces/allocator.h" -#include "libds/interfaces/buffer.h" -#include "libds/log.h" - -struct ds_tbm_allocator -{ - struct ds_allocator base; - tbm_bufmgr bufmgr; -}; - -struct ds_tbm_buffer -{ - struct ds_buffer base; - tbm_surface_h surface; -}; - -static const struct ds_allocator_interface tbm_allocator_iface; -static struct ds_tbm_buffer *tbm_buffer_from_buffer(struct ds_buffer *buffer); - -WL_EXPORT struct ds_allocator * -ds_tbm_allocator_create(void) -{ - struct ds_tbm_allocator *alloc; - - alloc = calloc(1, sizeof *alloc); - if (!alloc) - return NULL; - - alloc->bufmgr = tbm_bufmgr_init(-1); - if (!alloc->bufmgr) { - ds_err("Could not initialize tbm_bufmgr"); - free(alloc); - return NULL; - } - - ds_allocator_init(&alloc->base, &tbm_allocator_iface, - DS_BUFFER_CAP_DATA_PTR); - - ds_inf("TBM allocator(%p) created", alloc); - - return &alloc->base; -} - -WL_EXPORT void * -ds_tbm_buffer_get_surface(struct ds_buffer *ds_buffer) -{ - struct ds_tbm_buffer *buffer; - - buffer = tbm_buffer_from_buffer(ds_buffer); - if (!buffer) - return NULL; - - return buffer->surface; -} - -static struct ds_tbm_allocator * -tbm_allocator_from_allocator(struct ds_allocator *ds_allocator) -{ - assert(ds_allocator->iface == &tbm_allocator_iface); - return (struct ds_tbm_allocator *)ds_allocator; -} - -static const struct ds_buffer_interface tbm_buffer_iface; - -static struct ds_tbm_buffer * -tbm_buffer_from_buffer(struct ds_buffer *buffer) -{ - assert(buffer->iface == &tbm_buffer_iface); - return (struct ds_tbm_buffer *)buffer; -} - -static void -tbm_buffer_destroy(struct ds_buffer *ds_buffer) -{ - struct ds_tbm_buffer *buffer; - - buffer = tbm_buffer_from_buffer(ds_buffer); - - ds_dbg("Destroy tbm buffer(%p)", buffer); - - tbm_surface_destroy(buffer->surface); - free(buffer); -} - -static bool -tbm_buffer_begin_data_ptr_access(struct ds_buffer *ds_buffer, uint32_t flags, - void **data, uint32_t *format, size_t *stride) -{ - struct ds_tbm_buffer *buffer; - tbm_surface_info_s info; - int tbm_access_flags = 0; - int ret; - - buffer = tbm_buffer_from_buffer(ds_buffer); - - if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ) - tbm_access_flags |= TBM_OPTION_READ; - else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE) - tbm_access_flags |= TBM_OPTION_WRITE; - - ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info); - if (ret != TBM_SURFACE_ERROR_NONE) { - ds_err("Could not map tbm_surface of buffer(%p)", buffer); - return false; - } - - *data = info.planes[0].ptr; - *format = info.format; - *stride = info.planes[0].stride; - - return true; -} - -static void -tbm_buffer_end_data_ptr_access(struct ds_buffer *ds_buffer) -{ - struct ds_tbm_buffer *buffer; - - buffer = tbm_buffer_from_buffer(ds_buffer); - - tbm_surface_unmap(buffer->surface); -} - -static const struct ds_buffer_interface tbm_buffer_iface = -{ - .destroy = tbm_buffer_destroy, - .begin_data_ptr_access = tbm_buffer_begin_data_ptr_access, - .end_data_ptr_access = tbm_buffer_end_data_ptr_access, -}; - -static void -tbm_allocator_destroy(struct ds_allocator *ds_allocator) -{ - struct ds_tbm_allocator *alloc; - - alloc = tbm_allocator_from_allocator(ds_allocator); - - ds_inf("Destroy TBM allocator(%p)", alloc); - - tbm_bufmgr_deinit(alloc->bufmgr); - free(alloc); -} - -static struct ds_buffer * -tbm_allocator_create_buffer(struct ds_allocator *ds_allocator, - int width, int height, uint32_t format) -{ - static int num_buffers = 0; - struct ds_tbm_buffer *buffer; - - buffer = calloc(1, sizeof *buffer); - if (!buffer) - return NULL; - - ds_buffer_init(&buffer->base, &tbm_buffer_iface, width, height); - - buffer->surface = tbm_surface_create(width, height, TBM_FORMAT_XRGB8888); - - ds_dbg("tbm buffer(%p) created: size(%dx%d) number of buffers: %d", - buffer, width, height, ++num_buffers); - - return &buffer->base; -} - -static const struct ds_allocator_interface tbm_allocator_iface = -{ - .destroy = tbm_allocator_destroy, - .create_buffer = tbm_allocator_create_buffer, -}; diff --git a/src/libds-tizen/backend/meson.build b/src/libds-tizen/backend/meson.build deleted file mode 100644 index 8a05e13..0000000 --- a/src/libds-tizen/backend/meson.build +++ /dev/null @@ -1 +0,0 @@ -subdir('tdm') diff --git a/src/libds-tizen/backend/tdm/backend.c b/src/libds-tizen/backend/tdm/backend.c deleted file mode 100644 index 21fb025..0000000 --- a/src/libds-tizen/backend/tdm/backend.c +++ /dev/null @@ -1,176 +0,0 @@ -#include -#include - -#include "libds/log.h" - -#include "tdm.h" - -static const struct ds_backend_interface tdm_backend_iface; - -static void tdm_backend_handle_display_destroy(struct wl_listener *listener, - void *data); -static void tdm_backend_destroy(struct ds_tdm_backend *tdm); -static int tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data); - -WL_EXPORT struct ds_backend * -ds_tdm_backend_create(struct wl_display *display) -{ - struct ds_tdm_backend *tdm; - struct wl_event_loop *loop; - tdm_error err; - - ds_inf("Initializing TDM backend"); - - tdm = calloc(1, sizeof *tdm); - if (!tdm) - return NULL; - - ds_backend_init(&tdm->base, display, &tdm_backend_iface); - - tdm->wl_display = display; - tdm->clock = CLOCK_MONOTONIC; // FIXME - - wl_list_init(&tdm->outputs); - wl_list_init(&tdm->buffers); - - tdm->tdm_display = tdm_display_init(&err); - if (err != TDM_ERROR_NONE) { - ds_err("Could not initialize tdm_display"); - goto err_display; - } - - err = tdm_display_get_fd(tdm->tdm_display, &tdm->fd); - if (err != TDM_ERROR_NONE || tdm->fd < 0) { - ds_err("Could not get fd from tdm_display: err(%d)", err); - goto err_fd; - } - - loop = wl_display_get_event_loop(display); - tdm->tdm_event = wl_event_loop_add_fd(loop, tdm->fd, WL_EVENT_READABLE, - tdm_backend_handle_tdm_event, tdm); - if (!tdm->tdm_event) { - ds_err("could not add fd event handler for tdm event"); - goto err_event; - } - - tdm->display_destroy.notify = tdm_backend_handle_display_destroy; - wl_display_add_destroy_listener(display, &tdm->display_destroy); - - return &tdm->base; - -err_event: - close(tdm->fd); -err_fd: - tdm_display_deinit(tdm->tdm_display); -err_display: - free(tdm); - - return NULL; -} - -struct ds_tdm_backend * -tdm_backend_from_backend(struct ds_backend *backend) -{ - assert(backend->iface == &tdm_backend_iface); - return (struct ds_tdm_backend *)backend; -} - -static void -tdm_backend_destroy(struct ds_tdm_backend *tdm) -{ - struct ds_tdm_output *output, *tmp_output; - struct ds_tdm_buffer *buffer, *tmp_buffer; - - wl_list_for_each_safe(output, tmp_output, &tdm->outputs, link) - ds_output_destroy(&output->base); - - wl_list_for_each_safe(buffer, tmp_buffer, &tdm->buffers, link) - destroy_tdm_buffer(buffer); - - wl_list_remove(&tdm->display_destroy.link); - wl_event_source_remove(tdm->tdm_event); - close(tdm->fd); - tdm_display_deinit(tdm->tdm_display); - ds_backend_finish(&tdm->base); - free(tdm); -} - -static bool -tdm_backend_scan_outputs(struct ds_tdm_backend *tdm) -{ - struct ds_tdm_output *output; - tdm_output *tdm_output; - tdm_error err; - int num_outputs, i; - - err = tdm_display_get_output_count(tdm->tdm_display, &num_outputs); - if (err != TDM_ERROR_NONE) { - ds_err("Could not get number of outputs: err(%d)", err); - return false; - } - - for (i = 0; i < num_outputs; i++) { - tdm_output = tdm_display_get_output(tdm->tdm_display, i, &err); - if (err != TDM_ERROR_NONE || !tdm_output) { - ds_err("Could not get output from tdm_display: index(%d) err(%d)", - i, err); - continue; - } - - output = create_tdm_output(tdm, tdm_output); - if (!output) { - ds_err("Could not create output: index(%d)", i); - continue; - } - - wl_list_insert(&tdm->outputs, &output->link); - - wl_signal_emit(&tdm->base.events.new_output, &output->base); - } - - return true; -} - -static bool -tdm_backend_iface_start(struct ds_backend *backend) -{ - struct ds_tdm_backend *tdm; - - tdm = tdm_backend_from_backend(backend); - return tdm_backend_scan_outputs(tdm); -} - -static void -tdm_backend_iface_destroy(struct ds_backend *backend) -{ - struct ds_tdm_backend *tdm; - - tdm = tdm_backend_from_backend(backend); - tdm_backend_destroy(tdm); -} - -static const struct ds_backend_interface tdm_backend_iface = -{ - .start = tdm_backend_iface_start, - .destroy = tdm_backend_iface_destroy, - .get_drm_fd = NULL, -}; - -static void -tdm_backend_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_tdm_backend *tdm; - - tdm = wl_container_of(listener, tdm, display_destroy); - tdm_backend_destroy(tdm); -} - -static int -tdm_backend_handle_tdm_event(int fd, uint32_t mask, void *data) -{ - struct ds_tdm_backend *tdm = data; - - tdm_display_handle_events(tdm->tdm_display); - - return 0; -} diff --git a/src/libds-tizen/backend/tdm/meson.build b/src/libds-tizen/backend/tdm/meson.build deleted file mode 100644 index 932559f..0000000 --- a/src/libds-tizen/backend/tdm/meson.build +++ /dev/null @@ -1,13 +0,0 @@ -libds_tizen_files += files( - 'backend.c', - 'output.c', - 'tdm_buffer_queue.c', -) - -libtdm = dependency('libtdm', required: true) -libtbm = dependency('libtbm', required: true) - -libds_tizen_deps += [ - libtdm, - libtbm -] diff --git a/src/libds-tizen/backend/tdm/output.c b/src/libds-tizen/backend/tdm/output.c deleted file mode 100644 index 10b9666..0000000 --- a/src/libds-tizen/backend/tdm/output.c +++ /dev/null @@ -1,425 +0,0 @@ -#include -#include - -#include - -#include "libds/log.h" -#include "libds-tizen/allocator/tbm.h" - -#include "tdm.h" -#include "tdm_buffer_queue.h" - -static const struct ds_output_interface tdm_output_iface; -static bool output_init_modes(struct ds_tdm_output *output); -static void output_destroy(struct ds_tdm_output *output); -static void output_init_hwc(struct ds_tdm_output *output); -static bool output_update_mode(struct ds_tdm_output *output); -static bool output_set_pending_fb(struct ds_tdm_output *output, - struct ds_buffer *ds_buffer); -static bool output_hwc_commit(struct ds_tdm_output *output); - -WL_EXPORT struct ds_tdm_output * -ds_tdm_output_from_output(struct ds_output *ds_output) -{ - if (ds_output->iface != &tdm_output_iface) { - ds_err("Given ds_output is not for ds_tdm_output"); - return NULL; - } - - return (struct ds_tdm_output *)ds_output; -} - -WL_EXPORT struct ds_tdm_buffer_queue * -ds_tdm_output_get_buffer_queue(struct ds_tdm_output *output) -{ - if (output->queue) - return output->queue; - - output->queue = create_buffer_queue(output); - if (!output->queue) { - ds_err("Could not create tbm_queue with output(%p)", output); - return NULL; - } - - return output->queue; -} - -struct ds_tdm_output * -create_tdm_output(struct ds_tdm_backend *tdm, tdm_output *tdm_output) -{ - struct ds_tdm_output *output; - tdm_output_conn_status conn; - tdm_error err; - - output = calloc(1, sizeof *output); - if (!output) - return NULL; - - ds_output_init(&output->base, &tdm->base, &tdm_output_iface, - tdm->wl_display); - - output->backend = tdm; - output->tdm.output = tdm_output; - - err = tdm_output_get_conn_status(tdm_output, &conn); - if (err != TDM_ERROR_NONE) { - ds_err("Could not get connection status of tdm output(%p): err(%d)", - tdm_output, err); - goto err_status; - } - - if (conn == TDM_OUTPUT_CONN_STATUS_CONNECTED) { - output->status = DS_TDM_OUTPUT_CONNECTED; - - if (!output_init_modes(output)) { - ds_err("Could not initialize modes of tdm output(%p)", - tdm_output); - goto err_status; - } - } - else if (conn == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) { - output->status = DS_TDM_OUTPUT_DISCONNECTED; - } - - if (tdm_output_get_hwc(output->tdm.output, NULL) != NULL) - output_init_hwc(output); - - ds_inf("TDM output(%p) created: hwc(%p)", output, output->tdm.hwc); - - return output; - -err_status: - free(output); - - return NULL; -} - -static struct ds_tdm_output * -tdm_output_from_output(struct ds_output *ds_output) -{ - assert(ds_output->iface == &tdm_output_iface); - return (struct ds_tdm_output *)ds_output; -} - -static void -output_iface_destroy(struct ds_output *ds_output) -{ - struct ds_tdm_output *output; - - output = tdm_output_from_output(ds_output); - output_destroy(output); -} - -void -destroy_tdm_buffer(struct ds_tdm_buffer *buffer) -{ - if (buffer == NULL) - return; - - if (!buffer->released) - wl_list_remove(&buffer->buffer_release.link); - - wl_list_remove(&buffer->buffer_destroy.link); - wl_list_remove(&buffer->link); - free(buffer); -} - -static void -buffer_handle_buffer_release(struct wl_listener *listener, void *data) -{ - struct ds_tdm_buffer *buffer; - - buffer = wl_container_of(listener, buffer, buffer_release); - wl_list_remove(&buffer->buffer_release.link); - buffer->released = true; -} - -static void -buffer_handle_buffer_destroy(struct wl_listener *listener, void *data) -{ - struct ds_tdm_buffer *buffer; - - buffer = wl_container_of(listener, buffer, buffer_destroy); - destroy_tdm_buffer(buffer); -} - -static struct ds_tdm_buffer * -create_tdm_buffer(struct ds_tdm_backend *backend, struct ds_buffer *ds_buffer) -{ - struct ds_tdm_buffer *buffer; - tbm_surface_h surface; - - surface = ds_tbm_buffer_get_surface(ds_buffer); - if (!surface) { - ds_err("Could not get tbm_surface_h"); - return NULL; - } - - buffer = calloc(1, sizeof *buffer); - if (!buffer) - return NULL; - - buffer->surface = surface; - buffer->buffer = ds_buffer; - wl_list_insert(&backend->buffers, &buffer->link); - - buffer->buffer_destroy.notify = buffer_handle_buffer_destroy; - ds_buffer_add_destroy_listener(ds_buffer, &buffer->buffer_destroy); - - return buffer; -} - -static struct ds_tdm_buffer * -get_or_create_tdm_buffer(struct ds_tdm_backend *backend, - struct ds_buffer *ds_buffer) -{ - struct ds_tdm_buffer *buffer; - - wl_list_for_each(buffer, &backend->buffers, link) { - if (buffer->buffer == ds_buffer && buffer->released) { - goto out; - } - } - - buffer = create_tdm_buffer(backend, ds_buffer); - -out: - buffer->released = false; - - buffer->buffer_release.notify = buffer_handle_buffer_release; - ds_buffer_add_release_listener(ds_buffer, &buffer->buffer_release); - - ds_buffer_lock(buffer->buffer); - - return buffer; -} - -static void -output_update_front_buffer(struct ds_tdm_output *output) -{ - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); - output->front_buffer = output->back_buffer; - output->back_buffer = NULL; -} - -static void -output_attach_back_buffer(struct ds_tdm_output *output, - struct ds_buffer *buffer) -{ - if (output->back_buffer) - ds_buffer_unlock(output->back_buffer); - output->back_buffer = buffer; -} - -static bool -output_iface_commit(struct ds_output *ds_output) -{ - struct ds_tdm_output *output; - - output = tdm_output_from_output(ds_output); - - if (ds_output->pending.committed & DS_OUTPUT_STATE_MODE) { - if (!output_update_mode(output)) { - ds_err("Could not update TDM mode"); - return false; - } - } - - if (ds_output->pending.committed & DS_OUTPUT_STATE_BUFFER) { - if (!output_set_pending_fb(output, ds_output->pending.buffer)) - ds_err("Could not update buffer"); - } - - if (!output_hwc_commit(output)) { - ds_err("Could not commit tdm output"); - if (output->back_buffer) - ds_buffer_unlock(output->back_buffer); - } - - return true; -} - -static const struct ds_output_interface tdm_output_iface = -{ - .destroy = output_iface_destroy, - .commit = output_iface_commit, -}; - -static void -output_destroy(struct ds_tdm_output *output) -{ - struct ds_tdm_output_mode *mode, *mode_tmp; - - wl_list_for_each_safe(mode, mode_tmp, &output->base.modes, base.link) { - wl_list_remove(&mode->base.link); - free(mode); - } - - if (output->back_buffer) - ds_buffer_unlock(output->back_buffer); - - if (output->front_buffer) - ds_buffer_unlock(output->front_buffer); - - if (output->queue) - buffer_queue_destroy(output->queue); - - free(output); -} - -static bool -output_init_modes(struct ds_tdm_output *output) -{ - struct ds_tdm_output_mode *mode; - const tdm_output_mode *tdm_modes, *tdm_mode; - tdm_error err; - int num_modes, i; - - err = tdm_output_get_available_modes(output->tdm.output, &tdm_modes, - &num_modes); - if (err != TDM_ERROR_NONE) { - ds_err("Could not get available modes: output(%p)", output); - return false; - } - - ds_dbg("Detected modes:"); - - for (i = 0; i < num_modes; i++) { - tdm_mode = &tdm_modes[i]; - - mode = calloc(1, sizeof *mode); - if (!mode) { - ds_err("Could not allocate memory"); - continue; - } - - mode->tdm_mode = tdm_mode; - mode->base.width = tdm_mode->hdisplay; - mode->base.height = tdm_mode->vdisplay; - mode->base.refresh = (int32_t)tdm_mode->vrefresh; // FIXME - - if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_PREFERRED) - mode->base.preferred = true; - - ds_dbg(" %dx%d@%d %s", mode->base.width, mode->base.height, - mode->base.refresh, - mode->base.preferred ? "(preferred)" : ""); - - if (tdm_mode->type & TDM_OUTPUT_MODE_TYPE_DEFAULT) - wl_list_insert(&output->base.modes, &mode->base.link); - else - wl_list_insert(output->base.modes.prev, &mode->base.link); - } - - return true; -} - -static void -output_init_hwc(struct ds_tdm_output *output) -{ - tdm_error err; - - output->tdm.hwc = tdm_output_get_hwc(output->tdm.output, &err); - if (err != TDM_ERROR_NONE || !output->tdm.hwc) { - ds_err("Could not get tdm_hwc: output(%p)", output); - return; - } -} - -static bool -output_update_mode(struct ds_tdm_output *output) -{ - const struct ds_tdm_output_mode *mode; - tdm_error err; - - mode = (struct ds_tdm_output_mode *)output->base.pending.mode; - - ds_inf("TDM output(%p) set mode %dx%d %d mHz", output, - mode->base.width, mode->base.height, mode->base.refresh); - - err = tdm_output_set_mode(output->tdm.output, mode->tdm_mode); - if (err != TDM_ERROR_NONE) - return false; - - return true; -} - -static bool -output_set_pending_fb(struct ds_tdm_output *output, - struct ds_buffer *ds_buffer) -{ - 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); - if (queue_buffer) { - ds_buffer_lock(ds_buffer); - surface = queue_buffer->surface; - } - } - - if (!surface) { - buffer = get_or_create_tdm_buffer(output->backend, ds_buffer); - if (!buffer) - return false; - - 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) { - ds_err("Could not set hwc client target buffer"); - ds_buffer_unlock(ds_buffer); - return false; - } - - output_attach_back_buffer(output, ds_buffer); - - 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) { - ds_err("Could not hwc commit"); - return false; - } - - return true; -} diff --git a/src/libds-tizen/backend/tdm/tdm.h b/src/libds-tizen/backend/tdm/tdm.h deleted file mode 100644 index f19483f..0000000 --- a/src/libds-tizen/backend/tdm/tdm.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef DS_TIZEN_BACKEND_TDM_H -#define DS_TIZEN_BACKEND_TDM_H - -#include - -#include - -#include "libds/interfaces/backend.h" -#include "libds/interfaces/output.h" - -enum ds_tdm_output_status { - DS_TDM_OUTPUT_DISCONNECTED, - DS_TDM_OUTPUT_CONNECTED, -}; - -struct ds_tdm_output_mode { - struct ds_output_mode base; - const tdm_output_mode *tdm_mode; -}; - -struct ds_tdm_backend -{ - struct ds_backend base; - - tdm_display *tdm_display; - struct wl_display *wl_display; - struct wl_event_source *tdm_event; - - struct wl_list outputs; // ds_tdm_output.link - struct wl_list buffers; // ds_tdm_buffer.link - - struct wl_listener display_destroy; - - clockid_t clock; - int fd; -}; - -struct ds_tdm_output -{ - struct ds_output base; - - struct ds_tdm_backend *backend; - struct ds_tdm_buffer_queue *queue; - struct ds_buffer *front_buffer, *back_buffer; - - struct { - tdm_output *output; - tdm_hwc *hwc; - } tdm; - - struct wl_list link; - - enum ds_tdm_output_status status; -}; - -struct ds_tdm_buffer -{ - struct ds_buffer *buffer; - tbm_surface_h surface; - struct wl_list link; // ds_wl_backend.buffers - - struct wl_listener buffer_release; - struct wl_listener buffer_destroy; - - bool released; -}; - -struct ds_tdm_backend *tdm_backend_from_backend(struct ds_backend *backend); - -struct ds_tdm_output *create_tdm_output(struct ds_tdm_backend *tdm, - tdm_output *tdm_output); - -void destroy_tdm_buffer(struct ds_tdm_buffer *buffer); - - -#endif diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.c b/src/libds-tizen/backend/tdm/tdm_buffer_queue.c deleted file mode 100644 index 7a2a1aa..0000000 --- a/src/libds-tizen/backend/tdm/tdm_buffer_queue.c +++ /dev/null @@ -1,311 +0,0 @@ -#include -#include -#include -#include - -#include "libds/log.h" -#include "libds/interfaces/buffer.h" - -#include "tdm.h" -#include "tdm_buffer_queue.h" - -static void -buffer_queue_handle_acquirable(tbm_surface_queue_h surface_queue, - void *data); -static struct ds_tdm_queue_buffer * -create_queue_buffer(struct ds_tdm_buffer_queue *queue, - tbm_surface_h surface); -static void queue_buffer_destroy(struct ds_tdm_queue_buffer *buffer); -static void queue_buffer_drop(struct ds_tdm_queue_buffer *buffer); -static struct ds_buffer * -queue_buffer_acquire(struct ds_tdm_queue_buffer *buffer); -static int buffer_queue_handle_acquirable_efd(int fd, uint32_t mask, - void *data); - -WL_EXPORT void * -ds_tdm_buffer_queue_get_native_queue(struct ds_tdm_buffer_queue *queue) -{ - return (void *)queue->tbm_surface_queue; -} - -WL_EXPORT struct ds_buffer * -ds_tdm_buffer_queue_acquire(struct ds_tdm_buffer_queue *queue) -{ - struct ds_tdm_queue_buffer *buffer; - tbm_surface_h surface; - tbm_surface_queue_error_e err; - - if (!tbm_surface_queue_can_acquire(queue->tbm_surface_queue, 0)) - return NULL; - - err = tbm_surface_queue_acquire(queue->tbm_surface_queue, &surface); - if (err != TBM_SURFACE_QUEUE_ERROR_NONE || - surface == NULL) { - ds_err("Could not acquire tbm_surface from queue(%p)", queue); - return NULL; - } - - wl_list_for_each(buffer, &queue->buffers, link) { - if (buffer->surface == surface) - return queue_buffer_acquire(buffer); - } - - buffer = create_queue_buffer(queue, surface); - if (!buffer) { - ds_err("Could not create tbm_queue_buffer with queue(%p)", queue); - return NULL; - } - - wl_list_insert(&queue->buffers, &buffer->link); - - return queue_buffer_acquire(buffer); -} - -WL_EXPORT void -ds_tdm_buffer_queue_add_acquirable_listener(struct ds_tdm_buffer_queue *queue, - struct wl_listener *listener) -{ - wl_signal_add(&queue->events.acquirable, listener); -} - -struct ds_tdm_buffer_queue * -create_buffer_queue(struct ds_tdm_output *output) -{ - struct ds_tdm_buffer_queue *queue; - tdm_error err; - - queue = calloc(1, sizeof *queue); - if (!queue) - return NULL; - - wl_list_init(&queue->buffers); - - wl_signal_init(&queue->events.acquirable); - - queue->tbm_surface_queue = - tdm_hwc_get_client_target_buffer_queue(output->tdm.hwc, &err); - if (err != TDM_ERROR_NONE || - queue->tbm_surface_queue == NULL) { - ds_err("Could not get target buffer queue: err(%d)", err); - free(queue); - return NULL; - } - - tbm_surface_queue_reset(queue->tbm_surface_queue, - output->base.pending.mode->width, - output->base.pending.mode->height, - tbm_surface_queue_get_format(queue->tbm_surface_queue)); - - /* The callback function for tbm_surface_queue_add_acquirable_cb() may be - * called on different thread. This eventfd is to emit a signal of - * events.acquirable on the thread getting this buffer queue. */ - queue->acquirable_efd = eventfd(0, EFD_NONBLOCK); - if (queue->acquirable_efd < 0) { - ds_log_errno(DS_ERR, - "Could not create eventfd for acquirable callback"); - free(queue); - return NULL; - } - - queue->acquirable_source = wl_event_loop_add_fd( - wl_display_get_event_loop(output->backend->wl_display), - queue->acquirable_efd, - WL_EVENT_READABLE, - buffer_queue_handle_acquirable_efd, - queue); - - tbm_surface_queue_add_acquirable_cb(queue->tbm_surface_queue, - buffer_queue_handle_acquirable, (void *)queue); - - return queue; -} - -void -buffer_queue_destroy(struct ds_tdm_buffer_queue *queue) -{ - struct ds_tdm_queue_buffer *buffer, *buffer_tmp; - - wl_list_for_each_safe(buffer, buffer_tmp, &queue->buffers, link) - queue_buffer_drop(buffer); - - wl_event_source_remove(queue->acquirable_source); - close(queue->acquirable_efd); - tbm_surface_queue_destroy(queue->tbm_surface_queue); - free(queue); -} - -struct ds_tdm_queue_buffer * -buffer_queue_find_buffer(struct ds_tdm_buffer_queue *queue, - struct ds_buffer *ds_buffer) -{ - struct ds_tdm_queue_buffer *buffer; - - wl_list_for_each(buffer, &queue->buffers, link) { - if (&buffer->base == ds_buffer) - return buffer; - } - - return NULL; -} - -static void -buffer_queue_handle_acquirable(tbm_surface_queue_h surface_queue, void *data) -{ - struct ds_tdm_buffer_queue *queue = data; - uint64_t acquirable = 1; - int ret; - - ret = write(queue->acquirable_efd, &acquirable, sizeof(acquirable)); - if (ret < 0) - ds_log_errno(DS_ERR, "Could not write eventfd for acquirable buffer"); -} - -static const struct ds_buffer_interface queue_buffer_iface; - -static struct ds_tdm_queue_buffer * -create_queue_buffer(struct ds_tdm_buffer_queue *queue, tbm_surface_h surface) -{ - struct ds_tdm_queue_buffer *buffer; - - buffer = calloc(1, sizeof *buffer); - if (!buffer) - return NULL; - - ds_buffer_init(&buffer->base, &queue_buffer_iface, - tbm_surface_get_width(surface), - tbm_surface_get_height(surface)); - - buffer->queue = queue; - buffer->surface = surface; - - return buffer; -} - -static void -queue_buffer_destroy(struct ds_tdm_queue_buffer *buffer) -{ - free(buffer); -} - -static struct ds_tdm_queue_buffer * -queue_buffer_from_buffer(struct ds_buffer *ds_buffer) -{ - assert(ds_buffer->iface == &queue_buffer_iface); - return (struct ds_tdm_queue_buffer *)ds_buffer; -} - -static void -queue_buffer_iface_destroy(struct ds_buffer *ds_buffer) -{ - struct ds_tdm_queue_buffer *buffer; - - buffer = queue_buffer_from_buffer(ds_buffer); - queue_buffer_destroy(buffer); -} - -static bool -queue_buffer_iface_begin_data_ptr_access(struct ds_buffer *ds_buffer, - uint32_t flags, void **data, uint32_t *format, size_t *stride) -{ - struct ds_tdm_queue_buffer *buffer; - tbm_surface_info_s info; - int tbm_access_flags = 0; - int ret; - - buffer = queue_buffer_from_buffer(ds_buffer); - - if (!buffer->surface) { - ds_err("No tbm_surface. It's a dropped buffer(%p)", buffer); - return false; - } - - if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ) - tbm_access_flags |= TBM_OPTION_READ; - else if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE) - tbm_access_flags |= TBM_OPTION_WRITE; - - ret = tbm_surface_map(buffer->surface, tbm_access_flags, &info); - if (ret != TBM_SURFACE_ERROR_NONE) { - ds_err("Could not map tbm_surface of buffer(%p)", buffer); - return false; - } - - *data = info.planes[0].ptr; - *format = info.format; - *stride = info.planes[0].stride; - - return true; -} - -static void -queue_buffer_iface_end_data_ptr_access(struct ds_buffer *ds_buffer) -{ - struct ds_tdm_queue_buffer *buffer; - - buffer = queue_buffer_from_buffer(ds_buffer); - if (!buffer->surface) { - ds_err("No tbm_surface. It's a dropped buffer(%p)", buffer); - return; - } - - tbm_surface_unmap(buffer->surface); -} - -static const struct ds_buffer_interface queue_buffer_iface = -{ - .destroy = queue_buffer_iface_destroy, - .begin_data_ptr_access = queue_buffer_iface_begin_data_ptr_access, - .end_data_ptr_access = queue_buffer_iface_end_data_ptr_access, -}; - -static void -queue_buffer_handle_buffer_release(struct wl_listener *listener, void *data) -{ - struct ds_tdm_queue_buffer *buffer; - - buffer = wl_container_of(listener, buffer, buffer_release); - - wl_list_remove(&buffer->buffer_release.link); - buffer->acquired = false; - - tbm_surface_queue_release(buffer->queue->tbm_surface_queue, - buffer->surface); -} - -static void -queue_buffer_drop(struct ds_tdm_queue_buffer *buffer) -{ - if (buffer->acquired) - wl_list_remove(&buffer->buffer_release.link); - - wl_list_remove(&buffer->link); - ds_buffer_drop(&buffer->base); - buffer->surface = NULL; -} - -static struct ds_buffer * -queue_buffer_acquire(struct ds_tdm_queue_buffer *buffer) -{ - assert(!buffer->acquired); - - buffer->acquired = true; - buffer->buffer_release.notify = queue_buffer_handle_buffer_release; - ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release); - - return ds_buffer_lock(&buffer->base); -} - -static int -buffer_queue_handle_acquirable_efd(int fd, uint32_t mask, void *data) -{ - struct ds_tdm_buffer_queue *queue = data; - uint64_t acquirable_event; - - if (read(fd, &acquirable_event, sizeof(acquirable_event)) < 0 && - errno != EAGAIN) - return -1; - - wl_signal_emit(&queue->events.acquirable, queue); - - return 0; -} diff --git a/src/libds-tizen/backend/tdm/tdm_buffer_queue.h b/src/libds-tizen/backend/tdm/tdm_buffer_queue.h deleted file mode 100644 index a983265..0000000 --- a/src/libds-tizen/backend/tdm/tdm_buffer_queue.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef DS_TIZEN_BACKEND_TDM_BUFFER_QUEUE_H -#define DS_TIZEN_BACKEND_TDM_BUFFER_QUEUE_H - -#include -#include - -#include "tdm.h" - -struct ds_tdm_buffer_queue -{ - tbm_surface_queue_h tbm_surface_queue; - struct wl_event_source *acquirable_source; - - struct wl_list buffers; // ds_tdm_queue_buffer.link - - struct { - struct wl_signal acquirable; - } events; - - int acquirable_efd; -}; - -struct ds_tdm_queue_buffer -{ - struct ds_buffer base; - - struct ds_tdm_output *output; - struct ds_tdm_buffer_queue *queue; - tbm_surface_h surface; - - struct wl_list link; - struct wl_listener buffer_release; - - bool acquired; -}; - -struct ds_tdm_buffer_queue *create_buffer_queue(struct ds_tdm_output *output); - -void buffer_queue_destroy(struct ds_tdm_buffer_queue *queue); - -struct ds_tdm_queue_buffer * -buffer_queue_find_buffer(struct ds_tdm_buffer_queue *queue, - struct ds_buffer *ds_buffer); - -#endif diff --git a/src/libds-tizen/dpms.c b/src/libds-tizen/dpms.c deleted file mode 100644 index 315d6c0..0000000 --- a/src/libds-tizen/dpms.c +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include -#include -#include "libds/log.h" -#include "libds/output.h" -#include "libds-tizen/dpms.h" -#include "tizen-dpms-server-protocol.h" -#include "util.h" - -struct ds_tizen_dpms -{ - struct wl_global *global; - struct wl_resource *res; - - struct wl_listener destroy; - - struct { - struct wl_signal destroy; - struct wl_signal set_dpms; - struct wl_signal get_dpms; - } events; - - bool binded; -}; - -#define TIZEN_DPMS_VERSION 1 - -static void dpms_handle_display_destroy(struct wl_listener *listener, - void *data); -static void dpms_bind(struct wl_client *wl_client, void *data, - uint32_t verison, uint32_t id); - -WL_EXPORT struct ds_tizen_dpms * -ds_tizen_dpms_create(struct wl_display *display) -{ - struct ds_tizen_dpms *dpms; - - dpms = calloc(1, sizeof *dpms); - if (!dpms) { - ds_err("dpms create fail : memory alloc failed"); - return NULL; - } - - dpms->global = wl_global_create(display, &tizen_dpms_manager_interface, - 1, dpms, dpms_bind); - if (!dpms->global) { - ds_err("global create fail : tizen_dpms_manager_interface failed"); - free(dpms); - return NULL; - } - - wl_signal_init(&dpms->events.destroy); - wl_signal_init(&dpms->events.set_dpms); - wl_signal_init(&dpms->events.get_dpms); - - dpms->destroy.notify = dpms_handle_display_destroy; - wl_display_add_destroy_listener(display, &dpms->destroy); - - ds_inf("global create : tizen_dpms_manager(%p)", dpms); - - return dpms; -} - -WL_EXPORT void -ds_tizen_dpms_add_destroy_listener(struct ds_tizen_dpms *dpms, - struct wl_listener *listener) -{ - wl_signal_add(&dpms->events.destroy, listener); -} - -WL_EXPORT void -ds_tizen_dpms_add_set_dpms_listener(struct ds_tizen_dpms *dpms, - struct wl_listener *listener) -{ - wl_signal_add(&dpms->events.set_dpms, listener); -} - -WL_EXPORT void -ds_tizen_dpms_add_get_dpms_listener(struct ds_tizen_dpms *dpms, - struct wl_listener *listener) -{ - wl_signal_add(&dpms->events.get_dpms, listener); -} - -WL_EXPORT void -ds_tizen_dpms_send_set_result(struct ds_tizen_dpms *dpms, - enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error) -{ - ds_dbg("dpms send set result : mode(%d), error(%d)", mode, error); - tizen_dpms_manager_send_set_state(dpms->res, mode, error); -} - -WL_EXPORT void -ds_tizen_dpms_send_get_result(struct ds_tizen_dpms *dpms, - enum ds_tizen_dpms_mode mode, enum ds_tizen_dpms_error error) -{ - ds_dbg("dpms send get result : mode(%d), error(%d)", mode, error); - tizen_dpms_manager_send_get_state(dpms->res, mode, error); -} - -static void -dpms_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_tizen_dpms *dpms; - - 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->destroy.link); - wl_resource_set_user_data(dpms->res, NULL); - wl_global_destroy(dpms->global); - free(dpms); -} - -static void -_tizen_dpms_manager_handle_destroy(struct wl_client *client, - struct wl_resource *resource) -{ - ds_inf("tizen_dpms_manager cb_destroy (res:%p)", resource); - wl_resource_destroy(resource); -} - -static void -_tizen_dpms_manager_handle_set_dpms(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *output, uint32_t mode) -{ - struct ds_tizen_dpms *dpms; - - dpms = wl_resource_get_user_data(resource); - - if (mode > DS_TIZEN_DPMS_MODE_OFF) { - ds_err("set dpms error : not supported mode(%d)", mode); - tizen_dpms_manager_send_set_state(resource, DS_TIZEN_DPMS_MODE_OFF, - DS_TIZEN_DPMS_ERROR_INVALID_PARAMETER); - return; - } - - struct ds_tizen_dpms_event event = { - .mode = mode, - }; - - wl_signal_emit(&dpms->events.set_dpms, &event); -} - -static void -_tizen_dpms_manager_handle_get_dpms(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *output) -{ - struct ds_tizen_dpms *dpms; - - dpms = wl_resource_get_user_data(resource); - - wl_signal_emit(&dpms->events.get_dpms, NULL); -} - -static const struct tizen_dpms_manager_interface dpms_impl = -{ - _tizen_dpms_manager_handle_destroy, - _tizen_dpms_manager_handle_set_dpms, - _tizen_dpms_manager_handle_get_dpms, -}; - -static void -_tizen_dpms_client_cb_destroy(struct wl_resource *resource) -{ - struct ds_tizen_dpms *dpms; - - ds_inf("tizen_dpms_client_cb_destroy (res:%p)", resource); - - dpms = wl_resource_get_user_data(resource); - if (dpms) { - dpms->binded = false; - dpms->res = NULL; - } -} - -static void -dpms_bind(struct wl_client *client, void *data, uint32_t version, - uint32_t id) -{ - struct ds_tizen_dpms *dpms = data; - - if (dpms->binded == true) { - //support only one client. - ds_err("dpms bind error : already binded."); - return; - } - - dpms->res = wl_resource_create(client, &tizen_dpms_manager_interface, - MIN(version, TIZEN_DPMS_VERSION), id); - if (dpms->res == NULL) { - ds_err("dpms bind error : wl_resource_create failed."); - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(dpms->res, &dpms_impl, dpms, - _tizen_dpms_client_cb_destroy); - - dpms->binded = true; -} diff --git a/src/libds-tizen/input-devicemgr/input-devicemgr.c b/src/libds-tizen/input-devicemgr/input-devicemgr.c deleted file mode 100644 index 84700d7..0000000 --- a/src/libds-tizen/input-devicemgr/input-devicemgr.c +++ /dev/null @@ -1,1063 +0,0 @@ -#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 deleted file mode 100644 index 8418b16..0000000 --- a/src/libds-tizen/input-devicemgr/input-devicemgr.h +++ /dev/null @@ -1,59 +0,0 @@ -#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 deleted file mode 100644 index 30924a4..0000000 --- a/src/libds-tizen/input-devicemgr/meson.build +++ /dev/null @@ -1,30 +0,0 @@ -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/keyrouter/keyrouter.c b/src/libds-tizen/keyrouter/keyrouter.c deleted file mode 100644 index 6b5b220..0000000 --- a/src/libds-tizen/keyrouter/keyrouter.c +++ /dev/null @@ -1,430 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "libds/log.h" -#include "libds-tizen/keyrouter.h" - -#include "util.h" -#include "keyrouter.h" - -static void -keyrouter_bind(struct wl_client *client, void *data, uint32_t version, - uint32_t id); -static bool -keyrouter_check_privilege(struct ds_tizen_keyrouter_client *keyrouter_client, - struct wl_client *client, uint32_t mode, uint32_t keycode); -static void -keyrouter_options_set(struct ds_tizen_keyrouter *keyrouter); - -static void -keyrouter_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_tizen_keyrouter *keyrouter; - - keyrouter = wl_container_of(listener, keyrouter, display_destroy); - - ds_inf("Global destroy: ds_tizen_keyrouter(%p)", keyrouter); - - wl_signal_emit(&keyrouter->events.destroy, keyrouter); - - tizen_security_finish(); - - free(keyrouter->opts); - - wl_list_remove(&keyrouter->display_destroy.link); - - wl_global_destroy(keyrouter->global); - - keyrouter_grab_destroy(keyrouter->keyrouter_grab); - - free(keyrouter); -} - -WL_EXPORT struct ds_tizen_keyrouter * -ds_tizen_keyrouter_create(struct wl_display *display) -{ - struct ds_tizen_keyrouter *keyrouter; - - keyrouter = calloc(1, sizeof *keyrouter); - if (!keyrouter) { - return NULL; - } - - keyrouter->keyrouter_grab = keyrouter_grab_create(); - if (keyrouter->keyrouter_grab == NULL) { - ds_err("Failed to create keyrouter."); - free(keyrouter); - return NULL; - } - - keyrouter->global = wl_global_create(display, &tizen_keyrouter_interface, - 2, keyrouter, keyrouter_bind); - if (!keyrouter->global) { - keyrouter_grab_destroy(keyrouter->keyrouter_grab); - free(keyrouter); - return NULL; - } - - wl_list_init(&keyrouter->clients); - - wl_signal_init(&keyrouter->events.destroy); - - keyrouter->display_destroy.notify = keyrouter_handle_display_destroy; - wl_display_add_destroy_listener(display, &keyrouter->display_destroy); - - keyrouter_options_set(keyrouter); - - if (!tizen_security_init()) { - ds_inf("tizen_security_init() is not sucessful. keyrouter works without security."); - } - - ds_inf("Global created: ds_tizen_keyrouter(%p)", keyrouter); - - return keyrouter; -} - -WL_EXPORT void -ds_tizen_keyrouter_add_destroy_listener(struct ds_tizen_keyrouter *keyrouter, - struct wl_listener *listener) -{ - wl_signal_add(&keyrouter->events.destroy, listener); -} - -static void -keyrouter_handle_keygrab_set(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, - uint32_t key, uint32_t mode) -{ - struct ds_tizen_keyrouter_client *keyrouter_client; - struct ds_tizen_keyrouter *keyrouter; - int res = TIZEN_KEYROUTER_ERROR_NONE; - bool ret; - - keyrouter_client = wl_resource_get_user_data(resource); - keyrouter = keyrouter_client->keyrouter; - - ret = keyrouter_check_privilege(keyrouter_client, client, mode, key); - if (ret == false) { - tizen_keyrouter_send_keygrab_notify(resource, surface, - key, mode, TIZEN_KEYROUTER_ERROR_NO_PERMISSION); - return; - } - - res = keyrouter_grab_grab_key(keyrouter->keyrouter_grab, - mode, key, (void *)client); - if (res == TIZEN_KEYROUTER_ERROR_NONE && keyrouter_client->grabbed != true) - keyrouter_client->grabbed = true; - - tizen_keyrouter_send_keygrab_notify(resource, surface, key, mode, res); -} - -static void -keyrouter_handle_keygrab_unset(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, uint32_t key) -{ - struct ds_tizen_keyrouter_client *keyrouter_client; - struct ds_tizen_keyrouter *keyrouter; - int res = TIZEN_KEYROUTER_ERROR_NONE; - bool ret; - - keyrouter_client = wl_resource_get_user_data(resource); - keyrouter = keyrouter_client->keyrouter; - - /* ungrab TOP POSITION grab first, this grab mode is not check privilege */ - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_TOPMOST, key, (void *)client); - - ret = keyrouter_check_privilege(keyrouter_client, - client, TIZEN_KEYROUTER_MODE_NONE, key); - if (ret == false) { - tizen_keyrouter_send_keygrab_notify(resource, surface, key, - TIZEN_KEYROUTER_MODE_NONE, TIZEN_KEYROUTER_ERROR_NO_PERMISSION); - return; - } - - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_EXCLUSIVE, key, (void *)client); - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, key, (void *)client); - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_TOPMOST, key, (void *)client); - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_SHARED, key, (void *)client); - - tizen_keyrouter_send_keygrab_notify(resource, surface, key, TIZEN_KEYROUTER_MODE_NONE, res); -} - -static void -keyrouter_handle_get_keygrab_status(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, uint32_t key) -{ - tizen_keyrouter_send_keygrab_notify(resource, surface, key, - TIZEN_KEYROUTER_MODE_NONE, TIZEN_KEYROUTER_ERROR_NO_PERMISSION); -} - -static int -keyrouter_get_array_length(const struct wl_array *array) -{ - int *data = NULL; - int count = 0; - - wl_array_for_each(data, array) { - count++; - } - - return count; -} - -static void -keyrouter_handle_keygrab_set_list(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, struct wl_array *grab_list) -{ - struct ds_tizen_keyrouter_client *keyrouter_client; - struct ds_tizen_keyrouter *keyrouter; - struct wl_array *return_list; - struct ds_tizen_grab_data *grab_data = NULL; - int res = TIZEN_KEYROUTER_ERROR_NONE; - bool ret; - - keyrouter_client = wl_resource_get_user_data(resource); - keyrouter = keyrouter_client->keyrouter; - - if ((keyrouter_get_array_length(grab_list) % 3) != 0) { - ds_err("Invalid keycode and grab mode pair. Check arguments in a list."); - tizen_keyrouter_send_keygrab_notify_list(resource, surface, NULL); - return; - } - - wl_array_for_each(grab_data, grab_list) { - ret = keyrouter_check_privilege(keyrouter_client, client, grab_data->mode, grab_data->key); - if (ret == false) { - grab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION; - } else { - res = keyrouter_grab_grab_key(keyrouter->keyrouter_grab, - grab_data->mode, grab_data->key, (void *)client); - if (res == TIZEN_KEYROUTER_ERROR_NONE && keyrouter_client->grabbed != true) - keyrouter_client->grabbed = true; - - grab_data->err = res; - } - } - - return_list = grab_list; - - tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list); -} - -static void -keyrouter_handle_keygrab_unset_list(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, - struct wl_array *ungrab_list) -{ - struct ds_tizen_keyrouter_client *keyrouter_client; - struct ds_tizen_keyrouter *keyrouter; - struct wl_array *return_list = NULL; - struct ds_tizen_ungrab_data *ungrab_data = NULL; - bool ret; - - keyrouter_client = wl_resource_get_user_data(resource); - keyrouter = keyrouter_client->keyrouter; - - if ((keyrouter_get_array_length(ungrab_list) % 3) != 0) { - ds_err("Invalid keycode and grab mode pair. Check arguments in a list."); - tizen_keyrouter_send_keygrab_notify_list(resource, surface, NULL); - return; - } - - wl_array_for_each(ungrab_data, ungrab_list) { - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key, (void *)client); - - ret = keyrouter_check_privilege(keyrouter_client, client, - TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key); - if (!ret) { - ungrab_data->err = TIZEN_KEYROUTER_ERROR_NO_PERMISSION; - } else { - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_EXCLUSIVE, ungrab_data->key, (void *)client); - - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, ungrab_data->key, (void *)client); - - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_TOPMOST, ungrab_data->key, (void *)client); - - keyrouter_grab_ungrab_key(keyrouter->keyrouter_grab, - TIZEN_KEYROUTER_MODE_SHARED, ungrab_data->key, (void *)client); - - ungrab_data->err = TIZEN_KEYROUTER_ERROR_NONE; - } - } - - return_list = ungrab_list; - - tizen_keyrouter_send_keygrab_notify_list(resource, surface, return_list); -} - -static void -keyrouter_handle_get_keygrab_list(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface) -{ - tizen_keyrouter_send_getgrab_notify_list(resource, surface, NULL); -} - -static void -keyrouter_handle_set_register_none_key(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, - uint32_t data) -{ - tizen_keyrouter_send_set_register_none_key_notify(resource, NULL, 0); -} - -static void -keyrouter_handle_get_keyregister_status(struct wl_client *client, - struct wl_resource *resource, uint32_t key) -{ - tizen_keyrouter_send_keyregister_notify(resource, (int)false); -} - -static void -keyrouter_handle_set_input_config(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *surface, - uint32_t config_mode, uint32_t value) -{ - tizen_keyrouter_send_set_input_config_notify(resource, (int)false); -} - -static void -keyrouter_handle_destory(struct wl_client *client, - struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct tizen_keyrouter_interface tizen_keyrouter_impl = { - keyrouter_handle_keygrab_set, - keyrouter_handle_keygrab_unset, - keyrouter_handle_get_keygrab_status, - keyrouter_handle_keygrab_set_list, - keyrouter_handle_keygrab_unset_list, - keyrouter_handle_get_keygrab_list, - keyrouter_handle_set_register_none_key, - keyrouter_handle_get_keyregister_status, - keyrouter_handle_set_input_config, - keyrouter_handle_destory -}; - -static void -keyrouter_handle_resource_destory(struct wl_resource *resource) -{ - struct ds_tizen_keyrouter_client *keyrouter_client = wl_resource_get_user_data(resource); - - wl_list_remove(&keyrouter_client->link); - free(keyrouter_client); -} - -static void -keyrouter_bind(struct wl_client *client, void *data, uint32_t version, - uint32_t id) -{ - struct ds_tizen_keyrouter *keyrouter = data; - struct ds_tizen_keyrouter_client *keyrouter_client; - - keyrouter_client = calloc(1, sizeof *keyrouter_client); - if (keyrouter_client == NULL) { - wl_client_post_no_memory(client); - return; - } - - keyrouter_client->resource = - wl_resource_create(client, &tizen_keyrouter_interface, MIN(version, 2), id); - if (keyrouter_client->resource == NULL) { - ds_err("wl_resource_create() failed.(version :%d, id:%d)", version, id); - free(keyrouter_client); - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(keyrouter_client->resource, &tizen_keyrouter_impl, - keyrouter_client, keyrouter_handle_resource_destory); - - wl_list_insert(&keyrouter->clients, &keyrouter_client->link); -} - -static bool -keyrouter_check_privilege(struct ds_tizen_keyrouter_client *keyrouter_client, - struct wl_client *client, uint32_t mode, uint32_t keycode) -{ - struct ds_tizen_keyrouter *keyrouter = keyrouter_client->keyrouter; - - pid_t pid = 0; - uid_t uid = 0; - gid_t gid = 0; - - /* Top position grab is always allowed. This mode do not need privilege.*/ - if (mode == TIZEN_KEYROUTER_MODE_TOPMOST) - return true; - - // check no privilege option on the keycode - if (keyrouter->opts) { - if (keyrouter->opts[keycode].no_privilege) - return true; - } - - // grabbed client is already checked the privilege before. - if (keyrouter_client->grabbed) - return true; - - wl_client_get_credentials(client, &pid, &uid, &gid); - - return tizen_security_check_privilege(pid, uid, "http://tizen.org/privilege/keygrab"); -} - -static void -keyrouter_options_set(struct ds_tizen_keyrouter *keyrouter) -{ - FILE *file; - int keycode; - char *ret, *tmp, *buf_ptr, buf[1024] = {0,}; - - keyrouter->opts = calloc(KEYROUTER_MAX_KEYS, - sizeof(struct ds_tizen_keyrouter_key_options)); - if (!keyrouter->opts) { - return; - } - - file = fopen(KEYLAYOUT_DIR, "r"); - if (!file) { - ds_err("Failed to open key layout file(%s): (err msg: %m)\n", KEYLAYOUT_DIR); - free(keyrouter->opts); - keyrouter->opts = NULL; - return; - } - - while (!feof(file)) { - ret = fgets(buf, 1024, file); - if (!ret) continue; - - tmp = strtok_r(buf, " ", &buf_ptr); - tmp = strtok_r(NULL, " ", &buf_ptr); - if (!tmp) continue; - keycode = atoi(tmp); - if ((0 >= keycode) || (keycode >= KEYROUTER_MAX_KEYS)) { - ds_err("Currently %d key is invalid to support\n", keycode); - continue; - } - - keyrouter->opts[keycode].enabled = true; - - if (strstr(buf_ptr, "no_priv") != NULL) { - keyrouter->opts[keycode].no_privilege = true; - } - } - - fclose(file); -} diff --git a/src/libds-tizen/keyrouter/keyrouter.h b/src/libds-tizen/keyrouter/keyrouter.h deleted file mode 100644 index ffbb3cd..0000000 --- a/src/libds-tizen/keyrouter/keyrouter.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef DS_TIZEN_KEYROUTER_H -#define DS_TIZEN_KEYROUTER_H - -#include -#include -#include - -#define KEYROUTER_MAX_KEYS 512 - -struct ds_tizen_keyrouter_key_info -{ - void *data; - struct wl_list link; -}; - -struct ds_tizen_keyrouter_grabbed -{ - int keycode; - - struct { - struct wl_list excl; - struct wl_list or_excl; - struct wl_list top; - struct wl_list shared; - } grab; - - struct wl_list pressed; -}; - -struct ds_tizen_keyrouter_grab -{ - struct ds_tizen_keyrouter_grabbed *hard_keys; - - void *focus_client; - void *top_client; -}; - -struct ds_tizen_keyrouter_key_options -{ - bool enabled; - bool no_privilege; -}; - -struct ds_tizen_keyrouter -{ - struct wl_global *global; - - struct wl_list clients; - - struct wl_listener display_destroy; - - struct { - struct wl_signal destroy; - } events; - - struct ds_tizen_keyrouter_key_options *opts; - - struct ds_tizen_keyrouter_grab *keyrouter_grab; -}; - -struct ds_tizen_keyrouter_client -{ - struct ds_tizen_keyrouter *keyrouter; - - struct wl_resource *resource; - - bool grabbed; - - struct wl_list link; // ds_tizen_keyrouter::clients -}; - -struct ds_tizen_grab_data -{ - int key; - int mode; - int err; -}; - -struct ds_tizen_ungrab_data -{ - int key; - int err; -}; - -struct ds_tizen_keyrouter_grab * -keyrouter_grab_create(void); -void -keyrouter_grab_destroy(struct ds_tizen_keyrouter_grab *keyrouter_grab); -int -keyrouter_grab_grab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int type, int keycode, void *data); -void -keyrouter_grab_ungrab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int type, int keycode, void *data); -int -keyrouter_grab_key_process(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int keycode, int pressed, struct wl_list *delivery_list); -void -keyrouter_grab_set_focus_client(struct ds_tizen_keyrouter_grab *keyrouter_grab, - void *focus_client); -void -keyrouter_grab_set_top_client(struct ds_tizen_keyrouter_grab *keyrouter_grab, - void *top_client); -bool -keyrouter_grab_check_grabbed_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int keycode); - -#endif diff --git a/src/libds-tizen/keyrouter/keyrouter_grab.c b/src/libds-tizen/keyrouter/keyrouter_grab.c deleted file mode 100644 index 35c249a..0000000 --- a/src/libds-tizen/keyrouter/keyrouter_grab.c +++ /dev/null @@ -1,351 +0,0 @@ -#include -#include - -#include "libds/log.h" - -#include "keyrouter.h" - -static struct wl_list * -keyrouter_grab_get_grabbed_list(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int type, int keycode) -{ - switch(type) { - case TIZEN_KEYROUTER_MODE_EXCLUSIVE: - return &keyrouter_grab->hard_keys[keycode].grab.excl; - case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: - return &keyrouter_grab->hard_keys[keycode].grab.or_excl; - case TIZEN_KEYROUTER_MODE_TOPMOST: - return &keyrouter_grab->hard_keys[keycode].grab.top; - case TIZEN_KEYROUTER_MODE_SHARED: - return &keyrouter_grab->hard_keys[keycode].grab.shared; - default: - return NULL; - } -} - -bool -keyrouter_grab_check_grabbed_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, int keycode) -{ - struct wl_list *list; - - list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_EXCLUSIVE, keycode); - if (list && !wl_list_empty(list)) - return true; - - list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE, keycode); - if (list && !wl_list_empty(list)) - return true; - - list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_TOPMOST, keycode); - if (list && !wl_list_empty(list)) - return true; - - list = keyrouter_grab_get_grabbed_list(keyrouter_grab, TIZEN_KEYROUTER_MODE_SHARED, keycode); - if (list && !wl_list_empty(list)) - return true; - - return false; -} - -static bool -keyrouter_grab_check_duplicated_data(struct wl_list *list, void *data) -{ - struct ds_tizen_keyrouter_key_info *info; - - if (wl_list_empty(list)) - return false; - - wl_list_for_each(info, list, link) { - if (info->data == data) - return true; - } - - return false; -} - -static bool -keyrouter_grab_check_grabbed(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int type, int keycode, void *data) -{ - struct wl_list *list; - bool ret; - - list = keyrouter_grab_get_grabbed_list(keyrouter_grab, type, keycode); - if (list == NULL) { - ds_err("keycode(%d) had no list for type(%d).", keycode, type); - return false; - } - - switch(type) { - case TIZEN_KEYROUTER_MODE_EXCLUSIVE: - if (wl_list_empty(list) == false) - ret = true; - else - ret = false; - break; - case TIZEN_KEYROUTER_MODE_OVERRIDABLE_EXCLUSIVE: - ret = keyrouter_grab_check_duplicated_data(list, data); - break; - case TIZEN_KEYROUTER_MODE_TOPMOST: - ret = keyrouter_grab_check_duplicated_data(list, data); - break; - case TIZEN_KEYROUTER_MODE_SHARED: - ret = keyrouter_grab_check_duplicated_data(list, data); - break; - default: - ret = true; - break; - } - - return ret; -} - -void -keyrouter_grab_set_focus_client(struct ds_tizen_keyrouter_grab *keyrouter_grab, - void *focus_client) -{ - keyrouter_grab->focus_client = focus_client; - - if (focus_client) - ds_dbg("[%s] focus client has been set. (focus_client=0x%p)", __FUNCTION__, focus_client); - else - ds_dbg("[%s] focus client has been set to NULL.", __FUNCTION__); -} - -void -keyrouter_grab_set_top_client(struct ds_tizen_keyrouter_grab *keyrouter_grab, void *top_client) -{ - keyrouter_grab->top_client = top_client; - - if (top_client) - ds_dbg("[%s] top client has been set. (top_client=0x%p)", __FUNCTION__, top_client); - else - ds_dbg("[%s] top client has been set to NULL.", __FUNCTION__); -} - -int -keyrouter_grab_key_process(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int keycode, int pressed, struct wl_list *delivery_list) -{ - struct ds_tizen_keyrouter_key_info *info, *delivery; - int count = 0; - - if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) { - ds_err("Invalid keycode(%d)", keycode); - return 0; - } - - if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.excl)) { - info = wl_container_of(keyrouter_grab->hard_keys[keycode].grab.excl.next, info, link); - if (info) { - delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info)); - if (delivery == NULL) { - ds_err("Failed to allocate memory."); - return 0; - } - delivery->data = info->data; - wl_list_insert(delivery_list, &delivery->link); - ds_dbg("Exclusive Mode: keycode: %d to data: %p", keycode, info->data); - return 1; - } - } else if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.or_excl)) { - info = wl_container_of(keyrouter_grab->hard_keys[keycode].grab.or_excl.next, info, link); - if (info) { - delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info)); - if (delivery == NULL) { - ds_err("Failed to allocate memory."); - return 0; - } - delivery->data = info->data; - wl_list_insert(delivery_list, &delivery->link); - ds_dbg("OR-Excl Mode: keycode: %d to data: %p", keycode, info->data); - return 1; - } - } else if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.top)) { - wl_list_for_each(info, &keyrouter_grab->hard_keys[keycode].grab.top, link) { - if (keyrouter_grab->top_client && keyrouter_grab->top_client == info->data) { - delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info)); - if (delivery == NULL) { - ds_err("Failed to allocate memory."); - return 0; - } - delivery->data = info->data; - wl_list_insert(delivery_list, &delivery->link); - ds_dbg("Topmost Mode: keycode: %d to data: %p", keycode, info->data); - return 1; - } - } - } - - if (keyrouter_grab->focus_client) { - delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info)); - if (delivery == NULL) { - ds_err("Failed to allocate memory."); - return 0; - } - delivery->data = keyrouter_grab->focus_client; - wl_list_insert(delivery_list, &delivery->link); - count++; - ds_dbg("Focus: keycode: %d to data: %p, count: %d", keycode, delivery->data, count); - } - - if (!wl_list_empty(&keyrouter_grab->hard_keys[keycode].grab.shared)) { - wl_list_for_each(info, &keyrouter_grab->hard_keys[keycode].grab.shared, link) { - if (keyrouter_grab->focus_client && keyrouter_grab->focus_client == info->data) - continue; - delivery = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info)); - if (delivery == NULL) { - ds_err("Failed to allocate memory."); - return 0; - } - delivery->data = info->data; - wl_list_insert(delivery_list, &delivery->link); - count++; - ds_dbg("Shared: keycode: %d to data: %p, count: %d", keycode, info->data, count); - } - } - - return count; -} - -int -keyrouter_grab_grab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int type, int keycode, void *data) -{ - struct ds_tizen_keyrouter_key_info *info = NULL; - struct wl_list *list = NULL; - - if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) { - ds_err("Invalid keycode(%d)", keycode); - return TIZEN_KEYROUTER_ERROR_INVALID_KEY; - } - - if (keyrouter_grab_check_grabbed(keyrouter_grab, type, keycode, data)) - return TIZEN_KEYROUTER_ERROR_GRABBED_ALREADY; - - info = calloc(1, sizeof(struct ds_tizen_keyrouter_key_info)); - if (info == NULL) { - ds_err("Failed to allocate memory."); - return TIZEN_KEYROUTER_ERROR_NO_SYSTEM_RESOURCES; - } - info->data = data; - - wl_list_init(&info->link); - - list = keyrouter_grab_get_grabbed_list(keyrouter_grab, type, keycode); - if (!list) { - ds_err("keycode(%d) had no list for type(%d)", keycode, type); - free(info); - return TIZEN_KEYROUTER_ERROR_INVALID_MODE; - } - - if (!keyrouter_grab->hard_keys[keycode].keycode) - keyrouter_grab->hard_keys[keycode].keycode = keycode; - - wl_list_insert(list, &info->link); - - return TIZEN_KEYROUTER_ERROR_NONE; -} - -static void -keyrouter_list_remove_data(struct wl_list *list, void *data) -{ - struct ds_tizen_keyrouter_key_info *info, *tmp; - - if (wl_list_empty(list)) - return; - - wl_list_for_each_safe(info ,tmp, list, link) { - if (info->data == data) { - wl_list_remove(&info->link); - free(info); - } - } -} - -void -keyrouter_grab_ungrab_key(struct ds_tizen_keyrouter_grab *keyrouter_grab, - int type, int keycode, void *data) -{ - struct wl_list *list; - - if (keycode <= 0 || keycode >= KEYROUTER_MAX_KEYS) { - ds_err("Invalid keycode(%d)", keycode); - return; - } - - if (keyrouter_grab->hard_keys[keycode].keycode == 0) - return; - - list = keyrouter_grab_get_grabbed_list(keyrouter_grab, type, keycode); - if (list == NULL) { - ds_err("keycode(%d) had no list for type(%d)", keycode, type); - return; - } - - keyrouter_list_remove_data(list, data); -} - -struct ds_tizen_keyrouter_grab * -keyrouter_grab_create(void) -{ - struct ds_tizen_keyrouter_grab *keyrouter_grab = NULL; - int i; - - keyrouter_grab = calloc(1, sizeof(struct ds_tizen_keyrouter_grab)); - if (keyrouter_grab == NULL) { - ds_err("Failed to allocate memory."); - return NULL; - } - - /* FIXME: Who defined max keycode? */ - keyrouter_grab->hard_keys = calloc(KEYROUTER_MAX_KEYS, sizeof(struct ds_tizen_keyrouter_grabbed)); - if (keyrouter_grab == NULL) { - ds_err("Failed to allocate memory."); - free(keyrouter_grab); - return NULL; - } - - for (i = 0; i < KEYROUTER_MAX_KEYS; i++) { - /* Enable all of keys to grab */ - //keyrouter_grab->hard_keys[i].keycode = i; - wl_list_init(&keyrouter_grab->hard_keys[i].grab.excl); - wl_list_init(&keyrouter_grab->hard_keys[i].grab.or_excl); - wl_list_init(&keyrouter_grab->hard_keys[i].grab.top); - wl_list_init(&keyrouter_grab->hard_keys[i].grab.shared); - wl_list_init(&keyrouter_grab->hard_keys[i].pressed); - } - - return keyrouter_grab; -} - -static void -keyrouter_grab_delete_list(struct wl_list *list) -{ - struct ds_tizen_keyrouter_key_info *info, *tmp; - - if (wl_list_empty(list)) - return; - - wl_list_for_each_safe(info, tmp, list, link) { - wl_list_remove(&info->link); - free(info); - } -} - -void -keyrouter_grab_destroy(struct ds_tizen_keyrouter_grab *keyrouter_grab) -{ - int i; - - for (i = 0; i < KEYROUTER_MAX_KEYS; i++) { - keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.excl); - keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.or_excl); - keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.top); - keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].grab.shared); - keyrouter_grab_delete_list(&keyrouter_grab->hard_keys[i].pressed); - } - - free(keyrouter_grab->hard_keys); - free(keyrouter_grab); -} diff --git a/src/libds-tizen/keyrouter/meson.build b/src/libds-tizen/keyrouter/meson.build deleted file mode 100644 index 7b27d3b..0000000 --- a/src/libds-tizen/keyrouter/meson.build +++ /dev/null @@ -1,34 +0,0 @@ -libds_tizen_keyrouter_files = [ - 'keyrouter_grab.c', - 'keyrouter.c', -] - -libds_tizen_keyrouter_deps = [ - dep_libds, - dep_libds_tizen, - dependency('tizen-extension-server', required: true), -] - -keylayout_dir = get_option('keylayout_dir') - -lib_libds_tizen_keyrouter = shared_library('ds-tizen-keyrouter', libds_tizen_keyrouter_files, - dependencies: libds_tizen_keyrouter_deps, - include_directories: [ common_inc, include_directories('.'), include_directories('..') ], - version: meson.project_version(), - c_args: [ '-DKEYLAYOUT_DIR="@0@"'.format(keylayout_dir) ], - install: true -) - -dep_libds_tizen_keyrouter = declare_dependency( - link_with: lib_libds_tizen_keyrouter, - dependencies: libds_tizen_keyrouter_deps, - include_directories: [ common_inc, include_directories('.') ], -) - -pkgconfig = import('pkgconfig') -pkgconfig.generate(lib_libds_tizen_keyrouter, - version: meson.project_version(), - filebase: 'libds-tizen-keyrouter', - name: 'libds-tizen-keyrouter', - description: 'tizen keyrouter extension of libds-tizen for tizen platform', -) \ No newline at end of file diff --git a/src/libds-tizen/meson.build b/src/libds-tizen/meson.build deleted file mode 100644 index 8c7673b..0000000 --- a/src/libds-tizen/meson.build +++ /dev/null @@ -1,42 +0,0 @@ -libds_tizen_files = [ - 'pixel_format.c', - 'tbm_server.c', - 'dpms.c', -] - -libds_tizen_deps = [ - dep_libds, - 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/libds-tizen/pixel_format.c b/src/libds-tizen/pixel_format.c deleted file mode 100644 index 021652e..0000000 --- a/src/libds-tizen/pixel_format.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include - -#include "libds/log.h" -#include "pixel_format.h" - -#ifdef ARRAY_LENGTH -#undef ARRAY_LENGTH -#endif - -#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) - -struct ds_tbm_format -{ - uint32_t drm_format; - uint32_t tbm_format; -}; - -static const struct ds_tbm_format formats[] = -{ - { - .drm_format = DRM_FORMAT_ARGB8888, - .tbm_format = TBM_FORMAT_ARGB8888, - }, - { - .drm_format = DRM_FORMAT_XRGB8888, - .tbm_format = TBM_FORMAT_XRGB8888, - }, - /* TODO more format */ -}; - -uint32_t -convert_drm_format_to_tbm(uint32_t fmt) -{ - size_t i; - - for (i = 0; i < ARRAY_LENGTH(formats); i++) { - if (formats[i].drm_format == fmt) - return formats[i].tbm_format; - } - - ds_err("DRM format 0x%"PRIX32" has no TBM equivalent", fmt); - - return 0; -} - -uint32_t -convert_tbm_format_to_drm(uint32_t fmt) -{ - size_t i; - - for (i = 0; i < ARRAY_LENGTH(formats); i++) { - if (formats[i].tbm_format == fmt) - return formats[i].drm_format; - } - - ds_err("TBM format 0x%"PRIX32" has no DRM equivalent", fmt); - - return 0; -} diff --git a/src/libds-tizen/pixel_format.h b/src/libds-tizen/pixel_format.h deleted file mode 100644 index a63d096..0000000 --- a/src/libds-tizen/pixel_format.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef DS_TIZEN_PIXEL_FORMAT_H -#define DS_TIZEN_PIXEL_FORMAT_H - -#include - -uint32_t convert_drm_format_to_tbm(uint32_t fmt); - -uint32_t convert_tbm_format_to_drm(uint32_t fmt); - -#endif diff --git a/src/libds-tizen/tbm_server.c b/src/libds-tizen/tbm_server.c deleted file mode 100644 index ecb46db..0000000 --- a/src/libds-tizen/tbm_server.c +++ /dev/null @@ -1,268 +0,0 @@ -#include -#include -#include - -#include - -#include "libds/log.h" -#include "pixel_format.h" -#include "tbm_server.h" - -static const struct ds_buffer_resource_interface tbm_buffer_resource_iface; -static const struct ds_buffer_interface tbm_client_buffer_iface; - -static void tbm_server_handle_display_destroy(struct wl_listener *listener, - void *data); - -WL_EXPORT struct ds_tbm_server * -ds_tbm_server_create(struct wl_display *display) -{ - struct ds_tbm_server *tbm; - tbm_bufmgr bufmgr; - - tbm = calloc(1, sizeof *tbm); - if (!tbm) - return NULL; - - wl_signal_init(&tbm->events.destroy); - - tbm->wl_tbm = wayland_tbm_server_init(display, NULL, -1, 0); - if (!tbm->wl_tbm) { - goto err_wl_tbm; - } - - bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm); - if (!bufmgr) { - goto err_bind; - } - - if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) { - goto err_bind; - } - - tbm->display_destroy.notify = tbm_server_handle_display_destroy; - wl_display_add_destroy_listener(display, &tbm->display_destroy); - - ds_buffer_register_resource_interface(&tbm_buffer_resource_iface); - - return tbm; - -err_bind: - wayland_tbm_server_deinit(tbm->wl_tbm); -err_wl_tbm: - free(tbm); - - return NULL; -} - -WL_EXPORT void -ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm, - struct wl_listener *listener) -{ - wl_signal_add(&tbm->events.destroy, listener); -} - -WL_EXPORT struct ds_tbm_client_buffer * -ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer) -{ - if (ds_buffer->iface != &tbm_client_buffer_iface) - return NULL; - return (struct ds_tbm_client_buffer *)ds_buffer; -} - -WL_EXPORT tbm_surface_h -ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer) -{ - if (buffer->base.iface != &tbm_client_buffer_iface) - return NULL; - return buffer->surface; -} - -static void -tbm_server_handle_display_destroy(struct wl_listener *listener, void *data) -{ - struct ds_tbm_server *tbm; - - tbm = wl_container_of(listener, tbm, display_destroy); - - wl_signal_emit(&tbm->events.destroy, tbm); - - wayland_tbm_server_deinit(tbm->wl_tbm); - free(tbm); -} - -static void -tbm_client_buffer_handle_release(struct wl_listener *listener, void *data) -{ - struct ds_tbm_client_buffer *buffer; - - buffer = wl_container_of(listener, buffer, buffer_release); - if (buffer->resource) - wl_buffer_send_release(buffer->resource); -} - -static void -tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener, - void *data) -{ - struct ds_tbm_client_buffer *buffer; - - buffer = wl_container_of(listener, buffer, resource_destroy); - - buffer->resource = NULL; - buffer->surface = NULL; - wl_list_remove(&buffer->resource_destroy.link); - wl_list_init(&buffer->resource_destroy.link); - - ds_buffer_drop(&buffer->base); -} - -static struct ds_tbm_client_buffer * -tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer) -{ - assert(ds_buffer->iface == &tbm_client_buffer_iface); - return (struct ds_tbm_client_buffer *)ds_buffer; -} - -static void -tbm_client_buffer_iface_destroy(struct ds_buffer *ds_buffer) -{ - struct ds_tbm_client_buffer *buffer; - - buffer = tbm_client_buffer_from_buffer(ds_buffer); - - ds_inf("Destroy TBM client buffer(%p)", buffer); - - wl_list_remove(&buffer->resource_destroy.link); - wl_list_remove(&buffer->buffer_release.link); - free(buffer); -} - -static bool -tbm_client_buffer_iface_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_tbm_client_buffer *buffer; - tbm_surface_info_s info; - tbm_bo_access_option op = TBM_OPTION_NONE; - int err; - - buffer = tbm_client_buffer_from_buffer(ds_buffer); - - if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ) - op |= TBM_OPTION_READ; - - if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE) - op |= TBM_OPTION_WRITE; - - err = tbm_surface_map(buffer->surface, op, &info); - if (err != TBM_SURFACE_ERROR_NONE) { - ds_err("Failed tbm_surface_map()"); - return false; - } - - *format = convert_tbm_format_to_drm(buffer->format); - *stride = info.planes[0].stride; - *data = info.planes[0].ptr; - - return true; -} - -static void -tbm_client_buffer_iface_end_ptr_access(struct ds_buffer *ds_buffer) -{ - struct ds_tbm_client_buffer *buffer; - - buffer = tbm_client_buffer_from_buffer(ds_buffer); - - tbm_surface_unmap(buffer->surface); -} - -static const struct ds_buffer_interface tbm_client_buffer_iface = { - .destroy = tbm_client_buffer_iface_destroy, - .begin_data_ptr_access = tbm_client_buffer_iface_begin_data_ptr_access, - .end_data_ptr_access = tbm_client_buffer_iface_end_ptr_access, -}; - -static struct ds_tbm_client_buffer * -tbm_client_buffer_create(struct wl_resource *resource) -{ - struct ds_tbm_client_buffer *buffer; - tbm_surface_h surface; - int32_t width, height; - - surface = wayland_tbm_server_get_surface(NULL, resource); - if (!surface) { - ds_err("Could not get tbm_surface from wl_resource@%d", - wl_resource_get_id(resource)); - return NULL; - } - - width = tbm_surface_get_width(surface); - height = tbm_surface_get_height(surface); - - buffer = calloc(1, sizeof *buffer); - if (!buffer) - return NULL; - - ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height); - - buffer->resource = resource; - buffer->surface = surface; - buffer->format = tbm_surface_get_format(surface); - - buffer->buffer_release.notify = tbm_client_buffer_handle_release; - ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release); - - buffer->resource_destroy.notify = - tbm_client_buffer_handle_resource_destroy; - wl_resource_add_destroy_listener(resource, &buffer->resource_destroy); - - ds_inf("TBM client buffer(%p) created", buffer); - - return buffer; -} - -static struct ds_tbm_client_buffer * -tbm_client_buffer_get_or_create(struct wl_resource *resource) -{ - struct ds_tbm_client_buffer *buffer; - struct wl_listener *resource_destroy_listener; - - resource_destroy_listener = wl_resource_get_destroy_listener(resource, - tbm_client_buffer_handle_resource_destroy);; - if (resource_destroy_listener) { - buffer = wl_container_of(resource_destroy_listener, - buffer, resource_destroy); - return buffer; - } - - return tbm_client_buffer_create(resource); -} - -static bool -tbm_buffer_resource_iface_is_instance(struct wl_resource *resource) -{ - return !!wayland_tbm_server_get_surface(NULL, resource); -} - -static struct ds_buffer * -tbm_buffer_resource_iface_from_resource(struct wl_resource *resource) -{ - struct ds_tbm_client_buffer *buffer; - - buffer = tbm_client_buffer_get_or_create(resource); - if (!buffer) { - ds_err("Could not get or create ds_tbm_client_buffer"); - return NULL; - } - - return &buffer->base; -} - -static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = { - .name = "tbm", - .is_instance = tbm_buffer_resource_iface_is_instance, - .from_resource = tbm_buffer_resource_iface_from_resource, -}; diff --git a/src/libds-tizen/tbm_server.h b/src/libds-tizen/tbm_server.h deleted file mode 100644 index be56746..0000000 --- a/src/libds-tizen/tbm_server.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef DS_TIZEN_TBM_SERVER_H -#define DS_TIZEN_TBM_SERVER_H - -#include -#include -#include -#include "libds/interfaces/buffer.h" - -struct ds_tbm_server -{ - struct wayland_tbm_server *wl_tbm; - - struct wl_listener display_destroy; - - struct { - struct wl_signal destroy; - } events; -}; - -struct ds_tbm_client_buffer -{ - struct ds_buffer base; - - tbm_surface_h surface; - struct wl_resource *resource; - - struct wl_listener buffer_release; - struct wl_listener resource_destroy; - - uint32_t format; - size_t stride; -}; - -#endif diff --git a/src/libds-tizen/util.h b/src/libds-tizen/util.h deleted file mode 100644 index 126467c..0000000 --- a/src/libds-tizen/util.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef DS_UTIL_H -#define DS_UTIL_H - -#include - -#define MIN(a,b) ((a)<(b)?(a):(b)) - -bool -tizen_security_init(void); - -void -tizen_security_finish(void); - -bool -tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege); - -#endif diff --git a/src/libds-tizen/util/meson.build b/src/libds-tizen/util/meson.build deleted file mode 100644 index 0ec6a9d..0000000 --- a/src/libds-tizen/util/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -libds_tizen_files += files('security.c') -libds_tizen_deps += [ - dependency('cynara-client', required: true), - dependency('cynara-session', required: true), - dependency('libsmack', required: true) -] diff --git a/src/libds-tizen/util/security.c b/src/libds-tizen/util/security.c deleted file mode 100644 index b592577..0000000 --- a/src/libds-tizen/util/security.c +++ /dev/null @@ -1,165 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "libds/log.h" -#include "util.h" - -#define CYNARA_BUFSIZE 128 - -struct ds_cynara -{ - cynara *handle; - int references; -}; - -static struct ds_cynara ds_cynara; - -static bool ds_cynara_init(void); -static void ds_cynara_finish(void); -static bool ds_cynara_check_privilege(pid_t pid, uid_t uid, - const char *privilege); - -bool -tizen_security_check_privilege(pid_t pid, uid_t uid, const char *privilege) -{ - return ds_cynara_check_privilege(pid, uid, privilege); -} - -bool -tizen_security_init(void) -{ - return ds_cynara_init(); -} - -void -tizen_security_finish(void) -{ - ds_cynara_finish(); -} - -static void -print_cynara_error(int err, const char *fmt, ...) -{ - int ret; - va_list args; - char buf[CYNARA_BUFSIZE] = "\0"; - char tmp[CYNARA_BUFSIZE + CYNARA_BUFSIZE] = "\0"; - - if (fmt) { - va_start(args, fmt); - vsnprintf(tmp, CYNARA_BUFSIZE + CYNARA_BUFSIZE, fmt, args); - va_end(args); - } - - ret = cynara_strerror(err, buf, CYNARA_BUFSIZE); - if (ret != CYNARA_API_SUCCESS) { - ds_err("Failed to get cynara_strerror. error : %d (error log about %s: %d)\n", ret, tmp, err); - return; - } - - ds_err("%s is failed. (%s)\n", tmp, buf); -} - -static bool -ds_cynara_init(void) -{ - int ret = CYNARA_API_SUCCESS; - int retry_cnt = 0; - - if (++ds_cynara.references != 1) - return true; - - for (retry_cnt = 0; retry_cnt < 5; retry_cnt++) { - ds_dbg("Retry cynara initialize: %d\n", retry_cnt + 1); - - ret = cynara_initialize(&ds_cynara.handle, NULL); - - if (CYNARA_API_SUCCESS == ret) { - ds_dbg("Succeed to initialize cynara !\n"); - return true; - } - - print_cynara_error(ret, "cynara_initialize"); - } - - ds_err("Failed to initialize cynara! (error:%d, retry_cnt=%d)\n", - ret, retry_cnt); - - --ds_cynara.references; - - return false; - -} - -static void -ds_cynara_finish(void) -{ - if (ds_cynara.references < 1) { - ds_err("%s called without ds_cynara_init\n", __FUNCTION__); - return; - } - - if (--ds_cynara.references != 0) - return; - - cynara_finish(ds_cynara.handle); - ds_cynara.handle = NULL; -} - -static bool -ds_cynara_check_privilege(pid_t pid, uid_t uid, const char *privilege) -{ - bool res = false; - char *client_smack = NULL; - char *client_session = NULL; - char uid_str[16] = { 0, }; - int len = -1; - int ret = -1; - - if (!ds_cynara.handle) { - ds_err("ds_cynara has not been initialized.\n"); - return false; - } - - ret = smack_new_label_from_process((int)pid, &client_smack); - if (ret <= 0) - goto finish; - - snprintf(uid_str, 15, "%d", (int)uid); - - client_session = cynara_session_from_pid(pid); - if (!client_session) - goto finish; - - ret = cynara_check(ds_cynara.handle, client_smack, client_session, - uid_str, privilege); - - if (ret == CYNARA_API_ACCESS_ALLOWED) - res = true; - else - print_cynara_error(ret, "privilege: %s, client_smack: %s, pid: %d", - privilege, client_smack, pid); - -finish: - ds_dbg("Privilege Check For '%s' %s pid:%u uid:%u client_smack:%s(len:%d) " - "client_session:%s ret:%d", - privilege, res ? "SUCCESS" : "FAIL", pid, uid, - client_smack ? client_smack : "N/A", len, - client_session ? client_session: "N/A", ret); - - if (client_session) - free(client_session); - - if (client_smack) - free(client_smack); - - return res; -} diff --git a/src/meson.build b/src/meson.build index d739bfe..774c7eb 100644 --- a/src/meson.build +++ b/src/meson.build @@ -11,9 +11,6 @@ wayland_scanner = find_program( ) subdir('libds') -if get_option('tizen') - subdir('libds-tizen') -endif subdir('tests') subdir('examples') subdir('clients') -- 2.7.4