/* * BRLTTY - A background process providing access to the console screen (when in * text mode) for a blind person using a refreshable braille display. * * Copyright (C) 1995-2019 by The BRLTTY Developers. * * BRLTTY comes with ABSOLUTELY NO WARRANTY. * * This is free software, placed under the terms of the * GNU Lesser General Public License, as published by the Free Software * Foundation; either version 2.1 of the License, or (at your option) any * later version. Please see the file LICENSE-LGPL for details. * * Web Page: http://brltty.app/ * * This software is maintained by Dave Mielke . */ #include "prologue.h" #include #include #include "log.h" #include "brl_driver.h" #include "brldefs-xx.h" #define PROBE_RETRY_LIMIT 2 #define PROBE_INPUT_TIMEOUT 1000 #define MAXIMUM_RESPONSE_SIZE (0XFF + 4) #define MAXIMUM_TEXT_CELLS 0XFF BEGIN_KEY_NAME_TABLE(navigation) END_KEY_NAME_TABLE BEGIN_KEY_NAME_TABLES(all) KEY_NAME_TABLE(navigation), END_KEY_NAME_TABLES DEFINE_KEY_TABLE(all) BEGIN_KEY_TABLE_LIST &KEY_TABLE_DEFINITION(all), END_KEY_TABLE_LIST struct BrailleDataStruct { struct { unsigned char rewrite; unsigned char cells[MAXIMUM_TEXT_CELLS]; } text; }; static int writeBytes (BrailleDisplay *brl, const unsigned char *bytes, size_t count) { return writeBraillePacket(brl, NULL, bytes, count); } static int writePacket (BrailleDisplay *brl, const unsigned char *packet, size_t size) { unsigned char bytes[size]; unsigned char *byte = bytes; byte = mempcpy(byte, packet, size); return writeBytes(brl, bytes, byte-bytes); } static BraillePacketVerifierResult verifyPacket ( BrailleDisplay *brl, const unsigned char *bytes, size_t size, size_t *length, void *data ) { unsigned char byte = bytes[size-1]; switch (size) { case 1: switch (byte) { default: return BRL_PVR_INVALID; } break; default: break; } return BRL_PVR_INCLUDE; } static size_t readPacket (BrailleDisplay *brl, void *packet, size_t size) { return readBraillePacket(brl, NULL, packet, size, verifyPacket, NULL); } static int connectResource (BrailleDisplay *brl, const char *identifier) { static const SerialParameters serialParameters = { SERIAL_DEFAULT_PARAMETERS }; BEGIN_USB_CHANNEL_DEFINITIONS END_USB_CHANNEL_DEFINITIONS GioDescriptor descriptor; gioInitializeDescriptor(&descriptor); descriptor.serial.parameters = &serialParameters; descriptor.usb.channelDefinitions = usbChannelDefinitions; if (connectBrailleResource(brl, identifier, &descriptor, NULL)) { return 1; } return 0; } static int writeIdentityRequest (BrailleDisplay *brl) { static const unsigned char packet[] = {0}; return writePacket(brl, packet, sizeof(packet)); } static BrailleResponseResult isIdentityResponse (BrailleDisplay *brl, const void *packet, size_t size) { return BRL_RSP_UNEXPECTED; } static int brl_construct (BrailleDisplay *brl, char **parameters, const char *device) { if ((brl->data = malloc(sizeof(*brl->data)))) { memset(brl->data, 0, sizeof(*brl->data)); if (connectResource(brl, device)) { unsigned char response[MAXIMUM_RESPONSE_SIZE]; if (probeBrailleDisplay(brl, PROBE_RETRY_LIMIT, NULL, PROBE_INPUT_TIMEOUT, writeIdentityRequest, readPacket, &response, sizeof(response), isIdentityResponse)) { setBrailleKeyTable(brl, &KEY_TABLE_DEFINITION(all)); makeOutputTable(dotsTable_ISO11548_1); //MAKE_OUTPUT_TABLE(0X01, 0X02, 0X04, 0X08, 0X10, 0X20, 0X40, 0X80); brl->data->text.rewrite = 1; return 1; } disconnectBrailleResource(brl, NULL); } free(brl->data); } else { logMallocError(); } return 0; } static void brl_destruct (BrailleDisplay *brl) { disconnectBrailleResource(brl, NULL); if (brl->data) { free(brl->data); brl->data = NULL; } } static int brl_writeWindow (BrailleDisplay *brl, const wchar_t *text) { if (cellsHaveChanged(brl->data->text.cells, brl->buffer, brl->textColumns, NULL, NULL, &brl->data->text.rewrite)) { unsigned char cells[brl->textColumns]; translateOutputCells(cells, brl->data->text.cells, brl->textColumns); } return 1; } static int brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) { unsigned char packet[MAXIMUM_RESPONSE_SIZE]; size_t size; while ((size = readPacket(brl, packet, sizeof(packet)))) { logUnexpectedPacket(packet, size); } return (errno == EAGAIN)? EOF: BRL_CMD_RESTARTBRL; }