static struct KeyStroke getbrlkey (void) { unsigned char c, c_temp; /* character buffer */ KeyStroke keystroke; while (serialReadData (MB_serialDevice, &c, 1, 0, 0) == 1) { if (c != ESC) continue; /* advance to next ESC-sequence */ serialReadData (MB_serialDevice, &c, 1, 0, 0); /* read block number */ switch (c) { case 'T': /* front key message, (MB185CR only: also '0'-'9', '*', '#') */ case 'S': /* top key message [1-2-4--8-16-32] */ case 'R': /* cursor routing key [0 - maxkeys] */ keystroke.block = c; serialReadData (MB_serialDevice, &c, 1, 0, 0); /* read keynumber */ keystroke.key = c; serialReadData (MB_serialDevice, &c, 1, 0, 0); /* read trailing [CR] */ /* logMessage(LOG_NOTICE, "MultiBraille.o: Receiving: Key=%d, Block=%c", keystroke.key, keystroke.block); */ return keystroke; default: /* not supported command --> ignore */ c_temp = c; keystroke.block = EOF; /* invalid / not supported keystroke */ serialReadData (MB_serialDevice, &c, 1, 0, 0); /* read keynumber */ keystroke.key = 0; logMessage(LOG_NOTICE, "MultiBraille.o: Ignored: Key=%d, Block=%c", keystroke.key, c_temp); return keystroke; } } keystroke.block = EOF; keystroke.key = 0; return keystroke; }
/* Returns 0 if everything is right, -1 if an error occured while sending */ static ssize_t brl_writePacket(BrailleDisplay *brl, const void *packet, size_t size) { const unsigned char *p = packet; int lgtho = 1; unsigned char obuf[MAXPACKETSIZE]; const unsigned char *x; unsigned char *y = obuf; unsigned char chksum=0; int i,res; *y++ = 02; for (x=p; (x-p) < size; x++) { chksum ^= *x; if ((*x) <= 5) { *y = 01; y++; lgtho++; *y = ( *x ) | 0x40; } else *y = *x; y++; lgtho++; } if (chksum<=5) { *y = 1; y++; lgtho++; chksum |= 0x40; } *y = chksum; y++; lgtho++; *y = 3; y++; lgtho++; for (i=1; i<=5; i++) { if (serialWriteData(serialDevice,obuf,lgtho) != lgtho) continue; /* write failed, retry */ serialAwaitOutput(serialDevice); serialAwaitInput(serialDevice, 1000); res = serialReadData(serialDevice,&chksum,1,0,0); if ((res==1) && (chksum == 0x04)) return 0; } return (-1); }
static unsigned char getByte (void) { unsigned char byte; while (!serialAwaitInput(serialDevice, 1000000000)); serialReadData(serialDevice, &byte, 1, 0, 0); return byte; }
static ssize_t readSerialData ( GioHandle *handle, void *buffer, size_t size, int initialTimeout, int subsequentTimeout ) { return serialReadData(handle->serial.device, buffer, size, initialTimeout, subsequentTimeout); }
static int readByte (unsigned char *byte, int wait) { const int timeout = 100; ssize_t result = serialReadData(serialDevice, byte, sizeof(*byte), (wait? timeout: 0), timeout); if (result > 0) return 1; if (result == 0) errno = EAGAIN; return 0; }
static int readKey (void) { unsigned char key; unsigned char arg; if (serialReadData(serialDevice, &key, 1, 0, 0) != 1) return EOF; switch (key) { default: arg = 0; break; case KEY_FUNCTION: case KEY_FUNCTION2: case KEY_UPDATE: while (serialReadData(serialDevice, &arg, 1, 0, 0) != 1) asyncWait(1); break; } { int result = COMPOUND_KEY(key, arg); logMessage(LOG_DEBUG, "Key read: %4.4X", result); return result; } }
/* * 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-2013 by The BRLTTY Developers. * * BRLTTY comes with ABSOLUTELY NO WARRANTY. * * This is free software, placed under the terms of the * GNU General Public License, as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any * later version. Please see the file LICENSE-GPL for details. * * Web Page: http://mielke.cc/brltty/ * * This software is maintained by Dave Mielke <*****@*****.**>. */ #include "prologue.h" #include <stdio.h> #include <string.h> #include <errno.h> #include <locale.h> #include <limits.h> #ifndef MB_MAX_LEN #define MB_MAX_LEN 16 #endif /* MB_MAX_LEN */ #ifdef HAVE_ICONV_H #include <iconv.h> static iconv_t conversionDescriptor = NULL; #endif /* HAVE_ICONV_H */ #if defined(HAVE_PKG_CURSES) #define USE_CURSES #include <stdarg.h> #include <curses.h> #elif defined(HAVE_PKG_NCURSES) #define USE_CURSES #include <ncurses.h> #elif defined(HAVE_PKG_NCURSESW) #define USE_CURSES #include <ncursesw/ncurses.h> #else /* HAVE_PKG_ */ #warning curses package either unspecified or unsupported #define addstr(string) serialWriteData(ttyDevice, string, strlen(string)) #define addch(character) do { unsigned char __c = (character); serialWriteData(ttyDevice, &__c, 1); } while(0) #define getch() my_getch() #endif /* HAVE_PKG_CURSES */ #include "log.h" #include "parse.h" #include "charset.h" #ifdef USE_CURSES #define BRLPARM_TERM "term", #else /* USE_CURSES */ #define BRLPARM_TERM #endif /* USE_CURSES */ #ifdef HAVE_ICONV_H #define BRLPARM_CHARSET "charset", #else /* HAVE_ICONV_H */ #define BRLPARM_CHARSET #endif /* HAVE_ICONV_H */ typedef enum { PARM_BAUD, #ifdef USE_CURSES PARM_TERM, #endif /* USE_CURSES */ PARM_LINES, PARM_COLUMNS, #ifdef HAVE_ICONV_H PARM_CHARSET, #endif /* HAVE_ICONV_H */ PARM_LOCALE } DriverParameter; #define BRLPARMS "baud", BRLPARM_TERM "lines", "columns", BRLPARM_CHARSET "locale" #define BRL_HAVE_KEY_CODES #include "brl_driver.h" #include "braille.h" #include "io_serial.h" #define MAX_WINDOW_LINES 3 #define MAX_WINDOW_COLUMNS 80 #define MAX_WINDOW_SIZE (MAX_WINDOW_LINES * MAX_WINDOW_COLUMNS) static SerialDevice *ttyDevice = NULL; static FILE *ttyStream = NULL; static char *classificationLocale = NULL; #ifdef USE_CURSES static SCREEN *ttyScreen = NULL; #else /* USE_CURSES */ static inline int my_getch (void) { unsigned char c; if (serialReadData(ttyDevice, &c, 1, 0, 0) == 1) return c; return EOF; }
static int readSerialBytes (unsigned char *buffer, int count, int wait) { const int timeout = 100; return serialReadData(serialDevice, buffer, count, (wait? timeout: 0), timeout); }
static int brl_readCommand(BrailleDisplay *brl, KeyTableCommandContext context) { int res = EOF; long bytes = 0; unsigned char *pBuff; unsigned char buff[18 + 1]; #ifdef DEBUG char tmp[80]; #endif /* DEBUG */ /* Read info from Braille Line */ if((bytes = serialReadData(serialDevice, buff, 18, 0, 0)) >= 9){ #ifdef DEBUG sprintf(tmp, "Type %d, Bytes read: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x\n", type, buff[0], buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7], buff[8], buff[9]); write(brl_log, tmp, strlen(tmp)); #endif /* DEBUG */ /* Is a Key? */ if((pBuff=(unsigned char *)strstr((char *)buff, BRL_KEY))){ /* Byte A. Check Status sensors */ switch(*(pBuff+3)){ case KEY_ST_SENSOR1: res = BRL_CMD_HELP; break; case KEY_ST_SENSOR2: res = BRL_CMD_PREFMENU; break; case KEY_ST_SENSOR3: res = BRL_CMD_DISPMD; break; case KEY_ST_SENSOR4: res = BRL_CMD_INFO; break; } /* Check Main Sensors */ if(*(pBuff+3) >= KEY_MAIN_MIN && *(pBuff+3) <= KEY_MAIN_MAX){ /* Nothing */ } /* Byte B. Check Front Keys */ switch(*(pBuff+4)){ case KEY_DOWN: /* Down */ res = BRL_CMD_LNDN; break; case KEY_RIGHT: /* Right */ res = BRL_CMD_FWINRT; break; case KEY_CLICK: /* Eco20 Go to cursor */ /* Only for ECO20, haven't function keys */ if(model->Cols==20){ res = BRL_CMD_HOME; } break; case KEY_LEFT: /* Left */ res = BRL_CMD_FWINLT; break; case KEY_UP: /* Up */ res = BRL_CMD_LNUP; break; case KEY_UP|KEY_CLICK: /* Top of screen */ return(BRL_CMD_TOP); break; case KEY_DOWN|KEY_CLICK: /* Bottom of screen */ return(BRL_CMD_BOT); break; case KEY_LEFT|KEY_CLICK: /* Left one half window */ return(BRL_CMD_HWINLT); break; case KEY_RIGHT|KEY_CLICK: /* Right one half window */ return(BRL_CMD_HWINRT); break; } /* Byte C. Some Function Keys */ switch(*(pBuff+5)){ case KEY_F9: /* Nothing */ break; case KEY_ALT: /* Nothing */ break; case KEY_F0: /* Nothing */ break; case KEY_SHIFT: /* Cursor traking */ if(*(pBuff+6)==KEY_F8){ return(BRL_CMD_CSRTRK); } break; } /* Byte D. Rest of Function Keys */ switch(*(pBuff+6)){ case KEY_F1: /* Nothing */ break; case KEY_F2: /* go to cursor */ res = BRL_CMD_HOME; break; case KEY_F3: /* Nothing */ break; case KEY_F4: /* Nothing */ break; case KEY_F5: /* togle cursor visibility */ res = BRL_CMD_CSRVIS; break; case KEY_F6: /* Nothing */ break; case KEY_F7: /* Nothing */ break; case KEY_F8: /* Six dot mode */ res = BRL_CMD_SIXDOTS; break; } } } return(res); }
static int brl_construct(BrailleDisplay *brl, char **parameters, const char *device) { short ModelID = MODEL; unsigned char buffer[DIM_BRL_ID + 6]; if (!isSerialDevice(&device)) { unsupportedDevice(device); return 0; } rawdata = NULL; /* clear pointers */ /* Open the Braille display device */ if (!(serialDevice = serialOpenDevice(device))) goto failure; #ifdef DEBUG brl_log = open("/tmp/brllog", O_CREAT | O_WRONLY); if(brl_log < 0){ goto failure; } #endif /* DEBUG */ /* autodetecting ECO model */ do{ /* DTR back on */ serialRestartDevice(serialDevice, BAUDRATE); /* activate new settings */ /* The 2 next lines can be commented out to try autodetect once anyway */ if(ModelID != ECO_AUTO){ break; } if(serialReadData(serialDevice, &buffer, DIM_BRL_ID + 6, 600, 100) == DIM_BRL_ID + 6){ if(memcmp (buffer, BRL_ID, DIM_BRL_ID) == 0){ /* Possible values; 0x20, 0x40, 0x80 */ int tmpModel=buffer[DIM_BRL_ID] / 0x20; switch(tmpModel){ case 1: ModelID=0; break; case 2: ModelID=1; break; case 4: ModelID=2; break; default: ModelID=1; } } } }while(ModelID == ECO_AUTO); if(ModelID >= NB_MODEL || ModelID < 0){ goto failure; /* unknown model */ } /* Need answer to BR */ /*do{*/ serialWriteData(serialDevice, SYS_READY, DIM_SYS_READY); serialReadData(serialDevice, &buffer, DIM_BRL_READY + 6, 100, 100); /*}while(strncmp (buffer, BRL_READY, DIM_BRL_READY));*/ logMessage(LOG_DEBUG, "buffer is: %s",buffer); /* Set model params */ model = &Models[ModelID]; brl->textColumns = model->Cols; /* initialise size of main display */ brl->textRows = BRLROWS; /* ever is 1 in this type of braille lines */ MAKE_OUTPUT_TABLE(0X10, 0X20, 0X40, 0X01, 0X02, 0X04, 0X80, 0X08); /* Need to calculate the size; Cols + Status + 1 (space between) */ BrailleSize = brl->textColumns + model->NbStCells + 1; /* Allocate space for buffers */ rawdata = malloc(BrailleSize); /* Phisical size */ if(!rawdata){ goto failure; } /* Empty buffers */ memset(rawdata, 0, BrailleSize); memset(Status, 0, MAX_STCELLS); return 1; failure:; if(rawdata){ free(rawdata); } return 0; }
static int brl_construct (BrailleDisplay *brl, char **parameters, const char *device) { short n, success; /* loop counters, flags, etc. */ unsigned char *init_seq = (unsigned char *)"\002\0330"; /* string to send to Braille to initialise: [ESC][0] */ unsigned char *init_ack = (unsigned char *)"\002\033V"; /* string to expect as acknowledgement: [ESC][V]... */ unsigned char c; TimePeriod period; if (!isSerialDevice(&device)) { unsupportedDevice(device); return 0; } brlcols = -1; /* length of braille display (auto-detected) */ prevdata = rawdata = NULL; /* clear pointers */ /* No need to load translation tables, as these are now * defined in tables.h */ /* Now open the Braille display device for random access */ if (!(MB_serialDevice = serialOpenDevice(device))) goto failure; if (!serialRestartDevice(MB_serialDevice, BAUDRATE)) goto failure; if (!serialSetFlowControl(MB_serialDevice, SERIAL_FLOW_HARDWARE)) goto failure; /* MultiBraille initialisation procedure: * [ESC][V][Braillelength][Software Version][CR] * I guess, they mean firmware version with software version :*} * firmware version == [Software Version] / 10.0 */ success = 0; if (init_seq[0]) if (serialWriteData (MB_serialDevice, init_seq + 1, init_seq[0]) != init_seq[0]) goto failure; startTimePeriod (&period, ACK_TIMEOUT); /* initialise timeout testing */ n = 0; do { approximateDelay (20); if (serialReadData (MB_serialDevice, &c, 1, 0, 0) == 0) continue; if (n < init_ack[0] && c != init_ack[1 + n]) continue; if (n == init_ack[0]) { brlcols = c, success = 1; /* reading version-info */ /* firmware version == [Software Version] / 10.0 */ serialReadData (MB_serialDevice, &c, 1, 0, 0); logMessage (LOG_INFO, "MultiBraille: Version: %2.1f", c/10.0); /* read trailing [CR] */ serialReadData (MB_serialDevice, &c, 1, 0, 0); } n++; } while (!afterTimePeriod (&period, NULL) && n <= init_ack[0]); if (success && (brlcols != 25)) { if ((prevdata = malloc(brl->textColumns * brl->textRows))) { if ((rawdata = malloc(20 + (brl->textColumns * brl->textRows * 2)))) { brl->textColumns = brlcols; brl->textRows = BRLROWS; brl->statusColumns = 5; brl->statusRows = 1; { static const DotsTable dots = { 0X01, 0X02, 0X04, 0X80, 0X40, 0X20, 0X08, 0X10 }; makeOutputTable(dots); } return 1; } else { logMallocError(); } free(prevdata); } else { logMallocError(); } } failure: if (MB_serialDevice) { serialCloseDevice(MB_serialDevice); MB_serialDevice = NULL; } return 0; }
static int brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) { unsigned char byte; const InputMode *mode; const InputBinding *binding; { int result = serialReadData(serialDevice, &byte, 1, 0, 0); if (result == 0) { if (inputMode->temporary) if (afterTimePeriod(&inputPeriod, NULL)) resetInputMode(); return EOF; } if (result == -1) { logSystemError("read"); return BRL_CMD_RESTARTBRL; } } mode = inputMode; if (mode->temporary) resetInputMode(); switch (byte) { case KEY_F1: binding = &mode->keyF1; break; case KEY_F2: binding = &mode->keyF2; break; case KEY_LEFT: binding = &mode->keyLeft; break; case KEY_RIGHT: binding = &mode->keyRight; break; case KEY_UP: binding = &mode->keyUp; break; case KEY_DOWN: binding = &mode->keyDown; break; case KEY_CENTER: binding = &mode->keyCenter; break; default: logMessage(LOG_WARNING, "unhandled key: %s -> %02X", mode->name, byte); beep(brl); return EOF; } switch (binding->type) { case IBT_unbound: logMessage(LOG_WARNING, "unbound key: %s -> %02X", mode->name, byte); beep(brl); break; case IBT_command: return binding->value.command; case IBT_block: return binding->value.block + cursorOffset; case IBT_function: return binding->value.function(brl); case IBT_submode: { setInputMode(binding->value.submode); break; } default: logMessage(LOG_WARNING, "unhandled input binding type: %02X", binding->type); break; } return BRL_CMD_NOOP; }