����JFIFXX�����    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222����"��4�� ���,�PG"Z_�4�˷����kjز�Z�,F+��_z�,�© �����zh6�٨�ic�fu���#ډb���_�N�?��wQ���5-�~�I���8����TK<5o�Iv-�����k�_U_�����~b�M��d����Ӝ�U�Hh��?]��E�w��Q���k�{��_}qFW7HTՑ��Y��F�?_�'ϔ��_�Ջt��=||I ��6�έ"�����D���/[�k�9���Y�8ds|\���Ҿp6�Ҵ���]��.����6�z<�v��@]�i%��$j��~�g��J>��no����pM[me�i$[����s�o�ᘨ�˸ nɜG-�ĨU�ycP�3.DB�li�;��hj���x7Z^�N�h������N3u{�:j�x�힞��#M&��jL P@_���� P��&��o8������9�����@Sz6�t7#O�ߋ �s}Yf�T���lmr����Z)'N��k�۞p����w\�Tȯ?�8`�O��i{wﭹW�[�r�� ��Q4F�׊���3m&L�=��h3����z~��#�\�l :�F,j@�� ʱ�wQT����8�"kJO���6�֚l����}���R�>ډK���]��y����&����p�}b��;N�1�m�r$�|��7�>e�@B�TM*-iH��g�D�)� E�m�|�ؘbҗ�a��Ҿ����t4���o���G��*oCN�rP���Q��@z,|?W[0�����:�n,jWiE��W��$~/�hp\��?��{(�0���+�Y8rΟ�+����>S-S����VN;�}�s?.����� w�9��˟<���Mq4�Wv'��{)0�1mB��V����W[�����8�/<� �%���wT^�5���b��)iM� pg�N�&ݝ��VO~�q���u���9� ����!��J27����$O-���! �:�%H��� ـ����y�ΠM=t{!S�� oK8������t<����è:a������[�����ա�H���~��w��Qz`�po�^ ����Q��n� �,uu�C�$ ^���,������8�#��:�6��e�|~���!�3�3.�\0��q��o�4`.|� ����y�Q�`~;�d�ׯ,��O�Zw�������`73�v�܋�<���Ȏ�� ـ4k��5�K�a�u�=9Yd��$>x�A�&�� j0� ���vF��� Y�|�y��� ~�6�@c��1vOp�Ig����4��l�OD���L����� R���c���j�_�uX6��3?nk��Wy�f;^*B� ��@�~a�`��Eu������+���6�L��.ü>��}y���}_�O�6�͐�:�YrG�X��kG�����l^w���~㒶sy��Iu�!� W ��X��N�7BV��O��!X�2����wvG�R�f�T#�����t�/?���%8�^�W�aT��G�cL�M���I��(J����1~�8�?aT ���]����AS�E��(��*E}� 2��#I/�׍qz��^t�̔���b�Yz4x���t�){ OH��+(E��A&�N�������XT��o��"�XC��'���)}�J�z�p� ��~5�}�^����+�6����w��c��Q�|Lp�d�H��}�(�.|����k��c4^�"�����Z?ȕ ��a<�L�!039C� �Eu�C�F�Ew�ç ;�n?�*o���B�8�bʝ���'#Rqf���M}7����]����s2tcS{�\icTx;�\��7K���P���ʇ Z O-��~��c>"��?�������P��E��O�8��@�8��G��Q�g�a�Վ���󁶠�䧘��_%#r�>�1�z�a��eb��qcPѵ��n���#L��� =��׀t� L�7�`��V���A{�C:�g���e@�w1 Xp3�c3�ġ����p��M"'-�@n4���fG��B3�DJ�8[Jo�ߐ���gK)ƛ��$���� ���8�3�����+���� �����6�ʻ���� ���S�kI�*KZlT _`���?��K����QK�d����B`�s}�>���`��*�>��,*@J�d�oF*����弝��O}�k��s��]��y�ߘ��c1G�V���<=�7��7����6�q�PT��tXԀ�!9*4�4Tހ3XΛex�46���Y��D ����� �BdemDa����\�_l,��G�/���֌7���Y�](�xTt^%�GE�����4�}bT���ڹ�����;Y)���B�Q��u��>J/J �⮶.�XԄ��j�ݳ�+E��d ��r�5�_D�1 ��o�� �B�x�΢�#���<��W�����8���R6�@g�M�.��� dr�D��>(otU��@x=��~v���2� ӣ�d�oBd��3�eO�6�㣷�����ݜ6��6Y��Qz`��S��{���\P�~z m5{J/L��1������<�e�ͅPu�b�]�ϔ���'������f�b� Zpw��c`"��i���BD@:)ִ�:�]��hv�E�w���T�l��P���"Ju�}��وV J��G6��. J/�Qgl߭�e�����@�z�Zev2u�)]կ�����7x���s�M�-<ɯ�c��r�v�����@��$�ޮ}lk���a���'����>x��O\�ZFu>�����ck#��&:��`�$�ai�>2Δ����l���oF[h��lE�ܺ�Πk:)���`�� $[6�����9�����kOw�\|���8}������ބ:��񶐕��I�A1/�=�2[�,�!��.}gN#�u����b��� ~��݊��}34q����d�E��Lc��$��"�[q�U�硬g^��%B �z���r�pJ�ru%v\h1Y�ne`ǥ:g���pQM~�^�Xi� ��`S�:V29.�P���V�?B�k�� AEvw%�_�9C�Q����wKekPؠ�\�;Io d�{ ߞo�c1eP����\� `����E=���@K<�Y���eڼ�J���w����{av�F�'�M�@/J��+9p���|]�����Iw &`��8���&M�hg��[�{��Xj��%��Ӓ�$��(����ʹN���<>�I���RY���K2�NPlL�ɀ)��&e����B+ь����( � �JTx���_?EZ� }@ 6�U���뙢ط�z��dWI�n` D����噥�[��uV��"�G&Ú����2g�}&m��?ċ�"����Om#��������� ��{�ON��"S�X��Ne��ysQ���@Fn��Vg���dX�~nj�]J�<�K]:��FW��b�������62�=��5f����JKw��bf�X�55��~J �%^����:�-�QIE��P��v�nZum� z � ~ə ���� ���ة����;�f��\v���g�8�1��f24;�V���ǔ�)����9���1\��c��v�/'Ƞ�w�������$�4�R-��t���� e�6�/�ġ �̕Ecy�J���u�B���<�W�ַ~�w[B1L۲�-JS΂�{���΃������A��20�c#��@ 0!1@AP"#2Q`$3V�%45a6�FRUq��� ����^7ׅ,$n�������+��F�`��2X'��0vM��p�L=������5��8������u�p~���.�`r�����\���O��,ư�0oS ��_�M�����l���4�kv\JSd���x���SW�<��Ae�IX����������$I���w�:S���y���›R��9�Q[���,�5�;�@]�%���u�@ *ro�lbI �� ��+���%m:�͇ZV�����u�̉����θau<�fc�.����{�4Ա� �Q����*�Sm��8\ujqs]{kN���)qO�y�_*dJ�b�7���yQqI&9�ԌK!�M}�R�;������S�T���1���i[U�ɵz�]��U)V�S6���3$K{�ߊ<�(� E]Զ[ǼENg�����'�\?#)Dkf��J���o��v���'�%ƞ�&K�u�!��b�35LX�Ϸ��63$K�a�;�9>,R��W��3�3� d�JeTYE.Mϧ��-�o�j3+y��y^�c�������VO�9NV\nd�1 ��!͕_)a�v;����թ�M�lWR1��)El��P;��yوÏ�u 3�k�5Pr6<�⒲l�!˞*��u־�n�!�l:����UNW ��%��Chx8vL'��X�@��*��)���̮��ˍ��� ���D-M�+J�U�kvK����+�x8��cY������?�Ԡ��~3mo��|�u@[XeY�C�\Kp�x8�oC�C�&����N�~3-H���� ��MX�s�u<`���~"WL��$8ξ��3���a�)|:@�m�\���^�`�@ҷ)�5p+��6���p�%i)P M���ngc�����#0Aruz���RL+xSS?���ʮ}()#�t��mˇ!��0}}y����<�e� �-ή�Ԩ��X������ MF���ԙ~l L.3���}�V뽺�v�����멬��Nl�)�2����^�Iq��a��M��qG��T�����c3#������3U�Ǎ���}��לS�|qa��ڃ�+���-��2�f����/��bz��ڐ�� �ݼ[2�ç����k�X�2�* �Z�d���J�G����M*9W���s{��w���T��x��y,�in�O�v��]���n����P�$�JB@=4�OTI�n��e�22a\����q�d���%�$��(���:���: /*�K[PR�fr\nڙdN���F�n�$�4�[�� U�zƶ����� �mʋ���,�ao�u 3�z� �x��Kn����\[��VFmbE;�_U��&V�Gg�]L�۪&#n%�$ɯ�dG���D�TI=�%+AB�Ru#��b4�1�»x�cs�YzڙJG��f��Il��d�eF'T� iA��T���uC�$����Y��H?����[!G`}���ͪ� �纤Hv\������j�Ex�K���!���OiƸ�Yj�+u-<���'q����uN�*�r\��+�]���<�wOZ.fp�ێ��,-*)V?j-kÊ#�`�r��dV����(�ݽBk�����G�ƛk�QmUڗe��Z���f}|����8�8��a���i��3'J�����~G_�^���d�8w������ R�`(�~�.��u���l�s+g�bv���W���lGc}��u���afE~1�Ue������Z�0�8�=e�� f@/�jqEKQQ�J��oN��J���W5~M>$6�Lt�;$ʳ{���^��6�{����v6���ķܰg�V�cnn �~z�x�«�,2�u�?cE+Ș�H؎�%�Za�)���X>uW�Tz�Nyo����s���FQƤ��$��*�&�LLXL)�1�" L��eO��ɟ�9=���:t��Z���c��Ž���Y?�ӭV�wv�~,Y��r�ۗ�|�y��GaF�����C�����.�+� ���v1���fήJ�����]�S��T��B��n5sW}y�$��~z�'�c ��8 ��� ,! �p��VN�S��N�N�q��y8z˱�A��4��*��'������2n<�s���^ǧ˭P�Jޮɏ�U�G�L�J�*#��<�V��t7�8����TĜ>��i}K%,���)[��z�21z ?�N�i�n1?T�I�R#��m-�����������������1����lA�`��fT5+��ܐ�c�q՝��ʐ��,���3�f2U�եmab��#ŠdQ�y>\��)�SLY����w#��.���ʑ�f��� ,"+�w�~�N�'�c�O�3F�������N<���)j��&��,-� �љ���֊�_�zS���TǦ����w�>��?�������n��U仆�V���e�����0���$�C�d���rP �m�׈e�Xm�Vu� �L��.�bֹ��� �[Դaզ���*��\y�8�Է:�Ez\�0�Kq�C b��̘��cө���Q��=0Y��s�N��S.���3.���O�o:���#���v7�[#߫ ��5�܎�L���Er4���9n��COWlG�^��0k�%<���ZB���aB_���������'=��{i�v�l�$�uC���mƎҝ{�c㱼�y]���W�i ��ߧc��m�H� m�"�"�����;Y�ߝ�Z�Ǔ�����:S#��|}�y�,/k�Ld� TA�(�AI$+I3��;Y*���Z��}|��ӧO��d�v��..#:n��f>�>���ȶI�TX��� 8��y����"d�R�|�)0���=���n4��6ⲑ�+��r<�O�܂~zh�z����7ܓ�HH�Ga롏���nCo�>������a ���~]���R���̲c?�6(�q�;5%� |�uj�~z8R=X��I�V=�|{v�Gj\gc��q����z�؋%M�ߍ����1y��#��@f^���^�>N�����#x#۹��6�Y~�?�dfPO��{��P�4��V��u1E1J �*|���%���JN��`eWu�zk M6���q t[�� ��g�G���v��WIG��u_ft����5�j�"�Y�:T��ɐ���*�;� e5���4����q$C��2d�}���� _S�L#m�Yp��O�.�C�;��c����Hi#֩%+) �Ӎ��ƲV���SYź��g |���tj��3�8���r|���V��1#;.SQ�A[���S������#���`n�+���$��$I �P\[�@�s��(�ED�z���P��])8�G#��0B��[ى��X�II�q<��9�~[Z멜�Z�⊔IWU&A>�P~�#��dp<�?����7���c��'~���5 ��+$���lx@�M�dm��n<=e�dyX��?{�|Aef ,|n3�<~z�ƃ�uۧ�����P��Y,�ӥQ�*g�#먙R�\���;T��i,��[9Qi歉����c>]9�� ��"�c��P�� �Md?٥��If�ت�u��k��/����F��9�c*9��Ǎ:�ØF���z�n*�@|I�ށ9����N3{'��[�'ͬ�Ҳ4��#}��!�V� Fu��,�,mTIk���v C�7v���B�6k�T9��1�*l� '~��ƞF��lU��'�M ����][ΩũJ_�{�i�I�n��$���L�� j��O�dx�����kza۪��#�E��Cl����x˘�o�����V���ɞ�ljr��)�/,�߬h�L��#��^��L�ф�,íMƁe�̩�NB�L�����iL����q�}��(��q��6IçJ$�W�E$��:������=#����(�K�B����zђ <��K(�N�۫K�w��^O{!����)�H���>x�������lx�?>Պ�+�>�W���,Ly!_�D���Ō�l���Q�!�[ �S����J��1��Ɛ�Y}��b,+�Lo�x�ɓ)����=�y�oh�@�꥟/��I��ѭ=��P�y9��� �ۍYӘ�e+�p�Jnϱ?V\SO%�(�t� ���=?MR�[Ș�����d�/ ��n�l��B�7j� ��!�;ӥ�/�[-���A�>�dN�sLj ��,ɪv��=1c�.SQ�O3�U���ƀ�ܽ�E����������̻��9G�ϷD�7(�}��Ävӌ\�y�_0[w ���<΍>����a_��[0+�L��F.�޺��f�>oN�T����q;���y\��bՃ��y�jH�<|q-eɏ�_?_9+P���Hp$�����[ux�K w�Mw��N�ی'$Y2�=��q���KB��P��~������Yul:�[<����F1�2�O���5=d����]Y�sw:���Ϯ���E��j,_Q��X��z`H1,#II ��d�wr��P˂@�ZJV����y$�\y�{}��^~���[:N����ߌ�U�������O��d�����ؾe��${p>G��3c���Ė�lʌ�� ת��[��`ϱ�-W����dg�I��ig2��� ��}s ��ؤ(%#sS@���~���3�X�nRG�~\jc3�v��ӍL��M[JB�T��s3}��j�Nʖ��W����;7��ç?=X�F=-�=����q�ߚ���#���='�c��7���ڑW�I(O+=:uxq�������������e2�zi+�kuG�R��������0�&e�n���iT^J����~\jy���p'dtG��s����O��3����9* �b#Ɋ�� p������[Bws�T�>d4�ۧs���nv�n���U���_�~,�v����ƜJ1��s�� �QIz��)�(lv8M���U=�;����56��G���s#�K���MP�=��LvyGd��}�VwWBF�'�à �?MH�U�g2�� ����!�p�7Q��j��ڴ����=��j�u��� Jn�A s���uM������e��Ɔ�Ҕ�!)'��8Ϣ�ٔ��ޝ(��Vp���צ֖d=�IC�J�Ǡ{q������kԭ�߸���i��@K����u�|�p=..�*+����x�����z[Aqġ#s2a�Ɗ���RR�)*HRsi�~�a &f��M��P����-K�L@��Z��Xy�'x�{}��Zm+���:�)�) IJ�-i�u���� ���ܒH��'�L(7�y�GӜq���� j��� 6ߌg1�g�o���,kر���tY�?W,���p���e���f�OQS��!K�۟cҒA�|ս�j�>��=⬒��˧L[�� �߿2JaB~R��u�:��Q�] �0H~���]�7��Ƽ�I���(}��cq '�ήET���q�?f�ab���ӥvr� �)o��-Q��_'����ᴎo��K������;��V���o��%���~OK ����*��b�f:���-ťIR��`B�5!RB@���ï�� �u �̯e\�_U�_������� g�ES��3�������QT��a����x����U<~�c?�*�#]�MW,[8O�a�x��]�1bC|踤�P��lw5V%�)�{t�<��d��5���0i�XSU��m:��Z�┵�i�"��1�^B�-��P�hJ��&)O��*�D��c�W��vM��)����}���P��ܗ-q����\mmζZ-l@�}��a��E�6��F�@��&Sg@���ݚ�M����� ȹ 4����#p�\H����dYDo�H���"��\��..R�B�H�z_�/5˘����6��KhJR��P�mƶi�m���3�,#c�co��q�a)*Pt����R�m�k�7x�D�E�\Y�閣_X�<���~�)���c[[�BP����6�Yq���S��0����%_����;��Àv�~�| VS؇ ��'O0��F0��\���U�-�d@�����7�SJ*z��3n��y��P����O���������m�~�P�3|Y��ʉr#�C�<�G~�.,! ���bqx���h~0=��!ǫ�jy����l�O,�[B��~��|9��ٱ����Xly�#�i�B��g%�S��������tˋ���e���ې��\[d�t)��.+u�|1 ������#�~Oj����hS�%��i.�~X���I�H�m��0n���c�1uE�q��cF�RF�o���7� �O�ꮧ� ���ۛ{��ʛi5�rw?׌#Qn�TW��~?y$��m\�\o����%W� ?=>S�N@�� �Ʈ���R����N�)�r"C�:��:����� �����#��qb��Y�. �6[��2K����2u�Ǧ�HYR��Q�MV��� �G�$��Q+.>�����nNH��q�^��� ����q��mM��V��D�+�-�#*�U�̒ ���p욳��u:�������IB���m���PV@O���r[b= �� ��1U�E��_Nm�yKbN�O���U�}�the�`�|6֮P>�\2�P�V���I�D�i�P�O;�9�r�mAHG�W�S]��J*�_�G��+kP�2����Ka�Z���H�'K�x�W�MZ%�O�YD�Rc+o��?�q��Ghm��d�S�oh�\�D�|:W������UA�Qc yT�q������~^�H��/��#p�CZ���T�I�1�ӏT����4��"�ČZ�����}��`w�#�*,ʹ�� ��0�i��課�Om�*�da��^gJ݅{���l�e9uF#T�ֲ��̲�ٞC"�q���ߍ ոޑ�o#�XZTp����@ o�8��(jd��xw�]�,f���`~�|,s��^����f�1���t��|��m�򸄭/ctr��5s��7�9Q�4�H1꠲BB@l9@���C�����+�wp�xu�£Yc�9��?`@#�o�mH�s2��)�=��2�.�l����jg�9$�Y�S�%*L������R�Y������7Z���,*=�䷘$�������arm�o�ϰ���UW.|�r�uf����IGw�t����Zwo��~5 ��YյhO+=8fF�)�W�7�L9lM�̘·Y���֘YLf�큹�pRF���99.A �"wz��=E\Z���'a� 2��Ǚ�#;�'}�G���*��l��^"q��+2FQ� hj��kŦ��${���ޮ-�T�٭cf�|�3#~�RJ����t��$b�(R��(����r���dx� >U b�&9,>���%E\� Ά�e�$��'�q't��*�א���ެ�b��-|d���SB�O�O��$�R+�H�)�܎�K��1m`;�J�2�Y~9��O�g8=vqD`K[�F)k�[���1m޼c��n���]s�k�z$@��)!I �x՝"v��9=�ZA=`Ɠi �:�E��)`7��vI��}d�YI�_ �o�:ob���o ���3Q��&D&�2=�� �Ά��;>�h����y.*ⅥS������Ӭ�+q&����j|UƧ����}���J0��WW< ۋS�)jQR�j���Ư��rN)�Gű�4Ѷ(�S)Ǣ�8��i��W52���No˓� ۍ%�5brOn�L�;�n��\G����=�^U�dI���8$�&���h��'���+�(������cȁ߫k�l��S^���cƗjԌE�ꭔ��gF���Ȓ��@���}O���*;e�v�WV���YJ\�]X'5��ղ�k�F��b 6R�o՜m��i N�i����>J����?��lPm�U��}>_Z&�KK��q�r��I�D�Չ~�q�3fL�:S�e>���E���-G���{L�6p�e,8��������QI��h��a�Xa��U�A'���ʂ���s�+טIjP�-��y�8ۈZ?J$��W�P� ��R�s�]��|�l(�ԓ��sƊi��o(��S0��Y� 8�T97.�����WiL��c�~�dxc�E|�2!�X�K�Ƙਫ਼�$((�6�~|d9u+�qd�^3�89��Y�6L�.I�����?���iI�q���9�)O/뚅����O���X��X�V��ZF[�یgQ�L��K1���RҖr@v�#��X�l��F���Нy�S�8�7�kF!A��sM���^rkp�jP�DyS$N���q��nxҍ!U�f�!eh�i�2�m���`�Y�I�9r�6� �TF���C}/�y�^���Η���5d�'��9A-��J��>{�_l+�`��A���[�'��յ�ϛ#w:݅�%��X�}�&�PSt�Q�"�-��\縵�/����$Ɨh�Xb�*�y��BS����;W�ջ_mc�����vt?2}1�;qS�d�d~u:2k5�2�R�~�z+|HE!)�Ǟl��7`��0�<�,�2*���Hl-��x�^����'_TV�gZA�'j� ^�2Ϊ��N7t�����?w�� �x1��f��Iz�C-Ȗ��K�^q�;���-W�DvT�7��8�Z�������� hK�(P:��Q- �8�n�Z���܃e貾�<�1�YT<�,�����"�6{/ �?�͟��|1�:�#g��W�>$����d��J��d�B��=��jf[��%rE^��il:��B���x���Sּ�1հ��,�=��*�7 fcG��#q� �eh?��2�7�����,�!7x��6�n�LC�4x��},Geǝ�tC.��vS �F�43��zz\��;QYC,6����~;RYS/6���|2���5���v��T��i����������mlv��������&� �nRh^ejR�LG�f���? �ۉҬܦƩ��|��Ȱ����>3����!v��i�ʯ�>�v��オ�X3e���_1z�Kȗ\<������!�8���V��]��?b�k41�Re��T�q��mz��TiOʦ�Z��Xq���L������q"+���2ۨ��8}�&N7XU7Ap�d�X��~�׿��&4e�o�F��� �H����O���č�c�� 懴�6���͉��+)��v;j��ݷ�� �UV�� i��� j���Y9GdÒJ1��詞�����V?h��l����l�cGs�ځ�������y�Ac�����\V3�? �� ܙg�>qH�S,�E�W�[�㺨�uch�⍸�O�}���a��>�q�6�n6����N6�q������N ! 1AQaq�0@����"2BRb�#Pr���3C`��Scst���$4D���%Td�� ?���N����a��3��m���C���w��������xA�m�q�m���m������$����4n淿t'��C"w��zU=D�\R+w�p+Y�T�&�պ@��ƃ��3ޯ?�Aﶂ��aŘ���@-�����Q�=���9D��ռ�ѻ@��M�V��P��܅�G5�f�Y<�u=,EC)�<�Fy'�"�&�չ�X~f��l�KԆV��?�� �W�N����=(� �;���{�r����ٌ�Y���h{�١������jW����P���Tc�����X�K�r��}���w�R��%��?���E��m�� �Y�q|����\lEE4���r���}�lsI�Y������f�$�=�d�yO����p�����yBj8jU�o�/�S��?�U��*������ˍ�0������u�q�m [�?f����a�� )Q�>����6#������� ?����0UQ����,IX���(6ڵ[�DI�MNލ�c&���υ�j\��X�R|,4��� j������T�hA�e��^���d���b<����n�� �즇�=!���3�^�`j�h�ȓr��jẕ�c�,ٞX����-����a�ﶔ���#�$��]w�O��Ӫ�1y%��L�Y<�wg#�ǝ�̗`�x�xa�t�w��»1���o7o5��>�m뭛C���Uƃߜ}�C���y1Xνm�F8�jI���]����H���ۺиE@I�i;r�8ӭ����V�F�Շ| ��&?�3|x�B�MuS�Ge�=Ӕ�#BE5G�����Y!z��_e��q�р/W>|-�Ci߇�t�1ޯќd�R3�u��g�=0 5��[?�#͏��q�cf���H��{ ?u�=?�?ǯ���}Z��z���hmΔ�BFTW�����<�q�(v� ��!��z���iW]*�J�V�z��gX֧A�q�&��/w���u�gYӘa���; �i=����g:��?2�dž6�ى�k�4�>�Pxs����}������G�9��3 ���)gG�R<>r h�$��'nc�h�P��Bj��J�ҧH� -��N1���N��?��~��}-q!=��_2hc�M��l�vY%UE�@|�v����M2�.Y[|y�"Eï��K�ZF,�ɯ?,q�?v�M 80jx�"�;�9vk�����+ ֧�� �ȺU��?�%�vcV��mA�6��Qg^M����A}�3�nl� QRN�l8�kkn�'�����(��M�7m9و�q���%ޟ���*h$Zk"��$�9��: �?U8�Sl��,,|ɒ��xH(ѷ����Gn�/Q�4�P��G�%��Ա8�N��!� �&�7�;���eKM7�4��9R/%����l�c>�x;������>��C�:�����t��h?aKX�bhe�ᜋ^�$�Iհ �hr7%F$�E��Fd���t��5���+�(M6�t����Ü�UU|zW�=a�Ts�Tg������dqP�Q����b'�m���1{|Y����X�N��b �P~��F^F:����k6�"�j!�� �I�r�`��1&�-$�Bevk:y���#yw��I0��x��=D�4��tU���P�ZH��ڠ底taP��6����b>�xa����Q�#� WeF��ŮNj�p�J* mQ�N����*I�-*�ȩ�F�g�3 �5��V�ʊ�ɮ�a��5F���O@{���NX��?����H�]3��1�Ri_u��������ѕ�� ����0��� F��~��:60�p�͈�S��qX#a�5>���`�o&+�<2�D����: �������ڝ�$�nP���*)�N�|y�Ej�F�5ټ�e���ihy�Z �>���k�bH�a�v��h�-#���!�Po=@k̆IEN��@��}Ll?j�O������߭�ʞ���Q|A07x���wt!xf���I2?Z��<ץ�T���cU�j��]��陎Ltl �}5�ϓ��$�,��O�mˊ�;�@O��jE��j(�ا,��LX���LO���Ц�90�O �.����a��nA���7������j4 ��W��_ٓ���zW�jcB������y՗+EM�)d���N�g6�y1_x��p�$Lv:��9�"z��p���ʙ$��^��JԼ*�ϭ����o���=x�Lj�6�J��u82�A�H�3$�ٕ@�=Vv�]�'�qEz�;I˼��)��=��ɯ���x �/�W(V���p�����$ �m�������u�����񶤑Oqˎ�T����r��㠚x�sr�GC��byp�G��1ߠ�w e�8�$⿄����/�M{*}��W�]˷.�CK\�ުx���/$�WPw���r� |i���&�}�{�X� �>��$-��l���?-z���g����lΆ���(F���h�vS*���b���߲ڡn,|)mrH[���a�3�ר�[1��3o_�U�3�TC�$��(�=�)0�kgP���� ��u�^=��4 �WYCҸ:��vQ�ר�X�à��tk�m,�t*��^�,�}D*� �"(�I��9R����>`�`��[~Q]�#af��i6l��8���6�:,s�s�N6�j"�A4���IuQ��6E,�GnH��zS�HO�uk�5$�I�4��ؤ�Q9�@��C����wp�BGv[]�u�Ov���0I4���\��y�����Q�Ѹ��~>Z��8�T��a��q�ޣ;z��a���/��S��I:�ܫ_�|������>=Z����8:�S��U�I�J��"IY���8%b8���H��:�QO�6�;7�I�S��J��ҌAά3��>c���E+&jf$eC+�z�;��V����� �r���ʺ������my�e���aQ�f&��6�ND��.:��NT�vm�<- u���ǝ\MvZY�N�NT��-A�>jr!S��n�O 1�3�Ns�%�3D@���`������ܟ 1�^c<���� �a�ɽ�̲�Xë#�w�|y�cW�=�9I*H8�p�^(4���՗�k��arOcW�tO�\�ƍR��8����'�K���I�Q�����?5�>[�}��yU�ײ -h��=��% q�ThG�2�)���"ו3]�!kB��*p�FDl�A���,�eEi�H�f�Ps�����5�H:�Փ~�H�0Dت�D�I����h�F3�������c��2���E��9�H��5�zԑ�ʚ�i�X�=:m�xg�hd(�v����׊�9iS��O��d@0ڽ���:�p�5�h-��t�&���X�q�ӕ,��ie�|���7A�2���O%P��E��htj��Y1��w�Ѓ!����  ���� ࢽ��My�7�\�a�@�ţ�J �4�Ȼ�F�@o�̒?4�wx��)��]�P��~�����u�����5�����7X ��9��^ܩ�U;Iꭆ 5 �������eK2�7(�{|��Y׎ �V��\"���Z�1� Z�����}��(�Ǝ"�1S���_�vE30>���p;� ΝD��%x�W�?W?v����o�^V�i�d��r[��/&>�~`�9Wh��y�;���R��� ;;ɮT��?����r$�g1�K����A��C��c��K��l:�'��3 c�ﳯ*"t8�~l��)���m��+U,z��`(�>yJ�?����h>��]��v��ЍG*�{`��;y]��I�T� ;c��NU�fo¾h���/$���|NS���1�S�"�H��V���T���4��uhǜ�]�v;���5�͠x��'C\�SBpl���h}�N����� A�Bx���%��ޭ�l��/����T��w�ʽ]D�=����K���ž�r㻠l4�S�O?=�k �M:� ��c�C�a�#ha���)�ѐxc�s���gP�iG��{+���x���Q���I= �� z��ԫ+ �8"�k�ñ�j=|����c ��y��CF��/��*9ж�h{ �?4�o� ��k�m�Q�N�x��;�Y��4膚�a�w?�6�>e]�����Q�r�:����g�,i"�����ԩA�*M�<�G��b�if��l^M��5� �Ҩ�{����6J��ZJ�����P�*�����Y���ݛu�_4�9�I8�7���������,^ToR���m4�H��?�N�S�ѕw��/S��甍�@�9H�S�T��t�ƻ���ʒU��*{Xs�@����f�����֒Li�K{H�w^���������Ϥm�tq���s� ���ք��f:��o~s��g�r��ט� �S�ѱC�e]�x���a��) ���(b-$(�j>�7q�B?ӕ�F��hV25r[7 Y� }L�R��}����*sg+��x�r�2�U=�*'WS��ZDW]�WǞ�<��叓���{�$�9Ou4��y�90-�1�'*D`�c�^o?(�9��u���ݐ��'PI&� f�Jݮ�������:wS����jfP1F:X �H�9dԯ���˝[�_54 �}*;@�ܨ�� ð�yn�T���?�ןd�#���4rG�ͨ��H�1�|-#���Mr�S3��G�3�����)�.᧏3v�z֑��r����$G"�`j �1t��x0<Ɔ�Wh6�y�6��,œ�Ga��gA����y��b��)��h�D��ß�_�m��ü �gG;��e�v��ݝ�nQ� ��C����-�*��o���y�a��M��I�>�<���]obD��"�:���G�A��-\%LT�8���c�)��+y76���o�Q�#*{�(F�⽕�y����=���rW�\p���۩�c���A���^e6��K������ʐ�cVf5$�'->���ՉN"���F�"�UQ@�f��Gb~��#�&�M=��8�ט�JNu9��D��[̤�s�o�~������ G��9T�tW^g5y$b��Y'��س�Ǵ�=��U-2 #�MC�t(�i� �lj�@Q 5�̣i�*�O����s�x�K�f��}\��M{E�V�{�υ��Ƈ�����);�H����I��fe�Lȣr�2��>��W�I�Ȃ6������i��k�� �5�YOxȺ����>��Y�f5'��|��H+��98pj�n�.O�y�������jY��~��i�w'������l�;�s�2��Y��:'lg�ꥴ)o#'Sa�a�K��Z� �m��}�`169�n���"���x��I ��*+� }F<��cГ���F�P�������ֹ*�PqX�x۩��,� ��N�� �4<-����%����:��7����W���u�`����� $�?�I��&����o��o��`v�>��P��"��l���4��5'�Z�gE���8���?��[�X�7(��.Q�-��*���ތL@̲����v��.5���[��=�t\+�CNܛ��,g�SQnH����}*F�G16���&:�t��4ُ"A��̣��$�b �|����#rs��a�����T�� ]�<�j��BS�('$�ɻ� �wP;�/�n��?�ݜ��x�F��yUn�~mL*-�������Xf�wd^�a�}��f�,=t�׵i�.2/wpN�Ep8�OР���•��R�FJ� 55TZ��T �ɭ�<��]��/�0�r�@�f��V��V����Nz�G��^���7hZi����k��3�,kN�e|�vg�1{9]_i��X5y7� 8e]�U����'�-2,���e"����]ot�I��Y_��n�(JҼ��1�O ]bXc���Nu�No��pS���Q_���_�?i�~�x h5d'�(qw52] ��'ޤ�q��o1�R!���`ywy�A4u���h<קy���\[~�4�\ X�Wt/� 6�����n�F�a8��f���z �3$�t(���q��q�x��^�XWeN'p<-v�!�{�(>ӽDP7��ո0�y)�e$ٕv�Ih'Q�EA�m*�H��RI��=:��� ���4牢) �%_iN�ݧ�l]� �Nt���G��H�L��� ɱ�g<���1V�,�J~�ٹ�"K��Q�� 9�HS�9�?@��k����r�;we݁�]I�!{ �@�G�[�"��`���J:�n]�{�cA�E����V��ʆ���#��U9�6����j�#Y�m\��q�e4h�B�7��C�������d<�?J����1g:ٳ���=Y���D�p�ц� ׈ǔ��1�]26؜oS�'��9�V�FVu�P�h�9�xc�oq�X��p�o�5��Ա5$�9W�V(�[Ak�aY錎qf;�'�[�|���b�6�Ck��)��#a#a˙��8���=äh�4��2��C��4tm^ �n'c���]GQ$[Wҿ��i���vN�{Fu ��1�gx��1┷���N�m��{j-,��x�� Ūm�ЧS�[�s���Gna���䑴�� x�p 8<������97�Q���ϴ�v�aϚG��Rt�Һ׈�f^\r��WH�JU�7Z���y)�vg=����n��4�_)y��D'y�6�]�c�5̪�\� �PF�k����&�c;��cq�$~T�7j ���nç]�<�g ":�to�t}�159�<�/�8������m�b�K#g'I'.W�����6��I/��>v��\�MN��g���m�A�yQL�4u�Lj�j9��#44�t��l^�}L����n��R��!��t��±]��r��h6ٍ>�yҏ�N��fU�� ���� Fm@�8}�/u��jb9������he:A�y�ծw��GpΧh�5����l}�3p468��)U��d��c����;Us/�֔�YX�1�O2��uq�s��`hwg�r~�{ R��mhN��؎*q 42�*th��>�#���E����#��Hv�O����q�}�����6�e��\�,Wk�#���X��b>��p}�դ��3���T5��†��6��[��@�P�y*n��|'f�֧>�lư΂�̺����SU�'*�q�p�_S�����M�� '��c�6�����m�� ySʨ;M��r���Ƌ�m�Kxo,���Gm�P��A�G�:��i��w�9�}M(�^�V��$ǒ�ѽ�9���|���� �a����J�SQ�a���r�B;����}���ٻ֢�2�%U���c�#�g���N�a�ݕ�'�v�[�OY'��3L�3�;,p�]@�S��{ls��X�'���c�jw�k'a�.��}�}&�� �dP�*�bK=ɍ!����;3n�gΊU�ߴmt�'*{,=SzfD� A��ko~�G�aoq�_mi}#�m�������P�Xhύ����mxǍ�΂���巿zf��Q���c���|kc�����?���W��Y�$���_Lv����l߶��c���`?����l�j�ݲˏ!V��6����U�Ђ(A���4y)H���p�Z_�x��>���e��R��$�/�`^'3qˏ�-&Q�=?��CFVR �D�fV�9��{�8g�������n�h�(P"��6�[�D���< E�����~0<@�`�G�6����Hг�cc�� �c�K.5��D��d�B���`?�XQ��2��ٿyqo&+�1^� DW�0�ꊩ���G�#��Q�nL3��c���������/��x ��1�1[y�x�პCW��C�c�UĨ80�m�e�4.{�m��u���I=��f�����0QRls9���f���������9���~f�����Ǩ��a�"@�8���ȁ�Q����#c�ic������G��$���G���r/$W�(��W���V�"��m�7�[m�A�m����bo��D� j����۳� l���^�k�h׽����� ��#� iXn�v��eT�k�a�^Y�4�BN��ĕ��0 !01@Q"2AaPq3BR������?���@4�Q�����T3,���㺠�W�[=JK�Ϟ���2�r^7��vc�:�9 �E�ߴ�w�S#d���Ix��u��:��Hp��9E!�� V 2;73|F��9Y���*ʬ�F��D����u&���y؟��^EA��A��(ɩ���^��GV:ݜDy�`��Jr29ܾ�㝉��[���E;Fzx��YG��U�e�Y�C���� ����v-tx����I�sם�Ę�q��Eb�+P\ :>�i�C'�;�����k|z�رn�y]�#ǿb��Q��������w�����(�r|ӹs��[�D��2v-%��@;�8<a���[\o[ϧw��I!��*0�krs)�[�J9^��ʜ��p1)� "��/_>��o��<1����A�E�y^�C��`�x1'ܣn�p��s`l���fQ��):�l����b>�Me�jH^?�kl3(�z:���1ŠK&?Q�~�{�ٺ�h�y���/�[��V�|6��}�KbX����mn[-��7�5q�94�������dm���c^���h� X��5��<�eޘ>G���-�}�دB�ޟ� ��|�rt�M��V+�]�c?�-#ڛ��^ǂ}���Lkr���O��u�>�-D�ry� D?:ޞ�U��ǜ�7�V��?瓮�"�#���r��չģVR;�n���/_� ؉v�ݶe5d�b9��/O��009�G���5n�W����JpA�*�r9�>�1��.[t���s�F���nQ� V 77R�]�ɫ8����_0<՜�IF�u(v��4��F�k�3��E)��N:��yڮe��P�`�1}�$WS��J�SQ�N�j�ٺ��޵�#l���ј(�5=��5�lǏmoW�v-�1����v,W�mn��߀$x�<����v�j(����c]��@#��1������Ǔ���o'��u+����;G�#�޸��v-lη��/(`i⣍Pm^���ԯ̾9Z��F��������n��1��� ��]�[��)�'������:�֪�W��FC����� �B9،!?���]��V��A�Վ�M��b�w��G F>_DȬ0¤�#�QR�[V��kz���m�w�"��9ZG�7'[��=�Q����j8R?�zf�\a�=��O�U����*oB�A�|G���2�54 �p��.w7� �� ��&������ξxGHp� B%��$g�����t�Џ򤵍z���HN�u�Я�-�'4��0��;_��3 !01"@AQa2Pq#3BR������?��ʩca��en��^��8���<�u#��m*08r��y�N"�<�Ѳ0��@\�p��� �����Kv�D��J8�Fҽ� �f�Y��-m�ybX�NP����}�!*8t(�OqѢ��Q�wW�K��ZD��Δ^e��!� ��B�K��p~�����e*l}z#9ң�k���q#�Ft�o��S�R����-�w�!�S���Ӥß|M�l޶V��!eˈ�8Y���c�ЮM2��tk���� ������J�fS����Ö*i/2�����n]�k�\���|4yX�8��U�P.���Ы[���l��@"�t�<������5�lF���vU�����W��W��;�b�cД^6[#7@vU�xgZv��F�6��Q,K�v��� �+Ъ��n��Ǣ��Ft���8��0��c�@�!�Zq s�v�t�;#](B��-�nῃ~���3g������5�J�%���O������n�kB�ĺ�.r��+���#�N$?�q�/�s�6��p��a����a��J/��M�8��6�ܰ"�*������ɗud"\w���aT(����[��F��U՛����RT�b���n�*��6���O��SJ�.�ij<�v�MT��R\c��5l�sZB>F��<7�;EA��{��E���Ö��1U/�#��d1�a�n.1ě����0�ʾR�h��|�R��Ao�3�m3 ��%�� ���28Q� ��y��φ���H�To�7�lW>����#i`�q���c����a��� �m,B�-j����݋�'mR1Ήt�>��V��p���s�0IbI�C.���1R�ea�����]H�6����������4B>��o��](��$B���m�����a�!=��?�B� K�Ǿ+�Ծ"�n���K��*��+��[T#�{E�J�S����Q�����s�5�:�U�\wĐ�f�3����܆&�)����I���Ԇw��E T�lrTf6Q|R�h:��[K�� �z��c֧�G�C��%\��_�a�84��HcO�bi��ؖV��7H �)*ģK~Xhչ0��4?�0��� �E<���}3���#���u�?�� ��|g�S�6ꊤ�|�I#Hڛ� �ա��w�X��9��7���Ŀ%�SL��y6č��|�F�a 8���b��$�sק�h���b9RAu7�˨p�Č�_\*w��묦��F ����4D~�f����|(�"m���NK��i�S�>�$d7SlA��/�²����SL��|6N�}���S�˯���g��]6��; �#�.��<���q'Q�1|KQ$�����񛩶"�$r�b:���N8�w@��8$�� �AjfG|~�9F ���Y��ʺ��Bwؒ������M:I岎�G��`s�YV5����6��A �b:�W���G�q%l�����F��H���7�������Fsv7��k�� 403WebShell
403Webshell
Server IP : 14.139.229.36  /  Your IP : 10.1.1.9
Web Server : Apache
System : Linux gbpuat-tech.ac.in 4.18.0-240.15.1.el8_3.x86_64 #1 SMP Mon Mar 1 17:16:16 UTC 2021 x86_64
User : apache ( 48)
PHP Version : 7.2.24
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /proc/self/root/usr/share/doc/brlapi/Manual-BrlAPI/English/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/self/root/usr/share/doc/brlapi/Manual-BrlAPI/English/BrlAPI.txt
  BrlAPI Reference manual
  Sébastien Hinderer <Sebastien.Hinderer@ens-lyon.org>
  Samuel Thibault <Samuel.Thibault@ens-lyon.org>
  V1.4, December 2006

  This document describes BrlAPI.
  ______________________________________________________________________

  Table of Contents


  1. Introduction
     1.1 Concepts
     1.2 How to read this manual

  2. General description of BrlAPI
     2.1 Historical notes.
     2.2 Why BrlAPI is part of brltty .
     2.3 How it works.
        2.3.1 Connection.
        2.3.2 Authorization.
        2.3.3 Real use of the braille terminal.
           2.3.3.1 Braille display and braille key presses processing.
           2.3.3.2 Raw mode.
           2.3.3.3 Suspend Mode.
           2.3.3.4 Remarks.
        2.3.4 Disconnection.

  3. Concurrency management between BrlAPI clients
     3.1 VT switching
     3.2 A pile of "paper sheets"
     3.3 Hierarchy
     3.4 The X-window case
     3.5 Detaching

  4. Installation and configuration of BrlAPI
  5. Library description
     5.1 Connecting to BrlAPI
     5.2 Getting driver name
     5.3 Getting display size
     5.4 Entering raw mode, immediately leaving raw mode.
     5.5 Getting tty control
     5.6 Writing something on the display
     5.7 Waiting for a key press
     5.8 Understanding commands
     5.9 Leaving tty control
     5.10 Disconnecting from BrlAPI
     5.11 Putting everything together...

  6. Writing ( BrlAPI -compliant) drivers for brltty
     6.1 Overview of the driver's structure
     6.2 Basic driver structure
     6.3 Enhancements for BrlAPI
        6.3.1 Reading braille key codes
           6.3.1.1 Remarks
        6.3.2 Exchanging raw data packets
           6.3.2.1 Remarks.

  7. Protocol reference
     7.1 Reliable packet transmission channel
     7.2 Responses from the server
     7.3 Operating modes
     7.4 Details for each type of packet
        7.4.1 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
              BRLAPI_ERROR_PROTOCOL_VERSION error packet is returned and
              the connection is closed.
        7.4.2 BRLAPI_PACKET_AUTH
        7.4.3 BRLAPI_PACKET_GETDRIVERNAME (see brlapi_getDriverName() )
        7.4.4 BRLAPI_PACKET_GETMODELID (see brlapi_getModelIdentifier() )
        7.4.5 BRLAPI_PACKET_GETDISPLAYSIZE (see brlapi_getDisplaySize() )
        7.4.6 BRLAPI_PACKET_ENTERTTYMODE (see brlapi_enterTtyMode() and
              brlapi_enterTtyModeWithPath() )
        7.4.7 BRLAPI_PACKET_KEY (see brlapi_readKey() )
        7.4.8 BRLAPI_PACKET_SETFOCUS (see brlapi_setFocus() )
        7.4.9 BRLAPI_PACKET_LEAVETTYMODE (see brlapi_leaveTtyMode() )
        7.4.10 BRLAPI_PACKET_IGNOREKEYRANGE and
               BRLAPI_PACKET_ACCEPTKEYRANGE (see brlapi_ignoreKeyRange()
               and brlapi_acceptKeyRange() )
        7.4.11 BRLAPI_PACKET_WRITE (see brlapi_write() )
        7.4.12 BRLAPI_PACKET_ENTERRAWMODE (see brlapi_enterRawMode() )
        7.4.13 BRLAPI_PACKET_LEAVERAWMODE (see brlapi_leaveRawMode() )
        7.4.14 BRLAPI_PACKET_PACKET (see brlapi_sendRaw() and
               brlapi_recvRaw() )
        7.4.15 BRLAPI_PACKET_SUSPENDDRIVER (see brlapi_suspendDriver() )


  ______________________________________________________________________

  1.  Introduction

  BrlAPI is a service provided by the 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 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 brltty.

  1.1.  Concepts

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


     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.

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

     Braille keyboard
        The keyboard of the braille terminal.

     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.

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

     Client
        An application designed to handle a braille terminal thanks to
        BrlAPI.

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

     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.

     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 brltty), whereas codes used for returning
        keypresses may vary between drivers.

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

     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.

     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.

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

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

     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.


  1.2.  How to read this manual

  This manual is split in five parts.


     ``General description''
        Describes more precisely what BrlAPI is and how it works in
        collaboration with 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
        BrlAPI does in reaction to client instructions. These
        explanations will take place at a user level.

     ``Concurrency management''
        This part explains how concurrency between BrlAPI clients is
        handled thanks to focus tellers.

     ``Installation and configuration''
        This part explains in detail how to install and configure the
        API. For instructions on how to install and configure brltty,
        please report to the brltty documentation.

     ``Library description''
        This part describes how client applications can communicate with
        the server using the BrlAPI library that comes with brltty. Each
        function will be briefly described, classified by categories.
        More exhaustive descriptions of every function are available in
        the corresponding online manual pages.

     ``Writing braille drivers''
        This part describes how the braille drivers included in brltty
        should be written in order to take advantage of BrlAPI's
        services.

     ``Protocol reference''
        This part describes in detail the communication protocol that is
        used to communicate between server and clients.


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

  Reading chapters ``General description'', ``Concurrency management''
  and ``Installation and configuration'' is recommended, since they
  provide useful information and (hopefully) lead to a good
  understanding of BrlAPI, for an efficient use.

  Chapter ``Library description'' concerns writing applications that
  take advantage of braille terminals so as to bring specific (and more
  useful) information to blind people.

  Chapter ``Drivers'' is for braille driver implementation: either
  adding a braille driver to brltty or modifying an existing one so that
  it can benefit from BrlAPI's features, this chapter will be of
  interest, since it describes exactly what is needed to write a driver
  for brltty: the core of drivers interface for instance.

  Finally, chapter ``Protocol reference'' is for not using the library,
  but using the BrlAPI server directly, when the library might not be
  sufficient: it describes the underlying protocol that will have to be
  used to do so.

  2.  General description of BrlAPI

  Here is explained what 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 BrlAPI's functionalities, please see
  chapter ``Libary description''.

  2.1.  Historical notes.

  Originally, 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 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).

  2.2.  Why BrlAPI is part of brltty .

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

  On the one hand, integration to brltty allows us to use the increasing
  number of drivers written for 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,
  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 brltty and client applications possible, it
  seemed easier to add the communication mechanisms to brltty's core,
  instead of writing an external program providing them.

  2.3.  How it works.

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

  2.3.1.  Connection.

  The first thing any client application has to do is to connect (in the
  Unix sense of the word) to 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 brltty's side.

  2.3.2.  Authorization.

  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 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, 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 BrlAPI.  To see how to do that, please see chapter
  ``Installation and configuration''.

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

  2.3.3.  Real use of the braille terminal.

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

  2.3.3.1.  Braille display and braille key presses processing.

  If the client wants to display something on the braille display or to
  process braille keys itself, rather than letting 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, BrlAPI will
  completely discard 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, 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
  brltty command. If it is not, the key code is converted into a brltty
  command and returned to 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 brltty
  can continue its job, or another client can take control of it.

  2.3.3.2.  Raw mode.

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

  2.3.3.3.  Suspend Mode.

  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.

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

  2.3.3.4.  Remarks.


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

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

  ·  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 BrlAPI before each operation.

  2.3.4.  Disconnection.

  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.

  3.  Concurrency management between BrlAPI clients

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

  3.1.  VT switching

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

  As described in ``General Description'', before being able to write
  output, a BrlAPI client has to "get" a tty, i.e. it sends to the
  BrlAPI server the number of the linux' Virtual Tty on which it is
  running.  The 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.

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

  Let's say VT 1 is active, then the BrlAPI server shows brltty's output
  on the braille display. I.e. the usual brltty screen reading appears.
  Moreover, when braille keys are pressed, they are passed to brltty, so
  that usual screen reading can be performed. When the user switches to
  VT 2, brltty (as focus teller) tells it to the BrlAPI server, which
  then remembers that client A has got it and has produced some output.
  The server then displays this output on the braille display. Note that
  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, BrlAPI looks
  whether it is in the list of keys that client A said to be of his
  interest. If it is, it is passed to A (and not to brltty). If it
  isn't, it is passed to brltty (and not to A).

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

  3.2.  A pile of "paper sheets"

  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. brltty is
  represented by the bottom sheet on which its screen reading is
  written, and client A by the top sheet on which its output is written.
  A's sheet hence "covers" brltty's sheet: A's output "mask" brltty's
  screen reading.

  A may yet want to temporarily let 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, brltty's output is automatically
  shown (by transparency in the sheet representation), just like if A
  had released the Tty.

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

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

  The sheet order is determined by the Tty "get"ting order. Some
  mecanism will be added in near future for clients to precise "at which
  level its sheet should be inserted" so as to avoid race conditions on
  the "get"ting order.

  3.3.  Hierarchy

  Now, what happens when running some 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 screen
  window is active. This hence forms a tree of Ttys: the "root" being
  the vga driver's output, whose sons are VTs, and VT 3 has the screen
  windows as sons. Brltty is a focus teller for the root, screen will
  have to be a focus teller for VT 3.  Screen should then get VT 3, not
  display anything (so that the usual brltty screen reading will be
  shown by transparency), and tell the BrlAPI server which screen window
  is active (at startup and at each window switch). This is not
  implemented directly in screen yet, but this may be achieved via a
  second brltty daemon running the Screen driver (but it isn't yet able
  to get the current window number though) and the BrlAPI driver.

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

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

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

  3.4.  The X-window case

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

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

  Screen readers are not bound to a particular window, so they should
  call brlapi_enterTtyModeWithPath(NULL, 0) to let the BrlAPI library
  only send the content of WINDOWPATH, expressing that screen readers
  take the whole tty. The user should notably launch xbrlapi, which is a
  focus teller for X-window as well as a keyboard simulator (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 brltty daemon
  running the at-spi screen driver and the BrlAPI driver can also be
  launched. All three would get the VT of the X session, in that order
  (for now): xbrlapi first, then orca and brltty at last. When the X
  focus is on an AT-SPI terminal, brltty will hence be able to grab the
  braille display and key presses. Else orca would get them. And xbrlapi
  would finally get remaining key presses and simulate them.

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

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

  3.5.  Detaching

  Several programs allow detaching: screen and VNC for instance. In such
  situation, an intermediate 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
  BrlAPI server. This intermediate server is yet to be written (but it
  is actually relatively close to be).

  4.  Installation and configuration of BrlAPI

  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:



       ______________________________________________________________________
       # addgroup brlapi
       # chgrp brlapi /etc/brlapi.key
       # chmod g+r /etc/brlapi.key
       # addgroup user1 brlapi
       # addgroup user2 brlapi
       ...
       ______________________________________________________________________



  5.  Library description

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

  The historical test program for BrlAPI was something like:

  ·  connect to BrlAPI

  ·  get driver id

  ·  get driver name

  ·  get display size

  ·  try entering raw mode, immediately leave raw mode.

  ·  get tty control

  ·  write something on the display

  ·  wait for a key press

  ·  leave tty control

  ·  disconnect from BrlAPI

  It is here rewritten, its working briefly explained.

  5.1.  Connecting to BrlAPI

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



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



  The connection might fail, so testing is needed.

  5.2.  Getting driver name

  Knowing the type of the braille device might be useful:



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



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

  5.3.  Getting display size

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



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



  5.4.  Entering raw mode, immediately leaving raw mode.

  Entering raw mode is very simple:



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



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

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

  5.5.  Getting tty control

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



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



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

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

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

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

  5.6.  Writing something on the display

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



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



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

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

  5.7.  Waiting for a key press

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



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



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

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

  5.8.  Understanding commands

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



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



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



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



  Eventually, named equivalents are provided:



       ______________________________________________________________________
        brlapi_describedKeyCode_t dkey;
        int i;

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



  5.9.  Leaving tty control

  Let's now leave the tty:



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



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

  5.10.  Disconnecting from BrlAPI

  Let's disconnect from BrlAPI:



       ______________________________________________________________________
        brlapi_closeConnection();
       ______________________________________________________________________



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

  5.11.  Putting everything together...



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

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

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

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

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

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

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

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

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

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

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

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

        } else brlapi_perror("brlapi_writeText");

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

        } else brlapi_perror("brlapi_enterTtyMode");

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



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

  6.  Writing ( BrlAPI -compliant) drivers for brltty

  In this chapter, we will describe in details how to write a driver for
  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.

  6.1.  Overview of the driver's structure

  A braille driver is in fact a library that is either dynamically
  loaded by brltty at startup, or statically linked to it during the
  compilation, depending on the options given to the ./configure 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 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.

  6.2.  Basic driver structure

  Every brltty driver must 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


      #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) { ... }



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


      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;



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

  The 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 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 tty
  argument, and to configure the associated communication port. The
  parameters argument contains parameters passed to the driver with the
  -B command-line option. It's up to the driver's author to decide
  wether 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 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 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 brl_writeStatus() function is very similar to brl_writeWindow().
  The only difference is that whereas brl_writeWindow() writes on the
  main braille display, brl_writeStatus() writes on an auxiliary braille
  display, which occasionaly appears on some braille terminals. The
  remarks that have been done concerning optimizations for refreshing
  the display still apply here.

  The 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 brltty's core, which in turn will process them.  The
  first argument, of type BrailleDisplay, is for future use, and can
  safely be ignored for the moment. The second argument indicates in
  which context (state) brltty is. For instance, it specifies if 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 brltty. For a complete list of
  available command codes, please have a look at brl.h in the Programs
  subdirectory. Two codes have special meanings:


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

     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.


  6.3.  Enhancements for BrlAPI

  To improve the level of service provided to client applications
  communicating with braille drivers through 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 BrlAPI:


  ·  reading braille terminal specific key codes,

  ·  exchanging raw data packets between the braille terminal and a
     client application running on the PC.

  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
  ``Introduction'' and ``General description''.

  6.3.1.  Reading braille key codes

  When a client takes control of a tty and asks for getting raw key
  codes, it has, like in command mode, the possibility to mask some
  keys. The masked keys will then be passed to brltty. This assumes the
  existence of a conversion mechanism from key codes to brltty commands.
  This conversion mechanism can only be implemented by the braille
  driver, since it is the only piece of code that knows about braille
  terminal specific key codes. So, to make it possible for client
  applications to read raw key codes, the driver has to define the
  following macro:

  #define BRL_HAVE_KEY_CODES


  and the following functions:

  static int brl_readKey(BrailleDisplay *)
  int brl_keyToCommand(BrailleDisplay *brl, DriverCommandContext caller, int code)



  The semantics of brl_readKey() is very similar to brl_readCommand()'s,
  with one essential difference: a key code is not context-dependant, so
  no context argument needs to be given to this function. Moreover, the
  code this function returns is driver-specific, and has to be properly
  defined by the driver's author so that client applications can rely on
  it.

  The brl_keyToCommand() function's purpose is to convert a key code as
  delivered by brl_readKey() into a brltty command. As explained above,
  this function is called by brlapi when a key is pressed on the braille
  keyboard that is ignored by the client application. The corresponding
  command is then returned to brltty.

  6.3.1.1.  Remarks

  When these two functions are present, the only thing brl_readCommand()
  has to do is to call brl_readKey() and then call brl_keyToCommand()
  with the value returned by the first function as argument.

  6.3.2.  Exchanging raw data packets

  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:


  #define BRL_HAVE_PACKET_IO



  The prototypes of the functions the driver should define are:


  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)



  brl_writePacket() sends a packet of size bytes, stored at 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.

  brl_readPacket() reads a packet of at most 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.

  brl_rescue() is called by 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.

  6.3.2.1.  Remarks.


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

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

  7.  Protocol reference

  Under some circumstances, it may be preferable to communicate directly
  with BrlAPI's server rather than using 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.

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

  7.1.  Reliable packet transmission channel

  The protocol between 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 BrlAPI
  needs a reliable packet transmission channel.

  To achieve this, BrlAPI uses a TCP-based connection, on which packets
  are transmitted this way:


  ·  the size in bytes of the packet is transmitted first as an integer,

  ·  then the type of the packet, as an integer,

  ·  and finally the packet data.

  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 BRLAPI_PACKET_* constants defined in
  api_protocol.h. Each type of packet will be further discussed below.

  BrlAPI's library ships two functions to achieve packets sending and
  receiving using this protocol: brlapi_writePacket and
  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.

  7.2.  Responses from the server

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


  ·  a BRLAPI_PACKET_ACK packet, with no data, which means the operation
     corresponding to the received packet was successful,

  ·  or a BRLAPI_PACKET_ERROR packet, the data being an integer which
     should be one of BRLAPI_ERROR_* constants. This means the operation
     corresponding to the received packet failed.

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


  ·  a packet of the same type, its data being the response,

  ·  or a BRLAPI_PACKET_ERROR packet.

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

  7.3.  Operating modes

  The connection between the client and the server can be in either of
  the four following modes:


  ·  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 BRLAPI_PACKET_VERSION packet that announces the
     server version. The client must send back a BRLAPI_PACKET_VERSION
     for announcing its own version too.  The server then sends a
     BRLAPI_PACKET_AUTH packet that announces which authorization
     methods are allowed. The client can then send BRLAPI_PACKET_AUTH
     packets, which makes the connection enter normal mode.  If no
     authorization is needed, the server can announce the NONE method,
     the client then doesn't need to send a BRLAPI_PACKET_AUTH packet.



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

     ·  BRLAPI_PACKET_GETDRIVERNAME or BRLAPI_PACKET_GETDISPLAYSIZE to
        get pieces of information from the server,

     ·  BRLAPI_PACKET_ENTERTTYMODE to enter tty handling mode,

     ·  BRLAPI_PACKET_ENTERRAWMODE to enter raw mode,



  ·  tty handling mode: the client holds the control of a tty: 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:

     ·  BRLAPI_PACKET_ENTERTYMODE to switch to another tty, but how key
        presses should be sent mustn't change,

     ·  BRLAPI_PACKET_LEAVETTYMODE to leave tty handling mode and go
        back to normal mode,

     ·  BRLAPI_PACKET_IGNOREKEYRANGE and BRLAPI_PACKET_ACCEPTKEYRANGE to
        mask and unmask keys,

     ·  BRLAPI_PACKET_WRITE to display text on this tty,

     ·  BRLAPI_PACKET_ENTERRAWMODE to enter raw mode,

     ·  BRLAPI_PACKET_GETDRIVERNAME or BRLAPI_PACKET_GETDISPLAYSIZE to
        get pieces of information from the server,

     And the server might send BRLAPI_PACKET_KEY packets to signal key
     presses.


  ·  raw mode: the client wants to exchange packets directly with the
     braille terminal. Only these types of packet will be accepted.

     ·  BRLAPI_PACKET_LEAVERAWMODE to get back to previous mode, either
        normal or tty handling mode.

     ·  BRLAPI_PACKET_PACKET to send a packet to the braille terminal.

     And the server might send BRLAPI_PACKET_PACKET packets to give
     received packets from the terminal to the client.

  ·  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 BRLAPI_PACKET_RESUME

  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.

  7.4.  Details for each type of packet

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

  7.4.1.  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
  BRLAPI_ERROR_PROTOCOL_VERSION error packet is returned and the connec-
  tion is closed.

  7.4.2.  BRLAPI_PACKET_AUTH

  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 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
  BRLAPI_PACKET_AUTH shouldn't be sent by the client.

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

  Authorization methods are as follow:


  ·  NONE: the client doesn't need to send an authorization packet.

  ·  KEY: data holds a secret key, the authorization is successful only
     if the key matches the server secret key.

  ·  CREDENTIALS: Operating-System-specific credentials are explicitely
     sent over the socket, the authorization is successful if the server
     considers the credentials sufficient.

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

  7.4.3.  BRLAPI_PACKET_GETDRIVERNAME (see brlapi_getDriverName() )

  This should be sent by the client when it needs the full name of the
  current brltty driver. The returned string is \0 terminated.

  7.4.4.  BRLAPI_PACKET_GETMODELID (see brlapi_getModelIdentifier() )

  This should be sent by the client when it needs to identify which
  model of braille display is currently used by brltty.  The returned
  string is \0 terminated.

  7.4.5.  BRLAPI_PACKET_GETDISPLAYSIZE (see brlapi_getDisplaySize() )

  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.

  7.4.6.  BRLAPI_PACKET_ENTERTTYMODE (see brlapi_enterTtyMode() and
  brlapi_enterTtyModeWithPath() )

  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. Finaly, how key presses
  should be reported is sent: either a driver name or "", preceded by
  the number of caracters in the driver name (0 in the case of ""), as
  an unsigned byte. This packet is then acknowledged by the server.

  7.4.7.  BRLAPI_PACKET_KEY (see brlapi_readKey() )

  As soon as the client gets a tty, it must be prepared to handle
  BRLAPI_PACKET_KEY incoming packets at any time (as soon as the key was
  pressed on the braille terminal, hopefuly).  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 BRLAPI_PACKET_ENTERTTYMODE
  packet.

  7.4.8.  BRLAPI_PACKET_SETFOCUS (see brlapi_setFocus() )

  For the server to know which tty is active, one particular client is
  responsible for sending 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 xbrlapi client would have sent a
  BRLAPI_PACKET_ENTERTTYMODE(7) and will send window IDs whenever X
  focus changes, allowing display and keypresses switching between
  xterms.

  7.4.9.  BRLAPI_PACKET_LEAVETTYMODE (see brlapi_leaveTtyMode() )

  This should be sent to free the tty and masked keys lists.  This is
  acknowledged by the server.

  7.4.10.  BRLAPI_PACKET_IGNOREKEYRANGE and BRLAPI_PACKET_ACCEPTKEYRANGE
  (see brlapi_ignoreKeyRange() and brlapi_acceptKeyRange() )

  If the client doesn't want every key press to be signaled to it, but
  some of them to be given to brltty for normal processing, it can send
  BRLAPI_PACKET_IGNOREKEYRANGE packets to tell ranges of key codes which
  shouldn't be sent to it, but given to brltty, and
  BRLAPI_PACKET_ACCEPTKEYRANGE packets to tell ranges of key codes which
  should be sent to it, and not given to brltty. The server keeps a
  dynamic list of ranges, so that arbitrary sequences of such packets
  can be sent.  For ranges, Data are 2 pairs of integers: the lower and
  the upper boundaries; lower and upper must be equal to tell one key,
  for instance.  For Sets, Data simply consists of pairs of integers,
  one per key in the set.

  7.4.11.  BRLAPI_PACKET_WRITE (see brlapi_write() )

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


  ·  A display number can be given as a integer, in case the braille
     display has several. If not given, usual display is used.

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

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

  ·  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 i+1 is set if bit i is
     set. This also corresponds to the low-order byte of the coding of
     unicode's braille row U+2800.

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

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

  ·  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 character, be it a combining or a
     double-width character.

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

  7.4.12.  BRLAPI_PACKET_ENTERRAWMODE (see brlapi_enterRawMode() )

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

  7.4.13.  BRLAPI_PACKET_LEAVERAWMODE (see brlapi_leaveRawMode() )

  To leave raw mode, the client must send a BRLAPI_PACKET_LEAVERAWMODE
  packet, which is acknowledged.

  7.4.14.  BRLAPI_PACKET_PACKET (see brlapi_sendRaw() and
  brlapi_recvRaw() )

  While in raw mode, only 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 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.

  7.4.15.  BRLAPI_PACKET_SUSPENDDRIVER (see brlapi_suspendDriver() )

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




Youez - 2016 - github.com/yon3zu
LinuXploit