static void handleButtonChange(struct Gamepad_device * device, DWORD lastValue, DWORD value) {
	bool down;
	unsigned int buttonIndex;
	
	for (buttonIndex = 0; buttonIndex < device->numButtons; buttonIndex++) {
		if ((lastValue ^ value) & (1 << buttonIndex)) {
			down = !!(value & (1 << buttonIndex));
			
			device->buttonStates[buttonIndex] = down;
			if (down && Gamepad_buttonDownCallback != NULL) {
				Gamepad_buttonDownCallback(device, buttonIndex, currentTime(), Gamepad_buttonDownContext);
			} else if (!down && Gamepad_buttonUpCallback != NULL) {
				Gamepad_buttonUpCallback(device, buttonIndex, currentTime(), Gamepad_buttonUpContext);
			}
		}
	}
}
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;
  }
}