<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.65"> <TITLE>BrlAPI Reference manual: Library description</TITLE> <LINK HREF="BrlAPI-6.html" REL=next> <LINK HREF="BrlAPI-4.html" REL=previous> <LINK HREF="BrlAPI.html#toc5" REL=contents> </HEAD> <BODY> <A HREF="BrlAPI-6.html">Next</A> <A HREF="BrlAPI-4.html">Previous</A> <A HREF="BrlAPI.html#toc5">Contents</A> <HR> <H2><A NAME="sec-library"></A> <A NAME="s5">5.</A> <A HREF="BrlAPI.html#toc5">Library description</A></H2> <P>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.</P> <P>The historical test program for <EM>BrlAPI</EM> was something like: <UL> <LI>connect to <EM>BrlAPI</EM></LI> <LI>get driver id</LI> <LI>get driver name</LI> <LI>get display size</LI> <LI>try entering raw mode, immediately leave raw mode.</LI> <LI>get tty control</LI> <LI>write something on the display</LI> <LI>wait for a key press</LI> <LI>leave tty control</LI> <LI>disconnect from <EM>BrlAPI</EM></LI> </UL> </P> <P>It is here rewritten, its working briefly explained.</P> <H2><A NAME="ss5.1">5.1</A> <A HREF="BrlAPI.html#toc5.1">Connecting to <EM>BrlAPI</EM></A> </H2> <P>Connection to <EM>BrlAPI</EM> is needed first, thanks to the <CODE>brlapi_openConnection</CODE> call. For this, a <CODE>brlapi_connectionSettings_t</CODE> variable must be filled which will hold the settings the library needs to connect to the server. Just giving <CODE>NULL</CODE> will work for local use. The other parameter lets you get back the parameters which were actually used to initialize connection. <CODE>NULL</CODE> will also be nice for now.</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> if (brlapi_openConnection(NULL, NULL)<0) { brlapi_perror("brlapi_openConnection"); exit(1); } </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>The connection might fail, so testing is needed.</P> <H2><A NAME="ss5.2">5.2</A> <A HREF="BrlAPI.html#toc5.2">Getting driver name</A> </H2> <P>Knowing the type of the braille device might be useful:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> char name[BRLAPI_MAXNAMELENGTH+1]; if (brlapi_getDriverName(name, sizeof(name)) < 0) brlapi_perror("brlapi_getDriverName"); else fprintf(stderr, "Driver name: %s\n", name); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>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.</P> <H2><A NAME="ss5.3">5.3</A> <A HREF="BrlAPI.html#toc5.3">Getting display size</A> </H2> <P>Before writing on the braille display, the size should be always first checked to be sure everything will hold on it:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> 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":""); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <H2><A NAME="ss5.4">5.4</A> <A HREF="BrlAPI.html#toc5.4">Entering raw mode, immediately leaving raw mode.</A> </H2> <P>Entering raw mode is very simple:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> 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(); } </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>Not every driver supports raw mode, so testing is needed.</P> <P>While in raw mode, <CODE>brlapi_sendRaw</CODE> and <CODE>brlapi_recvRaw</CODE> 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!</P> <H2><A NAME="ss5.5">5.5</A> <A HREF="BrlAPI.html#toc5.5">Getting tty control</A> </H2> <P>Let's now display something on the device. control of the tty must be get first:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> fprintf(stderr, "Taking control of the tty... "); if (brlapi_enterTtyMode(BRLAPI_TTY_DEFAULT, NULL) >= 0) { fprintf(stderr, "Ok\n"); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>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.</P> <P>The server is asked to send <EM>brltty</EM> commands, which are device-independent.</P> <P>Getting control might fail if, for instance, another application already took control of this tty, so testing is needed.</P> <P>From now on, the braille display is detached from the screen.</P> <H2><A NAME="ss5.6">5.6</A> <A HREF="BrlAPI.html#toc5.6">Writing something on the display</A> </H2> <P>The application can now write things on the braille display without altering the screen display:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> fprintf(stderr, "Writing to braille display... "); if (brlapi_writeText(0, "Press a braille key to continue...") >= 0) { fprintf(stderr, "Ok\n"); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>The cursor is also asked <EM>not</EM> to be shown: its position is set to 0.</P> <P>"Writing to braille display... Ok" is now displayed on the screen, and "Press a braille key to continue..." on the braille display.</P> <H2><A NAME="ss5.7">5.7</A> <A HREF="BrlAPI.html#toc5.7">Waiting for a key press</A> </H2> <P>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:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> 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); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>The command is returned, as described in <CODE><brlapi_constants.h></CODE> and <CODE><brlapi_keycodes.h></CODE>. It is not transmitted to <EM>brltty</EM>: it is up to the application to define the behavior, here cleanly exitting, as described below.</P> <P>The first parameter tells the lib to block until a key press is indeed read.</P> <H2><A NAME="ss5.8">5.8</A> <A HREF="BrlAPI.html#toc5.8">Understanding commands</A> </H2> <P>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: </P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> 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; } </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>Another way is to ask BrlAPI to expand the keycode into separate information parts:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> 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); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>Eventually, named equivalents are provided:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> 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"); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <H2><A NAME="ss5.9">5.9</A> <A HREF="BrlAPI.html#toc5.9">Leaving tty control</A> </H2> <P>Let's now leave the tty:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> fprintf(stderr, "Leaving tty... "); if (brlapi_leaveTtyMode() >= 0) fprintf(stderr, "Ok\n"); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>But control of another tty can still be get for instance, by calling <CODE>brlapi_enterTtyMode()</CODE> again...</P> <H2><A NAME="ss5.10">5.10</A> <A HREF="BrlAPI.html#toc5.10">Disconnecting from <EM>BrlAPI</EM></A> </H2> <P>Let's disconnect from <EM>BrlAPI</EM>:</P> <P> <BLOCKQUOTE><CODE> <HR> <PRE> brlapi_closeConnection(); </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>The application can as well still need to connect to another server on another computer for instance, by calling <CODE>brlapi_openConnection()</CODE> again...</P> <H2><A NAME="ss5.11">5.11</A> <A HREF="BrlAPI.html#toc5.11">Putting everything together...</A> </H2> <P> <BLOCKQUOTE><CODE> <HR> <PRE> #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; } </PRE> <HR> </CODE></BLOCKQUOTE> </P> <P>This should compile well thanks to <CODE>gcc apiclient.c -o apiclient -lbrlapi</CODE></P> <HR> <A HREF="BrlAPI-6.html">Next</A> <A HREF="BrlAPI-4.html">Previous</A> <A HREF="BrlAPI.html#toc5">Contents</A> </BODY> </HTML>