static void onDeviceRemoved(void * context, IOReturn result, void * sender, IOHIDDeviceRef device) { unsigned int deviceIndex; for (deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) { if (((struct Gamepad_devicePrivate *) devices[deviceIndex]->privateData)->deviceRef == device) { if (Gamepad_deviceRemoveCallback != NULL) { Gamepad_deviceRemoveCallback(devices[deviceIndex], Gamepad_deviceRemoveContext); } disposeDevice(devices[deviceIndex]); numDevices--; for (; deviceIndex < numDevices; deviceIndex++) { devices[deviceIndex] = devices[deviceIndex + 1]; } return; } } }
static void processQueuedEvent(struct Gamepad_queuedEvent event) { switch (event.eventType) { case GAMEPAD_EVENT_DEVICE_ATTACHED: if (Gamepad_deviceAttachCallback != NULL) { Gamepad_deviceAttachCallback(event.eventData, Gamepad_deviceAttachContext); } break; case GAMEPAD_EVENT_DEVICE_REMOVED: if (Gamepad_deviceRemoveCallback != NULL) { Gamepad_deviceRemoveCallback(event.eventData, Gamepad_deviceRemoveContext); } break; case GAMEPAD_EVENT_BUTTON_DOWN: if (Gamepad_buttonDownCallback != NULL) { struct Gamepad_buttonEvent * buttonEvent = event.eventData; Gamepad_buttonDownCallback(buttonEvent->device, buttonEvent->buttonID, buttonEvent->timestamp, Gamepad_buttonDownContext); } break; case GAMEPAD_EVENT_BUTTON_UP: if (Gamepad_buttonUpCallback != NULL) { struct Gamepad_buttonEvent * buttonEvent = event.eventData; Gamepad_buttonUpCallback(buttonEvent->device, buttonEvent->buttonID, buttonEvent->timestamp, Gamepad_buttonUpContext); } break; case GAMEPAD_EVENT_AXIS_MOVED: if (Gamepad_axisMoveCallback != NULL) { struct Gamepad_axisEvent * axisEvent = event.eventData; Gamepad_axisMoveCallback(axisEvent->device, axisEvent->axisID, axisEvent->value, axisEvent->lastValue, axisEvent->timestamp, Gamepad_axisMoveContext); } break; } }
void Gamepad_processEvents() { unsigned int deviceIndex; static bool inProcessEvents; JOYINFOEX info; MMRESULT result; struct Gamepad_device * device; struct Gamepad_devicePrivate * devicePrivate; if (!inited || inProcessEvents) { return; } inProcessEvents = true; for (deviceIndex = 0; deviceIndex < numDevices; deviceIndex++) { device = devices[deviceIndex]; devicePrivate = device->privateData; info.dwSize = sizeof(info); info.dwFlags = JOY_RETURNALL; result = joyGetPosEx(devicePrivate->joystickID, &info); if (result == JOYERR_UNPLUGGED) { if (Gamepad_deviceRemoveCallback != NULL) { Gamepad_deviceRemoveCallback(device, Gamepad_deviceRemoveContext); } disposeDevice(device); numDevices--; for (; deviceIndex < numDevices; deviceIndex++) { devices[deviceIndex] = devices[deviceIndex + 1]; } } else if (result == JOYERR_NOERROR) { if (info.dwXpos != devicePrivate->lastState.dwXpos) { handleAxisChange(device, devicePrivate->xAxisIndex, info.dwXpos); } if (info.dwYpos != devicePrivate->lastState.dwYpos) { handleAxisChange(device, devicePrivate->yAxisIndex, info.dwYpos); } if (info.dwZpos != devicePrivate->lastState.dwZpos) { handleAxisChange(device, devicePrivate->zAxisIndex, info.dwZpos); } if (info.dwRpos != devicePrivate->lastState.dwRpos) { handleAxisChange(device, devicePrivate->rAxisIndex, info.dwRpos); } if (info.dwUpos != devicePrivate->lastState.dwUpos) { handleAxisChange(device, devicePrivate->uAxisIndex, info.dwUpos); } if (info.dwVpos != devicePrivate->lastState.dwVpos) { handleAxisChange(device, devicePrivate->vAxisIndex, info.dwVpos); } if (info.dwPOV != devicePrivate->lastState.dwPOV) { handlePOVChange(device, devicePrivate->lastState.dwPOV, info.dwPOV); } if (info.dwButtons != devicePrivate->lastState.dwButtons) { handleButtonChange(device, devicePrivate->lastState.dwButtons, info.dwButtons); } devicePrivate->lastState = info; } } inProcessEvents = false; }