/*
 * QEMU Baum Braille Device
 *
 * Copyright (c) 2008, 2010-2011, 2016-2017 Samuel Thibault
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "chardev/char.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "hw/usb.h"
#include "ui/console.h"
#include <brlapi.h>
#include <brlapi_constants.h>
#include <brlapi_keycodes.h>
#include "qom/object.h"

#if 0
#define DPRINTF(fmt, ...) \
        printf(fmt, ## __VA_ARGS__)
#else
#define DPRINTF(fmt, ...)
#endif

#define ESC 0x1B

#define BAUM_REQ_DisplayData            0x01
#define BAUM_REQ_GetVersionNumber       0x05
#define BAUM_REQ_GetKeys                0x08
#define BAUM_REQ_SetMode                0x12
#define BAUM_REQ_SetProtocol            0x15
#define BAUM_REQ_GetDeviceIdentity      0x84
#define BAUM_REQ_GetSerialNumber        0x8A

#define BAUM_RSP_CellCount              0x01
#define BAUM_RSP_VersionNumber          0x05
#define BAUM_RSP_ModeSetting            0x11
#define BAUM_RSP_CommunicationChannel   0x16
#define BAUM_RSP_PowerdownSignal        0x17
#define BAUM_RSP_HorizontalSensors      0x20
#define BAUM_RSP_VerticalSensors        0x21
#define BAUM_RSP_RoutingKeys            0x22
#define BAUM_RSP_Switches               0x23
#define BAUM_RSP_TopKeys                0x24
#define BAUM_RSP_HorizontalSensor       0x25
#define BAUM_RSP_VerticalSensor         0x26
#define BAUM_RSP_RoutingKey             0x27
#define BAUM_RSP_FrontKeys6             0x28
#define BAUM_RSP_BackKeys6              0x29
#define BAUM_RSP_CommandKeys            0x2B
#define BAUM_RSP_FrontKeys10            0x2C
#define BAUM_RSP_BackKeys10             0x2D
#define BAUM_RSP_EntryKeys              0x33
#define BAUM_RSP_JoyStick               0x34
#define BAUM_RSP_ErrorCode              0x40
#define BAUM_RSP_InfoBlock              0x42
#define BAUM_RSP_DeviceIdentity         0x84
#define BAUM_RSP_SerialNumber           0x8A
#define BAUM_RSP_BluetoothName          0x8C

#define BAUM_TL1 0x01
#define BAUM_TL2 0x02
#define BAUM_TL3 0x04
#define BAUM_TR1 0x08
#define BAUM_TR2 0x10
#define BAUM_TR3 0x20

#define BUF_SIZE 256

#define X_MAX   84
#define Y_MAX   1

struct BaumChardev {
    Chardev parent;

    brlapi_handle_t *brlapi;
    int brlapi_fd;
    unsigned int x, y;
    bool deferred_init;

    uint8_t in_buf[BUF_SIZE];
    uint8_t in_buf_used;
    uint8_t out_buf[BUF_SIZE];
    uint8_t out_buf_used, out_buf_ptr;

    QEMUTimer *cellCount_timer;
};
typedef struct BaumChardev BaumChardev;

#define TYPE_CHARDEV_BRAILLE "chardev-braille"
DECLARE_INSTANCE_CHECKER(BaumChardev, BAUM_CHARDEV,
                         TYPE_CHARDEV_BRAILLE)

/* Let's assume NABCC by default */
enum way {
    DOTS2ASCII,
    ASCII2DOTS
};
static const uint8_t nabcc_translation[2][256] = {
#ifndef BRLAPI_DOTS
#define BRLAPI_DOTS(d1,d2,d3,d4,d5,d6,d7,d8) \
    ((d1?BRLAPI_DOT1:0)|\
     (d2?BRLAPI_DOT2:0)|\
     (d3?BRLAPI_DOT3:0)|\
     (d4?BRLAPI_DOT4:0)|\
     (d5?BRLAPI_DOT5:0)|\
     (d6?BRLAPI_DOT6:0)|\
     (d7?BRLAPI_DOT7:0)|\
     (d8?BRLAPI_DOT8:0))
#endif
#define DO(dots, ascii) \
    [DOTS2ASCII][dots] = ascii, \
    [ASCII2DOTS][ascii] = dots
    DO(0, ' '),
    DO(BRLAPI_DOTS(1, 0, 0, 0, 0, 0, 0, 0), 'a'),
    DO(BRLAPI_DOTS(1, 1, 0, 0, 0, 0, 0, 0), 'b'),
    DO(BRLAPI_DOTS(1, 0, 0, 1, 0, 0, 0, 0), 'c'),
    DO(BRLAPI_DOTS(1, 0, 0, 1, 1, 0, 0, 0), 'd'),
    DO(BRLAPI_DOTS(1, 0, 0, 0, 1, 0, 0, 0), 'e'),
    DO(BRLAPI_DOTS(1, 1, 0, 1, 0, 0, 0, 0), 'f'),
    DO(BRLAPI_DOTS(1, 1, 0, 1, 1, 0, 0, 0), 'g'),
    DO(BRLAPI_DOTS(1, 1, 0, 0, 1, 0, 0, 0), 'h'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 0, 0, 0, 0), 'i'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 1, 0, 0, 0), 'j'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 0, 0, 0, 0), 'k'),
    DO(BRLAPI_DOTS(1, 1, 1, 0, 0, 0, 0, 0), 'l'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 0, 0, 0, 0), 'm'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 1, 0, 0, 0), 'n'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 1, 0, 0, 0), 'o'),
    DO(BRLAPI_DOTS(1, 1, 1, 1, 0, 0, 0, 0), 'p'),
    DO(BRLAPI_DOTS(1, 1, 1, 1, 1, 0, 0, 0), 'q'),
    DO(BRLAPI_DOTS(1, 1, 1, 0, 1, 0, 0, 0), 'r'),
    DO(BRLAPI_DOTS(0, 1, 1, 1, 0, 0, 0, 0), 's'),
    DO(BRLAPI_DOTS(0, 1, 1, 1, 1, 0, 0, 0), 't'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 0, 1, 0, 0), 'u'),
    DO(BRLAPI_DOTS(1, 1, 1, 0, 0, 1, 0, 0), 'v'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 1, 1, 0, 0), 'w'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 0, 1, 0, 0), 'x'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 1, 1, 0, 0), 'y'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 1, 1, 0, 0), 'z'),

    DO(BRLAPI_DOTS(1, 0, 0, 0, 0, 0, 1, 0), 'A'),
    DO(BRLAPI_DOTS(1, 1, 0, 0, 0, 0, 1, 0), 'B'),
    DO(BRLAPI_DOTS(1, 0, 0, 1, 0, 0, 1, 0), 'C'),
    DO(BRLAPI_DOTS(1, 0, 0, 1, 1, 0, 1, 0), 'D'),
    DO(BRLAPI_DOTS(1, 0, 0, 0, 1, 0, 1, 0), 'E'),
    DO(BRLAPI_DOTS(1, 1, 0, 1, 0, 0, 1, 0), 'F'),
    DO(BRLAPI_DOTS(1, 1, 0, 1, 1, 0, 1, 0), 'G'),
    DO(BRLAPI_DOTS(1, 1, 0, 0, 1, 0, 1, 0), 'H'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 0, 0, 1, 0), 'I'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 1, 0, 1, 0), 'J'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 0, 0, 1, 0), 'K'),
    DO(BRLAPI_DOTS(1, 1, 1, 0, 0, 0, 1, 0), 'L'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 0, 0, 1, 0), 'M'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 1, 0, 1, 0), 'N'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 1, 0, 1, 0), 'O'),
    DO(BRLAPI_DOTS(1, 1, 1, 1, 0, 0, 1, 0), 'P'),
    DO(BRLAPI_DOTS(1, 1, 1, 1, 1, 0, 1, 0), 'Q'),
    DO(BRLAPI_DOTS(1, 1, 1, 0, 1, 0, 1, 0), 'R'),
    DO(BRLAPI_DOTS(0, 1, 1, 1, 0, 0, 1, 0), 'S'),
    DO(BRLAPI_DOTS(0, 1, 1, 1, 1, 0, 1, 0), 'T'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 0, 1, 1, 0), 'U'),
    DO(BRLAPI_DOTS(1, 1, 1, 0, 0, 1, 1, 0), 'V'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 1, 1, 1, 0), 'W'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 0, 1, 1, 0), 'X'),
    DO(BRLAPI_DOTS(1, 0, 1, 1, 1, 1, 1, 0), 'Y'),
    DO(BRLAPI_DOTS(1, 0, 1, 0, 1, 1, 1, 0), 'Z'),

    DO(BRLAPI_DOTS(0, 0, 1, 0, 1, 1, 0, 0), '0'),
    DO(BRLAPI_DOTS(0, 1, 0, 0, 0, 0, 0, 0), '1'),
    DO(BRLAPI_DOTS(0, 1, 1, 0, 0, 0, 0, 0), '2'),
    DO(BRLAPI_DOTS(0, 1, 0, 0, 1, 0, 0, 0), '3'),
    DO(BRLAPI_DOTS(0, 1, 0, 0, 1, 1, 0, 0), '4'),
    DO(BRLAPI_DOTS(0, 1, 0, 0, 0, 1, 0, 0), '5'),
    DO(BRLAPI_DOTS(0, 1, 1, 0, 1, 0, 0, 0), '6'),
    DO(BRLAPI_DOTS(0, 1, 1, 0, 1, 1, 0, 0), '7'),
    DO(BRLAPI_DOTS(0, 1, 1, 0, 0, 1, 0, 0), '8'),
    DO(BRLAPI_DOTS(0, 0, 1, 0, 1, 0, 0, 0), '9'),

    DO(BRLAPI_DOTS(0, 0, 0, 1, 0, 1, 0, 0), '.'),
    DO(BRLAPI_DOTS(0, 0, 1, 1, 0, 1, 0, 0), '+'),
    DO(BRLAPI_DOTS(0, 0, 1, 0, 0, 1, 0, 0), '-'),
    DO(BRLAPI_DOTS(1, 0, 0, 0, 0, 1, 0, 0), '*'),
    DO(BRLAPI_DOTS(0, 0, 1, 1, 0, 0, 0, 0), '/'),
    DO(BRLAPI_DOTS(1, 1, 1, 0, 1, 1, 0, 0), '('),
    DO(BRLAPI_DOTS(0, 1, 1, 1, 1, 1, 0, 0), ')'),

    DO(BRLAPI_DOTS(1, 1, 1, 1, 0, 1, 0, 0), '&'),
    DO(BRLAPI_DOTS(0, 0, 1, 1, 1, 1, 0, 0), '#'),

    DO(BRLAPI_DOTS(0, 0, 0, 0, 0, 1, 0, 0), ','),
    DO(BRLAPI_DOTS(0, 0, 0, 0, 1, 1, 0, 0), ';'),
    DO(BRLAPI_DOTS(1, 0, 0, 0, 1, 1, 0, 0), ':'),
    DO(BRLAPI_DOTS(0, 1, 1, 1, 0, 1, 0, 0), '!'),
    DO(BRLAPI_DOTS(1, 0, 0, 1, 1, 1, 0, 0), '?'),
    DO(BRLAPI_DOTS(0, 0, 0, 0, 1, 0, 0, 0), '"'),
    DO(BRLAPI_DOTS(0, 0, 1, 0, 0, 0, 0, 0), '\''),
    DO(BRLAPI_DOTS(0, 0, 0, 1, 0, 0, 0, 0), '`'),
    DO(BRLAPI_DOTS(0, 0, 0, 1, 1, 0, 1, 0), '^'),
    DO(BRLAPI_DOTS(0, 0, 0, 1, 1, 0, 0, 0), '~'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 0, 1, 1, 0), '['),
    DO(BRLAPI_DOTS(1, 1, 0, 1, 1, 1, 1, 0), ']'),
    DO(BRLAPI_DOTS(0, 1, 0, 1, 0, 1, 0, 0), '{'),
    DO(BRLAPI_DOTS(1, 1, 0, 1, 1, 1, 0, 0), '}'),
    DO(BRLAPI_DOTS(1, 1, 1, 1, 1, 1, 0, 0), '='),
    DO(BRLAPI_DOTS(1, 1, 0, 0, 0, 1, 0, 0), '<'),
    DO(BRLAPI_DOTS(0, 0, 1, 1, 1, 0, 0, 0), '>'),
    DO(BRLAPI_DOTS(1, 1, 0, 1, 0, 1, 0, 0), '$'),
    DO(BRLAPI_DOTS(1, 0, 0, 1, 0, 1, 0, 0), '%'),
    DO(BRLAPI_DOTS(0, 0, 0, 1, 0, 0, 1, 0), '@'),
    DO(BRLAPI_DOTS(1, 1, 0, 0, 1, 1, 0, 0), '|'),
    DO(BRLAPI_DOTS(1, 1, 0, 0, 1, 1, 1, 0), '\\'),
    DO(BRLAPI_DOTS(0, 0, 0, 1, 1, 1, 0, 0), '_'),
};

/* The guest OS has started discussing with us, finish initializing BrlAPI */
static int baum_deferred_init(BaumChardev *baum)
{
    int tty = BRLAPI_TTY_DEFAULT;
    QemuConsole *con;

    if (baum->deferred_init) {
        return 1;
    }

    if (brlapi__getDisplaySize(baum->brlapi, &baum->x, &baum->y) == -1) {
        brlapi_perror("baum: brlapi__getDisplaySize");
        return 0;
    }
    if (baum->y > Y_MAX) {
        baum->y = Y_MAX;
    }
    if (baum->x > X_MAX) {
        baum->x = X_MAX;
    }

    con = qemu_console_lookup_by_index(0);
    if (con && qemu_console_is_graphic(con)) {
        tty = qemu_console_get_window_id(con);
        if (tty == -1)
            tty = BRLAPI_TTY_DEFAULT;
    }

    if (brlapi__enterTtyMode(baum->brlapi, tty, NULL) == -1) {
        brlapi_perror("baum: brlapi__enterTtyMode");
        return 0;
    }
    baum->deferred_init = 1;
    return 1;
}

/* The serial port can receive more of our data */
static void baum_chr_accept_input(struct Chardev *chr)
{
    BaumChardev *baum = BAUM_CHARDEV(chr);
    int room, first;

    if (!baum->out_buf_used)
        return;
    room = qemu_chr_be_can_write(chr);
    if (!room)
        return;
    if (room > baum->out_buf_used)
        room = baum->out_buf_used;

    first = BUF_SIZE - baum->out_buf_ptr;
    if (room > first) {
        qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, first);
        baum->out_buf_ptr = 0;
        baum->out_buf_used -= first;
        room -= first;
    }
    qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, room);
    baum->out_buf_ptr += room;
    baum->out_buf_used -= room;
}

/* We want to send a packet */
static void baum_write_packet(BaumChardev *baum, const uint8_t *buf, int len)
{
    Chardev *chr = CHARDEV(baum);
    g_autofree uint8_t *io_buf = g_malloc(1 + 2 * len);
    uint8_t *cur = io_buf;
    int room;
    *cur++ = ESC;
    while (len--)
        if ((*cur++ = *buf++) == ESC)
            *cur++ = ESC;
    room = qemu_chr_be_can_write(chr);
    len = cur - io_buf;
    if (len <= room) {
        /* Fits */
        qemu_chr_be_write(chr, io_buf, len);
    } else {
        int first;
        uint8_t out;
        /* Can't fit all, send what can be, and store the rest. */
        qemu_chr_be_write(chr, io_buf, room);
        len -= room;
        cur = io_buf + room;
        if (len > BUF_SIZE - baum->out_buf_used) {
            /* Can't even store it, drop the previous data... */
            assert(len <= BUF_SIZE);
            baum->out_buf_used = 0;
            baum->out_buf_ptr = 0;
        }
        out = baum->out_buf_ptr;
        baum->out_buf_used += len;
        first = BUF_SIZE - baum->out_buf_ptr;
        if (len > first) {
            memcpy(baum->out_buf + out, cur, first);
            out = 0;
            len -= first;
            cur += first;
        }
        memcpy(baum->out_buf + out, cur, len);
    }
}

/* Called when the other end seems to have a wrong idea of our display size */
static void baum_cellCount_timer_cb(void *opaque)
{
    BaumChardev *baum = BAUM_CHARDEV(opaque);
    uint8_t cell_count[] = { BAUM_RSP_CellCount, baum->x * baum->y };
    DPRINTF("Timeout waiting for DisplayData, sending cell count\n");
    baum_write_packet(baum, cell_count, sizeof(cell_count));
}

/* Try to interpret a whole incoming packet */
static int baum_eat_packet(BaumChardev *baum, const uint8_t *buf, int len)
{
    const uint8_t *cur = buf;
    uint8_t req = 0;

    if (!len--)
        return 0;
    if (*cur++ != ESC) {
        while (*cur != ESC) {
            if (!len--)
                return 0;
            cur++;
        }
        DPRINTF("Dropped %td bytes!\n", cur - buf);
    }

#define EAT(c) do {\
    if (!len--) \
        return 0; \
    if ((c = *cur++) == ESC) { \
        if (!len--) \
            return 0; \
        if (*cur++ != ESC) { \
            DPRINTF("Broken packet %#2x, tossing\n", req); \
            if (timer_pending(baum->cellCount_timer)) {    \
                timer_del(baum->cellCount_timer);     \
                baum_cellCount_timer_cb(baum);             \
            } \
            return (cur - 2 - buf); \
        } \
    } \
} while (0)

    EAT(req);
    switch (req) {
    case BAUM_REQ_DisplayData:
    {
        uint8_t cells[X_MAX * Y_MAX], c;
        uint8_t text[X_MAX * Y_MAX];
        uint8_t zero[X_MAX * Y_MAX];
        int cursor = BRLAPI_CURSOR_OFF;
        int i;

        /* Allow 100ms to complete the DisplayData packet */
        timer_mod(baum->cellCount_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                       NANOSECONDS_PER_SECOND / 10);
        for (i = 0; i < baum->x * baum->y ; i++) {
            EAT(c);
            cells[i] = c;
            if ((c & (BRLAPI_DOT7|BRLAPI_DOT8))
                    == (BRLAPI_DOT7|BRLAPI_DOT8)) {
                cursor = i + 1;
                c &= ~(BRLAPI_DOT7|BRLAPI_DOT8);
            }
            c = nabcc_translation[DOTS2ASCII][c];
            if (!c) {
                c = '?';
            }
            text[i] = c;
        }
        timer_del(baum->cellCount_timer);

        memset(zero, 0, baum->x * baum->y);

        brlapi_writeArguments_t wa = {
            .displayNumber = BRLAPI_DISPLAY_DEFAULT,
            .regionBegin = 1,
            .regionSize = baum->x * baum->y,
            .text = (char *)text,
            .textSize = baum->x * baum->y,
            .andMask = zero,
            .orMask = cells,
            .cursor = cursor,
            .charset = (char *)"ISO-8859-1",
        };

        if (brlapi__write(baum->brlapi, &wa) == -1)
            brlapi_perror("baum brlapi_write");
        break;
    }
    case BAUM_REQ_SetMode:
    {
        uint8_t mode, setting;
        DPRINTF("SetMode\n");
        EAT(mode);
        EAT(setting);
        /* ignore */
        break;
    }
    case BAUM_REQ_SetProtocol:
    {
        uint8_t protocol;
        DPRINTF("SetProtocol\n");
        EAT(protocol);
        /* ignore */
        break;
    }
    case BAUM_REQ_GetDeviceIdentity:
    {
        uint8_t identity[17] = { BAUM_RSP_DeviceIdentity,
            'B','a','u','m',' ','V','a','r','i','o' };
        DPRINTF("GetDeviceIdentity\n");
        identity[11] = '0' + baum->x / 10;
        identity[12] = '0' + baum->x % 10;
        baum_write_packet(baum, identity, sizeof(identity));
        break;
    }
    case BAUM_REQ_GetVersionNumber:
    {
        uint8_t version[] = { BAUM_RSP_VersionNumber, 1 }; /* ? */
        DPRINTF("GetVersionNumber\n");
        baum_write_packet(baum, version, sizeof(version));
        break;
    }
    case BAUM_REQ_GetSerialNumber:
    {
        uint8_t serial[] = { BAUM_RSP_SerialNumber,
            '0','0','0','0','0','0','0','0' };
        DPRINTF("GetSerialNumber\n");
        baum_write_packet(baum, serial, sizeof(serial));
        break;
    }
    case BAUM_REQ_GetKeys:
    {
        DPRINTF("Get%0#2x\n", req);
        /* ignore */
        break;
    }
    default:
        DPRINTF("unrecognized request %0#2x\n", req);
        do
            if (!len--)
                return 0;
        while (*cur++ != ESC);
        cur--;
        break;
    }
    return cur - buf;
}

/* The other end is writing some data.  Store it and try to interpret */
static int baum_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
    BaumChardev *baum = BAUM_CHARDEV(chr);
    int tocopy, cur, eaten, orig_len = len;

    if (!len)
        return 0;
    if (!baum->brlapi)
        return len;
    if (!baum_deferred_init(baum))
        return len;

    while (len) {
        /* Complete our buffer as much as possible */
        tocopy = len;
        if (tocopy > BUF_SIZE - baum->in_buf_used)
            tocopy = BUF_SIZE - baum->in_buf_used;

        memcpy(baum->in_buf + baum->in_buf_used, buf, tocopy);
        baum->in_buf_used += tocopy;
        buf += tocopy;
        len -= tocopy;

        /* Interpret it as much as possible */
        cur = 0;
        while (cur < baum->in_buf_used &&
                (eaten = baum_eat_packet(baum, baum->in_buf + cur, baum->in_buf_used - cur)))
            cur += eaten;

        /* Shift the remainder */
        if (cur) {
            memmove(baum->in_buf, baum->in_buf + cur, baum->in_buf_used - cur);
            baum->in_buf_used -= cur;
        }

        /* And continue if any data left */
    }
    return orig_len;
}

/* Send the key code to the other end */
static void baum_send_key(BaumChardev *baum, uint8_t type, uint8_t value)
{
    uint8_t packet[] = { type, value };
    DPRINTF("writing key %x %x\n", type, value);
    baum_write_packet(baum, packet, sizeof(packet));
}

static void baum_send_key2(BaumChardev *baum, uint8_t type, uint8_t value,
                           uint8_t value2)
{
    uint8_t packet[] = { type, value, value2 };
    DPRINTF("writing key %x %x\n", type, value);
    baum_write_packet(baum, packet, sizeof(packet));
}

/* We got some data on the BrlAPI socket */
static void baum_chr_read(void *opaque)
{
    BaumChardev *baum = BAUM_CHARDEV(opaque);
    brlapi_keyCode_t code;
    int ret;
    if (!baum->brlapi)
        return;
    if (!baum_deferred_init(baum))
        return;
    while ((ret = brlapi__readKey(baum->brlapi, 0, &code)) == 1) {
        DPRINTF("got key %"BRLAPI_PRIxKEYCODE"\n", code);
        /* Emulate */
        switch (code & BRLAPI_KEY_TYPE_MASK) {
        case BRLAPI_KEY_TYPE_CMD:
            switch (code & BRLAPI_KEY_CMD_BLK_MASK) {
            case BRLAPI_KEY_CMD_ROUTE:
                baum_send_key(baum, BAUM_RSP_RoutingKey, (code & BRLAPI_KEY_CMD_ARG_MASK)+1);
                baum_send_key(baum, BAUM_RSP_RoutingKey, 0);
                break;
            case 0:
                switch (code & BRLAPI_KEY_CMD_ARG_MASK) {
                case BRLAPI_KEY_CMD_FWINLT:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TL2);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_FWINRT:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TR2);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_LNUP:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TR1);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_LNDN:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TR3);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_TOP:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TL1|BAUM_TR1);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_BOT:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TL3|BAUM_TR3);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_TOP_LEFT:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TL2|BAUM_TR1);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_BOT_LEFT:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TL2|BAUM_TR3);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_HOME:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TL2|BAUM_TR1|BAUM_TR3);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                case BRLAPI_KEY_CMD_PREFMENU:
                    baum_send_key(baum, BAUM_RSP_TopKeys, BAUM_TL1|BAUM_TL3|BAUM_TR1);
                    baum_send_key(baum, BAUM_RSP_TopKeys, 0);
                    break;
                }
            }
            break;
        case BRLAPI_KEY_TYPE_SYM:
            {
                brlapi_keyCode_t keysym = code & BRLAPI_KEY_CODE_MASK;
                if (keysym < 0x100) {
                    uint8_t dots = nabcc_translation[ASCII2DOTS][keysym];
                    if (dots) {
                        baum_send_key2(baum, BAUM_RSP_EntryKeys, 0, dots);
                        baum_send_key2(baum, BAUM_RSP_EntryKeys, 0, 0);
                    }
                }
                break;
            }
        }
    }
    if (ret == -1 && (brlapi_errno != BRLAPI_ERROR_LIBCERR || errno != EINTR)) {
        brlapi_perror("baum: brlapi_readKey");
        brlapi__closeConnection(baum->brlapi);
        g_free(baum->brlapi);
        baum->brlapi = NULL;
    }
}

static void char_braille_finalize(Object *obj)
{
    BaumChardev *baum = BAUM_CHARDEV(obj);

    timer_free(baum->cellCount_timer);
    if (baum->brlapi) {
        brlapi__closeConnection(baum->brlapi);
        g_free(baum->brlapi);
    }
}

static void baum_chr_open(Chardev *chr,
                          ChardevBackend *backend,
                          bool *be_opened,
                          Error **errp)
{
    BaumChardev *baum = BAUM_CHARDEV(chr);
    brlapi_handle_t *handle;

    handle = g_malloc0(brlapi_getHandleSize());
    baum->brlapi = handle;

    baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL);
    if (baum->brlapi_fd == -1) {
        error_setg(errp, "brlapi__openConnection: %s",
                   brlapi_strerror(brlapi_error_location()));
        g_free(handle);
        baum->brlapi = NULL;
        return;
    }
    baum->deferred_init = 0;

    baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);

    qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);
}

static void char_braille_class_init(ObjectClass *oc, void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->open = baum_chr_open;
    cc->chr_write = baum_chr_write;
    cc->chr_accept_input = baum_chr_accept_input;
}

static const TypeInfo char_braille_type_info = {
    .name = TYPE_CHARDEV_BRAILLE,
    .parent = TYPE_CHARDEV,
    .instance_size = sizeof(BaumChardev),
    .instance_finalize = char_braille_finalize,
    .class_init = char_braille_class_init,
};
module_obj(TYPE_CHARDEV_BRAILLE);

static void register_types(void)
{
    type_register_static(&char_braille_type_info);
}

type_init(register_types);
