From 05395542a8a745a308439241469f0d2268d6aa72 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Wed, 10 May 2023 20:33:40 +0100 Subject: [PATCH] dev: implement writing/reading input events to/from input devices --- dev/core.c | 20 +++++ dev/input.c | 39 ++++++++++ include/socks/device.h | 13 ++++ include/socks/input.h | 170 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 242 insertions(+) create mode 100644 include/socks/input.h diff --git a/dev/core.c b/dev/core.c index dfe030a..d811dc6 100644 --- a/dev/core.c +++ b/dev/core.c @@ -79,6 +79,26 @@ struct device *device_alloc(void) return DEVICE_CAST(dev_object); } +kern_status_t device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read) +{ + switch (dev->dev_type) { + case DEV_TYPE_INPUT: + return input_device_read(dev, buf, size, bytes_read); + default: + return KERN_UNSUPPORTED; + } +} + +kern_status_t device_write(struct device *dev, const void *buf, size_t size, size_t *bytes_written) +{ + return KERN_UNSUPPORTED; +} + +struct device *cast_to_device(struct object *obj) +{ + return DEVICE_CAST(obj); +} + static kern_status_t device_object_destroy(struct object *obj) { return KERN_OK; diff --git a/dev/input.c b/dev/input.c index 6b6be23..80d12d7 100644 --- a/dev/input.c +++ b/dev/input.c @@ -1,4 +1,5 @@ #include +#include struct input_device *input_device_create(void) { @@ -8,5 +9,43 @@ struct input_device *input_device_create(void) } dev->dev_type = DEV_TYPE_INPUT; + + struct input_device *input_dev = INPUT_DEVICE(dev); + if (ringbuffer_init(&input_dev->i_events, INPUT_DEVICE_EVENT_QUEUE_SIZE * sizeof(struct input_event)) != KERN_OK) { + /* TODO destroy device */ + return NULL; + } + return INPUT_DEVICE(dev); } + +kern_status_t input_device_report_event(struct input_device *dev, const struct input_event *ev, bool noblock) +{ + struct ringbuffer *event_queue = &dev->i_events; + enum ringbuffer_flags flags = RB_NORMAL; + if (noblock) { + flags = RB_NOBLOCK; + } + + size_t r = ringbuffer_write(event_queue, sizeof *ev, ev, flags); + + return r == sizeof *ev ? KERN_OK : KERN_WOULD_BLOCK; +} + +kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read) +{ + if (dev->dev_type != DEV_TYPE_INPUT || (size % sizeof (struct input_event)) != 0) { + return KERN_INVALID_ARGUMENT; + } + + struct input_device *input_dev = INPUT_DEVICE(dev); + struct ringbuffer *event_queue = &input_dev->i_events; + + size_t r = ringbuffer_read(event_queue, size, buf, RB_NORMAL); + + if (bytes_read) { + *bytes_read = r; + } + + return KERN_OK; +} diff --git a/include/socks/device.h b/include/socks/device.h index 5f93765..e48ef46 100644 --- a/include/socks/device.h +++ b/include/socks/device.h @@ -4,11 +4,15 @@ #include #include #include +#include struct device; +struct input_event; #define DEV_NAME_MAX OBJECT_NAME_MAX +#define INPUT_DEVICE_EVENT_QUEUE_SIZE 128 + #define BLOCK_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_BLOCK ? &(dev)->blk : NULL); #define CHAR_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_CHAR ? &(dev)->chr : NULL); #define NET_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_NET ? &(dev)->net : NULL); @@ -63,6 +67,7 @@ struct net_device { struct input_device { struct input_device_ops *i_ops; + struct ringbuffer i_events; }; struct bus_device { @@ -103,6 +108,11 @@ static inline void device_unlock_irqrestore(struct device *dev, unsigned long fl object_unlock(&dev->dev_base, flags); } +extern kern_status_t device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read); +extern kern_status_t device_write(struct device *dev, const void *buf, size_t size, size_t *bytes_written); + +extern struct device *cast_to_device(struct object *obj); + extern struct char_device *char_device_create(void); extern struct block_device *block_device_create(void); extern struct net_device *net_device_create(void); @@ -136,4 +146,7 @@ static inline struct device *bus_device_base(struct bus_device *dev) extern kern_status_t device_register(struct device *dev, 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); + #endif diff --git a/include/socks/input.h b/include/socks/input.h new file mode 100644 index 0000000..0dbcec3 --- /dev/null +++ b/include/socks/input.h @@ -0,0 +1,170 @@ +#ifndef SOCKS_INPUT_H_ +#define SOCKS_INPUT_H_ + +#include + +enum input_event_type { + INPUT_TYPE_UNKNOWN = 0x00u, + INPUT_TYPE_KEY = 0x01u, + INPUT_TYPE_MOTION = 0x02u, +}; + +enum input_event_motion_type { + INPUT_MOTION_TYPE_MOUSE = 0x01u, + INPUT_MOTION_TYPE_SCROLL = 0x02u, +}; + +enum input_keycode { + KEY_UNKNOWN = 0x00u, + KEY_A = 0x01u, + KEY_B = 0x02u, + KEY_C = 0x03u, + KEY_D = 0x04u, + KEY_E = 0x05u, + KEY_F = 0x06u, + KEY_G = 0x07u, + KEY_H = 0x08u, + KEY_I = 0x09u, + KEY_J = 0x0Au, + KEY_K = 0x0Bu, + KEY_L = 0x0Cu, + KEY_M = 0x0Du, + KEY_N = 0x0Eu, + KEY_O = 0x0Fu, + KEY_P = 0x10u, + KEY_Q = 0x11u, + KEY_R = 0x12u, + KEY_S = 0x13u, + KEY_T = 0x14u, + KEY_U = 0x15u, + KEY_V = 0x16u, + KEY_W = 0x17u, + KEY_X = 0x18u, + KEY_Y = 0x19u, + KEY_Z = 0x1Au, + KEY_KEY_1 = 0x1Bu, + KEY_KEY_2 = 0x1Cu, + KEY_KEY_3 = 0x1Du, + KEY_KEY_4 = 0x1Eu, + KEY_KEY_5 = 0x1Fu, + KEY_KEY_6 = 0x20u, + KEY_KEY_7 = 0x21u, + KEY_KEY_8 = 0x22u, + KEY_KEY_9 = 0x23u, + KEY_KEY_0 = 0x24u, + KEY_ENTER = 0x25u, + KEY_ESCAPE = 0x26u, + KEY_BACKSPACE = 0x27u, + KEY_TAB = 0x28u, + KEY_SPACE = 0x29u, + KEY_MINUS = 0x2Au, + KEY_EQUALS = 0x2Bu, + KEY_LEFT_BRACE = 0x2Cu, + KEY_RIGHT_BRACE = 0x2Du, + KEY_BACKSLASH = 0x2Eu, + KEY_NON_US_HASH = 0x2Fu, + KEY_SEMICOLON = 0x30u, + KEY_APOSTROPHE = 0x31u, + KEY_GRAVE_ACCENT = 0x32u, + KEY_COMMA = 0x33u, + KEY_DOT = 0x34u, + KEY_SLASH = 0x35u, + KEY_CAPS_LOCK = 0x36u, + KEY_F1 = 0x37u, + KEY_F2 = 0x38u, + KEY_F3 = 0x39u, + KEY_F4 = 0x3Au, + KEY_F5 = 0x3Bu, + KEY_F6 = 0x3Cu, + KEY_F7 = 0x3Du, + KEY_F8 = 0x3Eu, + KEY_F9 = 0x3Fu, + KEY_F10 = 0x40u, + KEY_F11 = 0x41u, + KEY_F12 = 0x42u, + KEY_PRINT_SCREEN = 0x43u, + KEY_SCROLL_LOCK = 0x44u, + KEY_PAUSE = 0x45u, + KEY_INSERT = 0x46u, + KEY_HOME = 0x47u, + KEY_PAGE_UP = 0x48u, + KEY_DELETE = 0x49u, + KEY_END = 0x4Au, + KEY_PAGE_DOWN = 0x4Bu, + KEY_RIGHT = 0x4Cu, + KEY_LEFT = 0x4Du, + KEY_DOWN = 0x4Eu, + KEY_UP = 0x4Fu, + KEY_NUM_LOCK = 0x50u, + KEY_KEYPAD_SLASH = 0x51u, + KEY_KEYPAD_ASTERISK = 0x52u, + KEY_KEYPAD_MINUS = 0x53u, + KEY_KEYPAD_PLUS = 0x54u, + KEY_KEYPAD_ENTER = 0x55u, + KEY_KEYPAD_1 = 0x56u, + KEY_KEYPAD_2 = 0x57u, + KEY_KEYPAD_3 = 0x58u, + KEY_KEYPAD_4 = 0x59u, + KEY_KEYPAD_5 = 0x5Au, + KEY_KEYPAD_6 = 0x5Bu, + KEY_KEYPAD_7 = 0x5Cu, + KEY_KEYPAD_8 = 0x5Du, + KEY_KEYPAD_9 = 0x5Eu, + KEY_KEYPAD_0 = 0x5Fu, + KEY_KEYPAD_DOT = 0x60u, + KEY_NON_US_BACKSLASH = 0x61u, + KEY_KEYPAD_EQUALS = 0x62u, + KEY_MENU = 0x63u, + KEY_LEFT_CTRL = 0x64u, + KEY_LEFT_SHIFT = 0x65u, + KEY_LEFT_ALT = 0x66u, + KEY_LEFT_META = 0x67u, + KEY_RIGHT_CTRL = 0x68u, + KEY_RIGHT_SHIFT = 0x69u, + KEY_RIGHT_ALT = 0x6Au, + KEY_RIGHT_META = 0x6Bu, + KEY_MEDIA_MUTE = 0x6Cu, + KEY_MEDIA_VOLUME_INCREMENT = 0x6Du, + KEY_MEDIA_VOLUME_DECREMENT = 0x6Eu, +}; + +enum input_key_state { + INPUT_KEYSTATE_DOWN = 0x00u, + INPUT_KEYSTATE_UP = 0x01u, +}; + +enum input_button { + INPUT_BUTTON_MOUSE_LEFT = 0x00u, + INPUT_BUTTON_MOUSE_MIDDLE = 0x01u, + INPUT_BUTTON_MOUSE_RIGHT = 0x02u, + INPUT_BUTTON_MOUSE_BACK = 0x03u, + INPUT_BUTTON_MOUSE_FORWARD = 0x04u, +}; + +enum input_button_state { + INPUT_BUTTON_DOWN = 0x00u, + INPUT_BUTTON_UP = 0x01u, +}; + +struct input_event { + enum input_event_type ev_type; + union { + struct { + enum input_event_motion_type type; + int16_t movement_x; + int16_t movement_y; + } ev_motion; + + struct { + enum input_button button; + enum input_button_state state; + } ev_button; + + struct { + enum input_keycode key; + enum input_key_state state; + } ev_key; + }; +}; + +#endif