--- /dev/null
+#ifndef LIBDS_TIZEN_INPUT_DEVICEMGR_H
+#define LIBDS_TIZEN_INPUT_DEVICEMGR_H
+
+#include <wayland-server.h>
+
+#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
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);
};
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);
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)
%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} .
%{_bindir}/ds-simple-shm-shell
%{_bindir}/tinyds-tdm-dpms
%{_bindir}/ds-simple-dpms
+%{_bindir}/input-generator
%files tizen-keyrouter
%manifest %{name}.manifest
%{_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
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/epoll.h>
+
+#include <wayland-client.h>
+#include <tizen-extension-client-protocol.h>
+
+#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;
+}
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()
dependency('wayland-client', required: true),
wayland_tbm_client,
libtbm,
+ tizen_extension_client,
]
protocols = {
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,
+)
#include <tbm_surface.h>
#include <tbm_surface_internal.h>
#include "xdg-shell-client-protocol.h"
+#include <tizen-extension-client-protocol.h>
static uint64_t buffer_info_key;
#define BUFFER_INFO_KEY (unsigned long)(&buffer_info_key)
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 {
{
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 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);
}
}
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);
}
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");
}
}
};
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)
{
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
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);
tinyds_tdm_libinput_files,
dependencies: [
common_deps,
+ dep_libds_tizen_input_devicemgr,
dependency('pixman-1', required: true),
dependency('threads', required: true),
],
#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>
#define USE_TDM_BUFFER_QUEUE
#include "pixman-helper.h"
#define TINYDS_UNUSED __attribute__((unused))
+struct tinyds_keyboard;
struct tinyds_output
{
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_listener new_output;
struct wl_listener new_input;
struct wl_listener new_xdg_surface;
+
+ struct tinyds_keyboard *keyboard;
};
struct tinyds_view
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
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)
{
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,
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:
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);
"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);
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);
}
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
--- /dev/null
+#include <stdlib.h>
+#include <time.h> // gettimeofday()
+#include <libds/backend.h>
+#include <libds/log.h>
+#include <libds-tizen/input-devicemgr.h>
+#include <libds/interfaces/backend.h>
+#include <libds/interfaces/keyboard.h>
+#include <libds/seat.h>
+
+#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
--- /dev/null
+#ifndef DS_TIZEN_DEVICEMGR_H
+#define DS_TIZEN_DEVICEMGR_H
+
+#include <stdbool.h>
+#include <linux/uinput.h>
+#include <wayland-server.h>
+#include <tizen-extension-server-protocol.h>
+#include "libds/interfaces/input_device.h"
+#include <libds/seat.h>
+
+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
--- /dev/null
+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',
+)
)
subdir('keyrouter')
+subdir('input-devicemgr')
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);
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);
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
dev = get_libinput_input_device_from_input_device(ds_dev);
+ libinput_device_unref(dev->handle);
+
free(dev);
}
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);
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)
{
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);
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));