#include <libds/keyboard.h>
#include <libds/touch.h>
#include <libds/pointer.h>
+#include <libds/seat.h>
#define TINYDS_UNUSED __attribute__((unused))
struct ds_input_device *dev;
struct tinyds_server *server;
+ struct tinyds_view *focused_view;
+
struct wl_listener destroy;
struct wl_listener motion;
struct wl_listener motion_absolute;
struct ds_backend *backend;
struct ds_compositor *compositor;
struct ds_xdg_shell *xdg_shell;
+ struct ds_seat *seat;
struct tinyds_output output;
static void server_fini(struct tinyds_server *server);
static void server_add_view(struct tinyds_server *server,
struct ds_xdg_surface *xdg_surface);
+static struct tinyds_view *server_view_at(struct tinyds_server *server,
+ double lx, double ly, double *sx, double *sy);
static bool output_init(struct tinyds_output *output,
struct tinyds_server *server, struct ds_output *ds_output,
int width, int height);
{
struct tinyds_pointer *pointer;
struct ds_event_pointer_motion_absolute *event = data;
+ struct tinyds_view *view;
+ double ox, oy, sx, sy;
pointer = wl_container_of(listener, pointer, motion_absolute);
ds_inf("Pointer(%p) motion absolute: (x %f y %f) time(%d)",
pointer, event->x, event->y, event->time_msec);
+
+ ox = event->x * OUTPUT_WIDTH;
+ oy = event->y * OUTPUT_HEIGHT;
+ view = server_view_at(pointer->server, ox, oy, &sx, &sy);
+
+ if (pointer->focused_view != view) {
+ if (pointer->focused_view) {
+ ds_inf("Clear pointer focus from view(%p)", pointer->focused_view);
+ ds_seat_pointer_notify_clear_focus(pointer->server->seat);
+ pointer->focused_view = NULL;
+ }
+
+ if (view) {
+ ds_inf("Set pointer focus to view(%p)", view);
+ ds_seat_pointer_notify_enter(pointer->server->seat,
+ ds_xdg_surface_get_surface(view->xdg_surface), sx, sy);
+ pointer->focused_view = view;
+ }
+ }
+
+ if (view) {
+ ds_seat_pointer_notify_motion(pointer->server->seat,
+ event->time_msec, sx, sy);
+ }
}
static void
pointer = wl_container_of(listener, pointer, frame);
ds_inf("Pointer(%p) frame", pointer);
+ ds_seat_pointer_notify_frame(pointer->server->seat);
}
static void
break;
case DS_INPUT_DEVICE_POINTER:
server_add_pointer(server, dev);
+ ds_seat_set_capabilities(server->seat, WL_SEAT_CAPABILITY_POINTER);
break;
default:
ds_err("Unknown type(%d) of ds_input_device", dev_type);
ds_xdg_shell_add_new_surface_listener(server->xdg_shell,
&server->new_xdg_surface);
+ server->seat = ds_seat_create(display, "seat0" /* arbitrary name */);
+ if (!server->seat)
+ goto err;
+
return true;
err:
ds_inf("View(%p) added", view);
}
+static struct tinyds_view *
+server_view_at(struct tinyds_server *server, double lx, double ly,
+ double *sx, double *sy)
+{
+ struct tinyds_view *view;
+ struct ds_surface *surface;
+ struct ds_buffer *buffer;
+ int x, y, w = 0, h = 0;
+
+ wl_list_for_each(view, &server->views, link) {
+ surface = ds_xdg_surface_get_surface(view->xdg_surface);
+ buffer = ds_surface_get_buffer(surface);
+ ds_buffer_get_size(buffer, &w, &h);
+
+ x = view->x;
+ y = view->y;
+
+ if (lx >= x && lx <= w && ly >= y && ly <= h) {
+ *sx = lx - x;
+ *sy = ly - y;
+
+ return view;
+ }
+ }
+
+ return NULL;
+}
+
static void
view_destroy(struct tinyds_view *view)
{