File: BrlAPI.sgml

package info (click to toggle)
brltty 6.9-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 44,844 kB
  • sloc: ansic: 154,246; java: 13,514; sh: 9,934; xml: 5,672; tcl: 2,679; makefile: 2,346; awk: 713; lisp: 366; python: 321; ml: 301
file content (1608 lines) | stat: -rw-r--r-- 67,158 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
<!doctype linuxdoc system>
<article>
<title>BrlAPI Reference manual
<author>
<name>Sébastien Hinderer <tt><htmlurl
url="mailto:Sebastien.Hinderer@ens-lyon.org"
name="&lt;Sebastien.Hinderer@ens-lyon.org&gt;"></tt><newline></name>
<and>
<name>Samuel Thibault <tt><htmlurl url="mailto:Samuel.Thibault@ens-lyon.org"
name="&lt;Samuel.Thibault@ens-lyon.org&gt;"></tt><newline></name>
</author>
<date>V1.5, November 2019
<abstract>
This document describes <tt>BrlAPI</tt>.
</abstract>
<toc>

<!-- rappel des attributs:
<bf/gras/ <em/mis en valeur/ <sf/sans serif/ <sl/slanted/ <tt/machine à écrire
<it/italique
-->

<!---->
<sect>Introduction<label id="sec-intro">
<!---->
<!-- Seb -->
<!-- an introduction explaining very briefly what BrlAPI does, the
vocabulary it uses, and how to read this documentation -->
<p><em/BrlAPI/ is a service provided by the <em/brltty/ daemon.

Its purpose is to allow programmers to write applications that take advantage
of a braille terminal in order to deliver a blind user suitable information
for his/her specific needs.

While an application communicates with the braille terminal, everything
<em/brltty/ sends to the braille terminal in the application's console is
ignored, whereas each piece of data coming from the braille terminal is sent to
the application, rather than to <em/brltty/.

<sect1>Concepts

<p> All throughout this manual, a few terms will be used which are either
specific to braille terminals, or introduced because of <em/BrlAPI/. They are defined
below. Taking a few minutes to go through this glossary will save a lot
of time and questions later.

<descrip>

<tag/Authorization key/
A file containing arbitrary data, that has to be sent to the server by the
client, to prove it is allowed to establish a connection and then control
the braille terminal.

<tag/Braille display/
The small screen on the braille terminal that is able to display braille text.

<tag/Braille keyboard/
The keyboard of the braille terminal.

<tag/Braille terminal/
A computer designed to display text in braille. In this case, the text is
supposed to come from another computer running Linux or any other Unix system.

<tag/Brltty/
The background process that gives a blind person access to the console screen
thanks to a braille terminal or speech synthetizer.

<tag/Client/
An application designed to handle a braille terminal thanks to <em/BrlAPI/.

<tag/Command/
A code returned by the driver, indicating an action to do, for instance
"go to previous line", "go to next line", etc.

<tag/Driver/
A library that has functions to communicate with a braille terminal.
Basically, a driver has functions to open communication with the
braille terminal, close the communication, write on the braille
display, and read keypresses from the braille keyboard, plus some special
functions that will be described in detail in this manual.

<tag/Key/
A code that is returned by the driver when a key is pressed. This is
different from a command, because the command concept is driver-independent
(all drivers use the same command codes - those defined by <em/brltty/), whereas
codes used for returning keypresses may vary between drivers.

<tag/BrlAPI's Library/
This library helps clients to connect and use <em/BrlAPI/'s
server thanks to a series of <tt/brlapi_/-prefixed functions.

<tag/Packet/
A sequence of bytes making up the atomic unit in communications, either between
braille drivers and braille terminals or between the server and clients.

<tag/Raw mode/
Mode in which the client application exchanges packets with the driver.
Normal operations like sending text for display or reading keypresses are
not available in this mode. It lets applications take advantage of advanced
functionalities of the driver's communication protocol.

<tag/Server/
The part of <em/brltty/ that controls incoming connections and communication
between clients and braille drivers.

<tag/Suspend mode/
Mode in which the server keeps the device driver closed, so that the client
can connect directly to the device.

<tag/Tty/
Synonym for console, terminal, ...  Linux' console consist of several Virtual
Ttys (VTs).  The screen program's windows also are Ttys.  X-window system's
xterms emulate Ttys as well.

</descrip>

<sect1>How to read this manual

<p>This manual is split in five parts.

<descrip>

<tag><ref id="sec-general" name="General description"></tag>
Describes more precisely what <em/BrlAPI/
is and how it works in collaboration with <em/brltty/'s core, the braille driver
and clients. In this part, a "connection-use-disconnection" scenario
will be described step by step, explaining for each step what <em/BrlAPI/ does in
reaction to client instructions. These explanations will take place at a
user level.

<tag><ref id="sec-concurrency" name="Concurrency management"></tag>
This part explains how concurrency between <em/BrlAPI/ clients is handled
thanks to focus tellers.

<tag><ref id="sec-install" name="Installation and configuration"></tag>
This part explains in detail how to install and configure the API. For
instructions on how to install and configure <em/brltty/, please report to
the <em/brltty/ documentation.

<tag><ref id="sec-library" name="Library description"></tag>
This part describes how client applications
can communicate with the server using the <em/BrlAPI/ library that
comes with <em/brltty/. Each function will be briefly described,
classified by categories. More exhaustive descriptions of every
function are available in the corresponding online manual pages.

<tag><ref id="sec-drivers" name="Writing braille drivers"></tag>
This part describes how the braille drivers included in <em/brltty/ should be
written in order to take advantage of <em/BrlAPI/'s services.

<tag><ref id="sec-protocol" name="Protocol reference"></tag>
This part describes in detail the communication
protocol that is used to communicate between server and clients.

</descrip>

What should be read probably depends on what should be done by applications with
<em/BrlAPI/.

Reading chapters <ref id="sec-general" name="General description">, <ref
id="sec-concurrency" name="Concurrency management"> and <ref id="sec-install"
name="Installation and configuration"> is recommended, since they provide
useful information and (hopefully) lead to a good understanding of <em/BrlAPI/,
for an efficient use.

Chapter <ref id="sec-library" Name="Library description"> concerns writing
applications that take advantage of braille terminals so as to bring specific
(and more useful) information to blind people.

Chapter <ref id="sec-drivers" Name="Drivers"> is for braille driver implementation: either adding a braille driver
to <em/brltty/ or modifying an existing one so that it can benefit from
<em/BrlAPI/'s features, this chapter will be of interest, since it describes
exactly what is needed to write a driver for <em/brltty/: the core
of drivers interface for instance.

Finally, chapter <ref id="sec-protocol" Name="Protocol reference"> is for <em/not using/ the library, but using the <em/BrlAPI/
server directly, when the library might not be sufficient: it describes the
underlying protocol that will have to be used to do so.

<!---->
<sect>General description of <em/BrlAPI/<label id="sec-general">
<!---->
<!-- a general documentation, which explains the issue and the design we
chose to handle it -->

<p>Here is explained what <em/BrlAPI/ is, and what it precisely does.
These explanations should be simple enough to be accessible to every user.
For a more technical review of <em/BrlAPI/'s functionalities, please see chapter
<ref id="sec-library" name="Library description">.

<sect1>Historical notes.

<p>Originally, <em/brltty/ was designed to give access to the Linux
console to visually impaired people, through a braille terminal
or a speech synthetizer. At that time, applications running in the
console were not taking care of the presence of a braille
terminal (most applications didn't even know what a braille
terminal was).

This situation where applications are not aware of the presence of a
special device is elegant of course, since it lets use an
unlimited number of applications which don't need to be specially
designed for visually impaired people.

However, it appeared that applications specially designed to take
advantage of a braille terminal could be wanted, to
provide the suitable information to blind users, for instance.
The idea of <em/BrlAPI/ is to propose an efficient communication
mechanism, to control the braille display, read keys from the
braille keyboard, or to exchange data with the braille terminal at
a lower level (e.g. to write file transfer protocols between
braille terminals and Linux systems).

<sect1>Why <em/BrlAPI/ is part of <em/brltty/.

<p>Instead of rewriting a whole communication program from
scratch, we chose to add communication
mechanisms to <em/brltty/. This choice has two main justifications.

On the one hand, integration to <em/brltty/ allows us to use the
increasing number of drivers written for <em/brltty/, thus handling
a large number of braille terminals without having to rewrite any
piece of existing code.

On the other hand, if an application chooses to send its own
information to the braille display, and to process braille keys,
<em/brltty/ has to be warned, so that it won't try to communicate
with the braille terminal while the application already does.
To make this synchronzation between <em/brltty/
and client applications possible, it seemed easier to add the
communication mechanisms to <em/brltty/'s core, instead of writing an
external program providing them.

<sect1>How it works.

<p>We are now going to describe the steps an application should
go through to get control of the braille terminal, and what
happens on <em/brltty/'s side at each step. This step-by-step
description will let us introduce more precisely some
concepts that are useful for every <em/BrlAPI/ user.

<sect2>Connection.

<p>The first thing any client application has to do is to
connect (in the Unix sense of the word) to <em/BrlAPI/ which is
an mere application server. If this is not
clear, the only thing to be remembered is that this
step allows the client application to let the server know about its
presence. At this stage, nothing special is done on <em/brltty/'s
side.

<sect2>Authorization.

<p>Since Unix is designed to allow many users to work on the
same machine, it's quite possible that there are more than one
user accounts on the system. Most probably, one doesn't want
any user with an account on the machine to be able to communicate
with the braille terminal (just imagine what would happen if,
while somebody was working with the braille terminal, another user
connected to the system began to communicate with it,
preventing the first one from doing his job...). That's why <em/BrlAPI/ has to
provide a way to determine whether a user who established a
connection is really allowed to communicate with the braille
terminal. To achieve this, <em/BrlAPI/ requires that each
application that wants to control a braille terminal sends an
authorization key before doing anything else. The control of
the braille terminal will only be possible for the client once
it has sent the proper authorization key. What is called
authorization key is in fact a Unix file containing data (it
must be non-empty) on your system. All the things you have to do is to give
read permissions on this file to users that are allowed to
communicate with the braille terminal, and only to them. This
way, only authorized users will have access to the
authorization key and then be able to send it to <em/BrlAPI/.
To see how to do that, please see chapter <ref id="sec-install" name="Installation and configuration">.

At the end of this step, the user is authorized to take
control of the braille terminal. On <em/brltty/'s side, some data
structures are allocated to store information on the client,
but this has no user-level side-effect.

<sect2>Real use of the braille terminal.

<p>Once the client is properly connected and authorized,
there are two possible types of communication with the braille
terminal. The chosen type of communication depends on what the
client plans to do. If its purpose is to display information on
the braille display or to process braille keys, it will have to
take control of the Linux tty on which it is running. If its
purpose is to exchange data with the braille terminal (e.g. for
file transfer), it will enter what is called "raw mode".

<sect3>Braille display and braille key presses processing.

<p>If the client wants to display something on the braille
display or to process braille keys itself, rather than letting
<em/brltty/ process them, it has to take control of the Linux
terminal it is running on.

Once a client has obtained the control of his tty, <em/BrlAPI/
will completely discard <em/brltty/'s display on this tty (and only
this one), leaving the braille display free for the client.

At the same time, if a key is pressed on the braille
keyboard, <em/BrlAPI/ checks whether the client application is
interested in this key or not. If it is, the key is passed to
it, either as a key code or as a <em/brltty/ command. If it is not, the
key code is converted into a <em/brltty/ command and returned to
<em/brltty/.

Once the client is not interested in displaying text
or reading braille keys any more, it has to leave the tty, so
that either <em/brltty/ can continue its job, or another client can
take control of it.

<sect3>Parameter handling.

<p>The server exposes some parameters to the client. Some parameters are global to
all clients (e.g. the braille display size), while others are local per client
(e.g. retaindots, i.e. whether to send Perkins presses as dot patterns or as
letters). Some parameters are read-only (e.g. the braille display size), while
others are read-write (e.g. retaindots). Some parameters may change during
execution, while others change only when a client set it.

Clients can either request the current value of a parameter, or set its value
(if it is read-write), or request the server to notify on value change.

<sect3>Raw mode.

<p>Only one client can be in raw mode at the same time. In
this mode, data coming from the braille terminal are checked
by the driver (to ensure they are valid), but instead of being processed,
they are delivered "as-is" to the client that is in raw mode.

In the other direction, packets sent to <em/BrlAPI/ by the
client that is in raw mode are passed to the driver which is
expected to deliver them to the braille terminal without any
modification.

<sect3>Suspend Mode.

<p>Only one client can be in suspend mode at the same time. This mode is also
exclusive with raw mode. In this mode, the server keeps the device driver
closed, and thus the client can open the device directly by itself.

<p><bf/This mode is not recommended/, since the client will then have to
reimplement device access. Raw mode should really be preferred, since it lets
the client take advantage of server's ability to talk with the device
(USB/bluetooth support for instance).

<sect3>Remarks.

<p>

<itemize>

<item>The operations described in the three previous
subsections are not completely mutually exclusive. An
application that controls its current tty can enter raw or suspend
mode, provided that no other application already is in this
mode.

<item>Not every braille driver supports raw mode. It has
to be specially (re)written to support it, since it has
to provide special functions to process incoming and outgoing
packets. The same restriction is true (but less strong)
concerning the ability to deliver/convert keycodes into
commands: not every driver has this ability, it has to be
modified to get it.

<item>Operations previously described can be repeated.
You can, for instance, use raw mode to transfer data onto
your braille terminal, display text in braille, return to raw
mode..., all that without having to reconnect to <em/BrlAPI/ before
each operation.

</itemize>

<sect2>Disconnection.

<p>Once the client has finished using the braille terminal, it
has to disconnect from the API, so that the memory structures
allocated for the connection can be freed and eventually used by
another client. This step is transparent for the user, in the
sense that it involves no change on the braille display.


<!---->
<sect>Concurrency management between <em/BrlAPI/ clients<label id="sec-concurrency">
<!---->
<!-- Sam -->
<!-- explain focus tellers, tty tree, & co -->

<p>
An essential purpose of <em/BrlAPI/ is to manage concurrent access to the
braille display between the <em/brltty/ daemon and applications. This
concurrency is managed "per Tty". We first describe this with a flat view, and
then consider Tty hierarchy.

<sect1>VT switching

<p>
Let's first describe how things work with the simple case of a single series of
Virtual Ttys (VTs), the linux console for instance.

<p>
As described in <ref id="sec-general" name="General Description">, before being able
to write output, a <em/BrlAPI/ client has to "get" a tty, i.e. it sends to the
<em/BrlAPI/ server the number of the linux' Virtual Tty on which it is running.
The <em/BrlAPI/ server uses this information so as to know which client's output
should be shown on the braille display, according to the focus teller's
information.

<p>
Let's say some client <em/A/ is running on VT 2.  It "got" VT 2 and wrote some
output on its <em/BrlAPI/ connection.  The focus teller is <em/brltty/ here: it
always tells to the <em/BrlAPI/ server which VT is currently shown on the screen
and gets usual keyboard presses (it is "active").

<p>
Let's say VT 1 is active, then the <em/BrlAPI/ server shows <em/brltty/'s output
on the braille display.  I.e. the usual <em/brltty/ screen reading appears.
Moreover, when braille keys are pressed, they are passed to <em/brltty/, so that
usual screen reading can be performed.  When the user switches to VT 2,
<em/brltty/ (as focus teller) tells it to the <em/BrlAPI/ server, which then
remembers that client <em/A/ has got it and has produced some output.  The
server then displays this output on the braille display.  Note that <em/A/
doesn't need to re-submit its output: the server had recorded it so as to be
able to show it as soon as the focus switches to VT 2.  Whenever some key of the
braille device is pressed, <em/BrlAPI/ looks whether it is in the list of keys
that client <em/A/ said to be of his interest.  If it is, it is passed to <em/A/
(and not to <em/brltty/). If it isn't, it is passed to <em/brltty/ (and not to
<em/A/).

<p>
As a consequence, whenever clients get and release Ttys and the user switches
between Ttys, either the <em/brltty/ screen reading or the client's output is
automatically shown according to rather natural rules.

<sect1>A pile of "paper sheets"

<p>
Let's look at VT 2 by itself. What is shown on the braille display can be seen
as the result of a pile of two paper sheets.  <em/brltty/ is represented by the
bottom sheet on which its screen reading is written, and client <em/A/ by the
top sheet on which its output is written. <em/A/'s sheet hence "covers"
<em/brltty/'s sheet: <em/A/'s output "mask" <em/brltty/'s screen reading.

<p>
<em/A/ may yet want to temporarily let <em/brltty/'s screen reading appear on VT
2, while still receiving some key presses, for instance.  For this, it sends a
"void" write.  The server then clears the recorded output for this connection
(in the sheet representation, the sheet becomes "transparent").  As a
consequence, <em/brltty/'s output is automatically shown (by transparency in the
sheet representation), just like if <em/A/ had released the Tty.

<p>
Keypresses are handled in a similar way: <em/A/'s desire to get key presses is
satisfied first before <em/brltty/.

<p>
Let's say some other client <em/B/ (probably launched by <em/A/) also gets VT 2
and outputs some text on its <em/BrlAPI/ connection.  This adds a third sheet,
on top of the two previous ones.  It means that the <em/BrlAPI/ server will show
<em/B/'s output on the braille device.  If <em/A/ then outputs some text, the
server will record it (on <em/A/'s sheet which hence becomes opaque again), but
it won't be displayed on the braille device, since <em/B/'s sheet is still at
the top and opaque (i.e. with some text on it).  But if <em/B/ issues a void
write, the server clears its output buffer (i.e. <em/B/'s sheet becomes
transparent), and as a result <em/A/'s output appear on the braille display (by
transparency through <em/B/'s sheet).

<p>
The sheet order is by default determined by the Tty "get"ting order. Clients
can however change their priority (which by default is 50) to a higher value in
order to show up higher in the pile, or to a lower value in order to hide lower
in the pile.

<sect1>Hierarchy

<p>
Now, what happens when running some <em/screen/ program on, say, VT 3?  It
emulates a series of Ttys, whose output actually appear on the same VT 3.
That's where a hierarchy level appears: the focus information is not only the VT
number but also, in the case of VT 3, which <em/screen/ window is active.  This
hence forms a <em/tree/ of Ttys: the "root" being the vga driver's output, whose
sons are VTs, and VT 3 has the <em/screen/ windows as sons.  <em/Brltty/ is a
focus teller for the root, <em/screen/ will have to be a focus teller for VT 3.
<em/Screen/ should then get VT 3, not display anything (so that the usual
<em/brltty/ screen reading will be shown by transparency), and tell the
<em/BrlAPI/ server which <em/screen/ window is active (at startup and at each
window switch).  This is not implemented directly in <em/screen/ yet, but this
may be achieved via a second <em/brltty/ daemon running the Screen driver (but
it isn't yet able to get the current window number though) and the <em/BrlAPI/
driver.

<p>
A <em/BrlAPI/ client <em/C/ running in some <em/screen/ window number 1 would
then have to get the Tty path "VT 3 then window 1", which is merely expressed
as "3 1".  The window number is available in the <tt/WINDOW/ environment
variable, set by <em/screen/. The VT number, which actually represents the "path
to screen's output" should be available in the <tt/WINDOWPATH/ environment
variable, also set by <em/screen/.  The client can thus merely concatenate the
content of <tt/WINDOWPATH/ (which could hold many levels of window numbers) and
of <tt/WINDOW/ and give the result as tty path to the <em/BrlAPI/ server, which
then knows precisely where the client's usual output resides.  In practice,
applications just need to call <tt/brlapi_enterTtyMode(BRLAPI_TTY_DEFAULT)/, and
the the <em/BrlAPI/ client library will automatically perform all that.

<p>
Whenever the user switches to VT 3, the <em/BrlAPI/ server remembers the window
that <em/screen/ told to be active.  If it was window 1, it then displays
<em/C/'s output (if any).  Else <em/brltty/'s usual screen reading is shown.
Of course, several clients may be run in window 1 as well, and the "sheet pile"
mechanism applies: <em/brltty/'s sheet first (at the root of the Ttys tree), then
<em/screen/'s sheet (which is transparent, on VT 3), then <em/C/'s sheet (on
window 1 of VT 3), then other clients' sheets (on the same window).

<p>
Ttys are hence organized in a tree, each client adding its sheet at some tty in
the tree.

<sect1>The X-window case

<p>
Let's say some X server is running on VT 7 of a Linux system. Xorg's <em/xinit/
and <em/xdm/ commands automatically set the X session's <tt/WINDOWPATH/
environment variable to "7", so that X11 <em/BrlAPI/ clients started from
the session just need to call <em/brlapi_enterTtyMode(xid)/ where <em/xid/
is the X-window ID of the window of the client. The <em/BrlAPI/ library
will automatically prepend the content of <tt/WINDOWPATH/ to it.

<p>
For text-based <em/BrlAPI/ clients running in an xterm (which should just call
<tt/brlapi_enterTtyMode(BRLAPI_TTY_DEFAULT)/ as explained in the previous
section), <em/BrlAPI/ detects the window id thanks to the <tt/WINDOWID/ variable
set by xterm.

<p>
Screen readers are not bound to a particular window, so they should call
<em/brlapi_enterTtyModeWithPath(NULL, 0)/ to let the <em/BrlAPI/ library only
send the content of <tt/WINDOWPATH/, expressing that screen readers take the
whole tty.  The user should notably launch <em/xbrlapi/, which is a focus
teller for X-window as well as a keyboard simulator (<em/brltty/ can't reliably
simulate them at the kernel level in such situation).  For accessing AT-SPI
contents (like gnome or kde applications), Orca should also be launched.  For
accessing AT-SPI terminals (like gnome-terminal) in the same way as in the
console, a second <em/brltty/ daemon running the at-spi screen driver and the
<em/BrlAPI/ driver can also be launched.  All three would get the VT of the
X session, in that order (for now): <em/xbrlapi/ first, then <em/orca/ and
<em/brltty/ at last.  When the X focus is on an AT-SPI terminal, <em/brltty/
will hence be able to grab the braille display and key presses.  Else <em/orca/
would get them.  And <em/xbrlapi/ would finally get remaining key presses and
simulate them.

<p>
Note: old versions of <tt/xinit/, <tt/xdm/, <tt/kdm/ or <tt/gdm/ do not
automatically set the <tt/WINDOWPATH/ variable. The user can set it by hand in
his <tt>~/.xsession</tt>, <tt>~/.xinitrc</tt>, <tt>~/.gdmrc</tt>... to "7"

<p>
Note: some Operating Systems like Solaris do not have VTs. In that case
<tt/WINDOWPATH/ is empty or not even set.  Everything explained above still
work fine.

<sect1>Detaching

<p>
Several programs allow detaching: <em/screen/ and <em/VNC/ for instance. In such
situation, an intermediate <em/BrlAPI/ server should be run for each such
session. Clients would connect to it, and it would prepend the "current tty"
path on the fly while forwarding things to the root <em/BrlAPI/ server. This
intermediate server is yet to be written (but it is actually relatively close to
be).


<!---->
<sect>Installation and configuration of <em/BrlAPI/<label id="sec-install">
<!---->
<!-- Seb -->
<!-- an installation and configuration documentation -->
<p>
<tt/make install/ will install libbrlapi.so in /lib, and include files in
/usr/include/brltty. An authorization key will also typically be set in
/etc/brlapi.key (if it is not, just create it and put arbitrary data in it), but
it won't be readable by anybody else than root. It is up
to you to define a group of users who will have the right to read it and hence
be able to connect to the server. For instance, you may want to do:

<tscreen><code>
# addgroup brlapi
# chgrp brlapi /etc/brlapi.key
# chmod g+r /etc/brlapi.key
# addgroup user1 brlapi
# addgroup user2 brlapi
...
</code></tscreen>


<!---->
<sect>Library description<label id="sec-library">
<!---->
<!-- the library documentation, for those who want to write
applications which use it, it should be split in: -->

<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.

<!-- a basic documentation, which briefly shows
how one is supposed to use our library, with trivial examples -->

<p>
The historical test program for <em/BrlAPI/ was something like:
<itemize>
<item>connect to <em/BrlAPI/
<item>get driver id
<item>get driver name
<item>get display size
<item>try entering raw mode, immediately leave raw mode.
<item>get tty control
<item>write something on the display
<item>wait for a key press
<item>leave tty control
<item>disconnect from <em/BrlAPI/
</itemize>

It is here rewritten, its working briefly explained.

<sect1>Connecting to <em/BrlAPI/

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

<tscreen><code>
  if (brlapi_openConnection(NULL, NULL)==BRLAPI_INVALID_FILE_DESCRIPTOR) {
    brlapi_perror("brlapi_openConnection");
    exit(1);
  }
</code></tscreen>

The connection might fail, so testing is needed.

<sect1>Getting driver name

<p>Knowing the type of the braille device might be useful:

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

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.

<sect1>Getting display size

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

<tscreen><code>
  if (brlapi_getDisplaySize(&amp;x, &amp;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":"");
</code></tscreen>

<sect1>Entering raw mode, immediately leaving raw mode.

<p>Entering raw mode is very simple:

<tscreen><code>
  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();
  }
</code></tscreen>

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

While in raw mode, <tt>brlapi_sendRaw</tt> and <tt>brlapi_recvRaw</tt>
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!

<sect1>Getting tty control

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

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

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>The server is asked to send <em/brltty/ commands, which are device-independent.

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

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

<sect1>Writing something on the display

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

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

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

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

<sect1>Waiting for a key press

<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:

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

The command is returned, as described in <tt>&lt;brlapi_constants.h></tt>
and <tt>&lt;brlapi_keycodes.h></tt>.
It is not transmitted to <em/brltty/: it is up to the application to define
the behavior, here cleanly exiting, as described below.

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

<sect1>Understanding commands

<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: 

<tscreen><code>
        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;
	}
</code></tscreen>

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

<tscreen><code>
        brlapi_expandedKeyCode_t ekey;
	brlapi_expandKeyCode(key, &amp;ekey);
	fprintf(stderr, "type %u, command %u, argument %u, flags %u\n",
	  ekey.type, ekey.command, ekey.argument, ekey.flags);
</code></tscreen>

Eventually, named equivalents are provided:

<tscreen><code>
        brlapi_describedKeyCode_t dkey;
	int i;

	brlapi_describeKeyCode(key, &amp;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");
</code></tscreen>




<sect1>Leaving tty control

<p>Let's now leave the tty:

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

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

<sect1>Disconnecting from <em/BrlAPI/

<p>Let's disconnect from <em/BrlAPI/:

<tscreen><code>
  brlapi_closeConnection();
</code></tscreen>

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

<sect1>Putting everything together...

<p>
<tscreen><code>
#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)==BRLAPI_INVALID_FILE_DESCRIPTOR)
  {
    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(&amp;x, &amp;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, &amp;key) > 0) {
        brlapi_expandedKeyCode_t ekey;
        brlapi_describedKeyCode_t dkey;
	int i;

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

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

	brlapi_describeKeyCode(key, &amp;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;
}
</code></tscreen>

This should compile well thanks to
<tt>gcc apiclient.c -o apiclient -lbrlapi</tt>

<!---->
<sect>Writing (<em/BrlAPI/-compliant) drivers for <em/brltty/<label id="sec-drivers">
<!---->
<!-- Seb -->

<p>In this chapter, we will describe in details how to write a
driver for <em/brltty/. We begin with a general description of the
structure the driver should have, before explaining more precisely
what each function is supposed to do.

<sect1>Overview of the driver's structure

<p>A braille driver is in fact a library that is either
dynamically loaded by <em/brltty/ at startup, or statically linked to
it during the compilation, depending on the options given to the
<tt>./configure</tt> script.

This library has to provide every function needed by the core,
plus some additional functions, that are not mandatory, but which
improve communication with <em/BrlAPI/ and the service level provided
to client applications.

Basically, a driver library needs to provide a function to open
the communication with the braille terminal, one to close this
communication, one to read key codes from the braille keyboard, and
one to write text on the braille display. As we will see in a
moment, other functions are required.

Moreover, a driver can provide additional functionalities, by
defining some macros asserting that it has these functionalities,
and by defining associated functions.

<sect1>Basic driver structure

<p><em>Every</em> <em/brltty/ driver <em>must</em> consist in at least
a file called braille.c, located in an appropriate subdirectory of
the BrailleDrivers subdirectory. This braille.c file must have the
following layout

<verb>
    #include "prologue.h"
    /* Include standard C headers */
    #include "Programs/brl.h"
    #include "Programs/misc.h"
    #include "Programs/scr.h"
    #include "Programs/message.h"
    /* Include other files */

    static void brl_identify() { }

    static int brl_open(BrailleDisplay *brl, char **parameters, const char *tty) { ... }

    static void brl_close(BrailleDisplay *brl) { ... }

    static void brl_writeWindow(BrailleDisplay *brl) { ... }

    static void brl_writeStatus(BrailleDisplay *brl) { ... }

    static int brl_readCommand(BrailleDisplay *brl, DriverCommandContext context) { ... }
</verb>

Before giving a detailed description of what each function is
supposed to do, we define the <tt>BrailleDisplay</tt> structure,
since each function has an argument of type <tt>BrailleDisplay
*</tt>. The <tt>BrailleDisplay</tt> structure is defined like this:

<verb>
    typedef struct {

      int x, y; /* The dimensions of the display */

      int helpPage; /* The page number within the help file */

      unsigned char *buffer; /* The contents of the display */

      unsigned isCoreBuffer:1; /* The core allocated the buffer */

      unsigned resizeRequired:1; /* The display size has changed */

      unsigned int writeDelay;

      void (*bufferResized)(int rows, int columns);

    } BrailleDisplay;
</verb>

We now describe each function's semantics and calling
convention.

The <tt/brl_identify()/ function takes no argument and returns
nothing. It is called as soon as the driver is loaded, and its
purpose is to print some information about the driver in the system
log. To achieve this, the only thing this function has to do is to
call LOG_PRINT with appropriate arguments (log level and string to
put in the syslog).

The <tt/brl_open()/ function takes 3 arguments and returns an int. Its
purpose is to initialize the communication with the braille
terminal. Generally, this function has to open the file referred to by
the <tt/tty/ argument, and to configure the associated communication
port. The <tt/parameters/ argument contains parameters passed to the
driver with the -B command-line option. It's up to the driver's
author to decide whether or not he/she wants to use this argument,
and what for. The function can perform some additional tasks such
as trying to identify precisely which braille terminal model is
connected to the computer, by sending it a request and analyzing its
answer. The value that is finally returned depends on the success of
the initialization process. If it fails, th function has to return
-1. The function returns 0 on success.

The <tt/brl_close()/ function takes just one argument, and returns
nothing. The name of this function should be self-explanatory; it's
goal is to close (finish) the communication between the computer and
the braille terminal. In general, the only thing this function has
to do is to close the file descriptor associated to the braille
terminal's communication port.

The <tt/brl_writeWindow()/ function takes just one argument of type
BrailleDisplay, and returns nothing. This function displays the
specified text on the braille window. This routine is the right
place to check if the text that has to be displayed is not already
on the braille display, to send it only if necessary. More
generally, if the braille terminal supports partial refresh of the
display, the calculus of what exactly has to be sent to the braille
display to have a proper display, according to what was previously
displayed should be done in this function.

The <tt/brl_writeStatus()/ function is very similar to <tt/brl_writeWindow()/.
The only difference is that whereas <tt/brl_writeWindow()/ writes on the
main braille display, <tt/brl_writeStatus()/ writes on an auxiliary braille
display, which occasionally appears on some braille terminals. The
remarks that have been done concerning optimizations for refreshing
the display still apply here.

The <tt/brl_readCommand()/ function takes two arguments, and returns an
integer. Its purpose is to read commands from the braille keyboard
and to pass them to <em/brltty/'s core, which in turn will process them.
The first argument, of type <tt/BrailleDisplay/, is for future use, and
can safely be ignored for the moment. The second argument indicates
in which context (state) <em/brltty/ is. For instance, it specifies if
<em/brltty/ is in a menu, displays a help screen, etc. This information
can indeed be of some interest when translating a key into a
command, especially if the keys can have different meanings,
depending on the context. So, this function has to read keypresses
from the braille keyboard, and to convert them into commands,
according to the given context, these commands then being returned
to <em/brltty/. For a complete list of available command codes, please
have a look at <tt/brl.h/ in the Programs subdirectory. Two codes have special
meanings:

<descrip>

<tag/eof/ specifies that no command is available now, and that
no key is waiting to be converted into command in a near future.

<tag/CMD_NOOP/ specifies that no command is available, but
that one will be, soon. As a consequence, brl_readCommand will be
called again immediately. Returning CMD_NOOP is appropriate for
instance when a key is composed of two consecutive data packets.
When the first of them is received, one can expect that the second
will arrive quickly, so that trying to read it as soon as possible
is a good idea.

</descrip>

<sect1>Enhancements for <em/BrlAPI/

<p>To improve the level of service provided to client
applications communicating with braille drivers through <em/BrlAPI/, the
drivers should declare some additional functions that will then be
called by the API when needed.

For each additional feature that has to be implemented in a
driver, a specific macro must be defined, in addition to the
functions implementing that feature. For the moment, two features
are supported by <em/BrlAPI/:

<itemize>
<item>reading braille terminal specific key codes,

<item>exchanging raw data packets between the braille
terminal and a client application running on the PC.
</itemize>

For each feature presented below, only a short description of each
concerned macro and function will be given. For a more complete description
of concepts used here, please refer to chapters <ref id="sec-intro" name="Introduction"> and <ref id="sec-general" name="General description">.

<sect2>Exchanging raw data packets

<p>Under some circumstances, an application running on the PC
can be interested in a raw level communication with the braille
terminal. For instance, to implement a file transfer protocol,
commands to display braille or to read keys are not enough. In
such a case, one must have a way to send raw data to the
terminal, and to receive them from it.

A driver that wants to provide such a mechanism has to define
three functions: one to send packets, another one to receive them,
and the last one to reset the communication when problems occur.

The macro that declares that a driver is able to transmit packets
is:

<verb>
#define BRL_HAVE_PACKET_IO
</verb>

The prototypes of the functions the driver should define are:

<verb>
static int brl_writePacket(BrailleDisplay *brl, const unsigned char *packet, int size);
static int brl_readPacket(BrailleDisplay *brl, unsigned char *p, int size);
static void brl_rescue(BrailleDisplay *brl)
</verb>

<tt>brl_writePacket()</tt> sends a packet of <tt/size/ bytes, stored
at <tt/packet/, to the braille terminal. If the communication protocol
allows to determined if a packet has been send properly (e.g. the
terminal sends back an acknowledgement for each packet he
receives), then this function should wait the acknowledgement,
and, if it is not received, retransmission of the packet should take
place.

<tt>brl_readPacket()</tt> reads a packet of at most <tt/size/ bytes, and
stores it at the specified address. The read must not block. I.e.,
if no packet is available, the function should return immediately,
returning 0.

<tt>brl_rescue()</tt> is called by <em/BrlAPI/ when a client
application terminates without properly leaving the raw mode. This
function should restore the terminal's state, so that it is
able to display text in braille again.

<sect3>Remarks.

<p>
<itemize>
<item> If the driver provides such functions, every other
functions should use them, instead of trying to communicate
directly with the braille terminal. For instance, <tt/readCommand()/
should call <tt/readPacket()/, and then extract a key from the packet,
rather than reading directly from the communication port's file
descriptor. The same applies for <tt/brl_writeWindow()/, which should
use <tt/brl_writePacket()/, rather than writing on the communication
port's file descriptor.

<item> For the moment, the argument of type BrailleDisplay
can safely be ignored by the functions described here.

</itemize>

<!---->
<sect>Protocol reference<label id="sec-protocol">
<!---->
<!-- a boring documentation, explaining the underlying protocol of the api
in detail -->
<p>
Under some circumstances, it may be preferable to communicate directly with
<em/BrlAPI/'s server rather than using <em/BrlAPI/'s
library. Here are the needed details to be able
to do this. This chapter is also of interest if a precise understanding of
how the communication stuff works is desired, to be sure to understand how
to write multithreaded clients, for instance.

<p>
In all the following, <em/integer/ will mean an unsigned 32 bits integer in
network byte order (ie most significant bytes first).

<sect1>Reliable packet transmission channel

<p>
The protocol between <em/BrlAPI/'s server and clients is based on exchanges
of packets. So as to avoid locks due to packet loss, these exchanges are
supposed reliable, and ordering must be preserved, thus <em/BrlAPI/ needs
a reliable packet transmission channel.

<p>
To achieve this, <em/BrlAPI/ uses a TCP-based connection, on which packets
are transmitted this way:

<itemize>
<item>the size in bytes of the packet is transmitted first as an integer,
<item>then the type of the packet, as an integer,
<item>and finally the packet data.
</itemize>

<p>
The size does not include the { size, type } header, so that packets which
don't need any data have a size of 0 byte. The type of the packet can be
either of <tt/BRLAPI_PACKET_*/ constants defined in <tt/api_protocol.h/. Each type of
packet will be further discussed below.

<p>
<em/BrlAPI/'s library ships two functions to achieve packets sending and receiving
using this protocol: <tt/brlapi_writePacket/ and <tt/brlapi_readPacket/. It
is a good idea to use these functions rather than rewriting them, since this protocol
might change one day in favor of a real reliable packet transmission protocol
such as the experimental RDP.

<sect1>Responses from the server

<p>
As described below, many packets are `acknowledged'. It means that upon
reception, the server sends either:

<itemize>
<item>a <tt/BRLAPI_PACKET_ACK/ packet, with no data, which means the operation
corresponding to the received packet was successful,
<item>or a <tt/BRLAPI_PACKET_ERROR/ packet, the data being an integer
which should be one of <tt/BRLAPI_ERROR_*/ constants. This
means the operation corresponding to the received packet failed.
</itemize>

<p>
Some other packets need some information as a response.
Upon reception, the server will send either:

<itemize>
<item>a packet of the same type, its data being the response,
<item>or a <tt/BRLAPI_PACKET_ERROR/ packet.
</itemize>

<p>
If at some point an ill-formed or non-sense packet is received by the server,
and <tt/BRLAPI_PACKET_EXCEPTION/ is returned, holding the guilty packet for
further analysis.

<sect1>Operating modes
<p>
The connection between the client and the server can be in either of the 
four following modes:

<itemize>
<item>authorization mode: this is the initial mode, when the client hasn't
got the authorization to use the server yet. The server first sends a
<tt/BRLAPI_PACKET_VERSION/ packet that announces the server version. The client
must send back a <tt/BRLAPI_PACKET_VERSION/ for announcing its own version too.
The server then sends a <tt/BRLAPI_PACKET_AUTH/ packet that announces
which authorization methods are allowed. The client can then send
<tt/BRLAPI_PACKET_AUTH/ packets, which makes the connection enter normal mode.
If no authorization is needed, the server can announce the <tt/NONE/ method, the
client then doesn't need to send a <tt/BRLAPI_PACKET_AUTH/ packet.



<item>normal mode: the client is authorized to use the server, but didn't ask for a tty
or raw mode. The client can send either of these types of packet:
  <itemize>
  <item><tt/BRLAPI_PACKET_GETDRIVERNAME/
  or <tt/BRLAPI_PACKET_GETDISPLAYSIZE/ to get pieces of information from the server,
  <item><tt/BRLAPI_PACKET_ENTERTTYMODE/ to enter tty handling mode,
  <item><tt/BRLAPI_PACKET_ENTERRAWMODE/ to enter raw mode,
  </itemize>


<item>tty handling mode: the client holds the control of a tty: <em/brltty/ has
no power on it any more, masked keys excepted. It's up to the client to manage
display and keypresses. For this, it can send either of these types of packet:
  <itemize>
  <item><tt/BRLAPI_PACKET_LEAVETTYMODE/ to leave tty handling mode and go back to
  normal mode,
  <item><tt/BRLAPI_PACKET_IGNOREKEYRANGE/ and <tt/BRLAPI_PACKET_ACCEPTKEYRANGE/ to mask and unmask keys,
  <item><tt/BRLAPI_PACKET_WRITE/ to display text on this tty,
  <item><tt/BRLAPI_PACKET_ENTERRAWMODE/ to enter raw mode,
  <item><tt/BRLAPI_PACKET_GETDRIVERNAME/
  or <tt/BRLAPI_PACKET_GETDISPLAYSIZE/ to get pieces of information from the server,
  </itemize>
And the server might send <tt/BRLAPI_PACKET_KEY/ packets to signal key presses.


<item>raw mode: the client wants to exchange packets directly with the braille
terminal. Only these types of packet will be accepted.
  <itemize>
  <item><tt/BRLAPI_PACKET_LEAVERAWMODE/ to get back to previous mode, either normal or
  tty handling mode.
  <item><tt/BRLAPI_PACKET_PACKET/ to send a packet to the braille terminal.
  </itemize>
And the server might send <tt/BRLAPI_PACKET_PACKET/ packets to give received packets
from the terminal to the client.

<item>suspend mode: the client wants to completely drive the braille terminal.
The device driver is hence kept closed. No type of packet is allowed except
<tt/BRLAPI_PACKET_RESUME/
</itemize>

Termination of the connection is initiated by the client in normal mode by
simply closing its side of the socket. The server will then close the
connection.


<sect1>Details for each type of packet

<p>
Here is described the semantics of each type of packet. Most of them are
directly linked to some of <em/BrlAPI/'s library's functions. Reading their
online manual page as well will hence be of good help for understanding.

<sect2><tt/BRLAPI_PACKET_VERSION/
This must be the first packet ever transmitted from the server to the client and
from the client to the server. The server sends one first for letting the client
know its protocol version. Data is an integer indicating the protocol version.

Then client must then respond the same way for giving its
version.  If the protocol version can't be handled by the server, a
<tt/BRLAPI_ERROR_PROTOCOL_VERSION/ error packet is returned and the connection
is closed.

<sect2><tt/BRLAPI_PACKET_AUTH/
<p>
This must be the second packet ever transmitted from the server to the client
and from the client to the server. The server sends one first for letting the
client know which authorization methods are available.  Data is the allowed
authorization types, as integers.

If the <tt/NONE/ method is not announced by the server, the client can then try
to get authorized by sending packets whose data is the type of authorization
that is tried (as an integer), and eventually some data (if the authorization
type needs it).

If the authorization is successful, the server acknowledges the packet, and
other types of packets might be used, other <tt/BRLAPI_PACKET_AUTH/ shouldn't be
sent by the client.

If the authorization is not successful, the server sends a
<tt/BRLAPI_ERROR_AUTHENTICATION/ error, and the client can try another
authorization method.

Authorization methods are as follow:

<itemize>
  <item><tt/NONE/: the client doesn't need to send an authorization packet.
  <item><tt/KEY/: data holds a secret key, the authorization is successful only
if the key matches the server secret key.
  <item><tt/CREDENTIALS/: Operating-System-specific credentials are explicitly
sent over the socket, the authorization is successful if the server considers
the credentials sufficient.
</itemize>

Note: when the Operating system permits it, the server may use implicit
credential check, and then advertise the <tt/none/ method.

<sect2><tt/BRLAPI_PACKET_GETDRIVERNAME/ (see <em/brlapi_getDriverName()/)
<p>
This should be sent by the client when it needs the full name of
the current <tt/brltty/ driver. The returned string is \0 terminated.

<sect2><tt/BRLAPI_PACKET_GETMODELID/ (see <em/brlapi_getModelIdentifier()/)
<p>
This should be sent by the client when it needs to identify
which model of braille display is currently used by <tt/brltty/.
The returned string is \0 terminated.

<sect2><tt/BRLAPI_PACKET_GETDISPLAYSIZE/ (see <em/brlapi_getDisplaySize()/)
<p>
This should be sent by the client when it needs to know the braille display
size. The returned data are two integers: width and then height.

<sect2><tt/BRLAPI_PACKET_ENTERTTYMODE/ (see <em/brlapi_enterTtyMode()/ and
<em/brlapi_enterTtyModeWithPath()/)
<p>
This should be sent by the client to get control of a tty. Sent data are
first a series of integers: the first one gives the number of following
integers, which are the numbers of ttys that leads to the tty that
the application wants to take control of (it can be empty if the tty is 
one of the machine's VT). The last integer of this series tells the number of
the tty to get control of. Finally, how key presses should be reported is sent:
either a driver name or "", preceded by the number of characters in the driver
name (0 in the case of ""), as an unsigned byte. This packet is then
acknowledged by the server.

<sect2><tt/BRLAPI_PACKET_KEY/ (see <em/brlapi_readKey()/)
<p>
As soon as the client gets a tty, it must be prepared to handle
<tt/BRLAPI_PACKET_KEY/ incoming packets
at any time (as soon as the key
was pressed on the braille terminal, hopefully).
The data holds a key code as 2 integers, or
the key flags then the command code
as 2 integers, depending on what has been request in the
<tt/BRLAPI_PACKET_ENTERTTYMODE/ packet.

<sect2><tt/BRLAPI_PACKET_SETFOCUS/ (see <em/brlapi_setFocus()/)

<p>
For the server to know which tty is active, one particular client is responsible
for sending <tt/BRLAPI_PACKET_SETFOCUS/ packets. They hold a single integer telling
the new current tty. For instance, when running an X server on VT 7, the
<tt/xbrlapi/ client would have sent a <tt/BRLAPI_PACKET_ENTERTTYMODE(7)/ and will send
window IDs whenever X focus changes, allowing display and keypresses switching
between xterms.

<sect2><tt/BRLAPI_PACKET_LEAVETTYMODE/ (see <em/brlapi_leaveTtyMode()/)
<p>
This should be sent to free the tty and masked keys lists.
This is acknowledged by the server.

<sect2><tt/BRLAPI_PACKET_IGNOREKEYRANGE/ and <tt/BRLAPI_PACKET_ACCEPTKEYRANGE/
(see <em/brlapi_ignoreKeyRange()/ and <em/brlapi_acceptKeyRange()/)
<p>
If the client doesn't want every key press to be signaled to it, but some of
them to be given to <tt/brltty/ for normal processing, it can send
<tt/BRLAPI_PACKET_IGNOREKEYRANGE/ packets to
tell ranges of key codes which shouldn't be
sent to it, but given to <tt/brltty/, and <tt/BRLAPI_PACKET_ACCEPTKEYRANGE/
packets to tell ranges
of key codes which should be sent to it, and not given to
<tt/brltty/. The server keeps a dynamic list of ranges, so that arbitrary
sequences of such packets can be sent.
A range is composed of 2 keycodes: the "first" and the "last" boundaries.
Each keycode is composed of 2 integers: the key flags then the command code.
The range expressed by these two keycodes is the set of keycodes whose command
codes are between the command code of the "first" keycode and the "last" keycode
(inclusive), and whose flags contain at least the flags of the "first" keycode
and at most the flags of the "last" keycode. Setting the "first" and "last"
keycode to the same value express only one keycode, for instance. Setting the
first and last keycode to the same command code but setting no flags in the
"first" keycode and setting one flag in the "last" keycode expresses only two
keycode, with the same command code and no flags set except possibly the flag
that is set in the "last" keycode. Setting one flag <em/i/ in the "first"
keycode and setting the same flag plus another flag <em/j/ in the "last" keycode
expresses that the keycodes in the range have flag <em/i/ set and possibly flag
<em/j/ set, but no other flag. Several such ranges can be provided one after the
other.

<sect2><tt/BRLAPI_PACKET_WRITE/ (see <em/brlapi_write()/)
<p>
To display text on the braille terminal and set the position of the cursor,
the client can send a <tt/BRLAPI_PACKET_WRITE/ packet. The packet begins
with an integer holding flags (see <tt/BRLAPI_WF_*/). These flags indicate
which data will then be available, in the following order (corresponding to
flag weight):

<itemize>
<item> A display number can be given as a integer, in case the braille
display has several. If not given, usual display is used.
<item> A region must be given as two integers indicating the beginning and the
number of characters of the part of the braille display which is to be updated,
the first cell of the display being numbered 1. For braille displays that have
several lines, the first cell of the second line of the display is numbered the
length of lines plus one, etc., in other words the display is handled as the
concatenation of the lines of the display.
If the number is negative, its absolute value is taken into account, and the
update is padded or truncated to fill the rest of the display.
<item> The text to display can then be given, preceded by its size in bytes
expressed as an integer. It will erase the corresponding region in the AND and
OR fields. If the region size is positive, the text's length in characters must exactly match the region
size. For multibyte text, this is the number of wide characters. Notably,
combining and double-width characters count for 1.
<item> Then an AND field can be given, one byte per character: the 8-dot
representation of the above text will be AND-ed with this field, hence allowing
to erase some unwanted parts of characters. Dots are coded as described in
ISO/TR 11548-1: dot 1 is set iff bit 0 is set, dot 2 is set iff bit 1 is set,
...  dot <em/i+1/ is set if bit <em/i/ is set. This also corresponds to the
low-order byte of the coding of unicode's braille row <tt/U+2800/.
<item> As well, an OR field may be given, one byte per character: the 8-dot
result of the AND operation above (or the 8-dot representation of the text if
no AND operation was performed) is OR-ed with this field, hence allowing
to set some dots, to underline characters for instance.
<item> A cursor position can be specified. 1 representing
the first character of the display, 0 turning the cursor off. If not given,
the cursor (if any) is left unmodified.
<item> Last but not least, the charset of the text can be specified: the length
of the name first in one byte, then the name itself in ASCII characters. If the
charset is not specified, an 8-bit charset is assumed, and it is assumed to be
the same as the server's. Multibyte charsets may be used, AND and OR fields'
bytes will correspond to each text's wide <em/character/, be it a combining or a
double-width character.
</itemize>

A <tt/BRLAPI_PACKET_WRITE/ packet without any flag (and hence no data) means a
"void" WRITE: the server clears the output buffer for this connection.

<sect2><tt/BRLAPI_PACKET_ENTERRAWMODE/ (see <em/brlapi_enterRawMode()/)
<p>
To enter raw mode, the client must send a <tt/BRLAPI_PACKET_ENTERRAWMODE/ packet,
which is acknowledged. Once in raw mode, no other packet than
<tt/BRLAPI_PACKET_LEAVERAWMODE/ or <tt/BRLAPI_PACKET_PACKET/ will be accepted.
The data must hold the special value <tt/BRLAPI_DEVICE_MAGIC/: <tt/0xdeadbeef/, then
the name of the driver (one byte for the length, then the name) to avoid
erroneous raw mode activating.

<sect2><tt/BRLAPI_PACKET_LEAVERAWMODE/ (see <em/brlapi_leaveRawMode()/)
<p>
To leave raw mode, the client must send a <tt/BRLAPI_PACKET_LEAVERAWMODE/ packet, which
is acknowledged.

<sect2><tt/BRLAPI_PACKET_PACKET/ (see <em/brlapi_sendRaw()/ and
<em/brlapi_recvRaw()/)
<p>
While in raw mode, only <tt/BRLAPI_PACKET_PACKET/ packets can be exchanged between
the client and the server: to send a packet to the braille terminal, the
client merely sends a <tt/BRLAPI_PACKET_PACKET/ packet, its data being the packet to
send to the terminal. Whenever its receives a packet from the terminal, the
server does exactly the same, so that packet exchanges between the terminal and
the server are exactly reproduced between the server and the client.

<sect2><tt/BRLAPI_PACKET_SUSPENDDRIVER/ (see <em/brlapi_suspendDriver()/)
<p>
To enter suspend mode, the client must send a <tt/BRLAPI_PACKET_SUSPEND/ packet,
which is acknowledge. Once in suspend mode, no other packet than
<tt/BRLAPI_PACKET_RESUME/ will be accepted.
The data must hold the special value <tt/BRLAPI_DEVICE_MAGIC/: <tt/0xdeadbeef/,
then the name of the driver (one byte for the length, then the name) to avoid
erroneous raw mode activating.

<sect2><tt/BRLAPI_PACKET_PARAM_REQUEST/

<p>

This packet is sent by the client to request values of parameters. The packet
begins with an integer which holds flags (see <tt/BRLAPI_PARAMF_*/) which
describe which, how, and when the value should be returned by the server:
<itemize>
<item> When the <tt/BRLAPI_PARAMF_GLOBAL/ flag is set, the server will
return/subscribe the global value instead of the local value.
<item> When the <tt/BRLAPI_PARAMF_GET/ flag is set, the server acknowledges the
request by returning the latest value with a <tt/BRLAPI_PACKET_PARAM_VALUE/
packet. Otherwise the server acknowledges the request with a
<tt/BRLAPI_PACKET_ACK/ packet, without providing the value.
<item> When the <tt/BRLAPI_PARAMF_SUBSCRIBE/ flag is set, the server will keep
sending asynchronously the value of the parameter whenever it changes, with
<tt/BRLAPI_PACKET_PARAM_UPDATE/ packets, until
another request packet has the <tt/BRLAPI_PARAMF_UNSUBSCRIBE/ flag set for this
parameter.
<item> When the <tt/BRLAPI_PARAMF_SELF/ flag is set along
<tt/BRLAPI_PARAMF_SUBSCRIBE/, the server will send the value of the parameter
when it is changed even by the client itself.
<item> When the <tt/BRLAPI_PARAMF_UNSUBSCRIBE/ flag is set, the server
will stop sending asynchronously the value of the parameter with
<tt/BRLAPI_PACKET_PARAM_UPDATE/ packets.
</itemize>

It does not make sense to set both the <tt/BRLAPI_PARAMF_SUBSCRIBE/ and
<tt/BRLAPI_PARAMF_UNSUBSCRIBE/ flags.

Then an integer representing the parameter to be requested.
Then two integers that form (in big-endian order) a 64bit value used to
subspecify the precise parameter to be requested (e.g. a keycode number).

If several <tt/BRLAPI_PARAMF_SUBSCRIBE/ packets are sent by the client, as
many <tt/BRLAPI_PARAMF_UNSUBSCRIBE/ packets have to be sent by the client before
the server stops sending <tt/BRLAPI_PACKET_PARAM_UPDATE/ packets.

<sect2><tt/BRLAPI_PACKET_PARAM_VALUE/

<p>
This packet is sent by the client or the server to provide the value of a
parameter. The packet begins with an integer which holds flags (see
<tt/BRLAPI_PVF_*/) which describe which value is being transmitted:

<itemize>
<item> When the <tt/BRLAPI_PVF_GLOBAL/ flag is set, the value is the global value
instead of the local value.
</itemize>

Then an integer representing the parameter being transmitted. Then two integers
that form (in big-endian order) a 64bit value used to subspecify the precise
parameter being transmitted (e.g. a keycode number).  Eventually, the packet
contains the value.

When the packet is sent by the client, it defines the new value of the
parameter, and if it is a global value, the server broadcasts the new value to
all clients which have subscribed to updates. The packet is then acknowledged by
the server on success. If the value can not be changed, the server returns an
error (e.g. <tt/BRLAPI_ERROR_READONLY_PARAMETER/).

<sect2><tt/BRLAPI_PACKET_PARAM_VALUE/

This packet is sent asynchronously by the server to provide an update of a
value of a parameter. This is sent only if the client has previously sent a
<tt/BRLAPI_PACKET_PARAM_REQUEST/ packet with the <tt/BRLAPI_PARAMF_SUBSCRIBE/
for the corresponding parameter.

It is structured exactly like a <tt/BRLAPI_PACKET_PARAM_VALUE/ packet.

<sect2><tt/BRLAPI_PACKET_SYNCHRONIZE/

This packet is sent by the client and just acknowledged by the server. This
allows the client to perform a round-try with the server, thus collecting any
pending exception notification.

</article>