Next Previous Contents

5. Library description

Let's now see how one can write dedicated applications. Basic notions will be seen, along with a very simple client. Greater details are given as online manual pages.

The historical test program for BrlAPI was something like:

It is here rewritten, its working briefly explained.

5.1 Connecting to BrlAPI

Connection to BrlAPI is needed first, thanks to the brlapi_openConnection call. For this, a brlapi_connectionSettings_t variable must be filled which will hold the settings the library needs to connect to the server. Just giving NULL will work for local use. The other parameter lets you get back the parameters which were actually used to initialize connection. NULL will also be nice for now.


  if (brlapi_openConnection(NULL, NULL)<0) {
    brlapi_perror("brlapi_openConnection");
    exit(1);
  }

The connection might fail, so testing is needed.

5.2 Getting driver name

Knowing the type of the braille device might be useful:


  char name[BRLAPI_MAXNAMELENGTH+1];
  if (brlapi_getDriverName(name, sizeof(name)) < 0)
    brlapi_perror("brlapi_getDriverName");
  else
    fprintf(stderr, "Driver name: %s\n", name);

This is particularly useful before entering raw mode to achieve file transfers for instance, just to check that the device is really the one expected.

5.3 Getting display size

Before writing on the braille display, the size should be always first checked to be sure everything will hold on it:


  if (brlapi_getDisplaySize(&x, &y) < 0)
    brlapi_perror("brlapi_getDisplaySize");
  else
    fprintf(stderr, "Braille display has %d line%s of %d column%s\n",
      y, y>1?"s":"", x, x>1?"s":"");

5.4 Entering raw mode, immediately leaving raw mode.

Entering raw mode is very simple:


  fprintf(stderr, "Trying to enter in raw mode... ");
  if (brlapi_enterRawMode(name) < 0)
    brlapi_perror("brlapi_enterRawMode");
  else {
    fprintf(stderr, "Ok, leaving raw mode immediately\n");
    brlapi_leaveRawMode();
  }

Not every driver supports raw mode, so testing is needed.

While in raw mode, brlapi_sendRaw and brlapi_recvRaw can be used to send and get data directly to and from the device. It should be used with care, improper use might completely thrash the device!

5.5 Getting tty control

Let's now display something on the device. control of the tty must be get first:


  fprintf(stderr, "Taking control of the tty... ");
  if (brlapi_enterTtyMode(BRLAPI_TTY_DEFAULT, NULL) >= 0)
  {
    fprintf(stderr, "Ok\n");

The first parameter tells the server the number of the tty to take control of. Setting BRLAPI_TTY_DEFAULT lets the library determine it for us.

The server is asked to send brltty commands, which are device-independent.

Getting control might fail if, for instance, another application already took control of this tty, so testing is needed.

From now on, the braille display is detached from the screen.

5.6 Writing something on the display

The application can now write things on the braille display without altering the screen display:


    fprintf(stderr, "Writing to braille display... ");
    if (brlapi_writeText(0, "Press a braille key to continue...") >= 0)
    {
      fprintf(stderr, "Ok\n");

The cursor is also asked not to be shown: its position is set to 0.

"Writing to braille display... Ok" is now displayed on the screen, and "Press a braille key to continue..." on the braille display.

5.7 Waiting for a key press

To have a break for the user to be able to read these messages, a key press (a command here, which is driver-independent) may be waited for:


      fprintf(stderr, "Waiting until a braille key is pressed to continue... ");
      if (brlapi_readKey(1, &key) > 0)
        fprintf(stderr, "got it! (code=%"BRLAPI_PRIxKEYCODE")\n", key);

The command is returned, as described in <brlapi_constants.h> and <brlapi_keycodes.h>. It is not transmitted to brltty: it is up to the application to define the behavior, here cleanly exitting, as described below.

The first parameter tells the lib to block until a key press is indeed read.

5.8 Understanding commands

There are two kinds of commands: braille commands (line up/down, top/bottom, etc.) and X Keysyms (i.e. regular keyboard keys). One way to discover which key was pressed is to just use a switch statement:


        switch(key) {
          case BRLAPI_KEY_TYPE_CMD|BRLAPI_KEY_CMD_LNUP:
            fprintf(stderr, "line up\n");
            break;
          case BRLAPI_KEY_TYPE_CMD|BRLAPI_KEY_CMD_LNDN:
            fprintf(stderr, "line down\n");
            break;
          case BRLAPI_KEY_TYPE_SYM|XK_Tab:
            fprintf(stderr, "tab\n");
            break;
          default:
            fprintf(stderr, "unknown key\n");
            break;
        }

Another way is to ask BrlAPI to expand the keycode into separate information parts:


        brlapi_expandedKeyCode_t ekey;
        brlapi_expandKeyCode(key, &ekey);
        fprintf(stderr, "type %u, command %u, argument %u, flags %u\n",
          ekey.type, ekey.command, ekey.argument, ekey.flags);

Eventually, named equivalents are provided:


        brlapi_describedKeyCode_t dkey;
        int i;

        brlapi_describeKeyCode(key, &dkey);
        fprintf(stderr, "type %s, command %s, argument %u, flags",
          dkey.type, dkey.command, dkey.argument);
        for (i = 0; i < dkey.flags; i++)
          fprintf(stderr, " %s", dkey.flag[i]);
        fprintf(stderr, "\n");

5.9 Leaving tty control

Let's now leave the tty:


    fprintf(stderr, "Leaving tty... ");
    if (brlapi_leaveTtyMode() >= 0)
      fprintf(stderr, "Ok\n");

But control of another tty can still be get for instance, by calling brlapi_enterTtyMode() again...

5.10 Disconnecting from BrlAPI

Let's disconnect from BrlAPI:


  brlapi_closeConnection();

The application can as well still need to connect to another server on another computer for instance, by calling brlapi_openConnection() again...

5.11 Putting everything together...


#include <stdio.h>
#include <stdlib.h>
#include <brlapi.h>

int main()
{
  brlapi_keyCode_t key;
  char name[BRLAPI_MAXNAMELENGTH+1];
  unsigned int x, y;

/* Connect to BrlAPI */
  if (brlapi_openConnection(NULL, NULL)<0)
  {
    brlapi_perror("brlapi_openConnection");
    exit(1);
  }

/* Get driver name */
  if (brlapi_getDriverName(name, sizeof(name)) < 0)
    brlapi_perror("brlapi_getDriverName");
  else
    fprintf(stderr, "Driver name: %s\n", name);

/* Get display size */
  if (brlapi_getDisplaySize(&x, &y) < 0)
    brlapi_perror("brlapi_getDisplaySize");
  else
    fprintf(stderr, "Braille display has %d line%s of %d column%s\n",
      y, y>1?"s":"", x, x>1?"s":"");

/* Try entering raw mode, immediately go out from raw mode */
  fprintf(stderr, "Trying to enter in raw mode... ");
  if (brlapi_enterRawMode(name) < 0)
    brlapi_perror("brlapi_enterRawMode");
  else {
    fprintf(stderr, "Ok, leaving raw mode immediately\n");
    brlapi_leaveRawMode();
  }

/* Get tty control */
  fprintf(stderr, "Taking control of the tty... ");
  if (brlapi_enterTtyMode(BRLAPI_TTY_DEFAULT, NULL) >= 0)
  {
    fprintf(stderr, "Ok\n");

/* Write something on the display */
    fprintf(stderr, "Writing to braille display... ");
    if (brlapi_writeText(0, "Press a braille key to continue...") >= 0)
    {
      fprintf(stderr, "Ok\n");

/* Wait for a key press */
      fprintf(stderr, "Waiting until a braille key is pressed to continue... ");
      if (brlapi_readKey(1, &key) > 0) {
        brlapi_expandedKeyCode_t ekey;
        brlapi_describedKeyCode_t dkey;
        int i;

        fprintf(stderr, "got it! (code=%"BRLAPI_PRIxKEYCODE")\n", key);

        brlapi_expandKeyCode(key, &ekey);
        fprintf(stderr, "type %u, command %u, argument %u, flags %u\n",
          ekey.type, ekey.command, ekey.argument, ekey.flags);

        brlapi_describeKeyCode(key, &dkey);
        fprintf(stderr, "type %s, command %s, argument %u, flags",
          dkey.type, dkey.command, dkey.argument);
        for (i = 0; i < dkey.flags; i++)
          fprintf(stderr, " %s", dkey.flag[i]);
        fprintf(stderr, "\n");
      } else brlapi_perror("brlapi_readKey");

    } else brlapi_perror("brlapi_writeText");

/* Leave tty control */
    fprintf(stderr, "Leaving tty... ");
    if (brlapi_leaveTtyMode() >= 0)
      fprintf(stderr, "Ok\n");
    else brlapi_perror("brlapi_leaveTtyMode");

  } else brlapi_perror("brlapi_enterTtyMode");

/* Disconnect from BrlAPI */
  brlapi_closeConnection();
  return 0;
}

This should compile well thanks to gcc apiclient.c -o apiclient -lbrlapi


Next Previous Contents