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