Sébastien Sablé <sable@users.sourceforge.net>
This document explains how to develop using libbraille in the C/C++ languages. It is mostly intended for developers and not for simple users.
In this tutorial we will write a simple test program step by step that uses most functionalities of the Braille library. The complete test program is shown in annex and can be found in the test directory of the source distribution.
Interaction with the Braille library is done through functions starting with the braille_ prefix. In order to use those functions, you need to include a braille.h header.
/* test.c - Test program and simple example */ #include <stdio.h> #include <stdlib.h> #include "braille.h" // the required header
Most libbraille functions can return an error, usually by returning 0. In this case, it is possible to get a string describing precisely the problem by calling the braille_geterror() function.
if(!braille_init()) { fprintf(stderr, "Error initialising libbraille: %s\n", braille_geterror()); return 1; }
In order to run, libbraille must use a driver specific to the connected Braille display; it also needs to know what Braille table should be used to convert ASCII characters to Braille, as well as the port to which the display is connected.
Parameters like the Braille display or port can usally be autodetected so that it is not necessary to specify them. All parameters can also be configured through a configuration file [TODO: or through the windows registry on windows platforms].
However, an application may want to provide its own configuration system to configure libbraille parameters. In order to permit that, libbraille provides some functions to configure and request the current configuration.
The list of available drivers can be obtained with the following functions:
The following example shows how those functions can be used:
for(i = 0; i < braille_drivernum(); i++) { printf("driver [%d]: %s, supporting models: %s", i, braille_drivername(i), braille_drivermodels(i)); printf("\n"); }
Once the name of the driver to use has been selected, it can be configured in libbraille by using the braille_config like in this example where ``once'' is the name of a driver:
braille_config(BRL_DRIVER, "once");
Note that there is a special driver named ``auto''. This driver can be used when the Braille display should be autodetected.
The list of available Braille tables can be obtained with the following functions:
The following example shows how those functions can be used:
for(i = 0; i < braille_tablenum(); i++) { printf("table [%d]: %s, corresponding to: %s", i, braille_tablename(i), braille_tabledesc(i)); printf("\n"); }
Once the name of the table to use has been selected, it can be configured in libbraille by using the braille_config like in this example where ``french.tbl'' is the name of a table:
braille_config(BRL_TABLE, "french.tbl");
The braille_config function can be used to configure other parameters by changing the first argument:
A complete example:
braille_config(BRL_DEVICE, "COM1"); braille_config(BRL_DRIVER, "auto"); braille_config(BRL_TABLE, "foo.tbl"); braille_config(BRL_PATH, "/foo/bar/");
The braille_init function should be called right after configuration, before any other function of the library. It will parse the configuration file, autodetect the Braille display if necessary, load the correct driver and Braille table then initialise and configure the Braille display.
if(!braille_init()) { fprintf(stderr, "Error initialising libbraille: %s\n", braille_geterror()); return 1; }
Once the library has been initialised, it is possible to query the configuration that is used by using the braille_config function with a specific parameter:
The braille_size() function returns the number of cells of Braille display. The braille_statussize() function returns the number of additionnal cells for the status area.
printf("Libbraille version %s initialised correctly " "with driver %s using terminal %s with %d cells on device %s\n", braille_info(BRL_VERSION), braille_info(BRL_DRIVER), braille_info(BRL_TERMINAL), braille_size(), braille_info(BRL_DEVICE));
The easiest way to write something on the Braille display is to use the braille_display function. It must be called with a string terminated by NULL and will display that string on the display.
braille_display("test_libbraille started");
There is a more complex function to display something, when a better control of what is displayed is necessary, for example when displaying something other than text. What will be displayed is a combination of text and a filter that directly manipulates dots.
First you set the text with braille_write. Contrarly to braille_display, this function does not take a NULL terminated string as parameter, but a pointer to some chars and a number indicating the number of chars to read.
Then you use braille_filter to raise some dots. The first argument of braille_filter is an unsigned char corresponding to which dots have to be activated. The second argument is the number of the cell which has to be modified, starting at 0.
The dots 1, 2, 3, 4, 5, 6 and 7 correspond respectively to bits 0, 1, 2, 3, 4, 5, 6 and 7 of the unsigned char. For example, a cursor made of dots 7 and 8 corresponds to the binary number 00000011. There is a BRAILLE macro that makes it simple to get the correct value. It just takes as parameters the state of each dot.
Finally, braille_render is called. This function filters the text given by braille_write with the filter defined through braille_filter and send the data to the Braille display.
The following example display some text with a cursor under the first character:
{ char *hello_msg = "more complex test"; braille_write(hello_msg, strlen(hello_msg)); braille_filter(BRAILLE(0, 0, 0, 0, 0, 0, 1, 1), 0); braille_render(); }
Most Braille displays have some keys like cursors or function keys to interact with the computer. Some even feature a Braille keyboard to input text. Libbraille makes it possible to get an event when some of those keys are pressed by using the braille_read function.
Depending on the application, it is sometime necessary to control how much time a function can take before returning. There is a function called braille_timeout to configure how the braille_read function should behave:
When a key is pressed or at the time limit, the braille _read function returns a structure of type brl_key describing the event that happened.
The structure has an attribute named type describing the type of key pressed. It can have a few values:
/* we want the braille_read function to wait forever while no key has been pressed */ braille_timeout(-1); /* get the keys pressed on the display */ while(1) { signed char status; brl_key key; status = braille_read(&key); if(status == -1) { printf("error in braille_read: %s", braille_geterror()); } else if(status) { printf("Read key with type %d and code %d\n", key.type, key.code); switch(key.type) { case BRL_NONE: break; case BRL_CURSOR: printf("cursor: %d\n", key.code); break; case BRL_CMD: printf("command: "); switch(key.code) { case BRLK_HOME: printf("home\n"); break; case BRLK_BACKWARD: braille_display("backward"); printf("reading further left on the display\n"); break; case BRLK_FORWARD: braille_display("forward"); printf("reading further right on the display\n"); break; default: printf("unknown cmd\n"); break; } break; case BRL_KEY: printf("braille: 0x%x\n", key.braille); printf("code: %d ou 0x%x\n", key.code, key.code); printf("char: %c\n", key.code); break; default: printf("unknown type %d\n", key.type); } } }
Finally, the braille_close function must always be called when closing the Braille library. It will unload the driver, free resources and close the library.
braille_close(); printf("Leaving test_libbraille\n");
Libbraille is made of a shared library. In order to use it you need to link the library to your program.
For Visual C++ developpers, you need to add the libbraille-1.lib file to your project. An example Visual C++ project and the .lib file is available on the download page of the web site as libbraille-dev-x.x.x-VC6.zip
For unix developpers, linking the library is just a matter of adding the -lbraille option at compile time. For example, compiling the previous test code would be :
cc test.c -o test -lbraille
/* * test_libbraille.c - Test program and simple example */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "braille.h" int main(int argc, char *argv[]) { int i; printf("Starting test_libbraille\n"); for(i = 0; i < braille_drivernum(); i++) { printf("driver [%d]: %s, supporting models: %s", i, braille_drivername(i), braille_drivermodels(i)); printf("\n"); } for(i = 0; i < braille_tablenum(); i++) { printf("table [%d]: %s, corresponding to: %s", i, braille_tablename(i), braille_tabledesc(i)); printf("\n"); } /* uncomment to config some values without using the configuration file */ /* braille_config(BRL_DEVICE, "COM1"); */ /* braille_config(BRL_DRIVER, "eco"); */ /* or braille_config(BRL_DRIVER, "auto"); */ /* braille_config(BRL_TABLE, "foo.tbl"); */ /* braille_config(BRL_PATH, "/foo/bar/"); */ /* ... */ if(!braille_init()) { fprintf(stderr, "Error initialising libbraille: %s\n", braille_geterror()); fprintf(stderr, "Testing fake driver\n"); braille_config(BRL_DRIVER, "none"); if(!braille_init()) { fprintf(stderr, "Error initialising libbraille: %s\n", braille_geterror()); return 1; } } printf("Libbraille version %s initialised correctly " \ "with driver %s using terminal %s with %d cells on device %s\n", braille_info(BRL_VERSION), braille_info(BRL_DRIVER), braille_info(BRL_TERMINAL), braille_size(), braille_info(BRL_DEVICE)); /* we want the braille_read function to wait forever while no key has been pressed */ // braille_timeout(-1); /* we want the braille_read function to wait at most 1s while no key has been pressed */ braille_timeout(1000); printf("displaying string\n"); /* simple way to display something */ braille_display("test_libbraille started"); /* complex and powerful way to display something */ { char *hello_msg = "test_libbraille started"; braille_write(hello_msg, strlen(hello_msg)); braille_filter(BRAILLE(0, 0, 0, 0, 0, 0, 1, 1), 0); braille_filter(BRAILLE(0, 0, 0, 0, 0, 0, 1, 1), 23); braille_render(); } /* Displaying a few things on the status cells */ if(braille_statussize() > 0) braille_statusdisplay("abc"); /* get the keys pressed on the display */ while(1) { signed char status; brl_key key; status = braille_read(&key); if(status == -1) { printf("error in braille_read: %s", braille_geterror()); } else if(status) { printf("Read key with type %d and code %d\n", key.type, key.code); switch(key.type) { case BRL_NONE: break; case BRL_CURSOR: printf("cursor: %d\n", key.code); break; case BRL_CMD: printf("command: "); switch(key.code) { case BRLK_HOME: printf("home\n"); break; case BRLK_BACKWARD: braille_display("backward"); printf("reading further left on the display\n"); break; case BRLK_FORWARD: braille_display("forward"); printf("reading further right on the display\n"); break; default: printf("unknown cmd\n"); break; } break; case BRL_KEY: printf("braille: 0x%x\n", key.braille); printf("code: %d ou 0x%x\n", key.code, key.code); printf("char: %c\n", key.code); break; default: printf("unknown type %d\n", key.type); } } } /* now we stop everything */ braille_close(); printf("Leaving test_libbraille\n"); return 0; }