Beispiel #1
0
static int
brl_construct (BrailleDisplay *brl, char **parameters, const char *device) {
  if (!isSerialDevice(&device)) {
     unsupportedDevice(device);
     return 0;
  }

  if ((serialDevice = serialOpenDevice(device))) {
    if (serialRestartDevice(serialDevice, serialBaud)) {
      static const unsigned char request[] = {BNO_DESCRIBE};
      charactersPerSecond = serialBaud / 10;
      if (writePacket(brl, request, sizeof(request)) != -1) {
        while (serialAwaitInput(serialDevice, 100)) {
          ResponsePacket response;
          int size = getPacket(&response);
          if (size) {
            if (response.data.code == BNI_DESCRIBE) {
              statusCells = response.data.values.description.statusCells;
              brl->textColumns = response.data.values.description.textCells;
              brl->textRows = 1;
              brl->keyBindings = "keys";

              if ((statusCells == 5) && (brl->textColumns == 30)) {
                statusCells -= 2;
                brl->textColumns += 2;
              }
              dataCells = brl->textColumns * brl->textRows;
              cellCount = statusCells + dataCells;

              makeOutputTable(dotsTable_ISO11548_1);
              makeInputTable();

              if ((cellBuffer = malloc(cellCount))) {
                memset(cellBuffer, 0, cellCount);
                statusArea = cellBuffer;
                dataArea = statusArea + statusCells;
                refreshCells(brl);
                persistentKeyboardMode = KBM_NAVIGATE;
                temporaryKeyboardMode = persistentKeyboardMode;
                persistentRoutingOperation = BRL_BLK_ROUTE;
                temporaryRoutingOperation = persistentRoutingOperation;
                return 1;
              } else {
                logSystemError("cell buffer allocation");
              }
            } else {
              logUnexpectedPacket(response.bytes, size);
            }
          }
        }
      }
    }
    serialCloseDevice(serialDevice);
    serialDevice = NULL;
  }
  return 0;
}
Beispiel #2
0
static int
brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) {
  ResponsePacket packet;
  int size;

  while ((size = getPacket(&packet))) {
    switch (packet.data.code) {
      case BN_RSP_ROUTE:
        enqueueKey(BN_SET_RoutingKeys, packet.data.values.routingKey);
        break;

      case BN_RSP_DISPLAY:
        doVisualDisplay();
        break;

      default: {
        unsigned char set = BN_SET_NavigationKeys;
        unsigned char keys = packet.data.values.dotKeys & 0X3F;
        unsigned char base = BN_KEY_Dot1;
        unsigned char modifier = 0;

        switch (packet.data.code) {
          case BN_RSP_CHARACTER:
            if (keys) break;

          case BN_RSP_SPACE:
            modifier = BN_KEY_Space;
            break;

          case BN_RSP_BACKSPACE:
            modifier = BN_KEY_Backspace;
            break;

          case BN_RSP_ENTER:
            modifier = BN_KEY_Enter;
            break;

          case BN_RSP_THUMB:
            keys = packet.data.values.thumbKeys & 0X0F;
            base = BN_KEY_Previous;
            break;

          default:
            logUnexpectedPacket(packet.bytes, size);
            continue;
        }

        if (modifier) enqueueKeyEvent(set, modifier, 1);
        enqueueKeys(keys, set, base);
        if (modifier) enqueueKeyEvent(set, modifier, 0);
        break;
      }
    }
  }

  return (errno == EAGAIN)? EOF: BRL_CMD_RESTARTBRL;
}
Beispiel #3
0
int
probeBrailleDisplay (
  BrailleDisplay *brl, unsigned int retryLimit,
  GioEndpoint *endpoint, int inputTimeout,
  BrailleRequestWriter *writeRequest,
  BraillePacketReader *readPacket, void *responsePacket, size_t responseSize,
  BrailleResponseHandler *handleResponse
) {
  unsigned int retryCount = 0;

  if (!endpoint) endpoint = brl->gioEndpoint;

  while (writeRequest(brl)) {
    drainBrailleOutput(brl, 0);

    while (gioAwaitInput(endpoint, inputTimeout)) {
      size_t size = readPacket(brl, responsePacket, responseSize);
      if (!size) break;

      {
        BrailleResponseResult result = handleResponse(brl, responsePacket, size);

        switch (result) {
          case BRL_RSP_DONE:
            return 1;

          case BRL_RSP_UNEXPECTED:
            logUnexpectedPacket(responsePacket, size);
          case BRL_RSP_CONTINUE:
            break;

          default:
            logMessage(LOG_WARNING, "unimplemented braille response result: %u", result);
          case BRL_RSP_FAIL:
            return 0;
        }
      }
    }

    if (errno != EAGAIN)
#ifdef ETIMEDOUT
      if (errno != ETIMEDOUT)
#endif /* ETIMEDOUT */
        break;

    if (retryCount == retryLimit) break;
    retryCount += 1;
  }

  return 0;
}
Beispiel #4
0
static int
nextSerialPacket (BrailleDisplay *brl, unsigned char code, unsigned char *buffer, int size, int wait) {
  int length;

  if (wait)
    if (!awaitBrailleInput(brl, SERIAL_WAIT_TIMEOUT))
      return 0;

  while ((length = readSerialPacket(brl, buffer, size))) {
    if (buffer[0] == code) return length;
    logUnexpectedPacket(buffer, length);
  }

  return 0;
}
Beispiel #5
0
static int
nextSerialPacket (unsigned char code, unsigned char *buffer, int size, int wait) {
  int length;

  if (wait)
    if (!gioAwaitInput(gioEndpoint, SERIAL_WAIT_TIMEOUT))
      return 0;

  while ((length = readSerialPacket(buffer, size))) {
    if (buffer[0] == code) return length;
    logUnexpectedPacket(buffer, length);
  }

  return 0;
}
Beispiel #6
0
/* for BRL_ROUTING, the code is the ofset to route, starting from 0 */
static int brl_readKey(BrailleDisplay *brl)
{
  unsigned char ch, packet[MAXPACKETSIZE];
  static int routing = 0;
  ssize_t packetSize;
  packetSize = brl_readPacket(brl,packet,sizeof(packet));
  if (packetSize==0) return EOF;
  if ((packet[0]!=0x3c) && (packet[0]!=0x3d) && (packet[0]!=0x23)) {
    logUnexpectedPacket(packet, packetSize);
    return EOF;
  }
  ch = packet[1];
  if (routing) {
    routing=0;
    if (ch>=0xc0)  return (packet[1]-0xc0) | BRL_VSMSK_ROUTING;
    return EOF;
  }
  if ((ch>=0xc0) && (ch<=0xdf)) return (ch-0xc0) | BRL_VSMSK_FUNCTIONKEY;
  if (ch==0x91) {
    routing = 1;
    return BRL_CMD_NOOP;
  } 
  if ((ch>=0x20) && (ch<=0x9e)) {
    switch (ch) {
      case 0x80: ch = 0xc7; break;
      case 0x81: ch = 0xfc; break;
      case 0x82: ch = 0xe9; break;
      case 0x83: ch = 0xe2; break;
      case 0x84: ch = 0xe4; break;
      case 0x85: ch = 0xe0; break;
      case 0x87: ch = 0xe7; break;
      case 0x88: ch = 0xea; break;
      case 0x89: ch = 0xeb; break;
      case 0x8a: ch = 0xe8; break; 
      case 0x8b: ch = 0xef; break;
      case 0x8c: ch = 0xee; break;
      case 0x8f: ch = 0xc0; break;
      case 0x93: ch = 0xf4; break;
      case 0x94: ch = 0xf6; break;
      case 0x96: ch = 0xfb; break; 
      case 0x97: ch = 0xf9; break;
      case 0x9e: ch = 0x60; break;
    }
    return ch | BRL_VSMSK_CHAR;
  }
  return ch | BRL_VSMSK_OTHER;
}
Beispiel #7
0
static int
startDisplayMode (BrailleDisplay *brl) {
  static const unsigned char data[] = {MM_BLINK_NO, 0};

  if (writePacket(brl, MM_CMD_StartDisplayMode, 0, data, sizeof(data))) {
    if (gioAwaitInput(brl->gioEndpoint, START_INPUT_TIMEOUT)) {
      MM_CommandPacket response;
      size_t size = readPacket(brl, &response);

      if (size) {
        if (response.fields.header.id1 == MM_HEADER_ACK) return 1;
        logUnexpectedPacket(response.bytes, size);
      }
    }
  }

  return 0;
}
Beispiel #8
0
static int
identifyDisplay (BrailleDisplay *brl) {
  static const unsigned char identify[] = {'I', CR};

  if (writeBytes(brl, identify, sizeof(identify))) {
    if (serialAwaitInput(serialDevice, 1000)) {
      unsigned char identity[0X100];
      size_t length;

      if (readBytes(identity, sizeof(identity), &length)) {
        static const unsigned char prefix[] = {'b', 'r', 'a', 'u', 'd', 'i', ' '};
        if ((length >= sizeof(prefix)) &&
            (memcmp(identity, prefix, sizeof(prefix)) == 0)) {
          const unsigned char *bytes = memchr(identity, ',', length);
          if (bytes) {
            int count = length - (bytes - identity);
            int cells;

            ++bytes, --count;
            skipCharacter(' ', &bytes, &count);
            if (interpretNumber(&cells, &bytes, &count)) {
              if (!count) {
                logMessage(LOG_INFO, "Detected: %.*s", (int)length, identity);

                brl->textColumns = cells;
                brl->textRows = 1;

                return 1;
              }
            }
          }
        }

        logUnexpectedPacket(identity, length);
      }
    }
  }
  return 0;
}
Beispiel #9
0
static int
brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) {
  unsigned char packet[MAXIMUM_RESPONSE_SIZE];
  size_t size;

  while ((size = readPacket(brl, packet, sizeof(packet)))) {
    switch (packet[0]) {
      case 0XFD:
        switch (packet[1]) {
          case 0X2F:
            continue;

          default:
            break;
        }
        break;

      case 0XFC: {
        unsigned int key = packet[1];
        if ((key >= NP_KEY_ROUTING_MIN) && (key <= NP_KEY_ROUTING_MAX)) {
          enqueueKey(brl, NP_GRP_RoutingKeys, (key - NP_KEY_ROUTING_MIN));
          continue;
        } else {
          int press = !!(key & NP_KEY_NAVIGATION_PRESS);
          if (press) key &= ~NP_KEY_NAVIGATION_PRESS;
          enqueueKeyEvent(brl, NP_GRP_NavigationKeys, key, press);
          continue;
        }
        break;
      }
    }

    logUnexpectedPacket(packet, size);
  }

  return (errno == EAGAIN)? EOF: BRL_CMD_RESTARTBRL;
}
Beispiel #10
0
static int
brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) {
  InputPacket packet;
  int length;

  if (context == KTB_CTX_WAITING) return BRL_CMD_NOOP;
  if (writeFunction) return EOF;
  while (*initialCommand != EOF) enqueueCommand(*initialCommand++);

  while ((length = readPacket(brl, &packet))) {
    if ((packet.data.type >= IPT_MINIMUM_LINE) &&
        (packet.data.type <= IPT_MAXIMUM_LINE)) {
      enqueueCommand(BRL_CMD_BLK(GOTOLINE) | BRL_FLG_MOTION_TOLEFT | (packet.data.type - IPT_MINIMUM_LINE));
      writeFunction = writeLine;
      return EOF;
    }

    switch (packet.data.type) {
      case IPT_SEARCH_ATTRIBUTE:
      case IPT_CURRENT_LINE:
        enqueueCommand(BRL_CMD_HOME);
        enqueueCommand(BRL_CMD_LNBEG);
        writeFunction = writeLine;
        return EOF;

      case IPT_CURRENT_LOCATION:
        writeFunction = writeLocation;
        return EOF;

      default:
        logUnexpectedPacket(&packet, length);
        break;
    }
  }

  return (errno == EAGAIN)? EOF: BRL_CMD_RESTARTBRL;
}
Beispiel #11
0
static int
brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) {
  while (1) {
    unsigned char packet[3];
    int size = readPacket(brl, packet, sizeof(packet));
    if (size == 0) break;
    if (size < 0) return BRL_CMD_RESTARTBRL;

    switch (packet[1]) {
      default:
        break;

      case 1:
        return BRL_BLK_PASSDOTS | translateInputCell(packet[2]);

      case 2: {
        unsigned char column = packet[2];
        if (column && (column <= brl->textColumns)) return BRL_BLK_ROUTE + (column - 1);
        break;
      }

      case 3:
        switch (packet[2]) {
          default:
            break;

          // left rear: two columns, one row
          case 0X02: // ESC
            return BRL_CMD_LEARN;
          case 0X01: // M
            return BRL_CMD_PREFMENU;

          // left middle: cross
          case 0X06: // up
            return BRL_CMD_LNUP;
          case 0X03: // left
            return BRL_CMD_FWINLT;
          case 0X05: // right
            return BRL_CMD_FWINRT;
          case 0X04: // down
            return BRL_CMD_LNDN;

          // left front: two columns, three rows
          case 0X09: // ins
            return BRL_CMD_RETURN;
          case 0X0A: // E
            return BRL_CMD_TOP;
          case 0X0B: // supp
            return BRL_CMD_CSRTRK;
          case 0X0C: // L
            return BRL_CMD_BOT;
          case 0X07: // extra 1 (40s only)
            return BRL_CMD_CHRLT;
          case 0X08: // extra 2 (40s only)
            return BRL_CMD_CHRRT;

          case 0x0E: // left thumb
            return BRL_BLK_PASSKEY + BRL_KEY_BACKSPACE;
          case 0x0F: // right thumb
            return BRL_BLK_PASSDOTS;
          case 0x3F: // both thumbs
            return BRL_BLK_PASSKEY + BRL_KEY_ENTER;

          case 0X29: // key under dot 7
            return BRL_BLK_PASSKEY + BRL_KEY_ESCAPE;
          case 0X2A: // key under dot 8
            return BRL_BLK_PASSKEY + BRL_KEY_TAB;

          // right rear: one column, one row
          case 0X19: // extra 3 (40s only)
            return BRL_CMD_INFO;

          // right middle: one column, two rows
          case 0X1B: // extra 4 (40s only)
            return BRL_CMD_PRDIFLN;
          case 0X1A: // extra 5 (40s only)
            return BRL_CMD_NXDIFLN;

          // right front: one column, four rows
          case 0X2B: // slash (40s only)
            return BRL_CMD_FREEZE;
          case 0X2C: // asterisk (40s only)
            return BRL_CMD_DISPMD;
          case 0X2D: // minus (40s only)
            return BRL_CMD_ATTRVIS;
          case 0X2E: // plus (40s only)
            return BRL_CMD_CSRVIS;

          // first (top) row of numeric pad
          case 0X37: // seven (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_HOME;
          case 0X38: // eight (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_CURSOR_UP;
          case 0X39: // nine (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_PAGE_UP;

          // second row of numeric pad
          case 0X34: // four (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_CURSOR_LEFT;
          case 0X35: // five (40s only)
            return BRL_CMD_CSRJMP_VERT;
          case 0X36: // six (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_CURSOR_RIGHT;

          // third row of numeric pad
          case 0X31: // one (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_END;
          case 0X32: // two (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_CURSOR_DOWN;
          case 0X33: // three (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_PAGE_DOWN;

          // fourth (bottom) row of numeric pad
          case 0X28: // verr num (40s only)
            return BRL_CMD_SIXDOTS;
          case 0X30: // zero (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_INSERT;
          case 0X2F: // supp (40s only)
            return BRL_BLK_PASSKEY + BRL_KEY_DELETE;
        }
        break;

      /* When data is written to the display it acknowledges with:
       * 0X00 0X04 0Xxx
       * where xx is the number of bytes written.
       */
      case 4:
        continue;
    }

    logUnexpectedPacket(packet, size);
  }

  return EOF;
}
Beispiel #12
0
static int
brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) {
  ResponsePacket packet;
  int size;

  while ((size = getPacket(&packet))) {
    int (*handler)(BrailleDisplay *, unsigned char, KeyTableCommandContext);
    unsigned char data;

    switch (packet.data.code) {
      case BNI_CHARACTER:
        handler = interpretCharacter;
        data = packet.data.values.dotKeys;
        break;

      case BNI_SPACE:
        handler = interpretSpaceChord;
        data = packet.data.values.dotKeys;
        break;

      case BNI_BACKSPACE:
        handler = interpretBackspaceChord;
        data = packet.data.values.dotKeys;
        break;

      case BNI_ENTER:
        handler = interpretEnterChord;
        data = packet.data.values.dotKeys;
        break;

      case BNI_THUMB:
        handler = interpretThumbKeys;
        data = packet.data.values.thumbKeys;
        break;

      case BNI_ROUTE:
        handler = interpretRoutingKey;
        data = packet.data.values.routingKey;
        break;

      case BNI_DISPLAY:
        handler = visualDisplay;
        data = 0;
        break;

      default:
        logUnexpectedPacket(packet.bytes, size);
        continue;
    }

    currentKeyboardMode = temporaryKeyboardMode;
    temporaryKeyboardMode = persistentKeyboardMode;

    currentRoutingOperation = temporaryRoutingOperation;
    temporaryRoutingOperation = persistentRoutingOperation;

    return handler(brl, data, context);
  }

  return (errno == EAGAIN)? EOF: BRL_CMD_RESTARTBRL;
}
Beispiel #13
0
static int
brl_readCommand (BrailleDisplay *brl, KeyTableCommandContext context) {
  unsigned char buffer[0X100];
  size_t length;

  while (readBytes(buffer, sizeof(buffer), &length)) {
    const unsigned char *bytes = buffer;
    int count = length;

    if (count > 0) {
      unsigned char category = *bytes++;
      --count;

      switch (category) {
        case 'F': {
          int keys;
          writeAcknowledgement(brl);

          if (interpretNumber(&keys, &bytes, &count)) {
            if (!count) {
              switch (keys) {
                case  1: return BRL_CMD_TOP_LEFT;
                case  2: return BRL_CMD_FWINLT;
                case  3: return BRL_CMD_LNDN;
                case  4: return BRL_CMD_LNUP;
                case  5: return BRL_CMD_FWINRT;
                case  6: return BRL_CMD_BOT_LEFT;
                case 23: return BRL_CMD_LNBEG;
                case 56: return BRL_CMD_LNEND;
                case 14: return BRL_CMD_CSRVIS;
                case 25: return BRL_CMD_DISPMD;
                case 26: return BRL_CMD_INFO;
                case 36: return BRL_CMD_HOME;
              }
            }
          }

          break;
        }

        case 'K': {
          int key;
          writeAcknowledgement(brl);

          if (interpretNumber(&key, &bytes, &count)) {
            if (!count) {
              if ((key > 0) && (key <= brl->textColumns)) return BRL_BLK_ROUTE + (key - 1);
            }
          }

          break;
        }
      }
    }

    logUnexpectedPacket(buffer, length);
  }

  if (errno == EAGAIN) return EOF;
  return BRL_CMD_RESTARTBRL;
}