Some more fixes for the list management.
[screen-lua.git] / src / braille.c
blobe12fc8fe0ce8639ad0ee7462b1c7aa2e15058fbe
1 /*
2 * A braille interface to unix tty terminals
4 * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu
5 * Bill Barry barryb@dots.physics.orst.edu
7 * Copyright (c) 1995 by Science Access Project, Oregon State University.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3, or (at your option)
13 * any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program (see the file COPYING); if not, see
22 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 ****************************************************************
28 #include <stdio.h>
29 #include <fcntl.h>
30 #include <sys/stat.h>
32 #include "config.h"
33 #include "screen.h"
34 #include "extern.h"
35 #include "braille.h"
37 #ifdef HAVE_BRAILLE
40 extern int bd_init_powerbraille_40 __P((void));
41 extern int bd_init_powerbraille_80 __P((void));
42 extern int bd_init_navigator_40 __P((void));
44 extern struct layer *flayer;
45 extern struct display *displays, *display;
46 extern char *rc_name;
51 /* global variables */
53 struct braille_display bd;
55 struct bd_type {
56 char *name;
57 int (*init) __P((void));
60 static struct bd_type bd_typelist[] =
62 {"powerbraille_40", bd_init_powerbraille_40},
63 {"powerbraille_80", bd_init_powerbraille_80},
64 {"navigator_40" , bd_init_navigator_40}
67 static void position_braille_cursor __P((void));
68 static int initialize_braille_display_type __P((char *));
69 static int open_braille_device __P(());
70 static int load_braille_table __P((char *));
71 static void bd_signal __P((void));
72 static void bd_bc_left __P((void));
73 static void bd_bc_right __P((void));
74 static void bd_bc_up __P((void));
75 static void bd_bc_down __P((void));
76 static void bd_upper_left __P((void));
77 static void bd_upper_right __P((void));
78 static void bd_lower_left __P((void));
79 static void bd_lower_right __P((void));
80 static int bd_do_search __P((int, int, int));
81 static void bd_normalize __P((int, int));
82 static void bd_readev_fn __P((struct event *, char *));
83 static void bd_writeev_fn __P((struct event *, char *));
84 static void bd_selectev_fn __P((struct event *, char *));
86 static unsigned char btable_local [] =
88 0xC8,0xC1,0xC3,0xC9,0xD9,0xD1,0xCB,0xDB,
89 0xD3,0xCA,0xDA,0xC5,0xC7,0xCD,0xDD,0xD5,
90 0xCF,0xDF,0xD7,0xCE,0xDE,0xE5,0xE7,0xFA,
91 0xED,0xFD,0xF5,0xEA,0xF3,0xFB,0xD8,0xF8,
92 0x00,0x2E,0x10,0x3C,0x2B,0x29,0x2F,0x04,
93 0x37,0x3E,0x21,0x2C,0x20,0x24,0x28,0x0C,
94 0x34,0x02,0x06,0x12,0x32,0x22,0x16,0x36,
95 0x26,0x14,0x31,0x30,0x23,0x3F,0x1C,0x39,
96 0x48,0x41,0x43,0x49,0x59,0x51,0x4B,0x5B,
97 0x53,0x4A,0x5A,0x45,0x47,0x4D,0x5D,0x55,
98 0x4F,0x5F,0x57,0x4E,0x5E,0x65,0x67,0x7A,
99 0x6D,0x7D,0x75,0x6A,0x73,0x7B,0x58,0x38,
100 0x08,0x01,0x03,0x09,0x19,0x11,0x0B,0x1B,
101 0x13,0x0A,0x1A,0x05,0x07,0x0D,0x1D,0x15,
102 0x0F,0x1F,0x17,0x0E,0x1E,0x25,0x27,0x3A,
103 0x2D,0x3D,0x35,0x2A,0x33,0x3B,0x18,0x78,
104 0x88,0x81,0x83,0x89,0x99,0x91,0x8B,0x9B,
105 0x93,0x8A,0x9A,0x85,0x87,0x8D,0x9D,0x95,
106 0x8F,0x9F,0x97,0x8E,0x9E,0xA5,0xA7,0xBA,
107 0xAD,0xBD,0xB5,0xAA,0xB3,0xBB,0x98,0xB8,
108 0x40,0x6E,0x50,0x7C,0x6B,0x69,0x6F,0x44,
109 0x77,0x7E,0x61,0x6C,0x60,0x64,0x68,0x4C,
110 0x74,0x42,0x46,0x52,0x72,0x62,0x56,0x76,
111 0x66,0x54,0x71,0x70,0x63,0x7F,0x5C,0x79,
112 0xC0,0xEE,0xD0,0xFC,0xEB,0xE9,0xEF,0xC4,
113 0xF7,0xFE,0xE1,0xEC,0xE0,0xE4,0xE8,0xCC,
114 0xF4,0xC2,0xC6,0xD2,0xF2,0xE2,0xD6,0xF6,
115 0xE6,0xD4,0xF1,0xF0,0xE3,0xFF,0xDC,0xF9,
116 0x80,0xAE,0x90,0xBC,0xAB,0xA9,0xAF,0x84,
117 0xB7,0xBE,0xA1,0xAC,0xA0,0xA4,0xA8,0x8C,
118 0xB4,0x82,0x86,0x92,0xB2,0xA2,0x96,0xB6,
119 0xA6,0x94,0xB1,0xB0,0xA3,0xBF,0x9C,0xB9
122 void
123 InitBraille()
125 bd.bd_start_braille=0;
126 bd.bd_port = 0;
127 bd.bd_braille_table = SaveStr("internal us-braille.tbl");
128 bd.bd_type = 0;
129 bd.bd_baud = 9600;
130 bd.bd_bell = 1;
131 bd.bd_eightdot = 1;
132 bd.bd_info = 0;
133 bd.bd_link = 1;
134 bd.bd_ncells = 0;
135 bd.bd_width = 0;
136 bd.bd_ncrc = 1;
137 bd.bd_scroll = 1;
138 bd.bd_skip = 0;
139 bd.bd_using_braille = 0;
140 bd.bd_obuflen = 0;
141 bd.bd_fd = -1;
142 bcopy((char *)btable_local, bd.bd_btable, 256);
145 static int
146 initialize_braille_display_type(s)
147 char *s;
149 int i;
151 for (i = 0; i < sizeof(bd_typelist)/sizeof(*bd_typelist); i++)
152 if (!strcmp(s, bd_typelist[i].name))
153 break;
154 if (i == sizeof(bd_typelist)/sizeof(*bd_typelist))
156 Msg(0, "No entry for bd_type: %s ", s);
157 return -1;
159 bd.bd_type = bd_typelist[i].name;
160 if ((*bd_typelist[i].init)())
161 return -1;
163 if (!bd.bd_width)
164 bd.bd_width = bd.bd_ncells;
166 return 0;
169 void
170 StartBraille()
172 bd.bd_dpy = displays;
174 debug("StartBraille called\n");
175 evdeq(&bd.bd_readev);
176 evdeq(&bd.bd_writeev);
177 evdeq(&bd.bd_selectev);
178 bd.bd_using_braille = 0;
180 if (!bd.bd_start_braille)
181 return;
183 if (bd.bd_type == 0 || bd.bd_port == 0)
184 return;
186 if (bd.bd_fd < 0 && open_braille_device())
188 Msg(0, "bd_port turned off");
189 free(bd.bd_port);
190 bd.bd_port = 0;
191 return;
194 /* check if braille display is connected and turned on */
195 if (bd.bd_response_test())
197 Msg(0, "Make sure that braille display is connected and turned on. ");
198 Msg(0, "start_braille turned off");
199 bd.bd_start_braille = 0;
201 else
203 bd.bd_using_braille = 1;
204 bd.bd_readev.fd = bd.bd_writeev.fd = bd.bd_fd;
205 bd.bd_readev.type = EV_READ;
206 bd.bd_writeev.type = EV_WRITE;
207 bd.bd_selectev.type = EV_ALWAYS;
208 bd.bd_readev.data = bd.bd_writeev.data = bd.bd_selectev.data = (char *)&bd;
209 bd.bd_readev.handler = bd_readev_fn;
210 bd.bd_writeev.handler = bd_writeev_fn;
211 bd.bd_selectev.handler = bd_selectev_fn;
212 evenq(&bd.bd_readev);
213 bd.bd_writeev.condpos = &bd.bd_obuflen;
214 bd.bd_writeev.condneg = 0;
215 evenq(&bd.bd_writeev);
216 bd.bd_selectev.pri = -20;
217 evenq(&bd.bd_selectev);
222 static int
223 load_braille_table(tablename)
224 char *tablename;
226 int i, j, c, p;
227 FILE *fp;
228 char buffer[80], a[10];
230 if ((fp = secfopen(tablename, "r")) == 0)
232 Msg(errno, "Braille table not found: %s ", tablename);
233 return -1;
235 bzero(bd.bd_btable, 256);
236 /* format:
237 * Dec Hex Braille Description
238 * 7 07 (12-45--8) BEL
240 while (fgets(buffer, sizeof(buffer), fp))
242 if (buffer[0] == '#')
243 continue;
244 sscanf(buffer,"%d %x %8s", &i, &j, a);
245 if (i < 0 || i > 255)
246 continue;
247 for (j=1, p=1, c=0; j<9; j++, p*=2)
248 if (a[j] == '0' + j)
249 c += p;
250 bd.bd_btable[i] = c;
252 fclose(fp);
253 return 0;
257 static int
258 open_braille_device(s)
259 char *s;
261 char str[256];
263 sprintf(str, "%d cs8 -istrip ixon ixoff", bd.bd_baud);
264 bd.bd_fd = OpenTTY(bd.bd_port, str);
265 if (bd.bd_fd == -1)
267 Msg(errno, "open comm port failed: %s ", bd.bd_port);
268 return -1;
270 fcntl(bd.bd_fd, F_SETFL, FNBLOCK);
271 return 0;
275 static void
276 position_braille_cursor()
278 int sx = bd.bd_sx;
279 int bx = BD_FORE->w_bd_x;
280 int eol = BD_FORE->w_width;
281 int w = bd.bd_width;
283 if (bd.bd_scroll)
284 bx = sx - w + bd.bd_ncrc; /* keep rc centered in window */
285 else
286 bx = w * (int)(sx / w); /* increase bc in integral steps */
288 if (bx > eol - w)
289 bx = eol - w;
290 if (bx < 0)
291 bx = 0;
292 BD_FORE->w_bd_x = bx;
293 BD_FORE->w_bd_y = bd.bd_sy;
297 void
298 RefreshBraille()
300 int i, y, xs, xe;
301 int cursor_pos;
303 if (!bd.bd_using_braille)
304 return;
305 if (!BD_FORE)
306 return;
307 bcopy(bd.bd_line, bd.bd_oline, bd.bd_ncells);
308 bd.bd_refreshing = 1;
309 flayer = bd.bd_dpy->d_forecv->c_layer;
310 bd.bd_sx = flayer->l_x;
311 bd.bd_sy = flayer->l_y;
312 display = bd.bd_dpy;
313 if ((D_obufp != D_obuf) && bd.bd_link)
315 /* jump to real cursor */
316 debug("calling position_braille_cursor\n");
317 position_braille_cursor();
319 bclear(bd.bd_line, bd.bd_ncells);
321 y = BD_FORE->w_bd_y;
322 xs = BD_FORE->w_bd_x;
324 if (bd.bd_info & 1)
326 sprintf(bd.bd_line, "%02d%02d", (BD_FORE->w_bd_x + 1) % 100, (BD_FORE->w_bd_y + 1) % 100);
327 bd.bd_line[4] = ' ';
329 if (bd.bd_info & 2)
331 sprintf(bd.bd_line + bd.bd_ncells - 4, "%02d%02d",(bd.bd_sx +1) % 100, (bd.bd_sy +1) % 100);
334 xe = xs + bd.bd_width - 1;
336 if (xs > flayer->l_width - 1)
337 xs = flayer->l_width - 1;
338 if (xe > flayer->l_width - 1)
339 xe = flayer->l_width - 1;
341 if (D_status)
343 sprintf(bd.bd_line, "**%-*.*s", bd.bd_ncells - 2, bd.bd_ncells - 2, D_status_lastmsg ? D_status_lastmsg : "unknown msg");
344 xs = xe = -1;
346 else if (xs <= xe)
348 LayRedisplayLine(-1, xs, xe, 1);
349 LayRedisplayLine(y, xs, xe, 1);
352 debug1("Braille: got >%s<\n", bd.bd_line);
354 bd.bd_refreshing = 0;
356 if (y == bd.bd_sy && xs <= bd.bd_sx && bd.bd_sx <= xe)
357 cursor_pos = bd.bd_sx - xs + (bd.bd_info & 1 ? 4 : 0);
358 else
359 cursor_pos = bd.bd_ncells;
360 for (i = 0; i < bd.bd_ncells; i++)
361 if (bd.bd_line[i] != bd.bd_oline[i])
362 break;
363 if (bd.bd_cursorpos != cursor_pos || i < bd.bd_ncells)
364 bd.write_line_braille(bd.bd_line, bd.bd_ncells, cursor_pos);
365 bd.bd_cursorpos = cursor_pos;
369 /**********************************************************************
374 * So, why is there a Flush() down below? The reason is simple: the
375 * cursor warp (if bd_link is on) checks the obuf to see if something
376 * happened. If there would be no Flush, screen would warp the
377 * bd cursor if a bd movement command tries to ring the bell.
378 * (In other words: this is a gross hack!)
380 static void
381 bd_signal()
383 if (!bd.bd_bell)
384 return;
385 display = bd.bd_dpy;
386 if (D_obufp != D_obuf)
387 AddCStr(D_BL);
388 else
390 AddCStr(D_BL);
391 Flush(0);
395 static int
396 bd_do_search(y, xs, xe)
397 int y, xs, xe;
399 int oy = BD_FORE->w_bd_y;
401 if (!bd.bd_skip) /* no skip mode, found it */
403 if (xs > xe)
404 return 0;
405 bd.bd_searchmin = xs;
406 bd.bd_searchmax = xe;
407 return 1;
409 flayer = bd.bd_dpy->d_forecv->c_layer;
410 bd.bd_searchmax = -1;
411 bd.bd_searchmin = flayer->l_width;
412 if (xs <= xe)
414 BD_FORE->w_bd_y = y; /* stupid hack */
415 bd.bd_refreshing = bd.bd_searching = 1;
416 bd.bd_searchstart = xs;
417 bd.bd_searchend = xe;
418 LayRedisplayLine(-1, xs, xe, 1);
419 LayRedisplayLine(y, xs, xe, 1);
420 bd.bd_refreshing = bd.bd_searching = 0;
421 BD_FORE->w_bd_y = oy;
423 return bd.bd_searchmax >= 0;
426 static void
427 bd_normalize(x, y)
428 int x, y;
430 if (x > BD_FORE->w_width - bd.bd_width)
431 x = BD_FORE->w_width - bd.bd_width;
432 if (x < 0)
433 x = 0;
434 if (y < 0)
436 bd_signal();
437 y = 0;
439 if (y >= BD_FORE->w_height)
441 bd_signal();
442 y = BD_FORE->w_height - 1;
444 if (x != BD_FORE->w_bd_x || y != BD_FORE->w_bd_y)
445 bd.bd_moved = 1;
446 BD_FORE->w_bd_x = x;
447 BD_FORE->w_bd_y = y;
450 static void
451 bd_bc_left()
453 int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
454 int ex;
456 ex = bx - 1;
457 bx = 0;
458 for (; by >= 0; by--)
460 if (bd_do_search(by, 0, ex))
462 if (!bd.bd_skip && by != BD_FORE->w_bd_y)
463 bd_signal();
464 bx = bd.bd_searchmax + 1 - bd.bd_width;
465 break;
467 ex = BD_FORE->w_width - 1;
469 bd_normalize(bx, by);
472 static void
473 bd_bc_right()
475 int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
476 int sx;
478 sx = bx + bd.bd_width;
479 bx = BD_FORE->w_width - bd.bd_width;
480 for (; by < BD_FORE->w_height; by++)
482 if (bd_do_search(by, sx, BD_FORE->w_width - 1))
484 if (!bd.bd_skip && by != BD_FORE->w_bd_y)
485 bd_signal();
486 bx = bd.bd_searchmin;
487 break;
489 sx = 0;
491 bd_normalize(bx, by);
494 static void
495 bd_bc_up()
497 int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
499 for (by--; by >= 0; by--)
500 if (bd_do_search(by, bx, bx + bd.bd_width - 1))
501 break;
502 bd_normalize(bx, by);
505 static void
506 bd_bc_down()
508 int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
510 for (by++; by < BD_FORE->w_height; by++)
511 if (bd_do_search(by, bx, bx + bd.bd_width - 1))
512 break;
513 bd_normalize(bx, by);
517 static void
518 bd_upper_left()
520 bd_normalize(0, 0);
524 static void
525 bd_upper_right()
527 bd_normalize(BD_FORE->w_width - bd.bd_width, 0);
531 static void
532 bd_lower_left()
534 bd_normalize(0, BD_FORE->w_height - 1);
538 static void
539 bd_lower_right()
541 bd_normalize(BD_FORE->w_width - bd.bd_width, BD_FORE->w_height -1);
544 /**********************************************************************
549 static void
550 bd_check(x, c)
551 int x, c;
553 if (c == ' ')
554 return;
555 if (x < bd.bd_searchstart || x > bd.bd_searchend)
556 return;
557 if (x > bd.bd_searchmax)
558 bd.bd_searchmax = x;
559 if (x < bd.bd_searchmin)
560 bd.bd_searchmin = x;
565 /*ARGSUSED*/
566 void
567 BGotoPos(la, x, y)
568 struct layer *la;
569 int x, y;
573 /*ARGSUSED*/
574 void
575 BCDisplayLine(la, ml, y, xs, xe, isblank)
576 struct layer *la;
577 struct mline *ml;
578 int y, xs, xe;
579 int isblank;
581 int x;
582 int sx, ex;
583 char *l;
585 if (y != BD_FORE->w_bd_y)
586 return;
587 if (bd.bd_searching)
589 for (x = xs; x <= xe; x++)
590 bd_check(x, ml->image[x]);
591 return;
593 l = bd.bd_line;
594 sx = BD_FORE->w_bd_x;
595 ex = sx + bd.bd_width - 1;
596 if (bd.bd_info & 1)
597 l += 4;
598 for (x = xs; x <= xe; x++)
599 if (x >= sx && x <= ex)
600 l[x - sx] = ml->image[x];
603 /*ARGSUSED*/
604 void
605 BPutChar(la, c, x, y)
606 struct layer *la;
607 struct mchar *c;
608 int x, y;
610 int sx, ex;
611 char *l;
613 if (y != BD_FORE->w_bd_y)
614 return;
615 if (bd.bd_searching)
617 bd_check(x, c->image);
618 return;
620 l = bd.bd_line;
621 sx = BD_FORE->w_bd_x;
622 ex = sx + bd.bd_width - 1;
623 if (bd.bd_info & 1)
624 l += 4;
625 if (x >= sx && x <= ex)
626 l[x - sx] = c->image;
629 /*ARGSUSED*/
630 void
631 BPutStr(la, s, n, r, x, y)
632 struct layer *la;
633 char *s;
634 int n;
635 struct mchar *r;
636 int x, y;
638 int sx, ex;
639 char *l;
641 if (y != BD_FORE->w_bd_y)
642 return;
643 if (bd.bd_searching)
645 for (; n > 0; n--, s++, x++)
646 bd_check(x, *s);
647 return;
649 l = bd.bd_line;
650 sx = BD_FORE->w_bd_x;
651 ex = sx + bd.bd_width - 1;
652 if (bd.bd_info & 1)
653 l += 4;
654 for (; n > 0; n--, s++, x++)
655 if (x >= sx && x <= ex)
656 l[x - sx] = *s;
661 /**********************************************************************
665 static char *infonames[] = {"none", "bc", "sc", "bc+sc"};
667 void
668 DoBrailleAction(act, msgok)
669 struct action *act;
670 int msgok;
672 int nr, dosig;
673 int n, l, o;
674 char *s, **args;
675 struct stat st;
677 nr = act->nr;
678 args = act->args;
679 dosig = display && !*rc_name;
681 switch(nr)
683 case RC_BD_BELL:
684 if (ParseSwitch(act, &bd.bd_bell) || !msgok)
686 bd_signal();
687 break;
689 Msg(0, bd.bd_bell ? "bd_bell is on." : "bd_bell is off.");
690 break;
692 case RC_BD_EIGHTDOT:
693 if (ParseSwitch(act, &bd.bd_eightdot) || !msgok)
694 break;
695 Msg(0, "switched to %d-dots system.", bd.bd_eightdot ? 8 : 6);
696 break;
698 case RC_BD_INFO:
699 n = bd.bd_info;
700 if (*args)
702 if (strlen(*args) == 4)
703 n = args[0][n] - '0';
704 else if (ParseNum(act, &n))
705 break;
707 if (n < 0 && n > 3)
709 Msg(0, "Out of range; 0 <= bd_info >= 3 ");
710 break;
712 /* bd_width at the beginning is unknown */
713 if (bd.bd_width == 0)
714 break;
716 o = (bd.bd_info * 2 + 2) & 12;
717 l = (n * 2 + 2) & 12;
718 if (l >= bd.bd_ncells)
720 Msg(0, "bd_info is too large for braille display.");
721 break;
723 if (l >= bd.bd_width + o)
725 Msg(0, "bd_info is too large for bd_width.");
726 break;
728 bd.bd_width += o - l;
729 bd.bd_info = n;
731 if (msgok)
732 Msg(0, "bd_info is %s.", infonames[n]);
733 position_braille_cursor();
734 break;
736 case RC_BD_LINK:
737 if (*args == 0 && bd.bd_moved)
738 bd.bd_link = 0;
739 if (ParseSwitch(act, &bd.bd_link))
740 break;
741 if (bd.bd_link)
743 bd.bd_moved = 0;
744 if (dosig)
745 bd_signal();
746 position_braille_cursor();
748 if (msgok)
749 Msg(0, bd.bd_link ? "bd_link is on." : "bd_link is off.");
750 break;
752 case RC_BD_SKIP:
753 if (ParseSwitch(act, &bd.bd_skip))
754 break;
755 if (bd.bd_skip && dosig)
756 bd_signal();
757 if (msgok)
758 Msg(0, bd.bd_skip ? "bd_skip is on." : "bd_skip is off.");
759 break;
761 case RC_BD_SCROLL:
762 if (ParseSwitch(act, &bd.bd_scroll) || !msgok)
764 position_braille_cursor();
765 break;
767 Msg(0, bd.bd_scroll ? "bd_scroll is on." : "bd_scroll is off.");
768 break;
770 case RC_BD_NCRC:
771 n = bd.bd_ncrc;
772 if (*args)
774 if (args[0][0] == '+')
775 n = (n + atoi(*args + 1)) % bd.bd_width + 1;
776 else if (args[0][0] == '-')
777 n = (n - atoi(*args + 1)) % bd.bd_width + 1;
778 else if (ParseNum(act, &n))
779 break;
781 if (n < 1 || n > bd.bd_width)
783 Msg(0, "Out of range; 1 <= bd_ncrc >= %d", bd.bd_width);
784 break;
786 bd.bd_ncrc = n;
787 if (msgok)
788 Msg(0, "bd_ncrc status is: %d ", bd.bd_ncrc);
789 position_braille_cursor();
790 break;
792 case RC_BD_BRAILLE_TABLE:
793 s = 0;
794 if (*args)
796 if (ParseSaveStr(act, &s))
797 break;
798 if (load_braille_table(s))
800 free(s);
801 break;
803 if (bd.bd_braille_table)
804 free(bd.bd_braille_table);
805 bd.bd_braille_table = s;
807 if (msgok)
808 Msg(0, "bd_braille_table is: %s ", bd.bd_braille_table);
809 break;
811 case RC_BD_PORT:
812 s = 0;
813 if (*args)
815 if (ParseSaveStr(act, &s))
816 break;
818 if (stat(s, &st) || !S_ISCHR(st.st_mode) || access(s, R_OK|W_OK))
820 Msg(0, "Cannot access braille device port %s", s);
821 free(s);
822 break;
824 if (bd.bd_fd >= 0)
825 close(bd.bd_fd);
826 bd.bd_fd = -1;
827 if (bd.bd_port)
828 free(bd.bd_port);
829 bd.bd_port = s;
831 if (msgok)
832 Msg(0, "bd_port is: %s ", bd.bd_port ? bd.bd_port : "not set");
833 StartBraille();
834 break;
836 case RC_BD_TYPE:
837 s = 0;
838 if (*args)
839 if (ParseSaveStr(act, &s) || initialize_braille_display_type(s))
840 break;
841 if (msgok)
842 Msg(0, "bd_type is: %s ", bd.bd_type ? bd.bd_type : "not set");
843 StartBraille();
844 break;
846 case RC_BD_START_BRAILLE:
847 if (ParseSwitch(act, &bd.bd_start_braille))
848 break;
849 if (msgok)
850 Msg(0, bd.bd_start_braille ? "bd_start_braille is on." : "bd_start_braille is off.");
851 StartBraille();
852 break;
854 case RC_BD_WIDTH:
855 n = bd.bd_width;
856 if (*args)
858 if (ParseNum(act, &n))
859 break;
861 if (n <= 0)
863 Msg(0, "Invalid value for bd_width: %d ", n);
864 break;
866 l = (bd.bd_info * 2 + 2) & 12;
867 if (n > bd.bd_ncells - l || n < l)
869 Msg(0, "bd_info is too large for bd_width.");
870 break;
872 bd.bd_width = n;
873 if (msgok)
874 Msg(0, "bd_width is: %d ", bd.bd_width);
875 break;
877 case RC_BD_BC_LEFT:
878 bd_bc_left();
879 break;
881 case RC_BD_BC_RIGHT:
882 bd_bc_right();
883 break;
885 case RC_BD_BC_UP:
886 bd_bc_up();
887 break;
889 case RC_BD_BC_DOWN:
890 bd_bc_down();
891 break;
893 case RC_BD_UPPER_LEFT:
894 bd_upper_left();
895 break;
897 case RC_BD_UPPER_RIGHT:
898 bd_upper_right();
899 break;
901 case RC_BD_LOWER_LEFT:
902 bd_lower_left();
903 break;
905 case RC_BD_LOWER_RIGHT:
906 bd_lower_right();
907 break;
909 default:
910 break;
914 static void
915 bd_readev_fn(ev, data)
916 struct event *ev;
917 char *data;
919 bd.buttonpress();
922 static void
923 bd_writeev_fn(ev, data)
924 struct event *ev;
925 char *data;
927 int len;
929 if (bd.bd_obuflen == 0)
930 return;
931 if ((len = write(bd.bd_fd, bd.bd_obuf, bd.bd_obuflen)) < 0)
932 len = bd.bd_obuflen; /* dead braille display */
933 if ((bd.bd_obuflen -= len))
934 bcopy(bd.bd_obuf + len, bd.bd_obuf, bd.bd_obuflen);
937 static void
938 bd_selectev_fn(ev, data)
939 struct event *ev;
940 char *data;
942 RefreshBraille();
945 #endif /* HAVE_BRAILLE */