stellaris_input.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Gamepad style buttons connected to IRQ/GPIO lines
  3. *
  4. * Copyright (c) 2007 CodeSourcery.
  5. * Written by Paul Brook
  6. *
  7. * This code is licensed under the GPL.
  8. */
  9. #include "qemu/osdep.h"
  10. #include "hw/input/gamepad.h"
  11. #include "hw/irq.h"
  12. #include "migration/vmstate.h"
  13. #include "ui/console.h"
  14. typedef struct {
  15. qemu_irq irq;
  16. int keycode;
  17. uint8_t pressed;
  18. } gamepad_button;
  19. typedef struct {
  20. gamepad_button *buttons;
  21. int num_buttons;
  22. int extension;
  23. } gamepad_state;
  24. static void stellaris_gamepad_put_key(void * opaque, int keycode)
  25. {
  26. gamepad_state *s = (gamepad_state *)opaque;
  27. int i;
  28. int down;
  29. if (keycode == 0xe0 && !s->extension) {
  30. s->extension = 0x80;
  31. return;
  32. }
  33. down = (keycode & 0x80) == 0;
  34. keycode = (keycode & 0x7f) | s->extension;
  35. for (i = 0; i < s->num_buttons; i++) {
  36. if (s->buttons[i].keycode == keycode
  37. && s->buttons[i].pressed != down) {
  38. s->buttons[i].pressed = down;
  39. qemu_set_irq(s->buttons[i].irq, down);
  40. }
  41. }
  42. s->extension = 0;
  43. }
  44. static const VMStateDescription vmstate_stellaris_button = {
  45. .name = "stellaris_button",
  46. .version_id = 0,
  47. .minimum_version_id = 0,
  48. .fields = (VMStateField[]) {
  49. VMSTATE_UINT8(pressed, gamepad_button),
  50. VMSTATE_END_OF_LIST()
  51. }
  52. };
  53. static const VMStateDescription vmstate_stellaris_gamepad = {
  54. .name = "stellaris_gamepad",
  55. .version_id = 2,
  56. .minimum_version_id = 2,
  57. .fields = (VMStateField[]) {
  58. VMSTATE_INT32(extension, gamepad_state),
  59. VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state,
  60. num_buttons,
  61. vmstate_stellaris_button,
  62. gamepad_button),
  63. VMSTATE_END_OF_LIST()
  64. }
  65. };
  66. /* Returns an array of 5 output slots. */
  67. void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
  68. {
  69. gamepad_state *s;
  70. int i;
  71. s = g_new0(gamepad_state, 1);
  72. s->buttons = g_new0(gamepad_button, n);
  73. for (i = 0; i < n; i++) {
  74. s->buttons[i].irq = irq[i];
  75. s->buttons[i].keycode = keycode[i];
  76. }
  77. s->num_buttons = n;
  78. qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
  79. vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s);
  80. }