diff --git a/dev/input.c b/dev/input.c index 4167a9c..355b57f 100644 --- a/dev/input.c +++ b/dev/input.c @@ -38,7 +38,24 @@ kern_status_t input_device_report_event(struct input_device *dev, const struct i flags = S_NOBLOCK; } - size_t r = ringbuffer_write(event_queue, sizeof *ev, ev, flags); + struct input_event new_ev = *ev; + enum input_event_hook_flags hook_flags = 0; + + queue_foreach (struct input_event_hook, hook, &dev->i_hooks, hook_head) { + if (hook->hook_callback) { + hook->hook_callback(input_device_base(dev), &new_ev, &hook_flags, hook->hook_arg); + } + + if (hook_flags & INPUT_HOOK_SQUASH_EVENT) { + break; + } + } + + if (hook_flags & INPUT_HOOK_SQUASH_EVENT) { + return KERN_OK; + } + + size_t r = ringbuffer_write(event_queue, sizeof new_ev, &new_ev, flags); return r == sizeof *ev ? KERN_OK : KERN_WOULD_BLOCK; } @@ -61,6 +78,30 @@ kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size return KERN_OK; } +kern_status_t input_device_add_hook(struct device *dev, struct input_event_hook *hook) +{ + struct input_device *inputdev = INPUT_DEVICE(dev); + if (!inputdev) { + return KERN_INVALID_ARGUMENT; + } + + queue_push_back(&inputdev->i_hooks, &hook->hook_head); + + return KERN_OK; +} + +kern_status_t input_device_remove_hook(struct device *dev, struct input_event_hook *hook) +{ + struct input_device *inputdev = INPUT_DEVICE(dev); + if (!inputdev) { + return KERN_INVALID_ARGUMENT; + } + + queue_delete(&inputdev->i_hooks, &hook->hook_head); + + return KERN_OK; +} + static kern_status_t generate_name(struct input_device *dev, char out[DEV_NAME_MAX]) { snprintf(out, DEV_NAME_MAX, "input%u", dev->i_id); diff --git a/include/socks/device.h b/include/socks/device.h index 50be4a3..2377f4c 100644 --- a/include/socks/device.h +++ b/include/socks/device.h @@ -11,6 +11,7 @@ struct device; struct input_event; +struct input_event_hook; struct tty_device; #define DEV_NAME_MAX OBJECT_NAME_MAX @@ -94,6 +95,7 @@ struct input_device { struct input_device_ops *i_ops; unsigned int i_id; struct ringbuffer i_events; + struct queue i_hooks; }; struct bus_device { @@ -232,10 +234,42 @@ static inline struct device *framebuffer_device_base(struct framebuffer_device * return (struct device *)((char *)dev - offsetof(struct device, fb)); } +static inline struct object *char_device_object(struct char_device *dev) +{ + return &char_device_base(dev)->dev_base; +} + +static inline struct object *block_device_object(struct block_device *dev) +{ + return &block_device_base(dev)->dev_base; +} + +static inline struct object *net_device_object(struct net_device *dev) +{ + return &net_device_base(dev)->dev_base; +} + +static inline struct object *input_device_object(struct input_device *dev) +{ + return &input_device_base(dev)->dev_base; +} + +static inline struct object *bus_device_object(struct bus_device *dev) +{ + return &bus_device_base(dev)->dev_base; +} + +static inline struct object *framebuffer_device_object(struct framebuffer_device *dev) +{ + return &framebuffer_device_base(dev)->dev_base; +} + extern kern_status_t device_register(struct device *dev, struct driver *owner, struct device *parent); extern kern_status_t input_device_report_event(struct input_device *dev, const struct input_event *ev, bool noblock); extern kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags); +extern kern_status_t input_device_add_hook(struct device *dev, struct input_event_hook *hook); +extern kern_status_t input_device_remove_hook(struct device *dev, struct input_event_hook *hook); extern struct driver *driver_create(struct kext *self, const char *name); extern kern_status_t driver_destroy(struct driver *driver); diff --git a/include/socks/input.h b/include/socks/input.h index 0dbcec3..fbcc548 100644 --- a/include/socks/input.h +++ b/include/socks/input.h @@ -2,6 +2,14 @@ #define SOCKS_INPUT_H_ #include +#include +#include + +enum input_event_hook_flags { + INPUT_HOOK_SQUASH_EVENT = 0x01u, +}; + +struct device; enum input_event_type { INPUT_TYPE_UNKNOWN = 0x00u, @@ -167,4 +175,10 @@ struct input_event { }; }; +struct input_event_hook { + void(*hook_callback)(struct device *, struct input_event *, enum input_event_hook_flags *, void *); + void *hook_arg; + struct queue_entry hook_head; +}; + #endif