+++ /dev/null
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <time.h>
-
-#include <drm_fourcc.h>
-#include <pixman.h>
-#include <wayland-server.h>
-#include <libds/log.h>
-#include <libds/backend.h>
-#include <libds/output.h>
-#include <libds/compositor.h>
-#include <libds/xdg_shell.h>
-#include <libds-tizen/allocator/tbm.h>
-#include <libds-tizen/backend/tdm.h>
-#include <libds/backend/libinput.h>
-#include <libds-tizen/tbm_server.h>
-
-#include <libds/input_device.h>
-#include <libds/keyboard.h>
-#include <libds/touch.h>
-#include <libds/pointer.h>
-#include <libds/seat.h>
-#include <libds-tizen/input_devicemgr.h>
-#include <xkbcommon/xkbcommon.h>
-#include <libds/interfaces/keyboard.h>
-#include <libds-tizen/launch/effect.h>
-
-#define USE_TDM_BUFFER_QUEUE
-
-#ifdef USE_TDM_BUFFER_QUEUE
-#include "pixman-tbm-helper.h"
-#include "tinyds-tdm-renderer.h"
-#else
-#include <libds/swapchain.h>
-#endif
-
-#include "pixman-helper.h"
-
-#define TINYDS_UNUSED __attribute__((unused))
-struct tinyds_keyboard;
-struct tinyds_pointer;
-
-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 ds_tizen_effect *effect;
- struct ds_tizen_splash *splash;
-
- 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 wl_listener devicemgr_destroy;
- struct wl_listener pointer_warp;
- struct wl_listener effect_destroy;
- struct wl_listener effect_type_set;
- struct wl_listener effect_type_unset;
- struct wl_listener new_splash;
- struct wl_listener splash_owner;
-
- struct wl_list keyboards;
- struct wl_list pointers;
-};
-
-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;
-
- pid_t pid;
- int effect_type;
-};
-
-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 wl_list link; //tinyds_server::pointers
-};
-
-struct tinyds_keyboard
-{
- struct ds_input_device *dev;
- struct tinyds_server *server;
-
- struct wl_listener destroy;
- struct wl_listener key;
- struct wl_list link; //tinyds_server::keyboards
-};
-
-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);
-
-static struct tinyds_view *
-server_view_at(struct tinyds_server *server, double lx, double ly,
- double *sx, double *sy);
-
-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_populate_pid(struct tinyds_view *view)
-{
- pid_t pid;
- struct wl_client *client = NULL;
- struct ds_surface *surface = ds_xdg_surface_get_surface(view->xdg_surface);
-
- if (surface)
- client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
- wl_client_get_credentials(client, &pid, NULL, NULL);
-
- ds_inf("view pid(%u)", pid);
- view->pid = pid;
-
- view->effect_type = ds_tizen_effect_get_effect_type(view->server->effect, pid);
- ds_tizen_effect_unset_effect_type(view->server->effect, pid);
- ds_inf("view effect_type(%d)", view->effect_type);
-}
-
-static void
-view_handle_xdg_surface_map(struct wl_listener *listener,
- void *data TINYDS_UNUSED)
-{
- struct tinyds_view *view;
- struct ds_keyboard *keyboard;
- struct tinyds_keyboard *kbd;
- view = wl_container_of(listener, view, xdg_surface_map);
- view->mapped = true;
-
- view_populate_pid(view);
-
- wl_list_for_each(kbd, &view->server->keyboards, link) {
- keyboard = ds_input_device_get_keyboard(kbd->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);
- return;
- }
- }
-}
-
-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;
-
- view->pid = 0;
- view->effect_type = -1;
-
- ds_inf("view at (%d, %d)", view->x, view->y);
-}
-
-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);
-
- ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height);
-
- 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 void
-devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct tinyds_pointer *pointer;
- struct ds_tizen_input_devicemgr_event_pointer_warp *event = data;
- double sx = 0.f, sy = 0.f;
- struct tinyds_view *view = NULL;
-
- server = wl_container_of(listener, server, pointer_warp);
-
- ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface,
- event->x, event->y);
-
- wl_list_for_each(pointer, &server->pointers, link){
- if (!pointer->focused_view) continue;
- view = pointer->focused_view;
- }
- if (!view) return;
-
- if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) {
- ds_inf("Pointer is not on the requested surface");
- return;
- }
-
- server->output_x = view->x + (event->x * server->output->width);
- server->output_y = view->y + (event->y * server->output->height);
-
- server_view_at(server, server->output_x, server->output_y, &sx, &sy);
-
- ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f",
- sx, sy, server->output_x, server->output_y);
-
- ds_seat_pointer_notify_motion(server->seat,
- event->time_msec, sx, sy);
-}
-
-static void
-devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
-{
- struct tinyds_server *server =
- wl_container_of(listener, server, devicemgr_destroy);
-
- wl_list_remove(&server->devicemgr_destroy.link);
- wl_list_remove(&server->pointer_warp.link);
-
- server->devicemgr = NULL;
-}
-
-static void
-launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
-{
- struct tinyds_server *server =
- wl_container_of(listener, server, effect_destroy);
-
- wl_list_remove(&server->effect_destroy.link);
- wl_list_remove(&server->effect_type_set.link);
- wl_list_remove(&server->effect_type_unset.link);
- wl_list_remove(&server->new_splash.link);
-
- server->effect = NULL;
-}
-
-static void
-launch_effect_handle_type_set(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct ds_tizen_effect_event_type_set *event = data;
- struct tinyds_view *view = NULL;
- bool existing = false;
-
- server = wl_container_of(listener, server, effect_type_set);
-
- ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch");
-
- wl_list_for_each(view, &server->views, link) {
- if (view->pid == event->pid) {
- view->effect_type = event->effect_type;
- ds_inf("Launch effect. existing pid");
- existing = true;
- }
- }
- if (existing) {
- ds_tizen_effect_unset_effect_type(server->effect, event->pid);
- } else {
- ds_tizen_effect_set_effect_type(server->effect, event->pid, event->effect_type);
- }
-}
-
-static void
-launch_effect_handle_type_unset(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct ds_tizen_effect_event_type_unset *event = data;
- struct tinyds_view *view = NULL;
-
- server = wl_container_of(listener, server, effect_type_unset);
-
- ds_inf("Launch effect. type_unset: pid(%u)", event->pid);
-
- wl_list_for_each(view, &server->views, link) {
- if (view->pid == event->pid) {
- view->effect_type = -1;
- ds_inf("Launch effect. pid found");
- }
- }
- ds_tizen_effect_unset_effect_type(server->effect, event->pid);
-}
-
-static void
-launch_splash_handle_owner(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct ds_tizen_splash_event_owner *event = data;
- struct tinyds_view *view = NULL;
-
- server = wl_container_of(listener, server, splash_owner);
-
- ds_inf("Splash owner. pid(%u)", event->pid);
-
- wl_list_for_each(view, &server->views, link) {
- if (view->pid == event->pid) {
- if (event->pid == ds_tizen_splash_get_pid(server->splash))
- ;//
- else {
- ds_tizen_splash_set_pid(server->splash, event->pid);
- }
- }
- }
-}
-
-static void
-launch_effect_handle_new_splash(struct wl_listener *listener, void *data)
-{
- struct tinyds_server *server;
- struct ds_tizen_effect_event_new_splash *event = data;
- struct tinyds_view *view = NULL;
-
- server = wl_container_of(listener, server, new_splash);
-
- ds_inf("Launch new splash. splash(%p)", event->splash);
- if (!event->splash) return;
-
- server->splash = event->splash;
-
- // new view for "Launchscreen"
- view = calloc(1, sizeof *view);
- assert(view);
- wl_list_insert(server->views.prev, &view->link);
- view->pid = ds_tizen_splash_get_pid(event->splash);
-
- server->splash_owner.notify = launch_splash_handle_owner;
- ds_tizen_splash_add_owner_listener(server->splash,
- &server->splash_owner);
-}
-
-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);
-
- wl_list_init(&server->keyboards);
- wl_list_init(&server->pointers);
- 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);
-
- server->devicemgr_destroy.notify = devicemgr_handle_destroy;
- ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr,
- &server->devicemgr_destroy);
-
- server->pointer_warp.notify = devicemgr_handle_pointer_warp;
- ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr,
- &server->pointer_warp);
-
- server->effect = ds_tizen_effect_create(display);
- if (!server->effect) {
- goto err;
- }
-
- server->effect_destroy.notify = launch_effect_handle_destroy;
- ds_tizen_effect_add_destroy_listener(server->effect,
- &server->effect_destroy);
-
- server->effect_type_set.notify = launch_effect_handle_type_set;
- ds_tizen_effect_add_type_set_listener(server->effect,
- &server->effect_type_set);
-
- server->effect_type_unset.notify = launch_effect_handle_type_unset;
- ds_tizen_effect_add_type_unset_listener(server->effect,
- &server->effect_type_unset);
-
- server->new_splash.notify = launch_effect_handle_new_splash;
- ds_tizen_effect_add_new_splash_listener(server->effect,
- &server->new_splash);
-
- 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);
- wl_list_remove(&kbd->link);
-
- free(kbd);
-}
-
-static bool
-server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
-{
- switch (sym) {
- case XKB_KEY_BackSpace:
- wl_display_terminate(server->display);
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-static void
-keyboard_handle_key(struct wl_listener *listener, void *data)
-{
- struct tinyds_keyboard *kbd;
- struct ds_event_keyboard_key *event = data;
- struct ds_keyboard *ds_keyboard;
- struct xkb_state *xkb_state;
- const xkb_keysym_t *syms;
- 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);
-
- wl_list_insert(&server->keyboards, &kbd->link);
-
- 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);
- wl_list_remove(&pointer->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);
-
- pointer->focused_view = NULL;
-
- wl_list_insert(&server->pointers, &pointer->link);
-
- ds_inf("Pointer(%p) added", pointer);
-}
#include <libds/xdg_shell.h>
#include <libds-tizen/allocator/tbm.h>
#include <libds-tizen/backend/tdm.h>
+#include <libds/backend/libinput.h>
#include <libds-tizen/tbm_server.h>
#include <libds-tizen/dpms.h>
+#include <libds/input_device.h>
+#include <libds/keyboard.h>
+#include <libds/touch.h>
+#include <libds/pointer.h>
+#include <libds/seat.h>
+#include <libds-tizen/input_devicemgr.h>
+#include <xkbcommon/xkbcommon.h>
+#include <libds/interfaces/keyboard.h>
+#include <libds-tizen/launch/effect.h>
#define USE_TDM_BUFFER_QUEUE
#include "pixman-helper.h"
#define TINYDS_UNUSED __attribute__((unused))
+struct tinyds_keyboard;
+struct tinyds_pointer;
struct tinyds_output
{
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 ds_tizen_effect *effect;
+ struct ds_tizen_splash *splash;
struct tinyds_output *output;
struct tinyds_dpms *dpms;
struct wl_list views;
struct wl_listener new_output;
+ struct wl_listener new_input;
struct wl_listener new_xdg_surface;
+ struct wl_listener devicemgr_destroy;
+ struct wl_listener pointer_warp;
+ struct wl_listener effect_destroy;
+ struct wl_listener effect_type_set;
+ struct wl_listener effect_type_unset;
+ struct wl_listener new_splash;
+ struct wl_listener splash_owner;
+
+ struct wl_list keyboards;
+ struct wl_list pointers;
};
struct tinyds_view
int x, y;
bool mapped;
+
+ pid_t pid;
+ int effect_type;
+};
+
+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 wl_list link; //tinyds_server::pointers
+};
+
+struct tinyds_keyboard
+{
+ struct ds_input_device *dev;
+ struct tinyds_server *server;
+
+ struct wl_listener destroy;
+ struct wl_listener key;
+ struct wl_list link; //tinyds_server::keyboards
+};
+
+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 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);
+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);
+static struct tinyds_view *
+server_view_at(struct tinyds_server *server, double lx, double ly,
+ double *sx, double *sy);
int
main(void)
assert(socket);
ds_backend_start(server->backend);
+ ds_backend_start(server->input_backend);
setenv("WAYLAND_DISPLAY", socket, true);
}
static void
+view_populate_pid(struct tinyds_view *view)
+{
+ pid_t pid;
+ struct wl_client *client = NULL;
+ struct ds_surface *surface = ds_xdg_surface_get_surface(view->xdg_surface);
+
+ if (surface)
+ client = wl_resource_get_client(ds_surface_get_wl_resource(surface));
+ wl_client_get_credentials(client, &pid, NULL, NULL);
+
+ ds_inf("view pid(%u)", pid);
+ view->pid = pid;
+
+ view->effect_type = ds_tizen_effect_get_effect_type(view->server->effect, pid);
+ ds_tizen_effect_unset_effect_type(view->server->effect, pid);
+ ds_inf("view effect_type(%d)", view->effect_type);
+}
+
+static void
view_handle_xdg_surface_map(struct wl_listener *listener,
void *data TINYDS_UNUSED)
{
struct tinyds_view *view;
+ struct ds_keyboard *keyboard;
+ struct tinyds_keyboard *kbd;
view = wl_container_of(listener, view, xdg_surface_map);
view->mapped = true;
+
+ view_populate_pid(view);
+
+ wl_list_for_each(kbd, &view->server->keyboards, link) {
+ keyboard = ds_input_device_get_keyboard(kbd->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);
+ return;
+ }
+ }
}
static void
view->x = rand() % 1000;
view->y = rand() % 500;
+
+ view->pid = 0;
+ view->effect_type = -1;
+
+ ds_inf("view at (%d, %d)", view->x, view->y);
}
static void
output->output_frame.notify = output_handle_frame;
ds_output_add_frame_listener(ds_output, &output->output_frame);
+ ds_tizen_input_devicemgr_set_output_width_height(server->devicemgr, (uint32_t)output->width, (uint32_t)output->height);
+
server->output = output;
draw_output(output);
return true;
}
+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 void
+devicemgr_handle_pointer_warp(struct wl_listener *listener, void *data)
+{
+ struct tinyds_server *server;
+ struct tinyds_pointer *pointer;
+ struct ds_tizen_input_devicemgr_event_pointer_warp *event = data;
+ double sx = 0.f, sy = 0.f;
+ struct tinyds_view *view = NULL;
+
+ server = wl_container_of(listener, server, pointer_warp);
+
+ ds_inf("Pointer warp: surface(%p) x(%.2f) y(%.2f)", event->surface,
+ event->x, event->y);
+
+ wl_list_for_each(pointer, &server->pointers, link){
+ if (!pointer->focused_view) continue;
+ view = pointer->focused_view;
+ }
+ if (!view) return;
+
+ if (event->surface != ds_xdg_surface_get_surface(view->xdg_surface)) {
+ ds_inf("Pointer is not on the requested surface");
+ return;
+ }
+
+ server->output_x = view->x + (event->x * server->output->width);
+ server->output_y = view->y + (event->y * server->output->height);
+
+ server_view_at(server, server->output_x, server->output_y, &sx, &sy);
+
+ ds_inf("notify motion: sx:%.2f sy:%.2f, output_x:%.1f, output_y:%.1f",
+ sx, sy, server->output_x, server->output_y);
+
+ ds_seat_pointer_notify_motion(server->seat,
+ event->time_msec, sx, sy);
+}
+
+static void
+devicemgr_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
+{
+ struct tinyds_server *server =
+ wl_container_of(listener, server, devicemgr_destroy);
+
+ wl_list_remove(&server->devicemgr_destroy.link);
+ wl_list_remove(&server->pointer_warp.link);
+
+ server->devicemgr = NULL;
+}
+
+static void
+launch_effect_handle_destroy(struct wl_listener *listener, void *data TINYDS_UNUSED)
+{
+ struct tinyds_server *server =
+ wl_container_of(listener, server, effect_destroy);
+
+ wl_list_remove(&server->effect_destroy.link);
+ wl_list_remove(&server->effect_type_set.link);
+ wl_list_remove(&server->effect_type_unset.link);
+ wl_list_remove(&server->new_splash.link);
+
+ server->effect = NULL;
+}
+
+static void
+launch_effect_handle_type_set(struct wl_listener *listener, void *data)
+{
+ struct tinyds_server *server;
+ struct ds_tizen_effect_event_type_set *event = data;
+ struct tinyds_view *view = NULL;
+ bool existing = false;
+
+ server = wl_container_of(listener, server, effect_type_set);
+
+ ds_inf("Launch effect. type_set: pid(%u) type:%s", event->pid, (event->effect_type == 1) ? "depth-in" : "launch");
+
+ wl_list_for_each(view, &server->views, link) {
+ if (view->pid == event->pid) {
+ view->effect_type = event->effect_type;
+ ds_inf("Launch effect. existing pid");
+ existing = true;
+ }
+ }
+ if (existing) {
+ ds_tizen_effect_unset_effect_type(server->effect, event->pid);
+ } else {
+ ds_tizen_effect_set_effect_type(server->effect, event->pid, event->effect_type);
+ }
+}
+
+static void
+launch_effect_handle_type_unset(struct wl_listener *listener, void *data)
+{
+ struct tinyds_server *server;
+ struct ds_tizen_effect_event_type_unset *event = data;
+ struct tinyds_view *view = NULL;
+
+ server = wl_container_of(listener, server, effect_type_unset);
+
+ ds_inf("Launch effect. type_unset: pid(%u)", event->pid);
+
+ wl_list_for_each(view, &server->views, link) {
+ if (view->pid == event->pid) {
+ view->effect_type = -1;
+ ds_inf("Launch effect. pid found");
+ }
+ }
+ ds_tizen_effect_unset_effect_type(server->effect, event->pid);
+}
+
+static void
+launch_splash_handle_owner(struct wl_listener *listener, void *data)
+{
+ struct tinyds_server *server;
+ struct ds_tizen_splash_event_owner *event = data;
+ struct tinyds_view *view = NULL;
+
+ server = wl_container_of(listener, server, splash_owner);
+
+ ds_inf("Splash owner. pid(%u)", event->pid);
+
+ wl_list_for_each(view, &server->views, link) {
+ if (view->pid == event->pid) {
+ if (event->pid == ds_tizen_splash_get_pid(server->splash))
+ ;//
+ else {
+ ds_tizen_splash_set_pid(server->splash, event->pid);
+ }
+ }
+ }
+}
+
+static void
+launch_effect_handle_new_splash(struct wl_listener *listener, void *data)
+{
+ struct tinyds_server *server;
+ struct ds_tizen_effect_event_new_splash *event = data;
+ struct tinyds_view *view = NULL;
+
+ server = wl_container_of(listener, server, new_splash);
+
+ ds_inf("Launch new splash. splash(%p)", event->splash);
+ if (!event->splash) return;
+
+ server->splash = event->splash;
+
+ // new view for "Launchscreen"
+ view = calloc(1, sizeof *view);
+ assert(view);
+ wl_list_insert(server->views.prev, &view->link);
+ view->pid = ds_tizen_splash_get_pid(event->splash);
+
+ server->splash_owner.notify = launch_splash_handle_owner;
+ ds_tizen_splash_add_owner_listener(server->splash,
+ &server->splash_owner);
+}
+
static bool
init_server(struct tinyds_server *server, struct wl_display *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);
+ wl_list_init(&server->keyboards);
+ wl_list_init(&server->pointers);
+ 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) {
- ds_backend_destroy(server->backend);
- return false;
- }
+ if (!server->compositor)
+ goto err;
server->tbm_server = ds_tbm_server_create(display);
- if (!server->tbm_server) {
- ds_backend_destroy(server->backend);
- return false;
- }
+ if (!server->tbm_server)
+ goto err;
server->xdg_shell = ds_xdg_shell_create(display);
- if (!server->xdg_shell) {
- ds_backend_destroy(server->backend);
- return false;
- }
+ 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);
- if (!add_new_dpms(server)) {
- ds_backend_destroy(server->backend);
- return false;
+ if (!add_new_dpms(server))
+ goto err;
+
+ 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);
+
+ server->devicemgr_destroy.notify = devicemgr_handle_destroy;
+ ds_tizen_input_devicemgr_add_destroy_listener(server->devicemgr,
+ &server->devicemgr_destroy);
+
+ server->pointer_warp.notify = devicemgr_handle_pointer_warp;
+ ds_tizen_input_devicemgr_add_pointer_warp_listener(server->devicemgr,
+ &server->pointer_warp);
+
+ server->effect = ds_tizen_effect_create(display);
+ if (!server->effect) {
+ goto err;
}
+ server->effect_destroy.notify = launch_effect_handle_destroy;
+ ds_tizen_effect_add_destroy_listener(server->effect,
+ &server->effect_destroy);
+
+ server->effect_type_set.notify = launch_effect_handle_type_set;
+ ds_tizen_effect_add_type_set_listener(server->effect,
+ &server->effect_type_set);
+
+ server->effect_type_unset.notify = launch_effect_handle_type_unset;
+ ds_tizen_effect_add_type_unset_listener(server->effect,
+ &server->effect_type_unset);
+
+ server->new_splash.notify = launch_effect_handle_new_splash;
+ ds_tizen_effect_add_new_splash_listener(server->effect,
+ &server->new_splash);
+
return true;
+
+err:
+ ds_backend_destroy(server->backend);
+ ds_backend_destroy(server->input_backend);
+
+ return false;
}
static void
ds_tizen_dpms_send_get_result(dpms->ds_dpms, DS_TIZEN_DPMS_MODE_ON,
DS_TIZEN_DPMS_ERROR_NONE);
}
+
+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);
+ wl_list_remove(&kbd->link);
+
+ free(kbd);
+}
+
+static bool
+server_handle_keybinding(struct tinyds_server *server, xkb_keysym_t sym)
+{
+ switch (sym) {
+ case XKB_KEY_BackSpace:
+ wl_display_terminate(server->display);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static void
+keyboard_handle_key(struct wl_listener *listener, void *data)
+{
+ struct tinyds_keyboard *kbd;
+ struct ds_event_keyboard_key *event = data;
+ struct ds_keyboard *ds_keyboard;
+ struct xkb_state *xkb_state;
+ const xkb_keysym_t *syms;
+ 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);
+
+ wl_list_insert(&server->keyboards, &kbd->link);
+
+ 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);
+ wl_list_remove(&pointer->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);
+
+ pointer->focused_view = NULL;
+
+ wl_list_insert(&server->pointers, &pointer->link);
+
+ ds_inf("Pointer(%p) added", pointer);
+}