qemu/hw/input/stellaris_input.c
<<
>>
Prefs
   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
  10#include "qemu/osdep.h"
  11#include "hw/input/gamepad.h"
  12#include "hw/irq.h"
  13#include "migration/vmstate.h"
  14#include "ui/console.h"
  15
  16typedef struct {
  17    qemu_irq irq;
  18    int keycode;
  19    uint8_t pressed;
  20} gamepad_button;
  21
  22typedef struct {
  23    gamepad_button *buttons;
  24    int num_buttons;
  25    int extension;
  26} gamepad_state;
  27
  28static void stellaris_gamepad_put_key(void * opaque, int keycode)
  29{
  30    gamepad_state *s = (gamepad_state *)opaque;
  31    int i;
  32    int down;
  33
  34    if (keycode == 0xe0 && !s->extension) {
  35        s->extension = 0x80;
  36        return;
  37    }
  38
  39    down = (keycode & 0x80) == 0;
  40    keycode = (keycode & 0x7f) | s->extension;
  41
  42    for (i = 0; i < s->num_buttons; i++) {
  43        if (s->buttons[i].keycode == keycode
  44                && s->buttons[i].pressed != down) {
  45            s->buttons[i].pressed = down;
  46            qemu_set_irq(s->buttons[i].irq, down);
  47        }
  48    }
  49
  50    s->extension = 0;
  51}
  52
  53static const VMStateDescription vmstate_stellaris_button = {
  54    .name = "stellaris_button",
  55    .version_id = 0,
  56    .minimum_version_id = 0,
  57    .fields = (VMStateField[]) {
  58        VMSTATE_UINT8(pressed, gamepad_button),
  59        VMSTATE_END_OF_LIST()
  60    }
  61};
  62
  63static const VMStateDescription vmstate_stellaris_gamepad = {
  64    .name = "stellaris_gamepad",
  65    .version_id = 2,
  66    .minimum_version_id = 2,
  67    .fields = (VMStateField[]) {
  68        VMSTATE_INT32(extension, gamepad_state),
  69        VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state,
  70                                            num_buttons,
  71                                            vmstate_stellaris_button,
  72                                            gamepad_button),
  73        VMSTATE_END_OF_LIST()
  74    }
  75};
  76
  77/* Returns an array of 5 output slots.  */
  78void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
  79{
  80    gamepad_state *s;
  81    int i;
  82
  83    s = g_new0(gamepad_state, 1);
  84    s->buttons = g_new0(gamepad_button, n);
  85    for (i = 0; i < n; i++) {
  86        s->buttons[i].irq = irq[i];
  87        s->buttons[i].keycode = keycode[i];
  88    }
  89    s->num_buttons = n;
  90    qemu_add_kbd_event_handler(stellaris_gamepad_put_key, s);
  91    vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY,
  92                     &vmstate_stellaris_gamepad, s);
  93}
  94