static void *manymouse_thread(void* data) { fs_log("[MANYMOUSE] Thread running\n"); int k = g_fs_ml_input_device_count; g_first_manymouse_index = k; int mouse_count = ManyMouse_Init(); if (mouse_count < 0) { fs_log("[MANYMOUSE] Initialization failed (%d)\n", mouse_count); } else if (mouse_count == 0) { fs_log("MANYMOUSE: no mice found\n"); // no mice found, so we just quit using the library } for (int i = 0; i < mouse_count; i++) { const char *device = ManyMouse_DeviceName(i); const char *driver = ManyMouse_DriverName(); char *name; if (device[0] == 0 || g_ascii_strcasecmp(device, "mouse") == 0) { name = g_strdup("Mouse: Unnamed Mouse"); } else { name = g_strdup_printf("Mouse: %s", device); } // fs_ml_input_unique_device_name either returns name, or frees it // and return another name, so name must be malloced and owned by // caller name = fs_ml_input_unique_device_name(name); fs_log("MANYMOUSE: Adding %s (%s)\n", name, driver); g_fs_ml_input_devices[k].type = FS_ML_MOUSE; g_fs_ml_input_devices[k].index = k; g_fs_ml_input_devices[k].name = name; g_fs_ml_input_devices[k].alias = g_strdup_printf("MOUSE #%d", i + 2); k += 1; } // when done like this, I believe no memory barrier is needed when the // other thread polls g_manymouse_last_index g_manymouse_last_index = k; if (mouse_count < 0) { // ManyMouse library was not initialized return NULL; } ManyMouseEvent event; fs_ml_event *new_event; while (!fs_ml_is_quitting()) { // printf("..\n"); while (ManyMouse_PollEvent(&event)) { // printf(" -- event type %d -- \n", event.type); if (event.type == MANYMOUSE_EVENT_RELMOTION) { // printf("MANYMOUSE_EVENT_RELMOTION\n"); new_event = fs_ml_alloc_event(); new_event->type = FS_ML_MOUSEMOTION; new_event->motion.device = g_first_manymouse_index + \ event.device; if (event.item == 0) { new_event->motion.xrel = event.value; new_event->motion.yrel = 0; } else if (event.item == 1) { new_event->motion.xrel = 0; new_event->motion.yrel = event.value; } new_event->motion.x = FS_ML_NO_ABSOLUTE_MOUSE_POS; new_event->motion.y = FS_ML_NO_ABSOLUTE_MOUSE_POS; fs_ml_post_event(new_event); // ManyMouseEventType type; // unsigned int device; // unsigned int item; // int value; // int minval; // int maxval; } else if (event.type == MANYMOUSE_EVENT_BUTTON) { db_log(input, "MANYMOUSE: EVENT_BUTTON " "device %d item %d value %d\n", event.device, event.item, event.value); new_event = fs_ml_alloc_event(); new_event->type = event.value ? FS_ML_MOUSEBUTTONDOWN : FS_ML_MOUSEBUTTONUP; new_event->button.state = event.value != 0; new_event->button.device = g_first_manymouse_index + \ event.device; if (event.item == 0) { new_event->button.button = FS_ML_BUTTON_LEFT; } else if (event.item == 1) { new_event->button.button = FS_ML_BUTTON_RIGHT; } else if (event.item == 2) { new_event->button.button = FS_ML_BUTTON_MIDDLE; } else { new_event->button.button = 0; } fs_ml_post_event(new_event); } else if (event.type == MANYMOUSE_EVENT_ABSMOTION) { // printf("MANYMOUSE_EVENT_ABSMOTION\n"); } else if (event.type == MANYMOUSE_EVENT_SCROLL) { db_log(input, "MANYMOUSE: EVENT_SCROLL " "device %d item %d value %d\n", event.device, event.item, event.value); new_event = fs_ml_alloc_event(); new_event->type = FS_ML_MOUSEBUTTONDOWN; new_event->button.state = 1; new_event->button.device = g_first_manymouse_index + \ event.device; new_event->button.button = 0; if (event.item == 0) { if (event.value == 1) { new_event->button.button = FS_ML_BUTTON_WHEELUP; } else { new_event->button.button = FS_ML_BUTTON_WHEELDOWN; } } fs_ml_post_event(new_event); } } fs_ml_usleep(1000); } ManyMouse_Quit(); return NULL; }
void fs_ml_input_init() { FS_ML_INIT_ONCE; SDL_Init(SDL_INIT_JOYSTICK); fs_log("fs_ml_input_init\n"); if (fs_config_get_boolean(OPTION_MOUSE_INTEGRATION) == 1) { g_mouse_integration = 1; } g_cursor_mode = fs_config_get_boolean(OPTION_CURSOR); if (fs_config_check_auto(OPTION_CURSOR, FS_CONFIG_AUTO)) { if (fs_emu_mouse_integration()) { g_cursor_mode = 0; } else { g_cursor_mode = -1; } } g_input_queue = g_queue_new(); g_input_mutex = fs_mutex_create(); fs_log("calling fs_ml_video_init\n"); fs_ml_video_init(); int size = sizeof(fs_ml_input_device) * FS_ML_INPUT_DEVICES_MAX; // allocate zeroed memory g_fs_ml_input_devices = g_malloc0(size); fs_ml_initialize_keymap(); int k = 0; g_fs_ml_first_joystick_index = 0; g_fs_ml_input_devices[k].type = FS_ML_KEYBOARD; g_fs_ml_input_devices[k].index = k; g_fs_ml_input_devices[k].name = g_strdup("KEYBOARD"); g_fs_ml_input_devices[k].alias = g_strdup("KEYBOARD"); k += 1; g_fs_ml_input_device_count = k; fs_ml_mouse_init(); k = g_fs_ml_input_device_count; g_fs_ml_first_joystick_index = g_fs_ml_input_device_count; int num_joysticks = SDL_NumJoysticks(); fs_log("num joystick devices: %d\n", num_joysticks); if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) { fs_log("WARNING: Joystick module not initialized\n"); } for (int i = 0; i < num_joysticks; i++) { if (k == FS_ML_INPUT_DEVICES_MAX) { fs_log("WARNING: reached max num devices\n"); break; } SDL_Joystick *joystick = SDL_JoystickOpen(i); #ifdef USE_SDL2 char* name = g_ascii_strup(SDL_JoystickName(joystick), -1); #else char* name = g_ascii_strup(SDL_JoystickName(i), -1); #endif name = g_strstrip(name); if (name[0] == '\0') { g_free(name); name = g_ascii_strup("Unnamed", -1); } // fs_ml_input_unique_device_name either returns name, or frees it // and return another name, so name must be malloced and owned by // caller name = fs_ml_input_unique_device_name(name); g_fs_ml_input_devices[k].type = FS_ML_JOYSTICK; g_fs_ml_input_devices[k].index = k; g_fs_ml_input_devices[k].name = name; if (i == 0) { g_fs_ml_input_devices[k].alias = g_strdup("JOYSTICK"); } else { g_fs_ml_input_devices[k].alias = g_strdup_printf("JOYSTICK #%d", i + 1); } g_fs_ml_input_devices[k].hats = SDL_JoystickNumHats(joystick); g_fs_ml_input_devices[k].buttons = SDL_JoystickNumButtons(joystick); g_fs_ml_input_devices[k].axes = SDL_JoystickNumAxes(joystick); g_fs_ml_input_devices[k].balls = SDL_JoystickNumBalls(joystick); fs_log("joystick device #%02d found: %s\n", i + 1, name); fs_log("- %d buttons %d hats %d axes %d balls\n", g_fs_ml_input_devices[k].buttons, g_fs_ml_input_devices[k].hats, g_fs_ml_input_devices[k].axes, g_fs_ml_input_devices[k].balls); k += 1; } g_fs_ml_input_device_count = k; fs_ml_initialize_keymap(); }