diff --git a/CMakeLists.txt b/CMakeLists.txt index 30e3c1c..515d8aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ add_executable(${STRAY_EXECUTABLE_NAME} virt_ds4.c virt_ds5.c virt_mouse.c + virt_kbd.c devices_status.c ) @@ -46,6 +47,7 @@ add_executable(${ALLINONE_EXECUTABLE_NAME} virt_ds4.c virt_ds5.c virt_mouse.c + virt_kbd.c devices_status.c dev_evdev.c dev_iio.c diff --git a/dev_out.c b/dev_out.c index 2e6182d..ef4687f 100644 --- a/dev_out.c +++ b/dev_out.c @@ -6,6 +6,7 @@ #include "virt_ds4.h" #include "virt_ds5.h" #include "virt_mouse.h" +#include "virt_kbd.h" #include @@ -198,6 +199,140 @@ static void handle_incoming_message_gamepad_set( } } +static void handle_incoming_message_keyboard_set( + const dev_out_settings_t *const in_settings, + const in_message_keyboard_set_element_t *const msg_payload, + keyboard_status_t *const inout_kbd +) { + switch (msg_payload->type) { + case KEYBOARD_KEY_Q: + inout_kbd->q = msg_payload->value; + break; + case KEYBOARD_KEY_W: + inout_kbd->w = msg_payload->value; + break; + case KEYBOARD_KEY_E: + inout_kbd->e = msg_payload->value; + break; + case KEYBOARD_KEY_R: + inout_kbd->r = msg_payload->value; + break; + case KEYBOARD_KEY_T: + inout_kbd->t = msg_payload->value; + break; + case KEYBOARD_KEY_Y: + inout_kbd->y = msg_payload->value; + break; + case KEYBOARD_KEY_U: + inout_kbd->u = msg_payload->value; + break; + case KEYBOARD_KEY_I: + inout_kbd->i = msg_payload->value; + break; + case KEYBOARD_KEY_O: + inout_kbd->o = msg_payload->value; + break; + case KEYBOARD_KEY_P: + inout_kbd->p = msg_payload->value; + break; + case KEYBOARD_KEY_A: + inout_kbd->a = msg_payload->value; + break; + case KEYBOARD_KEY_S: + inout_kbd->s = msg_payload->value; + break; + case KEYBOARD_KEY_D: + inout_kbd->d = msg_payload->value; + break; + case KEYBOARD_KEY_F: + inout_kbd->f = msg_payload->value; + break; + case KEYBOARD_KEY_G: + inout_kbd->g = msg_payload->value; + break; + case KEYBOARD_KEY_H: + inout_kbd->h = msg_payload->value; + break; + case KEYBOARD_KEY_J: + inout_kbd->j = msg_payload->value; + break; + case KEYBOARD_KEY_K: + inout_kbd->k = msg_payload->value; + break; + case KEYBOARD_KEY_L: + inout_kbd->l = msg_payload->value; + break; + case KEYBOARD_KEY_Z: + inout_kbd->z = msg_payload->value; + break; + case KEYBOARD_KEY_X: + inout_kbd->x = msg_payload->value; + break; + case KEYBOARD_KEY_C: + inout_kbd->c = msg_payload->value; + break; + case KEYBOARD_KEY_V: + inout_kbd->v = msg_payload->value; + break; + case KEYBOARD_KEY_B: + inout_kbd->b = msg_payload->value; + break; + case KEYBOARD_KEY_N: + inout_kbd->n = msg_payload->value; + break; + case KEYBOARD_KEY_M: + inout_kbd->m = msg_payload->value; + break; + case KEYBOARD_KEY_UP: + inout_kbd->up = msg_payload->value; + break; + case KEYBOARD_KEY_DOWN: + inout_kbd->down = msg_payload->value; + break; + case KEYBOARD_KEY_LEFT: + inout_kbd->left = msg_payload->value; + break; + case KEYBOARD_KEY_RIGHT: + inout_kbd->right = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_0: + inout_kbd->num_0 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_1: + inout_kbd->num_1 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_2: + inout_kbd->num_2 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_3: + inout_kbd->num_3 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_4: + inout_kbd->num_4 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_5: + inout_kbd->num_5 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_6: + inout_kbd->num_6 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_7: + inout_kbd->num_7 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_8: + inout_kbd->num_8 = msg_payload->value; + break; + case KEYBOARD_KEY_NUM_9: + inout_kbd->num_9 = msg_payload->value; + break; + case KEYBOARD_KEY_LCRTL: + inout_kbd->lctrl = msg_payload->value; + break; + default: + fprintf(stderr, "key not implemented\n"); + } +} + static void handle_incoming_message( const dev_out_settings_t *const in_settings, const in_message_t *const msg, @@ -221,6 +356,12 @@ static void handle_incoming_message( &msg->data.mouse_event, &dev_stats->mouse ); + } else if (msg->type == KEYBOARD_SET_ELEMENT) { + handle_incoming_message_keyboard_set( + in_settings, + &msg->data.kbd_set, + &dev_stats->kbd + ); } } @@ -272,6 +413,15 @@ void *dev_out_thread_func(void *ptr) { printf("Mouse initialized: fd=%d\n", current_mouse_fd); } + virt_kbd_t keyboard_data; + const int kbd_init_res = virt_kbd_init(&keyboard_data); + if (kbd_init_res < 0) { + fprintf(stderr, "Unable to initialize virtual keyboard -- will continue regardless\n"); + } else { + current_keyboard_fd = virt_kbd_get_fd(&keyboard_data); + printf("Keyboard initialized: fd=%d\n", current_keyboard_fd); + } + const int64_t kbd_report_timing_us = 1125; const int64_t mouse_report_timing_us = 950; const int64_t gamepad_report_timing_us = 1250; @@ -342,6 +492,8 @@ void *dev_out_thread_func(void *ptr) { } else if (kbd_time_diff_usecs >= kbd_report_timing_us) { keyboard_last_hid_report_sent = now; + virt_kbd_send(&keyboard_data, &dev_out_data->dev_stats.kbd, &now); + // this does reset the for, ensuring every other device has nothing to say continue; } @@ -369,7 +521,9 @@ void *dev_out_thread_func(void *ptr) { FD_SET(current_mouse_fd, &read_fds); } - // TODO: FD_SET(current_keyboard_fd, &read_fds); + if (current_mouse_fd > 0) { + FD_SET(current_keyboard_fd, &read_fds); + } if (current_gamepad_fd > 0) { FD_SET(current_gamepad_fd, &read_fds); @@ -472,6 +626,14 @@ void *dev_out_thread_func(void *ptr) { } } + if ((current_keyboard_fd > 0) && (FD_ISSET(current_keyboard_fd, &read_fds))) { + // TODO: read keyboard events + } + + if ((current_mouse_fd > 0) && (FD_ISSET(current_mouse_fd, &read_fds))) { + // TODO: read mouse events + } + // read and handle incoming data: this data is packed into in_message_t if (dev_out_data->communication.type == ipc_unix_pipe) { if (FD_ISSET(dev_out_data->communication.endpoint.pipe.in_message_pipe_fd, &read_fds)) { @@ -523,6 +685,9 @@ void *dev_out_thread_func(void *ptr) { // close the mouse device virt_mouse_close(&mouse_data); + // close the keyboard device + virt_kbd_close(&keyboard_data); + // end communication if (dev_out_data->communication.type == ipc_server_sockets) { // close every client socket diff --git a/devices_status.c b/devices_status.c index 14e38c8..ddd1b97 100644 --- a/devices_status.c +++ b/devices_status.c @@ -1,7 +1,53 @@ #include "devices_status.h" +#include void kbd_status_init(keyboard_status_t *const stats) { stats->connected = true; + + stats->q = 0; + stats->w = 0; + stats->e = 0; + stats->r = 0; + stats->t = 0; + stats->y = 0; + stats->u = 0; + stats->i = 0; + stats->o = 0; + stats->p = 0; + stats->a = 0; + stats->s = 0; + stats->d = 0; + stats->f = 0; + stats->g = 0; + stats->h = 0; + stats->j = 0; + stats->k = 0; + stats->l = 0; + stats->z = 0; + stats->x = 0; + stats->c = 0; + stats->v = 0; + stats->b = 0; + stats->n = 0; + stats->m = 0; + + stats->num_1 = 0; + stats->num_2 = 0; + stats->num_3 = 0; + stats->num_4 = 0; + stats->num_5 = 0; + stats->num_6 = 0; + stats->num_7 = 0; + stats->num_8 = 0; + stats->num_9 = 0; + stats->num_0 = 0; + + stats->up = 0; + stats->down = 0; + stats->left = 0; + stats->right = 0; + + stats->lctrl = 0; } void mouse_status_init(mouse_status_t *const stats) { @@ -53,6 +99,7 @@ void gamepad_status_init(gamepad_status_t *const stats) { } void devices_status_init(devices_status_t *const stats) { + pthread_mutex_init(&stats->mutex, NULL); gamepad_status_init(&stats->gamepad); kbd_status_init(&stats->kbd); mouse_status_init(&stats->mouse); diff --git a/devices_status.h b/devices_status.h index 869e7a7..e32f42d 100644 --- a/devices_status.h +++ b/devices_status.h @@ -67,6 +67,15 @@ typedef struct gamepad_status { typedef struct keyboard_status { bool connected; + + uint8_t q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m; + + uint8_t num_1, num_2, num_3, num_4, num_5, num_6, num_7, num_8, num_9, num_0; + + uint8_t up, down, left, right; + + uint8_t lctrl; + } keyboard_status_t; diff --git a/message.h b/message.h index 372c124..7270f5d 100644 --- a/message.h +++ b/message.h @@ -82,23 +82,73 @@ typedef enum in_message_gamepad_action { GAMEPAD_ACTION_OPEN_STEAM_QAM, } in_message_gamepad_action_t; +typedef enum kbd_element { + KEYBOARD_KEY_Q, + KEYBOARD_KEY_W, + KEYBOARD_KEY_E, + KEYBOARD_KEY_R, + KEYBOARD_KEY_T, + KEYBOARD_KEY_Y, + KEYBOARD_KEY_U, + KEYBOARD_KEY_I, + KEYBOARD_KEY_O, + KEYBOARD_KEY_P, + KEYBOARD_KEY_A, + KEYBOARD_KEY_S, + KEYBOARD_KEY_D, + KEYBOARD_KEY_F, + KEYBOARD_KEY_G, + KEYBOARD_KEY_H, + KEYBOARD_KEY_J, + KEYBOARD_KEY_K, + KEYBOARD_KEY_L, + KEYBOARD_KEY_Z, + KEYBOARD_KEY_X, + KEYBOARD_KEY_C, + KEYBOARD_KEY_V, + KEYBOARD_KEY_B, + KEYBOARD_KEY_N, + KEYBOARD_KEY_M, + KEYBOARD_KEY_UP, + KEYBOARD_KEY_DOWN, + KEYBOARD_KEY_LEFT, + KEYBOARD_KEY_RIGHT, + KEYBOARD_KEY_NUM_1, + KEYBOARD_KEY_NUM_2, + KEYBOARD_KEY_NUM_3, + KEYBOARD_KEY_NUM_4, + KEYBOARD_KEY_NUM_5, + KEYBOARD_KEY_NUM_6, + KEYBOARD_KEY_NUM_7, + KEYBOARD_KEY_NUM_8, + KEYBOARD_KEY_NUM_9, + KEYBOARD_KEY_NUM_0, + KEYBOARD_KEY_LCRTL, +} kbd_element_t; + +typedef struct in_message_keyboard_set_element { + kbd_element_t type; + uint8_t value; +} in_message_keyboard_set_element_t; + typedef enum in_in_message_type { GAMEPAD_SET_ELEMENT, GAMEPAD_ACTION, MOUSE_EVENT, + KEYBOARD_SET_ELEMENT, } in_message_type_t; typedef struct in_message { in_message_type_t type; union { - //imu_in_message_t imu; - in_message_gamepad_action_t action; in_message_gamepad_set_element_t gamepad_set; in_message_mouse_event_t mouse_event; + + in_message_keyboard_set_element_t kbd_set; } data; } in_message_t; diff --git a/platform.c b/platform.c deleted file mode 100644 index dee1d51..0000000 --- a/platform.c +++ /dev/null @@ -1,276 +0,0 @@ -#include -#include -#include - -#include - -#include "platform.h" - -static const char* const platform_input_path = "/sys/devices/platform/asus-mcu.0/input/mode"; - -static int hidraw_cycle_to_mode(const char* const path, int controller_mode) { - int res = 0; - - if ((controller_mode < 0) || (controller_mode > 2)) { - res = -EINVAL; - goto hidraw_cycle_to_mode_err_mode; - } - - const char* hidraw_subdir = "/hidraw/"; - - const unsigned long len = strlen(path) + strlen(hidraw_subdir) + 64; - char* hidraw_path = malloc(len + 1); - if (hidraw_path == NULL) { - res = -ENOMEM; - goto hidraw_cycle_to_mode_err_path; - } - - memset(hidraw_path, 0, len + 1); - strcat(hidraw_path, path); - strcat(hidraw_path, hidraw_subdir); - - DIR *d; - struct dirent *dir; - d = opendir(hidraw_path); - if (d) { - while ((dir = readdir(d)) != NULL) { - if (strstr(dir->d_name, "hidraw") == NULL) { // h as in hidraw - continue; - } - - memset(hidraw_path, 0, len + 1); - strcat(hidraw_path, "/dev/"); - strcat(hidraw_path, dir->d_name); - - //strcat(hidraw_path, dir->d_name); - //strcat(hidraw_path, "/dev"); - - printf("Using hidraw located at: %s\n", hidraw_path); - - int fd = open(hidraw_path, O_RDWR); - if (fd == -1) { - fprintf(stderr, "Error opening hidraw device %s\n", hidraw_path); - - res = -EIO; - - goto hidraw_cycle_to_mode_err; - } - - for (int i = 0; i < 23; ++i) { - const int write_res = write(fd, &rc71l_mode_switch_commands[controller_mode][i][0], 64); - if (write_res != 64) { - fprintf(stderr, "Error writing packet %d/23: %d bytes sent, 64 expected\n", i, write_res); - break; - } - } - - close(fd); - - if (res == 0) { - printf("Control messages sent successfully.\n"); - } else { - goto hidraw_cycle_to_mode_err; - } - - } - } - - - -hidraw_cycle_to_mode_err: - free(hidraw_path); - -hidraw_cycle_to_mode_err_path: -hidraw_cycle_to_mode_err_mode: - return res; -} - -static char* find_device(struct udev *udev) { - struct udev_enumerate *const enumerate = udev_enumerate_new(udev); - if (enumerate == NULL) { - fprintf(stderr, "Error in udev_enumerate_new: mode switch will not be available.\n"); - return NULL; - } - - const int add_match_subsystem_res = udev_enumerate_add_match_subsystem(enumerate, "hid"); - if (add_match_subsystem_res != 0) { - fprintf(stderr, "Error in udev_enumerate_add_match_subsystem: %d\n", add_match_subsystem_res); - - udev_enumerate_unref(enumerate); - - return NULL; - } - - const int add_match_sysattr_res = udev_enumerate_add_match_sysattr(enumerate, "gamepad_mode", NULL); - if (add_match_sysattr_res != 0) { - fprintf(stderr, "Error in udev_enumerate_add_match_sysattr: %d\n", add_match_sysattr_res); - - udev_enumerate_unref(enumerate); - - return NULL; - } - - const int enumerate_scan_devices_res = udev_enumerate_scan_devices(enumerate); - if (enumerate_scan_devices_res != 0) { - fprintf(stderr, "Error in udev_enumerate_scan_devices: %d\n", enumerate_scan_devices_res); - - udev_enumerate_unref(enumerate); - - return NULL; - } - - struct udev_list_entry *const udev_lst_frst = udev_enumerate_get_list_entry(enumerate); - - struct udev_list_entry *list_entry = NULL; - udev_list_entry_foreach(list_entry, udev_lst_frst) { - const char* const name = udev_list_entry_get_name(list_entry); - - const unsigned long len = strlen(name) + 1; - char *const result = malloc(len); - memset(result, 0, len); - strncat(result, name, len - 1); - - udev_enumerate_unref(enumerate); - - return result; - } - - udev_enumerate_unref(enumerate); - return NULL; -} - -int init_platform(rc71l_platform_t *const platform) { - platform->udev = NULL; - - if (access(platform_input_path, F_OK) != 0) { - fprintf(stderr, "Unable to find the MCU platform mode file %s: asus-mcu not found.\n", platform_input_path); - - /* create udev object */ - platform->udev = udev_new(); - if (platform->udev == NULL) { - fprintf(stderr, "Cannot create udev context: mode switch will not be available.\n"); - platform->mode = -1; - return -ENOENT; - } - - char *const dev_name = find_device(platform->udev); - if (dev_name == NULL) { - fprintf(stderr, "Cannot locate asus-mcu device: mode switch will not be available.\n"); - platform->mode = -1; - return -ENOENT; - } else { - printf("Asus MCU over hidraw: %s -- mode will be reset\n", dev_name); - - platform->platform_mode = rc71l_platform_mode_hidraw; - platform->modes_count = 2; - platform->mode = 0; - - // reset to mode 0: game mode - const int reset_res = hidraw_cycle_to_mode(dev_name, 0); - if (reset_res != 0) { - fprintf(stderr, "Unable to reset Asus MCU over hidraw: %d -- Asus MCU will be unavailable.\n", reset_res); - - free(dev_name); - - return -EIO; - } - - // find_device does malloc - free(dev_name); - - return 0; - } - - return -ENOENT; - } - - FILE* mode_file = fopen(platform_input_path, "r"); - if (mode_file == NULL) { - fprintf(stderr, "Unable to open the MCU platform mode file %s: modes cannot be switched.\n", platform_input_path); - platform->mode = -1; - return -EINVAL; - } - - char mode_str[12]; - unsigned long read_bytes = fread((void*)&mode_str[0], 1, sizeof(mode_str), mode_file); - if (read_bytes < 1) { - fprintf(stderr, "Unable to read the MCU platform mode file %s: no bytes.\n", platform_input_path); - fclose(mode_file); - platform->mode = -1; - return -EINVAL; - } - - platform->mode = strtoul(&mode_str[0], NULL, 10); - - fclose(mode_file); - - printf("Asus MCU platform found: current mode %lu\n", platform->mode); - platform->modes_count = 2; - - platform->platform_mode = rc71l_platform_mode_asus_mcu; - - return 0; -} - -int cycle_mode(rc71l_platform_t *const platform) { - if (platform == NULL) { - return -ENOENT; - } - - char new_mode_str[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00 - }; - - unsigned long new_mode = (platform->mode + 1) % platform->modes_count; - sprintf(new_mode_str, "%lu\n", new_mode); - - if (platform->platform_mode == rc71l_platform_mode_hidraw) { - char *const dev_name = find_device(platform->udev); - if (dev_name == NULL) { - fprintf(stderr, "Unable to locate Asus MCU hidraw to mode-switch. Mode will not be switched.\n"); - return -ENOENT; - } - - const int next_mode = (platform->mode + 1) % platform->modes_count; - - const int reset_res = hidraw_cycle_to_mode(dev_name, next_mode); - if (reset_res != 0) { - fprintf(stderr, "Unable to change mode of Asus MCU over hidraw: %d.\n", reset_res); - } - - free(dev_name); - - platform->mode = next_mode; - - printf("Used hidraw to switch Asus MCU to mode %lu\n", platform->mode); - - return reset_res; - } else if (platform->platform_mode == rc71l_platform_mode_asus_mcu) { - FILE* mode_file = fopen(platform_input_path, "w"); - if (mode_file == NULL) { - fprintf(stderr, "Unable to open the MCU platform mode file %s: modes cannot be switched.\n", platform_input_path); - return -1; - } - - size_t len = strlen(new_mode_str); - const int write_bytes = fwrite((void*)&new_mode_str[0], 1, len, mode_file); - if (write_bytes < len) { - fprintf(stderr, "Error writing new mode: expected to write %d bytes, %d written.\n", (int)len, (int)write_bytes); - return -EIO; - } - - platform->mode = new_mode; - - printf("Used asus-mcu to switch Asus MCU to mode %lu\n", platform->mode); - - fclose(mode_file); - } - - return -ENOENT; -} - -int is_mouse_mode(rc71l_platform_t *const platform) { - return platform != NULL ? platform->mode == 1 : 0; -} diff --git a/platform.h b/platform.h deleted file mode 100644 index 26cbf0f..0000000 --- a/platform.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "rogue_enemy.h" - -typedef enum rc71l_platform_mode { - rc71l_platform_mode_hidraw, - rc71l_platform_mode_asus_mcu, -} rc71l_platform_mode_t; - -typedef struct rc71l_platform { - struct udev *udev; - - rc71l_platform_mode_t platform_mode; - - unsigned long mode; - unsigned int modes_count; -} rc71l_platform_t; - -int init_platform(rc71l_platform_t *const platform); - -int cycle_mode(rc71l_platform_t *const platform); - -int is_mouse_mode(rc71l_platform_t *const platform); diff --git a/rog_ally.c b/rog_ally.c index 8b201aa..e827627 100644 --- a/rog_ally.c +++ b/rog_ally.c @@ -219,7 +219,7 @@ static int asus_kbd_ev_map( sscanf(current_mode_str, "%d", ¤t_mode); const int new_mode = get_next_mode(current_mode); - printf("Current mode is set to %d (read from %s) -- switching to %d", current_mode, current_mode_str, new_mode); + printf("Current mode is set to %d (read from %s) -- switching to %d\n", current_mode, current_mode_str, new_mode); char new_mode_str[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; snprintf(new_mode_str, sizeof(new_mode_str) - 1, "%d", new_mode); @@ -236,10 +236,10 @@ static int asus_kbd_ev_map( } } else { close(gamepad_mode_fd); - fprintf(stderr, "Unable to read gamepad_mode file to get current mode: %d", errno); + fprintf(stderr, "Unable to read gamepad_mode file to get current mode: %d\n", errno); } } else { - fprintf(stderr, "Unable to open gamepad_mode file in read-only mode to get current mode: %d", errno); + fprintf(stderr, "Unable to open gamepad_mode file in read-only mode to get current mode: %d\n", errno); } free(tmp_path); @@ -283,6 +283,486 @@ static int asus_kbd_ev_map( } }; + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_Q) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_Q, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_W) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_W, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_E) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_E, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_R) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_R, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_T) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_T, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_Y) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_Y, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_U) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_U, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_I) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_I, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_O) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_O, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_P) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_P, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_A) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_A, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_S) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_S, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_D) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_D, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_F) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_F, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_G) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_G, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_H) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_H, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_J) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_J, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_K) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_K, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_L) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_L, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_Z) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_Z, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_X) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_X, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_C) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_C, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_V) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_V, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_B) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_B, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_N) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_N, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_M) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_M, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_0) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_0, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_1) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_1, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_2) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_2, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_3) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_3, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_4) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_4, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_5) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_5, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_6) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_6, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_7) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_7, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_8) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_8, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_9) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_NUM_9, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_UP) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_UP, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_DOWN) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_DOWN, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_LEFT) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_LEFT, + .value = e->ev[i].value + } + } + }; + + messages[written_msg++] = current_message; + } else if (e->ev[i].code == KEY_RIGHT) { + const in_message_t current_message = { + .type = KEYBOARD_SET_ELEMENT, + .data = { + .kbd_set = { + .type = KEYBOARD_KEY_RIGHT, + .value = e->ev[i].value + } + } + }; + messages[written_msg++] = current_message; } } else if (e->ev[i].type == EV_REL) { diff --git a/virt_kbd.c b/virt_kbd.c new file mode 100644 index 0000000..db8dbc0 --- /dev/null +++ b/virt_kbd.c @@ -0,0 +1,510 @@ +#include "virt_kbd.h" +#include "message.h" +#include + +int virt_kbd_init(virt_kbd_t *const kbd) { + int ret = -EINVAL; + + memset(kbd, 0, sizeof(virt_kbd_t)); + + int fd = open("/dev/uinput", O_RDWR); + if(fd < 0) { + ret = errno; + goto virt_mouse_init_err; + } + + ioctl(fd, UI_SET_EVBIT, EV_REL); + ioctl(fd, UI_SET_EVBIT, EV_KEY); + ioctl(fd, UI_SET_EVBIT, EV_MSC); + ioctl(fd, UI_SET_EVBIT, EV_SYN); + ioctl(fd, UI_SET_MSCBIT, MSC_TIMESTAMP); + ioctl(fd, UI_SET_KEYBIT, KEY_Q); + ioctl(fd, UI_SET_KEYBIT, KEY_W); + ioctl(fd, UI_SET_KEYBIT, KEY_E); + ioctl(fd, UI_SET_KEYBIT, KEY_R); + ioctl(fd, UI_SET_KEYBIT, KEY_T); + ioctl(fd, UI_SET_KEYBIT, KEY_Y); + ioctl(fd, UI_SET_KEYBIT, KEY_U); + ioctl(fd, UI_SET_KEYBIT, KEY_I); + ioctl(fd, UI_SET_KEYBIT, KEY_O); + ioctl(fd, UI_SET_KEYBIT, KEY_P); + ioctl(fd, UI_SET_KEYBIT, KEY_A); + ioctl(fd, UI_SET_KEYBIT, KEY_S); + ioctl(fd, UI_SET_KEYBIT, KEY_D); + ioctl(fd, UI_SET_KEYBIT, KEY_F); + ioctl(fd, UI_SET_KEYBIT, KEY_G); + ioctl(fd, UI_SET_KEYBIT, KEY_H); + ioctl(fd, UI_SET_KEYBIT, KEY_J); + ioctl(fd, UI_SET_KEYBIT, KEY_K); + ioctl(fd, UI_SET_KEYBIT, KEY_L); + ioctl(fd, UI_SET_KEYBIT, KEY_Z); + ioctl(fd, UI_SET_KEYBIT, KEY_X); + ioctl(fd, UI_SET_KEYBIT, KEY_C); + ioctl(fd, UI_SET_KEYBIT, KEY_V); + ioctl(fd, UI_SET_KEYBIT, KEY_B); + ioctl(fd, UI_SET_KEYBIT, KEY_N); + ioctl(fd, UI_SET_KEYBIT, KEY_M); + ioctl(fd, UI_SET_KEYBIT, KEY_1); + ioctl(fd, UI_SET_KEYBIT, KEY_2); + ioctl(fd, UI_SET_KEYBIT, KEY_3); + ioctl(fd, UI_SET_KEYBIT, KEY_4); + ioctl(fd, UI_SET_KEYBIT, KEY_5); + ioctl(fd, UI_SET_KEYBIT, KEY_6); + ioctl(fd, UI_SET_KEYBIT, KEY_7); + ioctl(fd, UI_SET_KEYBIT, KEY_8); + ioctl(fd, UI_SET_KEYBIT, KEY_9); + ioctl(fd, UI_SET_KEYBIT, KEY_0); + ioctl(fd, UI_SET_KEYBIT, KEYBOARD_KEY_LCRTL); + + struct uinput_setup dev = {0}; + strncpy(dev.name, VIRT_KBD_DEV_NAME, UINPUT_MAX_NAME_SIZE-1); + dev.id.bustype = BUS_VIRTUAL; + dev.id.vendor = VIRT_KBD_DEV_VENDOR_ID; + dev.id.product = VIRT_KBD_DEV_PRODUCT_ID; + dev.id.version = VIRT_KBD_DEV_VERSION; + + if(ioctl(fd, UI_DEV_SETUP, &dev) < 0) { + ret = errno > 0 ? errno : -1 * errno; + ret = ret == 0 ? -EIO : ret; + goto virt_mouse_init_err; + } + + if(ioctl(fd, UI_DEV_CREATE) < 0) { + ret = errno > 0 ? errno : -1 * errno; + ret = ret == 0 ? -EIO : ret; + goto virt_mouse_init_err; + } + + // initialization ok + kbd->fd = fd; + ret = 0; + +virt_mouse_init_err: + if (ret != 0) { + kbd->fd = -1; + close(fd); + } + + return ret; +} + +int virt_kbd_get_fd(virt_kbd_t *const kbd) { + return kbd->fd; +} + +int virt_kbd_send(virt_kbd_t *const kbd, keyboard_status_t *const status, struct timeval *const now) { + int res = 0; + + struct timeval syn_time; + gettimeofday(&syn_time, NULL); + + struct input_event tmp_ev; + gettimeofday(&tmp_ev.time, NULL); + if (now != NULL) { + tmp_ev.time = *now; + } + + tmp_ev.type = EV_KEY; + + if (status->q != kbd->prev_q) { + tmp_ev.code = KEY_Q; + tmp_ev.value = kbd->prev_q = status->q; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->w != kbd->prev_w) { + tmp_ev.code = KEY_W; + tmp_ev.value = kbd->prev_w = status->w; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->e != kbd->prev_e) { + tmp_ev.code = KEY_E; + tmp_ev.value = kbd->prev_e = status->e; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->r != kbd->prev_r) { + tmp_ev.code = KEY_R; + tmp_ev.value = kbd->prev_r = status->r; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->t != kbd->prev_t) { + tmp_ev.code = KEY_T; + tmp_ev.value = kbd->prev_t = status->t; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->y != kbd->prev_y) { + tmp_ev.code = KEY_Y; + tmp_ev.value = kbd->prev_y = status->y; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->u != kbd->prev_u) { + tmp_ev.code = KEY_U; + tmp_ev.value = kbd->prev_u = status->u; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->i != kbd->prev_i) { + tmp_ev.code = KEY_I; + tmp_ev.value = kbd->prev_i = status->i; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->o != kbd->prev_o) { + tmp_ev.code = KEY_O; + tmp_ev.value = kbd->prev_o = status->o; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->p != kbd->prev_p) { + tmp_ev.code = KEY_P; + tmp_ev.value = kbd->prev_p = status->p; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->a != kbd->prev_a) { + tmp_ev.code = KEY_A; + tmp_ev.value = kbd->prev_a = status->a; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->s != kbd->prev_s) { + tmp_ev.code = KEY_S; + tmp_ev.value = kbd->prev_s = status->s; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + + if (status->d != kbd->prev_d) { + tmp_ev.code = KEY_D; + tmp_ev.value = kbd->prev_d = status->d; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->f != kbd->prev_f) { + tmp_ev.code = KEY_F; + tmp_ev.value = kbd->prev_f = status->f; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->g != kbd->prev_g) { + tmp_ev.code = KEY_G; + tmp_ev.value = kbd->prev_g = status->g; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->h != kbd->prev_h) { + tmp_ev.code = KEY_H; + tmp_ev.value = kbd->prev_h = status->h; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->j != kbd->prev_j) { + tmp_ev.code = KEY_J; + tmp_ev.value = kbd->prev_j = status->j; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->k != kbd->prev_k) { + tmp_ev.code = KEY_K; + tmp_ev.value = kbd->prev_k = status->k; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->l != kbd->prev_l) { + tmp_ev.code = KEY_L; + tmp_ev.value = kbd->prev_l = status->l; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->z != kbd->prev_z) { + tmp_ev.code = KEY_Z; + tmp_ev.value = kbd->prev_z = status->z; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->x != kbd->prev_x) { + tmp_ev.code = KEY_X; + tmp_ev.value = kbd->prev_x = status->x; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->c != kbd->prev_c) { + tmp_ev.code = KEY_C; + tmp_ev.value = kbd->prev_c = status->c; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->v != kbd->prev_v) { + tmp_ev.code = KEY_V; + tmp_ev.value = kbd->prev_v = status->v; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->b != kbd->prev_b) { + tmp_ev.code = KEY_B; + tmp_ev.value = kbd->prev_b = status->b; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->n != kbd->prev_n) { + tmp_ev.code = KEY_N; + tmp_ev.value = kbd->prev_n = status->n; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->m != kbd->prev_m) { + tmp_ev.code = KEY_M; + tmp_ev.value = kbd->prev_m = status->m; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_0 != kbd->prev_num_0) { + tmp_ev.code = KEY_0; + tmp_ev.value = kbd->prev_num_0 = status->num_0; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_1 != kbd->prev_num_1) { + tmp_ev.code = KEY_1; + tmp_ev.value = kbd->prev_num_1 = status->num_1; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_2 != kbd->prev_num_2) { + tmp_ev.code = KEY_2; + tmp_ev.value = kbd->prev_num_2 = status->num_2; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_3 != kbd->prev_num_3) { + tmp_ev.code = KEY_3; + tmp_ev.value = kbd->prev_num_3 = status->num_3; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_4 != kbd->prev_num_4) { + tmp_ev.code = KEY_4; + tmp_ev.value = kbd->prev_num_4 = status->num_4; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_5 != kbd->prev_num_5) { + tmp_ev.code = KEY_5; + tmp_ev.value = kbd->prev_num_5 = status->num_5; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_6 != kbd->prev_num_6) { + tmp_ev.code = KEY_6; + tmp_ev.value = kbd->prev_num_6 = status->num_6; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_7 != kbd->prev_num_7) { + tmp_ev.code = KEY_7; + tmp_ev.value = kbd->prev_num_7 = status->num_7; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_8 != kbd->prev_num_8) { + tmp_ev.code = KEY_8; + tmp_ev.value = kbd->prev_num_8 = status->num_8; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->num_9 != kbd->prev_num_9) { + tmp_ev.code = KEY_9; + tmp_ev.value = kbd->prev_num_9 = status->num_9; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->lctrl != kbd->prev_lctrl) { + tmp_ev.code = KEYBOARD_KEY_LCRTL; + tmp_ev.value = kbd->prev_lctrl = status->lctrl; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->up != kbd->prev_up) { + tmp_ev.code = KEYBOARD_KEY_UP; + tmp_ev.value = kbd->prev_up = status->up; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->down != kbd->prev_down) { + tmp_ev.code = KEYBOARD_KEY_DOWN; + tmp_ev.value = kbd->prev_down = status->down; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->left != kbd->prev_left) { + tmp_ev.code = KEYBOARD_KEY_LEFT; + tmp_ev.value = kbd->prev_left = status->left; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + if (status->right != kbd->prev_right) { + tmp_ev.code = KEYBOARD_KEY_RIGHT; + tmp_ev.value = kbd->prev_right = status->right; + if (write(kbd->fd, &tmp_ev, sizeof(tmp_ev)) != sizeof(struct input_event)) { + res = errno < 0 ? errno : -1 * errno; + goto virt_kbd_send_err; + } + } + + #if 0 + const struct input_event timestamp_ev = { + .code = MSC_TIMESTAMP, + .type = EV_MSC, + .value = (now.tv_sec - secAtInit)*1000000 + (now.tv_usec - usecAtInit), + .time = now, + }; + const ssize_t timestamp_written = write(fd, (void*)×tamp_ev, sizeof(timestamp_ev)); + if (timestamp_written != sizeof(timestamp_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", timestamp_written, sizeof(timestamp_ev)); + } + #endif + + syn_time.tv_usec += 1; + const struct input_event syn_ev = { + .code = SYN_REPORT, + .type = EV_SYN, + .value = 0, + .time = syn_time, + }; + const ssize_t sync_written = write(kbd->fd, (void*)&syn_ev, sizeof(syn_ev)); + if (sync_written != sizeof(syn_ev)) { + fprintf(stderr, "Error in sync: written %ld bytes out of %ld\n", sync_written, sizeof(syn_ev)); + } + +virt_kbd_send_err: + return res; +} + +void virt_kbd_close(virt_kbd_t *const kbd) { + close(kbd->fd); +} \ No newline at end of file diff --git a/virt_kbd.h b/virt_kbd.h new file mode 100644 index 0000000..542039a --- /dev/null +++ b/virt_kbd.h @@ -0,0 +1,67 @@ +#pragma once + +#include "message.h" +#include "devices_status.h" + +#define VIRT_KBD_DEV_NAME "ROGueENEMY - kbd" +#define VIRT_KBD_DEV_VENDOR_ID 0x108c +#define VIRT_KBD_DEV_PRODUCT_ID 0x0323 +#define VIRT_KBD_DEV_VERSION 0x0111 + +typedef struct virt_kbd { + int fd; + + uint8_t prev_q; + uint8_t prev_w; + uint8_t prev_e; + uint8_t prev_r; + uint8_t prev_t; + uint8_t prev_y; + uint8_t prev_u; + uint8_t prev_i; + uint8_t prev_o; + uint8_t prev_p; + uint8_t prev_a; + uint8_t prev_s; + uint8_t prev_d; + uint8_t prev_f; + uint8_t prev_g; + uint8_t prev_h; + uint8_t prev_j; + uint8_t prev_k; + uint8_t prev_l; + uint8_t prev_z; + uint8_t prev_x; + uint8_t prev_c; + uint8_t prev_v; + uint8_t prev_b; + uint8_t prev_n; + uint8_t prev_m; + + uint8_t prev_num_1; + uint8_t prev_num_2; + uint8_t prev_num_3; + uint8_t prev_num_4; + uint8_t prev_num_5; + uint8_t prev_num_6; + uint8_t prev_num_7; + uint8_t prev_num_8; + uint8_t prev_num_9; + uint8_t prev_num_0; + + uint8_t prev_up; + uint8_t prev_down; + uint8_t prev_left; + uint8_t prev_right; + + uint8_t prev_lctrl; + +} virt_kbd_t; + +int virt_kbd_init(virt_kbd_t *const mouse); + +int virt_kbd_get_fd(virt_kbd_t *const mouse); + +int virt_kbd_send(virt_kbd_t *const mouse, keyboard_status_t *const status, struct timeval *const now); + +void virt_kbd_close(virt_kbd_t *const mouse); \ No newline at end of file diff --git a/virt_mouse.c b/virt_mouse.c index f09db6c..24374f8 100644 --- a/virt_mouse.c +++ b/virt_mouse.c @@ -1,7 +1,4 @@ #include "virt_mouse.h" -#include -#include -#include int virt_mouse_init(virt_mouse_t *const mouse) { int ret = -EINVAL; diff --git a/virt_mouse.h b/virt_mouse.h index 1ac8da5..2c6477a 100644 --- a/virt_mouse.h +++ b/virt_mouse.h @@ -4,7 +4,6 @@ #include "devices_status.h" #define VIRT_MOUSE_DEV_NAME "ROGueENEMY - mouse" - #define VIRT_MOUSE_DEV_VENDOR_ID 0x108c #define VIRT_MOUSE_DEV_PRODUCT_ID 0x0323 #define VIRT_MOUSE_DEV_VERSION 0x0111