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 + -
显示快捷键?