1/* bd-tsi.c, TSI specific key bindings and display commands 2 * 3 * dotscreen 4 * A braille interface to unix tty terminals 5 * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu 6 * Bill Barry barryb@dots.physics.orst.edu 7 * 8 * Copyright (c) 1995 by Science Access Project, Oregon State University. 9 * 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2, or (at your option) 14 * any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program (see the file COPYING); if not, write to the 23 * Free Software Foundation, Inc., 24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 25 * 26 **************************************************************** 27 */ 28 29#include "config.h" 30#include "screen.h" 31#include "extern.h" 32#include "braille.h" 33 34#ifdef HAVE_BRAILLE 35 36extern struct display *display; 37 38struct key2rc { 39 int key; 40 int nr; 41 char *arg1; 42 char *arg2; 43}; 44 45 46static int tsi_ctype = 1; /* cursor type, 0,1,2 */ 47 48static int tsi_line_type; /* indicates number of cells on powerbraille 49 display 01=20 cells 02=40 cells 03=80 cells */ 50 51static int display_status_tsi __P((void)); 52static int write_line_tsi __P((char *, int, int)); 53static void buttonpress_tsi __P((struct key2rc *)); 54static void buttonpress_navigator_40 __P((void)); 55static void buttonpress_powerbraille_40 __P((void)); 56static void buttonpress_powerbraille_80 __P((void)); 57 58int 59bd_init_powerbraille_40() 60{ 61 bd.write_line_braille = write_line_tsi; 62 bd.buttonpress = buttonpress_powerbraille_40; 63 bd.bd_response_test = display_status_tsi; 64 bd.bd_ncells = 40; 65 tsi_line_type = 2; 66 return 0; 67} 68 69int 70bd_init_powerbraille_80() 71{ 72 bd.write_line_braille = write_line_tsi; 73 bd.buttonpress = buttonpress_powerbraille_80; 74 bd.bd_response_test = display_status_tsi; 75 bd.bd_ncells = 80; 76 tsi_line_type = 3; 77 return 0; 78} 79 80int 81bd_init_navigator_40() 82{ 83 bd.write_line_braille = write_line_tsi; 84 bd.buttonpress = buttonpress_navigator_40; 85 bd.bd_response_test = display_status_tsi; 86 bd.bd_ncells = 40; 87 tsi_line_type = 2; 88 return 0; 89} 90 91static int 92display_status_tsi() 93{ 94 char obuf[3],ibuf[20]; 95 int r; 96 97 obuf[0] = 0xff; 98 obuf[1] = 0xff; 99 obuf[2] = 0x0a; 100 r = read(bd.bd_fd, ibuf, 20); /* flush the input port */ 101 r = write(bd.bd_fd, obuf, 3); 102 if (r != 3) 103 return -1; 104 105 /* we have written to the display asking for a response 106 we wait 1 second for the response, read it and if no 107 response we wait 2 seconds, if still no response, 108 return -1 to indicate no braille display available */ 109 sleep(1); 110 r = read(bd.bd_fd, ibuf, 2); 111 if (r == -1) 112 { 113 sleep(2); 114 r = read(bd.bd_fd, ibuf, 2); 115 } 116 debug2("first chars from braille display %d %d\n",ibuf[0],ibuf[1]); 117 if (r != 2 || ibuf[0] != 0 || ibuf[1] != 5) 118 return -1; 119 120 r= read(bd.bd_fd,ibuf,2); 121 if (r != 2) 122 return -1; 123 debug2("braille display size:%d dots:%d\n", ibuf[0], ibuf[1]); 124 bd.bd_ncells = (unsigned char)ibuf[0]; 125 if (bd.bd_ncells <= 1) 126 return -1; 127 r = read(bd.bd_fd,ibuf,1); 128 if (r != 1) 129 return -1; 130 if (r != -1) 131 if (ibuf[0] == 'V') 132 r = read(bd.bd_fd, ibuf, 3); 133 else 134 r = read(bd.bd_fd, ibuf + 1, 2) + 1; 135 if (r != 3) 136 return -1; 137 ibuf[3] = 0; 138 debug1("braille display version %s\n", ibuf); 139 bd.bd_version = atof(ibuf); 140 return 0; 141} 142 143 144static int 145write_line_tsi (bstr,line_length, cursor_pos) 146char *bstr; 147int line_length, cursor_pos; 148{ 149 int obp, i; 150 bd.bd_obuf[0] = 0xff; 151 bd.bd_obuf[1] = 0xff; 152 bd.bd_obuf[2] = tsi_line_type; 153 bd.bd_obuf[3] = 0x07; 154 bd.bd_obuf[4] = cursor_pos; 155 bd.bd_obuf[5] = tsi_ctype; 156 obp=6; 157 158 for (i=0; i < line_length; i++) 159 { 160 bd.bd_obuf[2*i+obp] = 0; 161 bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)(unsigned char)bstr[i]]; 162 } 163 for (i=line_length; i < bd.bd_ncells; i++) 164 { 165 bd.bd_obuf[2*i+obp] = 0; 166 bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)' ']; 167 } 168 169 bd.bd_obuflen = 2*bd.bd_ncells + obp ; 170 return 0; 171} 172 173static struct key2rc keys_navigator_40[] = { 174 {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ 175 {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ 176 {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ 177 {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ 178 {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ 179 {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ 180 {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ 181 {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ 182 {0x6000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */ 183 {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ 184 {0x12000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */ 185 {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ 186 {0xa000, RC_BD_INFO, "1032", 0}, /* bc 6, 8 */ 187 {0x14000000, RC_BD_INFO, "2301", 0}, /* sc 1, 3 */ 188 {0x4008000, RC_BD_INFO, "3330", 0}, /* bc+sc 1, 8 */ 189 {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ 190 {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */ 191 {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ 192 {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ 193 {0x10002000, RC_BD_SCROLL, 0, 0}, /* 3, 6 */ 194 {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ 195 {0x14000, RC_BD_SKIP, 0, 0}, /* 7, 9*/ 196 {-1, RC_ILLEGAL, 0, 0} 197}; 198 199static struct key2rc keys_powerbraille_40[] = { 200 {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ 201 {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ 202 {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ 203 {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ 204 {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ 205 {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ 206 {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ 207 {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ 208 {0x8002000, RC_BD_UPPER_LEFT, 0, 0}, /* 2, 6 */ 209 {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ 210 {0x20002000, RC_BD_LOWER_LEFT, 0, 0}, /* 3, 6 */ 211 {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ 212 {0x8008000, RC_BD_INFO, "1032", 0}, /* bc 2, 8 */ 213 {0x6000, RC_BD_INFO, "2301", 0}, /* 6, 7 */ 214 {0x8004000, RC_BD_INFO, "3330", 0}, /* bc+sc 2, 7 */ 215 {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ 216 {0x20008000, RC_BD_EIGHTDOT, 0, 0}, /* 4, 6 */ 217 {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ 218 {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ 219 {0xa000, RC_BD_SCROLL, 0, 0}, /* 6, 8 */ 220 {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ 221 {0x20004000, RC_BD_SKIP, 0, 0}, /* 4, 7 */ 222 {-1, RC_ILLEGAL, 0, 0} 223}; 224 225 226static struct key2rc keys_powerbraille_80[] = { 227 {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */ 228 {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */ 229 {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */ 230 {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */ 231 {0x40000, RC_BD_BC_LEFT, 0, 0}, /* 6 */ 232 {0x100000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */ 233 {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */ 234 {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */ 235 {0x44000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */ 236 {0x104000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */ 237 {0x50000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */ 238 {0x110000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */ 239 {0x8100000, RC_BD_INFO, "1032", 0}, /* 2, 8 */ 240 {0x8040000, RC_BD_INFO, "2301", 0}, /* 2, 6 */ 241 {0x140000, RC_BD_INFO, "3330", 0}, /* 6, 8 */ 242 {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */ 243 {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */ 244 {0x40000000, RC_STUFF, "\015", 0}, /* 5 */ 245 {0x20000, RC_BD_LINK, 0, 0}, /* 10 */ 246 {0x20004000, RC_BD_SCROLL, 0, 0}, /* 4, 7 */ 247 {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */ 248 {0x40010000, RC_BD_SKIP, 0, 0}, /* 5, 9 */ 249 {-1, RC_ILLEGAL, 0, 0} 250}; 251 252static void 253buttonpress_tsi(tab) 254struct key2rc *tab; 255{ 256 int i, nb; 257 int bkeys; 258 unsigned char buf[10]; 259 nb = read(bd.bd_fd, buf, 10); 260 debug1("buttonpress_tsi: read %d bytes\n", nb); 261 for (i=0, bkeys=0; i < nb; i++) 262 { 263 switch (buf[i] & 0xE0) 264 { 265 case 0x00: bkeys += ((int)(buf[i] & 0x1f) ); break; 266 case 0x20: bkeys += ((int)(buf[i] & 0x1f) << 5 ); break; 267 case 0x40: bkeys += ((int)(buf[i] & 0x1f) << 9 ); break; 268 case 0x60: bkeys += ((int)(buf[i] & 0x1f) << 13 ); break; 269 case 0xA0: bkeys += ((int)(buf[i] & 0x1f) << 18 ); break; 270 case 0xC0: bkeys += ((int)(buf[i] & 0x1f) << 22 ); break; 271 case 0xE0: bkeys += ((int)(buf[i] & 0x1f) << 26 ); break; 272 default: break; 273 } 274 } 275 debug1("bkeys %x\n", bkeys); 276 for (i = 0; tab[i].key != -1; i++) 277 if (bkeys == tab[i].key) 278 break; 279 debug1("bkey index %d\n", i); 280 if (tab[i].key != -1 && tab[i].nr != RC_ILLEGAL) 281 { 282 char *args[3]; 283 int argl[2]; 284 285 struct action act; 286 args[0] = tab[i].arg1; 287 args[1] = tab[i].arg2; 288 args[2] = 0; 289 argl[0] = args[0] ? strlen(args[0]) : 0; 290 argl[1] = args[1] ? strlen(args[1]) : 0; 291 act.nr = tab[i].nr; 292 act.args = args; 293 act.argl = argl; 294 display = bd.bd_dpy; 295 DoAction(&act, -2); 296 } 297} 298 299 300static void 301buttonpress_navigator_40() 302{ 303 buttonpress_tsi(keys_navigator_40); 304} 305 306static void 307buttonpress_powerbraille_40() 308{ 309 buttonpress_tsi(keys_powerbraille_40); 310} 311 312static void 313buttonpress_powerbraille_80() 314{ 315 buttonpress_tsi(keys_powerbraille_80); 316} 317 318#endif /* HAVE_BRAILLE */ 319 320 321