struct tizen_input_device_manager *devicemgr;
int notified;
bool blocked;
+ struct wl_surface *entered_surface;
};
struct window {
static void pointer_handle_button(void *data, struct wl_pointer *pointer,
uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
{
+ struct display *d = data;
+ static int warp_x = 0, warp_y = 0;
+
if (state == WL_POINTER_BUTTON_STATE_PRESSED) {
fprintf(stderr, "pointer_handle_button: PRESSED\n");
+
+ warp_x += 10;
+ warp_y += 10;
+ tizen_input_device_manager_pointer_warp(d->devicemgr,
+ d->entered_surface,
+ wl_fixed_from_int(warp_x),
+ wl_fixed_from_int(warp_y));
+ fprintf(stderr, "requesting pointer_warp: surface:%p sx: %d sy: %d\n",
+ d->entered_surface,
+ warp_x, warp_y);
}
else {
fprintf(stderr, "pointer_handle_button: RELEASED\n");
uint32_t serial, struct wl_surface *surface,
wl_fixed_t surface_x, wl_fixed_t surface_y)
{
+ struct display *d = data;
+
fprintf(stderr, "pointer_handle_enter surface_x:%d, surface_y:%d\n",
wl_fixed_to_int(surface_x), wl_fixed_to_int(surface_y));
+ d->entered_surface = surface;
}
static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer,
}
if ((caps & WL_SEAT_CAPABILITY_POINTER)) {
struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat);
- wl_pointer_add_listener(pointer, &pointer_listener, NULL);
+ wl_pointer_add_listener(pointer, &pointer_listener, d);
fprintf(stderr, "seat_handle_capabilities: pointer\n");
}
if ((caps & WL_SEAT_CAPABILITY_TOUCH)) {
#define TINYDS_UNUSED __attribute__((unused))
struct tinyds_keyboard;
+struct tinyds_pointer;
struct tinyds_output
{
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 tinyds_keyboard *keyboard;
+ struct wl_list keyboards;
+ struct wl_list pointers;
};
struct tinyds_view
struct wl_listener motion; //relative
struct wl_listener button;
struct wl_listener frame;
+ struct wl_list link; //tinyds_server::pointers
};
struct tinyds_keyboard
struct wl_listener destroy;
struct wl_listener key;
+ struct wl_list link; //tinyds_server::keyboards
};
struct tinyds_touch
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_view *view;
struct ds_keyboard *keyboard;
+ struct tinyds_keyboard *kbd;
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);
+ 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;
+ }
}
}
view->x = rand() % 1000;
view->y = rand() % 500;
+
+ ds_inf("view at (%d, %d)", view->x, view->y);
}
static void
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 bool
init_server(struct tinyds_server *server, struct wl_display *display)
{
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);
}
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);
+
return true;
err:
wl_list_remove(&kbd->destroy.link);
wl_list_remove(&kbd->key.link);
-
- kbd->server->keyboard = NULL;
+ wl_list_remove(&kbd->link);
free(kbd);
}
kbd->key.notify = keyboard_handle_key;
ds_keyboard_add_key_listener(ds_input_device_get_keyboard(dev), &kbd->key);
- server->keyboard = kbd;
+ wl_list_insert(&server->keyboards, &kbd->link);
ds_inf("Keyboard(%p) added", kbd);
}
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);
}
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);
}
#define LIBDS_TIZEN_INPUT_DEVICEMGR_H
#include <wayland-server.h>
+#include <libds/surface.h>
#ifdef __cplusplus
extern "C" {
struct wl_list link;
};
+struct ds_tizen_input_devicemgr_event_pointer_warp
+{
+ uint32_t time_msec;
+ struct ds_surface *surface;
+ double x, y;
+};
+
struct ds_tizen_input_devicemgr *
ds_tizen_input_devicemgr_create(struct ds_backend *backend,
struct ds_seat *seat);
struct ds_tizen_input_devicemgr *devicemgr,
struct wl_listener *listener);
+void
+ds_tizen_input_devicemgr_add_pointer_warp_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_resource *resource, uint32_t type, uint32_t x, uint32_t y,
uint32_t button);
static void
+device_manager_handle_pointer_warp(struct wl_client *client,
+ struct wl_resource *resource, struct wl_resource *surface,
+ wl_fixed_t x, wl_fixed_t y);
+static void
device_manager_handle_destroy(struct wl_client *client,
struct wl_resource *resource);
}
wl_signal_init(&tz_devicemgr->events.destroy);
+ wl_signal_init(&tz_devicemgr->events.pointer_warp);
wl_list_init(&tz_devicemgr->clients);
wl_list_init(&tz_devicemgr->devices.kbd->key.pressed);
wl_list_init(&tz_devicemgr->keymap_list);
wl_signal_add(&tz_devicemgr->events.destroy, listener);
}
+WL_EXPORT void
+ds_tizen_input_devicemgr_add_pointer_warp_listener(
+ struct ds_tizen_input_devicemgr *tz_devicemgr,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&tz_devicemgr->events.pointer_warp, listener);
+}
+
WL_EXPORT bool
ds_tizen_input_devicemgr_set_keymap_list(
struct ds_tizen_input_devicemgr *tz_devicemgr, struct wl_list *list)
.generate_key = device_manager_handle_generate_key,
.generate_pointer = device_manager_handle_generate_pointer,
.generate_touch = device_manager_handle_generate_touch,
- .pointer_warp = NULL,
+ .pointer_warp = device_manager_handle_pointer_warp,
.init_generator_with_name =
device_manager_handle_init_generator_with_name, // v2
.destroy = device_manager_handle_destroy, // v3
}
static void
+device_manager_handle_pointer_warp(struct wl_client *client,
+ struct wl_resource *resource, struct wl_resource *surface,
+ wl_fixed_t x, wl_fixed_t y)
+{
+ struct ds_tizen_input_devicemgr *tz_devicemgr;
+ int ret = TIZEN_INPUT_DEVICE_MANAGER_ERROR_NO_SYSTEM_RESOURCES;
+ int32_t new_x, new_y;
+ double transformed_x = .0, transformed_y = .0;
+ struct ds_tizen_input_devicemgr_event_pointer_warp ds_event;
+ struct timeval time;
+ unsigned int timestamp;
+
+ tz_devicemgr = wl_resource_get_user_data(resource);
+
+ if (!tz_devicemgr->devices.ptr ||
+ !tz_devicemgr->devices.ptr->input_device) {
+ ds_err("Pointer device is not initialized\n");
+ goto finish;
+ }
+
+ new_x = wl_fixed_to_int(x);
+ new_y = wl_fixed_to_int(y);
+
+ if (tz_devicemgr->output.width != 0 && tz_devicemgr->output.height != 0) {
+ transformed_x = new_x / (double)tz_devicemgr->output.width;
+ transformed_y = new_y / (double)tz_devicemgr->output.height;
+ }
+
+ gettimeofday(&time, NULL);
+ timestamp = time.tv_sec * 1000 + time.tv_usec / 1000;
+
+ ds_event.time_msec = timestamp;
+ ds_event.surface = ds_surface_from_resource(surface);
+ ds_event.x = transformed_x;
+ ds_event.y = transformed_y;
+ ds_inf("Pointer warp. surface:%p, x:%.2f, y:%.2f", ds_event.surface,
+ ds_event.x, ds_event.y);
+
+ wl_signal_emit(&tz_devicemgr->events.pointer_warp, &ds_event);
+ 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)
{
struct {
struct wl_signal destroy;
+ struct wl_signal pointer_warp; //ds_tizen_input_devicemgr_event_pointer_warp
} events;
struct wl_listener new_input;