void pad_connection_destroy(joypad_connection_t *joyconn) { unsigned i; for (i = 0; i < MAX_USERS; i ++) pad_connection_pad_deinit(&joyconn[i], i); }
static void iohidmanager_hid_device_remove(void *data, IOReturn result, void* sender) { struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)data; iohidmanager_hid_t *hid = (iohidmanager_hid_t*)hid_driver_get_data(); if (hid && adapter && (adapter->slot < MAX_USERS)) { input_config_autoconfigure_disconnect(adapter->slot, adapter->name); hid->buttons[adapter->slot] = 0; memset(hid->axes[adapter->slot], 0, sizeof(hid->axes)); pad_connection_pad_deinit(&hid->slots[adapter->slot], adapter->slot); free(adapter); } }
static void iohidmanager_hid_device_remove(void *data, IOReturn result, void* sender) { driver_t *driver = driver_get_ptr(); cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)data; iohidmanager_hid_t *hid = driver ? (iohidmanager_hid_t*)driver->hid_data : NULL; if (adapter && (adapter->slot < MAX_USERS)) { input_config_autoconfigure_disconnect(adapter->slot, adapter->name); apple->buttons[adapter->slot] = 0; memset(apple->axes[adapter->slot], 0, sizeof(apple->axes)); pad_connection_pad_deinit(&hid->slots[adapter->slot], adapter->slot); free(adapter); } }
static void iohidmanager_hid_device_remove(void *data, IOReturn result, void* sender) { struct iohidmanager_hid_adapter *adapter = (struct iohidmanager_hid_adapter*)data; iohidmanager_hid_t *hid = (iohidmanager_hid_t*) hid_driver_get_data(); if (hid && adapter && (adapter->slot < MAX_USERS)) { input_autoconfigure_disconnect(adapter->slot, adapter->name); hid->buttons[adapter->slot] = 0; memset(hid->axes[adapter->slot], 0, sizeof(hid->axes)); pad_connection_pad_deinit(&hid->slots[adapter->slot], adapter->slot); } if (adapter) { apple_input_rec_t* tmp = NULL; while(adapter->hats != NULL) { tmp = adapter->hats; adapter->hats = adapter->hats->next; free(tmp); } while(adapter->axes != NULL) { tmp = adapter->axes; adapter->axes = adapter->axes->next; free(tmp); } while(adapter->buttons != NULL) { tmp = adapter->buttons; adapter->buttons = adapter->buttons->next; free(tmp); } free(adapter); } }
static void remove_device(void* context, IOReturn result, void* sender) { apple_input_data_t *apple = (apple_input_data_t*)driver.input_data; struct pad_connection* connection = (struct pad_connection*)context; if (connection && connection->slot < MAX_USERS) { char msg[PATH_MAX_LENGTH]; snprintf(msg, sizeof(msg), "Joypad #%u (%s) disconnected.", connection->slot, "N/A"); msg_queue_push(g_extern.msg_queue, msg, 0, 60); RARCH_LOG("[apple_input]: %s\n", msg); apple->buttons[connection->slot] = 0; memset(apple->axes[connection->slot], 0, sizeof(apple->axes)); pad_connection_pad_deinit(&slots[connection->slot], connection->slot); free(connection); } }
static int32_t wiiusb_hid_release_adapter(struct wiiusb_adapter *adapter) { wiiusb_hid_t *hid = NULL; const char *name = NULL; if (!adapter) return -1; hid = adapter->hid; name = wiiusb_hid_joypad_name(hid, adapter->slot); input_autoconfigure_disconnect(adapter->slot, name); pad_connection_pad_deinit(&hid->connections[adapter->slot], adapter->slot); free(adapter->send_control_buffer); free(adapter->data); free(adapter); return 0; }
static void apple_hid_device_remove(void *data, IOReturn result, void* sender) { driver_t *driver = driver_get_ptr(); apple_input_data_t *apple = (apple_input_data_t*)driver->input_data; struct apple_hid_adapter *adapter = (struct apple_hid_adapter*)data; apple_hid_t *hid = driver ? (apple_hid_t*)driver->hid_data : NULL; if (adapter && (adapter->slot < MAX_USERS)) { char msg[PATH_MAX_LENGTH]; snprintf(msg, sizeof(msg), "Joypad #%u (%s) disconnected.", adapter->slot, adapter->name); rarch_main_msg_queue_push(msg, 0, 60, false); apple->buttons[adapter->slot] = 0; memset(apple->axes[adapter->slot], 0, sizeof(apple->axes)); pad_connection_pad_deinit(&hid->slots[adapter->slot], adapter->slot); free(adapter); } }
static int remove_adapter(void *data, struct libusb_device *dev) { struct libusb_adapter *adapter = (struct libusb_adapter*)&adapters; struct libusb_hid *hid = (struct libusb_hid*)data; while (adapter->next == NULL) return -1; if (adapter->next->device == dev) { struct libusb_adapter *new_next = NULL; const char *name = (const char*)adapter->next->name; input_config_autoconfigure_disconnect(adapter->slot, name); adapter->next->quitting = true; sthread_join(adapter->next->thread); pad_connection_pad_deinit(&hid->slots[adapter->slot], adapter->slot); slock_free(adapter->send_control_lock); fifo_free(adapter->send_control_buffer); libusb_release_interface(adapter->next->handle, adapter->next->interface_number); libusb_close(adapter->next->handle); new_next = adapter->next->next; free(adapter->next); adapter->next = new_next; return 0; } adapter = adapter->next; return -1; }
static void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) { unsigned i; bd_addr_t event_addr; struct btpad_queue_command* cmd = &commands[insert_position]; switch (packet_type) { case L2CAP_DATA_PACKET: for (i = 0; i < MAX_USERS; i ++) { struct btstack_hid_adapter *connection = &g_connections[i]; if (!connection || connection->state != BTPAD_CONNECTED) continue; if ( connection->channels[0] == channel || connection->channels[1] == channel) pad_connection_packet(&slots[connection->slot], connection->slot, packet, size); } break; case HCI_EVENT_PACKET: switch (packet[0]) { case BTSTACK_EVENT_STATE: RARCH_LOG("[BTstack]: HCI State %d.\n", packet[2]); switch (packet[2]) { case HCI_STATE_WORKING: btpad_queue_reset(); btpad_queue_hci_read_bd_addr(cmd); /* TODO: Where did I get 672 for MTU? */ bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672); btpad_queue_hci_inquiry(cmd, HCI_INQUIRY_LAP, 3, 1); btpad_queue_run(1); break; case HCI_STATE_HALTING: btpad_close_all_connections(); break; } break; case HCI_EVENT_COMMAND_STATUS: btpad_queue_run(packet[3]); break; case HCI_EVENT_COMMAND_COMPLETE: btpad_queue_run(packet[2]); if (COMMAND_COMPLETE_EVENT(packet, (*hci_read_bd_addr_ptr))) { bt_flip_addr_ptr(event_addr, &packet[6]); if (!packet[5]) RARCH_LOG("[BTpad]: Local address is %s.\n", bd_addr_to_str_ptr(event_addr)); else RARCH_LOG("[BTpad]: Failed to get local address (Status: %02X).\n", packet[5]); } break; case HCI_EVENT_INQUIRY_RESULT: if (packet[2]) { struct btstack_hid_adapter* connection = NULL; bt_flip_addr_ptr(event_addr, &packet[3]); connection = btpad_find_empty_connection(); if (!connection) return; RARCH_LOG("[BTpad]: Inquiry found device\n"); memset(connection, 0, sizeof(struct btstack_hid_adapter)); memcpy(connection->address, event_addr, sizeof(bd_addr_t)); connection->has_address = true; connection->state = BTPAD_CONNECTING; bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_CONTROL); bt_send_cmd_ptr(l2cap_create_channel_ptr, connection->address, PSM_HID_INTERRUPT); } break; case HCI_EVENT_INQUIRY_COMPLETE: /* This must be turned off during gameplay * as it causes a ton of lag. */ inquiry_running = !inquiry_off; if (inquiry_running) btpad_queue_hci_inquiry(cmd, HCI_INQUIRY_LAP, 3, 1); break; case L2CAP_EVENT_CHANNEL_OPENED: { uint16_t handle, psm, channel_id; struct btstack_hid_adapter *connection = NULL; bt_flip_addr_ptr(event_addr, &packet[3]); handle = READ_BT_16(packet, 9); psm = READ_BT_16(packet, 11); channel_id = READ_BT_16(packet, 13); connection = btpad_find_connection_for(handle, event_addr); if (!packet[2]) { if (!connection) { RARCH_LOG("[BTpad]: Got L2CAP 'Channel Opened' event for unrecognized device.\n"); break; } RARCH_LOG("[BTpad]: L2CAP channel opened: (PSM: %02X)\n", psm); connection->handle = handle; switch (psm) { case PSM_HID_CONTROL: connection->channels[0] = channel_id; break; case PSM_HID_INTERRUPT: connection->channels[1] = channel_id; break; default: RARCH_LOG("[BTpad]: Got unknown L2CAP PSM, ignoring (PSM: %02X).\n", psm); break; } if (connection->channels[0] && connection->channels[1]) { RARCH_LOG("[BTpad]: Got both L2CAP channels, requesting name.\n"); btpad_queue_hci_remote_name_request(cmd, connection->address, 0, 0, 0); } } else RARCH_LOG("[BTpad]: Got failed L2CAP 'Channel Opened' event (PSM: %02X, Status: %02X).\n", psm, packet[2]); } break; case L2CAP_EVENT_INCOMING_CONNECTION: { uint16_t handle, psm, channel_id; struct btstack_hid_adapter* connection = NULL; bt_flip_addr_ptr(event_addr, &packet[2]); handle = READ_BT_16(packet, 8); psm = READ_BT_16(packet, 10); channel_id = READ_BT_16(packet, 12); connection = btpad_find_connection_for(handle, event_addr); if (!connection) { connection = btpad_find_empty_connection(); if (!connection) break; RARCH_LOG("[BTpad]: Got new incoming connection\n"); memset(connection, 0, sizeof(struct btstack_hid_adapter)); memcpy(connection->address, event_addr, sizeof(bd_addr_t)); connection->has_address = true; connection->handle = handle; connection->state = BTPAD_CONNECTING; } RARCH_LOG("[BTpad]: Incoming L2CAP connection (PSM: %02X).\n", psm); bt_send_cmd_ptr(l2cap_accept_connection_ptr, channel_id); } break; case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: { struct btstack_hid_adapter *connection = NULL; bt_flip_addr_ptr(event_addr, &packet[3]); connection = btpad_find_connection_for(0, event_addr); if (!connection) { RARCH_LOG("[BTpad]: Got unexpected remote name, ignoring.\n"); break; } RARCH_LOG("[BTpad]: Got %.200s.\n", (char*)&packet[9]); connection->slot = pad_connection_pad_init(&slots[connection->slot], (char*)packet + 9, 0, 0, connection, &btpad_connection_send_control); connection->state = BTPAD_CONNECTED; } break; case HCI_EVENT_PIN_CODE_REQUEST: RARCH_LOG("[BTpad]: Sending Wiimote PIN.\n"); bt_flip_addr_ptr(event_addr, &packet[2]); btpad_queue_hci_pin_code_request_reply(cmd, event_addr, &packet[2]); break; case HCI_EVENT_DISCONNECTION_COMPLETE: { const uint32_t handle = READ_BT_16(packet, 3); if (!packet[2]) { struct btstack_hid_adapter* connection = btpad_find_connection_for(handle, 0); if (connection) { connection->handle = 0; pad_connection_pad_deinit(&slots[connection->slot], connection->slot); btpad_close_connection(connection); } } else RARCH_LOG("[BTpad]: Got failed 'Disconnection Complete' event (Status: %02X).\n", packet[2]); } break; case L2CAP_EVENT_SERVICE_REGISTERED: if (packet[2]) RARCH_LOG("[BTpad]: Got failed 'Service Registered' event (PSM: %02X, Status: %02X).\n", READ_BT_16(packet, 3), packet[2]); break; } break; } }