#include #include #include #include "global_defs.h" #include void open_wii(int* controller_event_fptrs, uint64_t* connected_controllers, int choice) { //Determine if WII REMOTE is connected via bluetooth int wii[4] = { 0 }; FILE* wii_pipe = popen("cat /proc/bus/input/devices | \ grep -A 5 \"^I: Bus=0005 Vendor=057e Product=0306\" | \ grep \"event\" | \ cut -d 't' -f2 | \ cut -d ' ' -f1 | \ paste - -s", \ "r"); fscanf(wii_pipe, "%2d %2d %2d %2d", &wii[GYRO], &wii[IR], &wii[BUTTONS], &wii[NUNCHUK]); if ( wii[GYRO] != 0 && wii[IR] != 0 && wii[BUTTONS] != 0) { //wii is connected, create strings of event PATHS, open event files char wii_events[NUM_EVENTS_WII][26]; snprintf(wii_events[GYRO], 25, "/dev/input/event%d", wii[GYRO]); snprintf(wii_events[IR], 25, "/dev/input/event%d", wii[IR]); snprintf(wii_events[BUTTONS], 25, "/dev/input/event%d", wii[BUTTONS]); controller_event_fptrs[WII_GYRO] = open(wii_events[GYRO], O_RDONLY); controller_event_fptrs[WII_IR] = open(wii_events[IR], O_RDONLY); controller_event_fptrs[WII_BUTTONS] = open(wii_events[BUTTONS], O_RDONLY); //tell user and program that this device is available for use *connected_controllers |= NINTENDO_GYRO_IR_AND_BUTTONS; if (choice) { fprintf(stderr, "%4d: NINTENDO WII GYRO\n", NINTENDO_GYRO_BIT); fprintf(stderr, "%4d: NINTENDO WII IR \n", NINTENDO_IR_BIT); fprintf(stderr, "%4d: NINTENDO WII BUTTONS\n", NINTENDO_BUTTONS_BIT); fprintf(stderr, "%4d: NINTENDO WII GYRO AND IR\n", NINTENDO_GYRO_AND_IR); fprintf(stderr, "%4d: NINTENDO WII GYRO AND BUTTONS\n", NINTENDO_GYRO_AND_BUTTONS); fprintf(stderr, "%4d: NINTENDO WII IR AND BUTTONS\n", NINTENDO_IR_AND_BUTTONS); fprintf(stderr, "%4d: NINTENDO WII GYRO AND IR AND BUTTONS\n", NINTENDO_GYRO_IR_AND_BUTTONS); } //NUNCHUK CONNECTED? if (wii[NUNCHUK] != 0) { *connected_controllers |= NINTENDO_ALL_BITS; snprintf(wii_events[NUNCHUK], 25, "/dev/input/event%d", wii[NUNCHUK]); controller_event_fptrs[WII_NUNCHUK] = open(wii_events[NUNCHUK], O_RDONLY); if (choice) { fprintf(stderr, "%4d: NINTENDO WII NUNCHUK\n", NINTENDO_NUNCHUK_BIT); fprintf(stderr, "%4d: NINTENDO WII GYRO AND NUNCHUK\n", NINTENDO_GYRO_AND_NUNCHUK); fprintf(stderr, "%4d: NINTENDO WII IR AND NUNCHUK\n", NINTENDO_IR_AND_NUNCHUK); fprintf(stderr, "%4d: NINTENDO WII BUTTONS AND NUNCHUK\n", NINTENDO_BUTTONS_AND_NUNCHUK); fprintf(stderr, "%4d: NINTENDO WII GYRO AND IR AND NUNCHUK\n", NINTENDO_GYRO_IR_AND_NUNCHUK); fprintf(stderr, "%4d: NINTENDO WII GYRO AND BUTTONS AND NUNCHUK\n", NINTENDO_GYRO_BUTTONS_AND_NUNCHUK); fprintf(stderr, "%4d: NINTENDO WII IR AND BUTTONS AND NUNCHUK\n", NINTENDO_IR_BUTTONS_AND_NUNCHUK); fprintf(stderr, "%4d: ALL NINTENDO BT\n", NINTENDO_ALL_BITS); } } } } void open_ps4_bt(int* controller_event_fptrs, uint64_t* connected_controllers, int choice) { int ps4[NUM_EVENTS_PS4] = { 0 }; FILE* ps4_bt_pipe = popen("cat /proc/bus/input/devices | grep -A 5 \"^I: Bus=0005 Vendor=054c Product=09cc\" | grep \"event\" | cut -d 't' -f2 | paste - -s", "r"); fscanf(ps4_bt_pipe, "%2d %2d %2d", &ps4[TOUCHPAD], &ps4[GYRO], &ps4[BUTTONS]); if ( ps4[TOUCHPAD] != 0 && ps4[GYRO] != 0 && ps4[BUTTONS] != 0) { char ps4_events[NUM_EVENTS_PS4][26]; snprintf(ps4_events[TOUCHPAD], 25, "/dev/input/event%d", ps4[TOUCHPAD]); snprintf(ps4_events[GYRO], 25, "/dev/input/event%d", ps4[GYRO]); snprintf(ps4_events[BUTTONS], 25, "/dev/input/event%d", ps4[BUTTONS]); controller_event_fptrs[PS4_BT_TOUCH] = open(ps4_events[TOUCHPAD], O_RDONLY); controller_event_fptrs[PS4_BT_GYRO] = open(ps4_events[GYRO], O_RDONLY); controller_event_fptrs[PS4_BT_BUTTONS] = open(ps4_events[BUTTONS], O_RDONLY); *connected_controllers |= PS4_BT_ALL_BITS; if (choice) { fprintf(stderr, "%4d: PS4 BT TOUCH \n", PS4_BT_TOUCH_BIT); fprintf(stderr, "%4d: PS4 BT GYRO\n", PS4_BT_GYRO_BIT); fprintf(stderr, "%4d: PS4 BT BUTTONS\n", PS4_BT_BUTTONS_BIT); fprintf(stderr, "%4d: PS4 BT TOUCH AND GYRO \n", PS4_BT_TOUCH_AND_GYRO); fprintf(stderr, "%4d: PS4 BT TOUCH AND BUTTONS\n", PS4_BT_TOUCH_AND_BUTTONS); fprintf(stderr, "%4d: PS4 BT GYRO AND BUTTONS\n", PS4_BT_GYRO_AND_BUTTONS); fprintf(stderr, "%4d: ALL PS4 BT\n", PS4_BT_ALL_BITS); } } } void open_ps4_wired(int* controller_event_fptrs, uint64_t* connected_controllers, int choice) { controller_event_fptrs[PS4_WIRED_GYRO] = open("/dev/input/by-id/usb-Sony_Interactive_Entertainment_Wireless_Controller-event-if03", O_RDONLY); controller_event_fptrs[PS4_WIRED_BUTTONS] = open("/dev/input/by-id/usb-Sony_Interactive_Entertainment_Wireless_Controller-if03-event-joystick", O_RDONLY); controller_event_fptrs[PS4_WIRED_TOUCH] = open("/dev/input/by-id/usb-Sony_Interactive_Entertainment_Wireless_Controller-if03-event-mouse", O_RDONLY); if (controller_event_fptrs[PS4_WIRED_GYRO] != -1 && controller_event_fptrs[PS4_WIRED_BUTTONS] != -1 && controller_event_fptrs[PS4_WIRED_TOUCH] != -1) { *connected_controllers |= PS4_WIRED_ALL_BITS; if (choice) { fprintf(stderr, "%4d: PS4 WIRED TOUCH\n", PS4_WIRED_TOUCH_BIT); fprintf(stderr, "%4d: PS4 WIRED GYRO\n", PS4_WIRED_GYRO_BIT); fprintf(stderr, "%4d: PS4 WIRED BUTTONS\n", PS4_WIRED_BUTTONS_BIT); fprintf(stderr, "%4d: PS4 WIRED TOUCH AND GYRO \n", PS4_WIRED_TOUCH_AND_GYRO); fprintf(stderr, "%4d: PS4 WIRED TOUCH AND BUTTONS\n", PS4_WIRED_TOUCH_AND_BUTTONS); fprintf(stderr, "%4d: PS4 WIRED GYRO AND BUTTONS\n", PS4_WIRED_GYRO_AND_BUTTONS); fprintf(stderr, "%4d: ALL PS4 WIRED\n", PS4_WIRED_ALL_BITS); } } } void open_steam(int* controller_event_fptrs, uint64_t* connected_controllers, int choice) { controller_event_fptrs[VALVE_STEAM] = open("/dev/input/by-id/usb-Valve_Software_Wired_Controller-if02-event-joystick", O_RDONLY); if (controller_event_fptrs[VALVE_STEAM] != -1) { *connected_controllers |= (uint64_t) 1; if (choice) { fprintf(stderr, "%4d: VALVE STEAM\n", 1); } } } void open_xbox_360(int* controller_event_fptrs, uint64_t* connected_controllers, int choice) { controller_event_fptrs[XBOX_360] = open("/dev/input/by-id/usb-©Microsoft_Xbox_360_Wireless_Receiver_for_Windows_E15D4C50-event-joystick", O_RDONLY); if (controller_event_fptrs[XBOX_360] != -1) { *connected_controllers |= (uint64_t) 2; if (choice) { fprintf(stderr, "%4d: XBOX 360\n", 2); } } } void close_unneeded_files(int num_exceptions, int controller_event_fptrs[], ...) { int* events_to_skip = (int *) malloc(sizeof(int) * num_exceptions); va_list list_of_args; va_start(list_of_args, controller_event_fptrs); //get arguments for (int i = 0; i < num_exceptions; ++i) { events_to_skip[i] = va_arg(list_of_args, int); } //close all but the provided arguments for (int i = 0; i < NUM_EVENTS; ++i) { for (int j = 0; j < num_exceptions; ++j) { if (i == events_to_skip[j]) { goto SKIP_CLOSE; } } close(controller_event_fptrs[i]); SKIP_CLOSE: } } void print_one_event(int controller_event_fptrs[], int index, int event_number) { struct input_event event1; int event_size = sizeof(struct input_event); time_t start_sec; char buffer[BUFSIZE]; int string_length; if (-1 == read(controller_event_fptrs[index], &event1, event_size)) { fprintf(stderr, "PROBLEM READING FILE!\n"); exit(-1); } start_sec = event1.time.tv_sec; while (read(controller_event_fptrs[index], &event1, event_size) != -1) { if (event1.type == 0) continue; string_length = snprintf(buffer, BUFSIZE - 1, "%d %5lu.%06lu %d %3d %11d\n", event_number, (unsigned long) event1.time.tv_sec - start_sec, (unsigned long) event1.time.tv_usec, event1.type, event1.code, event1.value); write(STDOUT_FILENO, buffer, string_length); } fprintf(stderr, "DISCONNECTED\n"); exit(-1); } void print_multiple_events(int num_exceptions, int controller_event_fptrs[], ...) { pid_t pids[num_exceptions]; //set all pids to -1 at start for (int i = 0; i < num_exceptions; ++i) { pids[i] = -1; } //get all the variadic pairs sent in and store them in an array of the appropriate size struct event_pairs pairs[num_exceptions]; va_list list_of_args; va_start(list_of_args, controller_event_fptrs); for (int i = 0; i < num_exceptions; ++i) { pairs[i] = va_arg(list_of_args, struct event_pairs); } //prepare to start printing inputs struct input_event event[num_exceptions]; int event_size = sizeof(struct input_event); //create the amount of processes appropriate to the number of events to print for (int i = 0; i < num_exceptions - 1; ++i) { pids[i] = fork(); if (pids[i] == 0) break; } //mark the parent bool isParent = true; for (int i = 0; i < num_exceptions; ++i) { if (pids[i] == 0) isParent &= false; } //find and run code just for the parent process (first event (a.k.a. index 0)) if (isParent) { char buffer[BUFSIZE]; int string_length; if ( -1 == read(controller_event_fptrs[pairs[0].event_fptr_index], &event[0], event_size)) { fprintf(stderr, "PROBLEM READING FILE!\n"); exit(-1); } size_t start_sec = event[0].time.tv_sec; while (read(controller_event_fptrs[pairs[0].event_fptr_index], &event[0], event_size) != -1) { if (event[0].type == 0) continue; string_length = snprintf(buffer, BUFSIZE, "%d %lu.%06lu %d %3d %11d\n", pairs[0].event_user_num, (unsigned long) event[0].time.tv_sec - start_sec, (unsigned long) event[0].time.tv_usec, event[0].type, event[0].code, event[0].value); write(STDOUT_FILENO, buffer, string_length); } fprintf(stderr, "DISCONNECTED\n"); } //find the child process(es) and run the correct code for each (event #2 onwards) (a.k.a. index 1+)) sleep(1); for (int i = 0; i < num_exceptions; ++i) { if (pids[i] == 0) { char buffer[BUFSIZE]; int string_length; if (-1 == read(controller_event_fptrs[pairs[i+1].event_fptr_index], &event[i+1], event_size)) { fprintf(stderr, "PROBLEM READING FILE!\n"); exit(-1); } size_t start_sec = event[i+1].time.tv_sec; while (read(controller_event_fptrs[pairs[i+1].event_fptr_index], &event[i+1], event_size) != -1) { if (event[i+1].type == 0) continue; string_length = snprintf(buffer, BUFSIZE, "%d %lu.%06lu %d %3d %11d\n", pairs[i+1].event_user_num, (unsigned long) event[i+1].time.tv_sec - start_sec, (unsigned long) event[i+1].time.tv_usec, event[i+1].type, event[i+1].code, event[i+1].value); write(STDOUT_FILENO, buffer, string_length); } fprintf(stderr, "DISCONNECTED\n"); } } }