#include "config.h"
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "libinput.h"
#include "evdev.h"
#include "libinput-private.h"
+static void
+post_event(struct libinput_device *device,
+ enum libinput_event_type type,
+ struct libinput_event *event);
+
void
keyboard_notify_key(struct libinput_device *device,
uint32_t time,
uint32_t key,
enum libinput_keyboard_key_state state)
{
- if (device->keyboard_listener)
- device->keyboard_listener->notify_key(
- time, key, state,
- device->keyboard_listener_data);
+ struct libinput_event_keyboard_key *key_event;
+
+ key_event = malloc(sizeof *key_event);
+ if (!key_event)
+ return;
+
+ *key_event = (struct libinput_event_keyboard_key) {
+ .time = time,
+ .key = key,
+ .state = state,
+ };
+
+ post_event(device, LIBINPUT_EVENT_KEYBOARD_KEY, &key_event->base);
}
void
li_fixed_t dx,
li_fixed_t dy)
{
- if (device->pointer_listener)
- device->pointer_listener->notify_motion(
- time, dx, dy,
- device->pointer_listener_data);
+ struct libinput_event_pointer_motion *motion_event;
+
+ motion_event = malloc(sizeof *motion_event);
+ if (!motion_event)
+ return;
+
+ *motion_event = (struct libinput_event_pointer_motion) {
+ .time = time,
+ .dx = dx,
+ .dy = dy,
+ };
+
+ post_event(device, LIBINPUT_EVENT_POINTER_MOTION, &motion_event->base);
}
void
li_fixed_t x,
li_fixed_t y)
{
- if (device->pointer_listener)
- device->pointer_listener->notify_motion_absolute(
- time, x, y,
- device->pointer_listener_data);
+ struct libinput_event_pointer_motion_absolute *motion_absolute_event;
+
+ motion_absolute_event = malloc(sizeof *motion_absolute_event);
+ if (!motion_absolute_event)
+ return;
+
+ *motion_absolute_event = (struct libinput_event_pointer_motion_absolute) {
+ .time = time,
+ .x = x,
+ .y = y,
+ };
+
+ post_event(device,
+ LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
+ &motion_absolute_event->base);
}
void
int32_t button,
enum libinput_pointer_button_state state)
{
- if (device->pointer_listener)
- device->pointer_listener->notify_button(
- time, button, state,
- device->pointer_listener_data);
+ struct libinput_event_pointer_button *button_event;
+
+ button_event = malloc(sizeof *button_event);
+ if (!button_event)
+ return;
+
+ *button_event = (struct libinput_event_pointer_button) {
+ .time = time,
+ .button = button,
+ .state = state,
+ };
+
+ post_event(device, LIBINPUT_EVENT_POINTER_BUTTON, &button_event->base);
}
void
enum libinput_pointer_axis axis,
li_fixed_t value)
{
- if (device->pointer_listener)
- device->pointer_listener->notify_axis(
- time, axis, value,
- device->pointer_listener_data);
+ struct libinput_event_pointer_axis *axis_event;
+
+ axis_event = malloc(sizeof *axis_event);
+ if (!axis_event)
+ return;
+
+ *axis_event = (struct libinput_event_pointer_axis) {
+ .time = time,
+ .axis = axis,
+ .value = value,
+ };
+
+ post_event(device, LIBINPUT_EVENT_POINTER_AXIS, &axis_event->base);
}
void
li_fixed_t y,
enum libinput_touch_type touch_type)
{
- if (device->touch_listener)
- device->touch_listener->notify_touch(
- time, slot, x, y, touch_type,
- device->touch_listener_data);
+ struct libinput_event_touch_touch *touch_event;
+
+ touch_event = malloc(sizeof *touch_event);
+ if (!touch_event)
+ return;
+
+ *touch_event = (struct libinput_event_touch_touch) {
+ .time = time,
+ .slot = slot,
+ .x = x,
+ .y = y,
+ .touch_type = touch_type,
+ };
+
+ post_event(device, LIBINPUT_EVENT_TOUCH_TOUCH, &touch_event->base);
}
-LIBINPUT_EXPORT void
-libinput_device_set_keyboard_listener(
- struct libinput_device *device,
- const struct libinput_keyboard_listener *listener,
- void *data)
+static void
+init_event_base(struct libinput_event *event, enum libinput_event_type type)
{
- device->keyboard_listener = listener;
- device->keyboard_listener_data = data;
+ event->type = type;
}
-LIBINPUT_EXPORT void
-libinput_device_set_pointer_listener(
- struct libinput_device *device,
- const struct libinput_pointer_listener *listener,
- void *data)
+static void
+post_event(struct libinput_device *device,
+ enum libinput_event_type type,
+ struct libinput_event *event)
{
- device->pointer_listener = listener;
- device->pointer_listener_data = data;
+ struct libinput_event **events = device->events;
+ size_t events_len = device->events_len;
+ size_t events_count = device->events_count;
+ size_t move_len;
+ size_t new_out;
+
+ events_count++;
+ if (events_count > events_len) {
+ if (events_len == 0)
+ events_len = 4;
+ else
+ events_len *= 2;
+ events = realloc(events, events_len * sizeof *events);
+ if (!events) {
+ fprintf(stderr, "Failed to reallocate event ring "
+ "buffer");
+ return;
+ }
+
+ if (device->events_count > 0 && device->events_in == 0) {
+ device->events_in = device->events_len;
+ } else if (device->events_count > 0 &&
+ device->events_out >= device->events_in) {
+ move_len = device->events_len - device->events_out;
+ new_out = events_len - move_len;
+ memmove(events + new_out,
+ device->events + device->events_out,
+ move_len * sizeof *events);
+ device->events_out = new_out;
+ }
+
+ device->events = events;
+ device->events_len = events_len;
+ }
+
+ init_event_base(event, type);
+
+ device->events_count = events_count;
+ events[device->events_in] = event;
+ device->events_in = (device->events_in + 1) % device->events_len;
}
-LIBINPUT_EXPORT void
-libinput_device_set_touch_listener(
- struct libinput_device *device,
- const struct libinput_touch_listener *listener,
- void *data)
+LIBINPUT_EXPORT struct libinput_event *
+libinput_device_get_event(struct libinput_device *device)
{
- device->touch_listener = listener;
- device->touch_listener_data = data;
+ struct libinput_event *event;
+
+ if (device->events_count == 0)
+ return NULL;
+
+ event = device->events[device->events_out];
+ device->events_out = (device->events_out + 1) % device->events_len;
+ device->events_count--;
+
+ return event;
}
LIBINPUT_EXPORT int
LIBINPUT_EXPORT void
libinput_device_destroy(struct libinput_device *device)
{
+ struct libinput_event *event;
+
+ while ((event = libinput_device_get_event(device)))
+ free(event);
+ free(device->events);
+
evdev_device_destroy((struct evdev_device *) device);
}
LIBINPUT_TOUCH_TYPE_CANCEL = 4,
};
+enum libinput_event_type {
+
+ LIBINPUT_EVENT_KEYBOARD_KEY = 300,
+
+ LIBINPUT_EVENT_POINTER_MOTION = 400,
+ LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
+ LIBINPUT_EVENT_POINTER_BUTTON,
+ LIBINPUT_EVENT_POINTER_AXIS,
+
+ LIBINPUT_EVENT_TOUCH_TOUCH = 500,
+};
+
+struct libinput_event {
+ enum libinput_event_type type;
+};
+
+struct libinput_event_keyboard_key {
+ struct libinput_event base;
+ uint32_t time;
+ uint32_t key;
+ enum libinput_keyboard_key_state state;
+};
+
+struct libinput_event_pointer_motion {
+ struct libinput_event base;
+ uint32_t time;
+ li_fixed_t dx;
+ li_fixed_t dy;
+};
+
+struct libinput_event_pointer_motion_absolute {
+ struct libinput_event base;
+ uint32_t time;
+ li_fixed_t x;
+ li_fixed_t y;
+};
+
+struct libinput_event_pointer_button {
+ struct libinput_event base;
+ uint32_t time;
+ int32_t button;
+ enum libinput_pointer_button_state state;
+};
+
+struct libinput_event_pointer_axis {
+ struct libinput_event base;
+ uint32_t time;
+ enum libinput_pointer_axis axis;
+ li_fixed_t value;
+};
+
+struct libinput_event_touch_touch {
+ struct libinput_event base;
+ uint32_t time;
+ int32_t slot;
+ li_fixed_t x;
+ li_fixed_t y;
+ enum libinput_touch_type touch_type;
+};
+
struct libinput_fd_handle;
typedef void (*libinput_fd_callback)(int fd, void *data);
void (*device_lost)(void *data);
};
-struct libinput_keyboard_listener {
- void (*notify_key)(uint32_t time,
- uint32_t key,
- enum libinput_keyboard_key_state state,
- void *data);
-};
-
-struct libinput_pointer_listener {
- void (*notify_motion)(uint32_t time,
- li_fixed_t dx,
- li_fixed_t dy,
- void *data);
- void (*notify_motion_absolute)(uint32_t time,
- li_fixed_t x,
- li_fixed_t y,
- void *data);
- void (*notify_button)(uint32_t time,
- int32_t button,
- enum libinput_pointer_button_state state,
- void *data);
- void (*notify_axis)(uint32_t time,
- enum libinput_pointer_axis axis,
- li_fixed_t value,
- void *data);
-};
-
-struct libinput_touch_listener {
- void (*notify_touch)(uint32_t time,
- int32_t slot,
- li_fixed_t x,
- li_fixed_t y,
- enum libinput_touch_type touch_type,
- void *data);
-};
-
struct libinput_seat;
struct libinput_device;
const struct libinput_device_interface *interface,
void *user_data);
-void
-libinput_device_set_keyboard_listener(
- struct libinput_device *device,
- const struct libinput_keyboard_listener *listener,
- void *data);
-
-void
-libinput_device_set_pointer_listener(
- struct libinput_device *device,
- const struct libinput_pointer_listener *listener,
- void *data);
-
-void
-libinput_device_set_touch_listener(
- struct libinput_device *device,
- const struct libinput_touch_listener *listener,
- void *data);
-
int
libinput_device_dispatch(struct libinput_device *device);
+struct libinput_event *
+libinput_device_get_event(struct libinput_device *device);
+
void
libinput_device_destroy(struct libinput_device *device);