static int on_cec_keypress(void* userdata, const cec_keypress key) { char value; switch (key.keycode) { case CEC_USER_CONTROL_CODE_UP: value = KEY_UP; break; case CEC_USER_CONTROL_CODE_DOWN: value = KEY_DOWN; break; case CEC_USER_CONTROL_CODE_LEFT: value = KEY_LEFT; break; case CEC_USER_CONTROL_CODE_RIGHT: value = KEY_RIGHT; break; case CEC_USER_CONTROL_CODE_ENTER: case CEC_USER_CONTROL_CODE_SELECT: value = KEY_ENTER; break; case CEC_USER_CONTROL_CODE_ROOT_MENU: value = KEY_TAB; break; case CEC_USER_CONTROL_CODE_AN_RETURN: case CEC_USER_CONTROL_CODE_EXIT: value = KEY_ESC; break; default: value = 0; break; } if (value != 0) { short code = 0x80 << 8 | value; LiSendKeyboardEvent(code, (key.duration > 0)?KEY_ACTION_UP:KEY_ACTION_DOWN, 0); } }
static bool evdev_handle_event(struct input_event *ev, struct input_device *dev) { bool gamepadModified = false; switch (ev->type) { case EV_SYN: if (dev->mouseDeltaX != 0 || dev->mouseDeltaY != 0) { LiSendMouseMoveEvent(dev->mouseDeltaX, dev->mouseDeltaY); dev->mouseDeltaX = 0; dev->mouseDeltaY = 0; } if (dev->mouseScroll != 0) { LiSendScrollEvent(dev->mouseScroll); dev->mouseScroll = 0; } if (dev->gamepadModified) { if (dev->controllerId < 0) { for (int i = 0; i < 4; i++) { if ((assignedControllerIds & (1 << i)) == 0) { assignedControllerIds |= (1 << i); dev->controllerId = i; break; } } //Use id 0 when too many gamepads are connected if (dev->controllerId < 0) dev->controllerId = 0; } LiSendMultiControllerEvent(dev->controllerId, dev->buttonFlags, dev->leftTrigger, dev->rightTrigger, dev->leftStickX, dev->leftStickY, dev->rightStickX, dev->rightStickY); dev->gamepadModified = false; } break; case EV_KEY: if (ev->code < sizeof(keyCodes)/sizeof(keyCodes[0])) { char modifier = 0; switch (ev->code) { case KEY_LEFTSHIFT: case KEY_RIGHTSHIFT: modifier = MODIFIER_SHIFT; break; case KEY_LEFTALT: case KEY_RIGHTALT: modifier = MODIFIER_ALT; break; case KEY_LEFTCTRL: case KEY_RIGHTCTRL: modifier = MODIFIER_CTRL; break; } if (modifier != 0) { if (ev->value) dev->modifiers |= modifier; else dev->modifiers &= ~modifier; } // Quit the stream if all the required quit keys are down if ((dev->modifiers & QUIT_MODIFIERS) == QUIT_MODIFIERS && ev->code == QUIT_KEY && ev->value != 0) { return false; } short code = 0x80 << 8 | keyCodes[ev->code]; LiSendKeyboardEvent(code, ev->value?KEY_ACTION_DOWN:KEY_ACTION_UP, dev->modifiers); } else { int mouseCode = 0; short gamepadCode = 0; switch (ev->code) { case BTN_LEFT: mouseCode = BUTTON_LEFT; break; case BTN_MIDDLE: mouseCode = BUTTON_MIDDLE; break; case BTN_RIGHT: mouseCode = BUTTON_RIGHT; break; default: if (ev->code == dev->map.btn_south) gamepadCode = A_FLAG; else if (ev->code == dev->map.btn_west) gamepadCode = X_FLAG; else if (ev->code == dev->map.btn_north) gamepadCode = Y_FLAG; else if (ev->code == dev->map.btn_east) gamepadCode = B_FLAG; else if (ev->code == dev->map.btn_dpad_up) gamepadCode = UP_FLAG; else if (ev->code == dev->map.btn_dpad_down) gamepadCode = DOWN_FLAG; else if (ev->code == dev->map.btn_dpad_right) gamepadCode = RIGHT_FLAG; else if (ev->code == dev->map.btn_dpad_left) gamepadCode = LEFT_FLAG; else if (ev->code == dev->map.btn_thumbl) gamepadCode = LS_CLK_FLAG; else if (ev->code == dev->map.btn_thumbr) gamepadCode = RS_CLK_FLAG; else if (ev->code == dev->map.btn_tl) gamepadCode = LB_FLAG; else if (ev->code == dev->map.btn_tr) gamepadCode = RB_FLAG; else if (ev->code == dev->map.btn_start) gamepadCode = PLAY_FLAG; else if (ev->code == dev->map.btn_select) gamepadCode = BACK_FLAG; else if (ev->code == dev->map.btn_mode) gamepadCode = SPECIAL_FLAG; } if (mouseCode != 0) { LiSendMouseButtonEvent(ev->value?BUTTON_ACTION_PRESS:BUTTON_ACTION_RELEASE, mouseCode); } else { gamepadModified = true; if (gamepadCode != 0) { if (ev->value) dev->buttonFlags |= gamepadCode; else dev->buttonFlags &= ~gamepadCode; } else if (ev->code == dev->map.btn_tl2) dev->leftTrigger = ev->value?UCHAR_MAX:0; else if (ev->code == dev->map.btn_tr2) dev->rightTrigger = ev->value?UCHAR_MAX:0; else { fprintf(stderr, "Unmapped button: %d\n", ev->code); gamepadModified = false; } } } break; case EV_REL: switch (ev->code) { case REL_X: dev->mouseDeltaX = ev->value; break; case REL_Y: dev->mouseDeltaY = ev->value; break; case REL_WHEEL: dev->mouseScroll = ev->value; break; } break; case EV_ABS: gamepadModified = true; if (ev->code == dev->map.abs_x) dev->leftStickX = evdev_convert_value(ev, dev, &dev->xParms, dev->map.reverse_x); else if (ev->code == dev->map.abs_y) dev->leftStickY = evdev_convert_value(ev, dev, &dev->yParms, dev->map.reverse_y); else if (ev->code == dev->map.abs_rx) dev->rightStickX = evdev_convert_value(ev, dev, &dev->rxParms, dev->map.reverse_rx); else if (ev->code == dev->map.abs_ry) dev->rightStickY = evdev_convert_value(ev, dev, &dev->ryParms, dev->map.reverse_ry); else if (ev->code == dev->map.abs_z) dev->leftTrigger = evdev_convert_value_byte(ev, dev, &dev->zParms); else if (ev->code == dev->map.abs_rz) dev->rightTrigger = evdev_convert_value_byte(ev, dev, &dev->rzParms); else if (ev->code == dev->map.abs_dpad_x) { int dir = evdev_convert_value_direction(ev, dev, &dev->dpadxParms, dev->map.reverse_dpad_x); if (dir == 1) { dev->buttonFlags |= RIGHT_FLAG; dev->buttonFlags &= ~LEFT_FLAG; } else if (dir == 0) { dev->buttonFlags &= ~RIGHT_FLAG; dev->buttonFlags &= ~LEFT_FLAG; } else { dev->buttonFlags &= ~RIGHT_FLAG; dev->buttonFlags |= LEFT_FLAG; } } else if (ev->code == dev->map.abs_dpad_y) { int dir = evdev_convert_value_direction(ev, dev, &dev->dpadyParms, dev->map.reverse_dpad_y); if (dir == 1) { dev->buttonFlags |= DOWN_FLAG; dev->buttonFlags &= ~UP_FLAG; } else if (dir == 0) { dev->buttonFlags &= ~DOWN_FLAG; dev->buttonFlags &= ~UP_FLAG; } else { dev->buttonFlags &= ~DOWN_FLAG; dev->buttonFlags |= UP_FLAG; } } else gamepadModified = false; break; } dev->gamepadModified |= gamepadModified; return true; }