baum.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 644 行 · 第 1/2 页

C
644
字号
/* * QEMU Baum Braille Device * * Copyright (c) 2008 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-common.h"#include "qemu-char.h"#include "qemu-timer.h"#include "usb.h"#include <assert.h>#include <brlapi.h>#include <brlapi_constants.h>#include <brlapi_keycodes.h>#ifdef CONFIG_SDL#include <SDL/SDL_syswm.h>#endif#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 256typedef struct {    CharDriverState *chr;    brlapi_handle_t *brlapi;    int brlapi_fd;    int x, y;    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;} BaumDriverState;/* Let's assume NABCC by default */static const uint8_t nabcc_translation[256] = {    [0] = ' ',#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    [BRLAPI_DOTS(1,0,0,0,0,0,0,0)] = 'a',    [BRLAPI_DOTS(1,1,0,0,0,0,0,0)] = 'b',    [BRLAPI_DOTS(1,0,0,1,0,0,0,0)] = 'c',    [BRLAPI_DOTS(1,0,0,1,1,0,0,0)] = 'd',    [BRLAPI_DOTS(1,0,0,0,1,0,0,0)] = 'e',    [BRLAPI_DOTS(1,1,0,1,0,0,0,0)] = 'f',    [BRLAPI_DOTS(1,1,0,1,1,0,0,0)] = 'g',    [BRLAPI_DOTS(1,1,0,0,1,0,0,0)] = 'h',    [BRLAPI_DOTS(0,1,0,1,0,0,0,0)] = 'i',    [BRLAPI_DOTS(0,1,0,1,1,0,0,0)] = 'j',    [BRLAPI_DOTS(1,0,1,0,0,0,0,0)] = 'k',    [BRLAPI_DOTS(1,1,1,0,0,0,0,0)] = 'l',    [BRLAPI_DOTS(1,0,1,1,0,0,0,0)] = 'm',    [BRLAPI_DOTS(1,0,1,1,1,0,0,0)] = 'n',    [BRLAPI_DOTS(1,0,1,0,1,0,0,0)] = 'o',    [BRLAPI_DOTS(1,1,1,1,0,0,0,0)] = 'p',    [BRLAPI_DOTS(1,1,1,1,1,0,0,0)] = 'q',    [BRLAPI_DOTS(1,1,1,0,1,0,0,0)] = 'r',    [BRLAPI_DOTS(0,1,1,1,0,0,0,0)] = 's',    [BRLAPI_DOTS(0,1,1,1,1,0,0,0)] = 't',    [BRLAPI_DOTS(1,0,1,0,0,1,0,0)] = 'u',    [BRLAPI_DOTS(1,1,1,0,0,1,0,0)] = 'v',    [BRLAPI_DOTS(0,1,0,1,1,1,0,0)] = 'w',    [BRLAPI_DOTS(1,0,1,1,0,1,0,0)] = 'x',    [BRLAPI_DOTS(1,0,1,1,1,1,0,0)] = 'y',    [BRLAPI_DOTS(1,0,1,0,1,1,0,0)] = 'z',    [BRLAPI_DOTS(1,0,0,0,0,0,1,0)] = 'A',    [BRLAPI_DOTS(1,1,0,0,0,0,1,0)] = 'B',    [BRLAPI_DOTS(1,0,0,1,0,0,1,0)] = 'C',    [BRLAPI_DOTS(1,0,0,1,1,0,1,0)] = 'D',    [BRLAPI_DOTS(1,0,0,0,1,0,1,0)] = 'E',    [BRLAPI_DOTS(1,1,0,1,0,0,1,0)] = 'F',    [BRLAPI_DOTS(1,1,0,1,1,0,1,0)] = 'G',    [BRLAPI_DOTS(1,1,0,0,1,0,1,0)] = 'H',    [BRLAPI_DOTS(0,1,0,1,0,0,1,0)] = 'I',    [BRLAPI_DOTS(0,1,0,1,1,0,1,0)] = 'J',    [BRLAPI_DOTS(1,0,1,0,0,0,1,0)] = 'K',    [BRLAPI_DOTS(1,1,1,0,0,0,1,0)] = 'L',    [BRLAPI_DOTS(1,0,1,1,0,0,1,0)] = 'M',    [BRLAPI_DOTS(1,0,1,1,1,0,1,0)] = 'N',    [BRLAPI_DOTS(1,0,1,0,1,0,1,0)] = 'O',    [BRLAPI_DOTS(1,1,1,1,0,0,1,0)] = 'P',    [BRLAPI_DOTS(1,1,1,1,1,0,1,0)] = 'Q',    [BRLAPI_DOTS(1,1,1,0,1,0,1,0)] = 'R',    [BRLAPI_DOTS(0,1,1,1,0,0,1,0)] = 'S',    [BRLAPI_DOTS(0,1,1,1,1,0,1,0)] = 'T',    [BRLAPI_DOTS(1,0,1,0,0,1,1,0)] = 'U',    [BRLAPI_DOTS(1,1,1,0,0,1,1,0)] = 'V',    [BRLAPI_DOTS(0,1,0,1,1,1,1,0)] = 'W',    [BRLAPI_DOTS(1,0,1,1,0,1,1,0)] = 'X',    [BRLAPI_DOTS(1,0,1,1,1,1,1,0)] = 'Y',    [BRLAPI_DOTS(1,0,1,0,1,1,1,0)] = 'Z',    [BRLAPI_DOTS(0,0,1,0,1,1,0,0)] = '0',    [BRLAPI_DOTS(0,1,0,0,0,0,0,0)] = '1',    [BRLAPI_DOTS(0,1,1,0,0,0,0,0)] = '2',    [BRLAPI_DOTS(0,1,0,0,1,0,0,0)] = '3',    [BRLAPI_DOTS(0,1,0,0,1,1,0,0)] = '4',    [BRLAPI_DOTS(0,1,0,0,0,1,0,0)] = '5',    [BRLAPI_DOTS(0,1,1,0,1,0,0,0)] = '6',    [BRLAPI_DOTS(0,1,1,0,1,1,0,0)] = '7',    [BRLAPI_DOTS(0,1,1,0,0,1,0,0)] = '8',    [BRLAPI_DOTS(0,0,1,0,1,0,0,0)] = '9',    [BRLAPI_DOTS(0,0,0,1,0,1,0,0)] = '.',    [BRLAPI_DOTS(0,0,1,1,0,1,0,0)] = '+',    [BRLAPI_DOTS(0,0,1,0,0,1,0,0)] = '-',    [BRLAPI_DOTS(1,0,0,0,0,1,0,0)] = '*',    [BRLAPI_DOTS(0,0,1,1,0,0,0,0)] = '/',    [BRLAPI_DOTS(1,1,1,0,1,1,0,0)] = '(',    [BRLAPI_DOTS(0,1,1,1,1,1,0,0)] = ')',    [BRLAPI_DOTS(1,1,1,1,0,1,0,0)] = '&',    [BRLAPI_DOTS(0,0,1,1,1,1,0,0)] = '#',    [BRLAPI_DOTS(0,0,0,0,0,1,0,0)] = ',',    [BRLAPI_DOTS(0,0,0,0,1,1,0,0)] = ';',    [BRLAPI_DOTS(1,0,0,0,1,1,0,0)] = ':',    [BRLAPI_DOTS(0,1,1,1,0,1,0,0)] = '!',    [BRLAPI_DOTS(1,0,0,1,1,1,0,0)] = '?',    [BRLAPI_DOTS(0,0,0,0,1,0,0,0)] = '"',    [BRLAPI_DOTS(0,0,1,0,0,0,0,0)] ='\'',    [BRLAPI_DOTS(0,0,0,1,0,0,0,0)] = '`',    [BRLAPI_DOTS(0,0,0,1,1,0,1,0)] = '^',    [BRLAPI_DOTS(0,0,0,1,1,0,0,0)] = '~',    [BRLAPI_DOTS(0,1,0,1,0,1,1,0)] = '[',    [BRLAPI_DOTS(1,1,0,1,1,1,1,0)] = ']',    [BRLAPI_DOTS(0,1,0,1,0,1,0,0)] = '{',    [BRLAPI_DOTS(1,1,0,1,1,1,0,0)] = '}',    [BRLAPI_DOTS(1,1,1,1,1,1,0,0)] = '=',    [BRLAPI_DOTS(1,1,0,0,0,1,0,0)] = '<',    [BRLAPI_DOTS(0,0,1,1,1,0,0,0)] = '>',    [BRLAPI_DOTS(1,1,0,1,0,1,0,0)] = '$',    [BRLAPI_DOTS(1,0,0,1,0,1,0,0)] = '%',    [BRLAPI_DOTS(0,0,0,1,0,0,1,0)] = '@',    [BRLAPI_DOTS(1,1,0,0,1,1,0,0)] = '|',    [BRLAPI_DOTS(1,1,0,0,1,1,1,0)] ='\\',    [BRLAPI_DOTS(0,0,0,1,1,1,0,0)] = '_',};/* The serial port can receive more of our data */static void baum_accept_input(struct CharDriverState *chr){    BaumDriverState *baum = chr->opaque;    int room, first;    if (!baum->out_buf_used)        return;    room = qemu_chr_can_read(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_read(chr, baum->out_buf + baum->out_buf_ptr, first);        baum->out_buf_ptr = 0;        baum->out_buf_used -= first;        room -= first;    }    qemu_chr_read(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(BaumDriverState *baum, const uint8_t *buf, int len){    uint8_t io_buf[1 + 2 * len], *cur = io_buf;    int room;    *cur++ = ESC;    while (len--)        if ((*cur++ = *buf++) == ESC)            *cur++ = ESC;    room = qemu_chr_can_read(baum->chr);    len = cur - io_buf;    if (len <= room) {        /* Fits */        qemu_chr_read(baum->chr, io_buf, len);    } else {        int first;        uint8_t out;        /* Can't fit all, send what can be, and store the rest. */        qemu_chr_read(baum->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){    BaumDriverState *baum = 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(BaumDriverState *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 %d 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 (qemu_timer_pending(baum->cellCount_timer)) { \                qemu_del_timer(baum->cellCount_timer); \                baum_cellCount_timer_cb(baum); \            } \            return (cur - 2 - buf); \

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?