text: /*
   * Gamepad style buttons connected to IRQ/GPIO lines
   *
   * Copyright (c) 2007 CodeSourcery.
   * Written by Paul Brook
   *
   * This code is licensed under the GPL.
   */
  #include "hw/hw.h"
  #include "hw/devices.h"
  #include "ui/console.h"
  
  typedef struct {
      qemu_irq irq;
      int keycode;
      uint8_t pressed;
  } gamepad_button;
  
  typedef struct {
      gamepad_button *buttons;
      int num_buttons;
      int extension;
  } gamepad_state;
  
  static void stellaris_gamepad_put_key(void * opaque, int keycode)
  {
      gamepad_state *s = (gamepad_state *)opaque;
      int i;
      int down;
  
      if (keycode == 0xe0 && !s->extension) {
          s->extension = 0x80;
          return;
      }
  
      down = (keycode & 0x80) == 0;
      keycode = (keycode & 0x7f) | s->extension;
  
      for (i = 0; i < s->num_buttons; i++) {
          if (s->buttons[i].keycode == keycode
                  && s->buttons[i].pressed != down) {
              s->buttons[i].pressed = down;
              qemu_set_irq(s->buttons[i].irq, down);
          }
      }
  
      s->extension = 0;
  }
  
  static const VMStateDescription vmstate_stellaris_button = {
      .name = "stellaris_button",
      .version_id = 0,
      .minimum_version_id = 0,
      .fields = (VMStateField[]) {
          VMSTATE_UINT8(pressed, gamepad_button),
          VMSTATE_END_OF_LIST()
      }
  };
  
  static const VMStateDescription vmstate_stellaris_gamepad = {
      .name = "stellaris_gamepad",
      .version_id = 1,
      .minimum_version_id = 1,
      .fields = (VMStateField[]) {
          VMSTATE_INT32(extension, gamepad_state),
          VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0,
                                vmstate_stellaris_button, gamepad_button),
          VMSTATE_END_OF_LIST()
      }
  };
  
  /* Returns an array 5 ouput slots.  */
  void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
  {
      gamepad_state *s;
      int i;
  
      s = (gamepad_state *)g_malloc0(sizeof (gamepad_state));
      s->buttons = (gamepad_button *)g_malloc0(n * sizeof (gamepad_button));
      for (i = 0; i < n; i++) {
          s->buttons[i].irq = irq[i];
          s->buttons[i].keycode = keycode[i];
      }
      s->num_buttons = n;
      qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
      vmstate_register(NULL, -1, &vmstate_stellaris_gamepad, s);
  }
  