1 /*
2 * $Id: io-curses.c,v 1.20 2001/02/13 23:38:06 danny Exp $
3 *
4 * Copyright � 1992, 1993, 1999, 2001 Free Software Foundation, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this software; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #ifdef WITH_DMALLOC
27 #include <dmalloc.h>
28 #endif
29
30 #include "proto.h"
31 #include "funcdef.h"
32 #include <stdio.h>
33
34 #if defined(HAVE_LIBNCURSES) && defined(HAVE_NCURSES_H)
35 #include <ncurses.h>
36 #else
37 #include <curses.h>
38 #endif
39
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <ctype.h>
43 #include <signal.h>
44 #undef NULL
45 #include "sysdef.h"
46 #include "global.h"
47 #include "cell.h"
48 #include "cmd.h"
49 #include "line.h"
50 #include "io-generic.h"
51 #include "io-edit.h"
52 #include "io-term.h"
53 #include "io-abstract.h"
54 #include "io-utils.h"
55 #include "lists.h"
56 #include "regions.h"
57 #include "window.h"
58 #include "key.h"
59 #include "input.h"
60 #include "info.h"
61 #include <term.h>
62
63 #define MIN_WIN_HEIGHT (cwin->flags&WIN_EDGES ? 2 : 1)
64 #define MIN_WIN_WIDTH (cwin->flags&WIN_EDGES ? 6 : 1)
65
66 static int redrew = 0;
67 static int textout = 0;
68 static int term_cursor_claimed = 0;
69
70 static void move_cursor_to (struct window *, CELLREF, CELLREF, int);
71
72 static int
curses_metric(char * str,int len)73 curses_metric (char * str, int len)
74 {
75 return len;
76 }
77
78 static struct input_view input_view
79 = {0, curses_metric, curses_metric, 0, 0, 0, 0, 0, 0, 0, 0, 0};
80
81 static void
_io_redraw_input(void)82 _io_redraw_input (void)
83 {
84 int pos;
85 int row = (input_view.current_info ? 0 : Global->input);
86
87 if (input_view.info_redraw_needed)
88 {
89 input_view.info_redraw_needed = 0;
90 io_repaint ();
91 return;
92 }
93
94 if (input_view.redraw_needed == NO_REDRAW)
95 return;
96
97 if (input_view.redraw_needed == FULL_REDRAW)
98 {
99 /* Redraw the prompt. */
100 move (row, 0);
101 if (input_view.expanded_keymap_prompt)
102 {
103 addstr (input_view.expanded_keymap_prompt);
104 clrtoeol ();
105 input_view.redraw_needed = NO_REDRAW;
106 return;
107 }
108 if (input_view.prompt_wid)
109 addstr (input_view.prompt);
110 pos = input_view.visibility_begin;
111 }
112 else
113 {
114 pos = input_view.redraw_needed;
115 move (row,
116 input_view.prompt_wid + pos - input_view.visibility_begin);
117 }
118
119 if ( input_view.input_area
120 && (input_view.visibility_end >= input_view.visibility_begin)
121 && (input_view.visibility_begin < strlen (input_view.input_area->buf)))
122 {
123 int x;
124 for (x = pos; x <= input_view.visibility_end; ++x)
125 addch (input_view.input_area->buf[x]);
126 }
127 clrtoeol ();
128 input_view.redraw_needed = NO_REDRAW;
129 }
130
131
132 #undef MIN
133 #define MIN(A,B) (((A) < (B)) ? (A) : (B))
134
135 void
redraw_info(void)136 redraw_info (void)
137 {
138 if (!input_view.current_info)
139 return;
140 {
141 int ipos = input_view.info_pos;
142 int stop = MIN (input_view.current_info->len, Global->scr_lines - 1 + ipos);
143 while (ipos < stop)
144 {
145 move (1 + ipos - input_view.info_pos, 0);
146 addstr (input_view.current_info->text[ipos]);
147 clrtoeol ();
148 ++ipos;
149 }
150 }
151 _io_redraw_input ();
152 }
153
154
155 static void
_io_fix_input(void)156 _io_fix_input (void)
157 {
158 iv_fix_input (&input_view);
159 }
160
161 static void
_io_move_cursor(void)162 _io_move_cursor (void)
163 {
164 iv_move_cursor (&input_view);
165 }
166
167 static void
_io_erase(int len)168 _io_erase (int len)
169 {
170 iv_erase (&input_view, len);
171 }
172
173 static void
_io_insert(int len)174 _io_insert (int len)
175 {
176 iv_insert (&input_view, len);
177 }
178
179 static void
_io_over(char * str,int len)180 _io_over (char * str, int len)
181 {
182 iv_over (&input_view, len);
183 }
184
185 static void
_io_display_cell_cursor(void)186 _io_display_cell_cursor (void)
187 {
188 int cell_cursor_row;
189 int cell_cursor_col;
190 int cc;
191 int rr;
192 int cwid;
193 int n;
194 int x, y;
195
196 if (input_view.current_info)
197 return;
198
199 if ( (curow < cwin->screen.lr)
200 || (cucol < cwin->screen.lc)
201 || (curow > cwin->screen.hr)
202 || (cucol > cwin->screen.hc))
203 return;
204
205 getyx (stdscr, y, x);
206 cell_cursor_col = cwin->win_over;
207 for (cc = cwin->screen.lc; cc < cucol; cc++)
208 cell_cursor_col += get_width (cc);
209 cell_cursor_row = cwin->win_down;
210 for (rr = cwin->screen.lr; rr < curow; rr++)
211 cell_cursor_row += get_height (rr);
212 cwid = get_width (cucol);
213 if (cwid > cwin->numc)
214 cwid = cwin->numc;
215 move (cell_cursor_row, cell_cursor_col);
216 standout ();
217 for (n = cwid; n; n--)
218 #ifdef A_STANDOUT
219 addch (inch () | A_STANDOUT);
220 #else
221 addch (inch ());
222 #endif
223 standend ();
224 move (y, x);
225 }
226
227 static void
_io_hide_cell_cursor(void)228 _io_hide_cell_cursor (void)
229 {
230 int cc;
231 int rr;
232 int cell_cursor_row;
233 int cell_cursor_col;
234 int cwid;
235 int n;
236 int x, y;
237
238 if (input_view.current_info)
239 return;
240 if ( (curow < cwin->screen.lr)
241 || (cucol < cwin->screen.lc)
242 || (curow > cwin->screen.hr)
243 || (cucol > cwin->screen.hc))
244 return;
245 getyx (stdscr, y, x);
246 cell_cursor_col = cwin->win_over;
247 for (cc = cwin->screen.lc; cc < cucol; cc++)
248 cell_cursor_col += get_width (cc);
249 cell_cursor_row = cwin->win_down;
250 for (rr = cwin->screen.lr; rr < curow; rr++)
251 cell_cursor_row += get_height (rr);
252 cwid = get_width (cucol);
253 if (cwid > cwin->numc)
254 cwid = cwin->numc;
255 move (cell_cursor_row, cell_cursor_col);
256 for (n = cwid; n; n--)
257 #ifdef A_STANDOUT
258 addch (inch () & ~A_STANDOUT);
259 #else
260 addch (inch ());
261 #endif
262 move (y, x);
263 }
264
265 /* Functions, etc for dealing with cell contents being displayed
266 on top of other cells. */
267
268 struct slops
269 {
270 int s_alloc, s_used;
271 struct s
272 {
273 CELLREF row, clo, chi;
274 } s_b[1];
275 };
276
277 static void
flush_slops(VOIDSTAR where)278 flush_slops (VOIDSTAR where)
279 {
280 struct slops *s;
281
282 s = where;
283 if (s)
284 s->s_used = 0;
285 }
286
287 static int
find_slop(VOIDSTAR where,CELLREF r,CELLREF c,CELLREF * cclp,CELLREF * cchp)288 find_slop (VOIDSTAR where, CELLREF r, CELLREF c, CELLREF *cclp, CELLREF *cchp)
289 {
290 int n;
291 struct slops *s;
292
293 s = where;
294 if (!s)
295 return 0;
296 for (n = 0; n < s->s_used; n++)
297 {
298 if (s->s_b[n].row == r && s->s_b[n].clo <= c && s->s_b[n].chi >= c)
299 {
300 *cclp = s->s_b[n].clo;
301 *cchp = s->s_b[n].chi;
302 return 1;
303 }
304 }
305 return 0;
306 }
307
308 static void
kill_slop(VOIDSTAR where,CELLREF r,CELLREF clo,CELLREF chi)309 kill_slop (VOIDSTAR where, CELLREF r, CELLREF clo, CELLREF chi)
310 {
311 int n;
312 struct slops *s;
313
314 s = where;
315 for (n = 0; n < s->s_used; n++)
316 {
317 if (s->s_b[n].row == r && s->s_b[n].clo == clo && s->s_b[n].chi == chi)
318 {
319 --(s->s_used);
320 s->s_b[n] = s->s_b[s->s_used];
321 return;
322 }
323 }
324 }
325
326 static void
set_slop(VOIDSTAR * wherep,CELLREF r,CELLREF clo,CELLREF chi)327 set_slop (VOIDSTAR *wherep, CELLREF r, CELLREF clo, CELLREF chi)
328 {
329 int n;
330 struct slops **sp;
331
332 sp = (struct slops **) wherep;
333 if (!*sp)
334 {
335 (*sp) = ck_malloc (sizeof (struct slops) + 2 * sizeof (struct s));
336 (*sp)->s_alloc = 2;
337 (*sp)->s_used = 1;
338 n = 0;
339 }
340 else
341 {
342 n = (*sp)->s_used++;
343 if ((*sp)->s_alloc == n)
344 {
345 (*sp)->s_alloc = n * 2;
346 (*sp) = ck_realloc ((*sp), sizeof (struct slops) + n * 2 * sizeof (struct s));
347 }
348 }
349 (*sp)->s_b[n].row = r;
350 (*sp)->s_b[n].clo = clo;
351 (*sp)->s_b[n].chi = chi;
352 }
353
354 static void
change_slop(VOIDSTAR where,CELLREF r,CELLREF olo,CELLREF ohi,CELLREF lo,CELLREF hi)355 change_slop (VOIDSTAR where,
356 CELLREF r, CELLREF olo, CELLREF ohi, CELLREF lo, CELLREF hi)
357 {
358 int n;
359 struct slops *s;
360
361 s = where;
362 for (n = 0; n < s->s_used; n++)
363 {
364 if (s->s_b[n].row == r && s->s_b[n].clo == olo && s->s_b[n].chi == ohi)
365 {
366 s->s_b[n].clo = lo;
367 s->s_b[n].chi = hi;
368 return;
369 }
370 }
371 }
372
373 static void
_io_open_display(void)374 _io_open_display (void)
375 {
376 initscr ();
377 scrollok (stdscr, 0);
378 #ifdef HAVE_CBREAK
379 cbreak ();
380 #else
381 crmode ();
382 #endif
383 raw ();
384 noecho ();
385 nonl ();
386 /* Must be after initscr() */
387 io_init_windows (LINES, COLS, 1, 2, 1, 1, 1, 1);
388 // io_init_windows (Global->scr_lines, Global->scr_cols, 1, 2, 1, 1, 1, 1);
389 info_rows = 1;
390 print_width = columns; /* Make ascii print width == terminal width. */
391 }
392
393 void
cont_curses(void)394 cont_curses(void)
395 {
396 #ifdef HAVE_CBREAK
397 cbreak ();
398 #else
399 crmode ();
400 #endif
401 raw ();
402 noecho ();
403 nonl ();
404 }
405
406
407 void
stop_curses(void)408 stop_curses(void)
409 {
410 #ifdef HAVE_CBREAK
411 nocbreak ();
412 #else
413 nocrmode ();
414 #endif
415 noraw ();
416 echo ();
417 nl ();
418 io_redisp ();
419 }
420
421 static void
_io_cellize_cursor(void)422 _io_cellize_cursor (void)
423 {
424 }
425
426 static void
_io_inputize_cursor(void)427 _io_inputize_cursor (void)
428 {
429 }
430
431 static void
_io_redisp(void)432 _io_redisp (void)
433 {
434 if (!term_cursor_claimed)
435 {
436 _io_redraw_input ();
437 if (!(input_view.current_info || input_active ||
438 input_view.expanded_keymap_prompt))
439 move_cursor_to (cwin, curow, cucol, 0);
440 else
441 move ((input_view.current_info ? 0 : Global->input),
442 input_view.prompt_wid + input_view.input_cursor -
443 input_view.visibility_begin);
444 }
445 {
446 struct rng * rng = &cwin->screen;
447 if ( (curow > rng->hr)
448 || (curow < rng->lr)
449 || (cucol > rng->hc)
450 || (cucol < rng->lc))
451 io_recenter_cur_win ();
452 }
453 refresh ();
454 }
455
456 static void
_io_repaint_win(struct window * win)457 _io_repaint_win (struct window *win)
458 {
459 io_repaint ();
460 }
461
462 static void
_io_repaint(void)463 _io_repaint (void)
464 {
465 CELLREF cc, rr;
466 int n, n1;
467 CELL *cp;
468 struct window *win;
469
470 clear ();
471 io_fix_input ();
472 redrew++;
473 if (input_view.current_info)
474 {
475 redraw_info ();
476 input_view.redraw_needed = FULL_REDRAW;
477 _io_redraw_input ();
478 return;
479 }
480
481 for (win = wins; win < &wins[nwin]; win++)
482 {
483 if (win->lh_wid)
484 {
485 move (win->win_down - 1, win->win_over - win->lh_wid);
486 printw ("#%*d ", win->lh_wid - 2, 1 + win - wins);
487 if (win->flags & WIN_EDGE_REV)
488 standout ();
489 cc = win->screen.lc;
490 do
491 {
492 n = get_width (cc);
493 if (n > win->numc)
494 n = win->numc;
495 if (n > 1)
496 {
497 char *ptr;
498 char buf[30];
499
500 if (Global->a0)
501 ptr = col_to_str (cc);
502 else
503 {
504 sprintf (buf, "C%u", cc);
505 ptr = buf;
506 }
507 --n;
508 n1 = strlen (ptr);
509 if (n < n1)
510 printw ("%.*s ", n, "###############");
511 else
512 {
513 n1 = (n - n1) / 2;
514 printw ("%*s%-*s ", n1, "", n - n1, ptr);
515 }
516 }
517 else if (n == 1)
518 addstr ("#");
519 }
520 while (cc++ < win->screen.hc);
521
522 rr = win->screen.lr;
523 n = win->win_down;
524 do
525 {
526 n1 = get_height (rr);
527 if (n1)
528 {
529 move (n, win->win_over - win->lh_wid);
530 if (Global->a0)
531 printw ("%-*d ", win->lh_wid - 1, rr);
532 else
533 printw ("R%-*d", win->lh_wid - 1, rr);
534 n += n1;
535 }
536 }
537 while (rr++ < win->screen.hr);
538
539 if (win->flags & WIN_EDGE_REV)
540 standend ();
541 }
542 flush_slops (win->win_slops);
543 find_cells_in_range (&(win->screen));
544 while ((cp = next_row_col_in_range (&rr, &cc)))
545 if (GET_TYP (cp))
546 io_pr_cell_win (win, rr, cc, cp);
547 }
548 if (!(cp = find_cell (curow, cucol)) || !GET_TYP (cp))
549 io_display_cell_cursor ();
550 input_view.redraw_needed = FULL_REDRAW;
551 _io_redraw_input ();
552 io_update_status ();
553 }
554
555 static void
_io_close_display(int e)556 _io_close_display (int e)
557 {
558 if (e == 0) {
559 clear ();
560 refresh ();
561 }
562
563 (void) endwin ();
564 }
565
566 static int
_io_input_avail(void)567 _io_input_avail (void)
568 {
569 return (FD_ISSET (0, &read_pending_fd_set)
570 || FD_ISSET (0, &exception_pending_fd_set));
571 }
572
573 static void
_io_scan_for_input(int block)574 _io_scan_for_input (int block)
575 {
576 /* This function only exists because X kbd events don't generate
577 * SIGIO. Under curses, the SIGIO hander does the work of this
578 * function.
579 * Attempt to have the curses mode be somewhat responsive even in
580 * the presence of an endless loop by explicitly looking for events
581 * here.
582 */
583 struct timeval tv;
584
585 tv.tv_sec = 0;
586 tv.tv_usec = 1000;
587 block_until_excitement(&tv);
588 }
589
590 static void
_io_wait_for_input(void)591 _io_wait_for_input (void)
592 {
593 pause ();
594 }
595
596 static int
_io_read_kbd(char * buf,int size)597 _io_read_kbd (char *buf, int size)
598 {
599 int r = read (0, buf, size);
600 FD_CLR (0, &read_pending_fd_set);
601 FD_CLR (0, &exception_pending_fd_set);
602 return r;
603 }
604
605
606 #if defined(SIGIO)
607
608
609 static void
_io_nodelay(int delayp)610 _io_nodelay (int delayp)
611 {
612 panic ("Trying to curses nodelay on a system with SIGIO.");
613 }
614
615 #else
616
617 static void
_io_nodelay(int delayp)618 _io_nodelay (int delayp)
619 {
620 nodelay (stdscr, delayp);
621 }
622
623 #endif
624
625 static int
_io_getch(void)626 _io_getch (void)
627 {
628 char ch;
629 return ((io_read_kbd (&ch, 1) != 1)
630 ? EOF
631 : ch);
632 }
633
634 static int
_io_get_chr(char * prompt)635 _io_get_chr (char *prompt)
636 {
637 int x;
638 mvaddstr (Global->input, 0, prompt);
639 clrtoeol ();
640 Global->topclear = 2;
641 refresh ();
642 ++term_cursor_claimed;
643 x = get_chr ();
644 --term_cursor_claimed;
645 return x;
646 }
647
648 #define BUFFER 10
649
650 static void
_io_bell(void)651 _io_bell (void)
652 {
653 #ifndef HAVE_GETCAP
654 putchar ('\007');
655 #else
656 static char *vb;
657 static int called = 0;
658
659 if (!called)
660 {
661 called++;
662 vb = getcap ("vb");
663 }
664 if (vb)
665 {
666 local_puts (vb);
667 }
668 else
669 {
670 local_putchar ('\007');
671 }
672 #endif
673 }
674
675 static void
move_cursor_to(struct window * win,CELLREF r,CELLREF c,int dn)676 move_cursor_to (struct window *win, CELLREF r, CELLREF c, int dn)
677 {
678 int cc;
679 int cell_cursor_col;
680 int rr;
681 int cell_cursor_row;
682
683 cell_cursor_col = win->win_over;
684 for (cc = win->screen.lc; cc < c; cc++)
685 cell_cursor_col += get_width (cc);
686 cell_cursor_row = win->win_down + dn;
687 for (rr = win->screen.lr; rr < r; rr++)
688 cell_cursor_row += get_height (rr);
689 move (cell_cursor_row, cell_cursor_col);
690 }
691
692 static void
_io_update_status(void)693 _io_update_status (void)
694 {
695 CELL *cp;
696 char *dec;
697 char *ptr;
698 static char hmbuf[40];
699 int wid;
700 int plen;
701 int dlen;
702 int yy, xx;
703
704 if (!user_status || input_view.current_info)
705 return;
706 getyx (stdscr, yy, xx);
707 move (Global->status, 0);
708 wid = columns - 2;
709
710 if (mkrow != NON_ROW)
711 {
712 struct rng r;
713
714 addch ('*');
715 --wid;
716 set_rng (&r, curow, cucol, mkrow, mkcol);
717 ptr = range_name (&r);
718 }
719 else
720 ptr = cell_name (curow, cucol);
721
722 addstr (ptr);
723 wid -= strlen (ptr);
724
725 if (how_many != 1)
726 {
727 sprintf (hmbuf, " {%d}", how_many);
728 addstr (hmbuf);
729 wid -= strlen (hmbuf);
730 }
731
732 if ((cp = find_cell (curow, cucol)) && cp->cell_formula)
733 {
734 dec = decomp (curow, cucol, cp);
735 dlen = strlen (dec);
736 }
737 else
738 {
739 dec = 0;
740 dlen = 0;
741 }
742
743 ptr = cell_value_string (curow, cucol, 1);
744 plen = strlen (ptr);
745
746 if (dec)
747 {
748 wid -= 4;
749 if (dlen + plen > wid)
750 {
751 if (plen + 3 > wid)
752 printw (" %.*s... [...]", wid - 6, ptr);
753 else
754 printw (" %s [%.*s...]", ptr, wid - plen - 3, dec);
755 }
756 else
757 printw (" %s [%s]", ptr, dec);
758 decomp_free ();
759 }
760 else if (plen)
761 {
762 --wid;
763 if (plen > wid)
764 printw (" %.*s...", wid - 3, ptr);
765 else
766 printw (" %s", ptr);
767 }
768
769 clrtoeol ();
770 move (yy, xx);
771 }
772
773 extern int auto_recalc;
774
775 static void
_io_clear_input_before(void)776 _io_clear_input_before (void)
777 {
778 textout = 0;
779 if (Global->topclear == 2)
780 {
781 move (Global->input, 0);
782 clrtoeol ();
783 Global->topclear = 0;
784 }
785 move (0, 0);
786 }
787
788 static void
_io_clear_input_after(void)789 _io_clear_input_after (void)
790 {
791 if (Global->topclear)
792 {
793 move (Global->input, 0);
794 clrtoeol ();
795 Global->topclear = 0;
796 }
797 }
798
799
800 static void
_io_pr_cell_win(struct window * win,CELLREF r,CELLREF c,CELL * cp)801 _io_pr_cell_win (struct window *win, CELLREF r, CELLREF c, CELL *cp)
802 {
803 int glowing;
804 int lenstr;
805 int j;
806 int wid, wwid;
807 int hgt;
808 char *ptr;
809 int yy, xx;
810
811 if (input_view.current_info)
812 return;
813
814 wid = get_width (c);
815 if (!wid)
816 return;
817 if (wid > win->numc)
818 wid = win->numc;
819 hgt = get_height (r);
820 if (!hgt)
821 return;
822 if (hgt > win->numr)
823 hgt = win->numr;
824
825 getyx (stdscr, yy, xx);
826 glowing = (r == curow && c == cucol && win == cwin);
827 ptr = print_cell (cp);
828 move_cursor_to (win, r, c, 0);
829 if (glowing)
830 standout ();
831 j = GET_JST (cp);
832 if (j == JST_DEF)
833 j = default_jst;
834 lenstr = strlen (ptr);
835
836 if (lenstr <= wid - 1)
837 {
838 CELLREF ccl, cch;
839
840 if (j == JST_LFT)
841 printw ("%-*.*s", wid, wid - 1, ptr);
842 else if (j == JST_RGT)
843 printw ("%*.*s ", wid - 1, wid - 1, ptr);
844 else if (j == JST_CNT)
845 {
846 wwid = (wid - 1) - lenstr;
847 printw ("%*s%*s ", (wwid + 1) / 2 + lenstr, ptr, wwid / 2, "");
848 }
849 #ifdef TEST
850 else
851 panic ("Unknown justification");
852 #endif
853 if (glowing)
854 standend ();
855
856 if (lenstr == 0 && c > win->screen.lc
857 && find_slop (win->win_slops, r, c - 1, &ccl, &cch))
858 {
859 CELLREF ccdl, ccdh;
860
861 if (find_slop (win->win_slops, r, c, &ccdl, &ccdh) && ccdl == c)
862 {
863 kill_slop (win->win_slops, r, ccdl, ccdh);
864 for (; ccdh != ccdl; --ccdh)
865 if (ccdh != c && (wwid = get_width (ccdh)))
866 {
867 move_cursor_to (win, r, ccdh, 0);
868 printw ("%*s", wwid, "");
869 }
870 }
871 kill_slop (win->win_slops, r, ccl, cch);
872 io_pr_cell (r, ccl, find_cell (r, ccl));
873 }
874 else if (find_slop (win->win_slops, r, c, &ccl, &cch))
875 {
876 kill_slop (win->win_slops, r, ccl, cch);
877 for (; cch != ccl; --cch)
878 if (cch != c && (wwid = get_width (cch)))
879 {
880 move_cursor_to (win, r, cch, 0);
881 printw ("%*s", wwid, "");
882 }
883 io_pr_cell (r, ccl, find_cell (r, ccl));
884 }
885 }
886 else
887 {
888 CELLREF cc = c;
889 CELL *ccp;
890 CELLREF ccl, cch;
891
892 for (wwid = wid; lenstr > wwid - 1; wwid += get_width (cc))
893 {
894 if (++cc > win->screen.hc
895 || ((ccp = find_cell (r, cc))
896 && GET_TYP (ccp)
897 && (GET_FORMAT (ccp) != FMT_HID
898 || (GET_FORMAT (ccp) == FMT_DEF
899 && default_fmt != FMT_HID))))
900 {
901 --cc;
902 break;
903 }
904 }
905
906 if (lenstr > wwid - 1) { /* FIXME: This construct needs to be checked */
907 if (GET_TYP (cp) == TYP_FLT)
908 ptr = adjust_prc (ptr, cp, wwid - 1, wid - 1, j);
909 else if (GET_TYP (cp) == TYP_INT)
910 ptr = (char *) numb_oflo;
911 }
912
913 if (wwid == 1)
914 {
915 addch (' ');
916 if (glowing)
917 standend ();
918 }
919 else if (wwid == wid)
920 {
921 printw ("%-*.*s ", wwid - 1, wwid - 1, ptr);
922 if (glowing)
923 standend ();
924 }
925 else if (glowing)
926 {
927 printw ("%.*s", wid, ptr);
928 standend ();
929 printw ("%-*.*s ", wwid - wid - 1, wwid - wid - 1, ptr + wid);
930 }
931 else if (r == curow && (cucol > c && cucol <= cc))
932 {
933 CELLREF ctmp;
934 int w_left;
935 int w_here;
936
937 w_left = wid;
938 for (ctmp = c + 1; ctmp < cucol; ctmp++)
939 w_left += get_width (ctmp);
940 printw ("%.*s", w_left, ptr);
941 standout ();
942 w_here = get_width (cucol);
943 if (wwid > w_left + w_here)
944 {
945 printw ("%-*.*s", w_here, w_here, ptr + w_left);
946 standend ();
947 printw ("%-*.*s ",
948 wwid - (w_left + w_here) - 1, wwid - (w_left + w_here) - 1,
949 ptr + w_left + w_here);
950 }
951 else
952 {
953 printw ("%-*.*s", w_here, w_here - 1, ptr + w_left);
954 standend ();
955 }
956 }
957 else
958 printw ("%-*.*s ", wwid - 1, wwid - 1, ptr);
959
960 if (find_slop (win->win_slops, r, c, &ccl, &cch))
961 {
962 change_slop (win->win_slops, r, ccl, cch, c, cc);
963 for (; cch > cc; --cch)
964 if ((wwid = get_width (cch)))
965 {
966 move_cursor_to (win, r, cch, 0);
967 printw ("%*s", wwid, "");
968 }
969 for (cch = c - 1; cch > ccl; --cch)
970 if ((wwid = get_width (cch)))
971 {
972 move_cursor_to (win, r, cch, 0);
973 printw ("%*s", wwid, "");
974 }
975 if (ccl != c)
976 io_pr_cell (r, ccl, find_cell (r, ccl));
977 }
978 else
979 set_slop ((VOIDSTAR *) (&(win->win_slops)), r, c, cc);
980 }
981 if ((hgt > 1) && Global->display_formula_mode)
982 {
983 move_cursor_to (win, r, c, 1);
984 ptr = decomp (r, c, cp);
985 printw ("%.*s ", wid - 1, ptr);
986 decomp_free ();
987 }
988 if (glowing)
989 io_update_status ();
990 move (yy, xx);
991 }
992
993
994 static void
_io_flush(void)995 _io_flush (void)
996 {
997 refresh ();
998 }
999
1000 void
_io_command_loop(int a)1001 _io_command_loop (int a)
1002 {
1003 command_loop (a, 0);
1004 }
1005
1006 void
tty_graphics(void)1007 tty_graphics (void)
1008 {
1009 FD_SET (0, &read_fd_set);
1010 FD_SET (0, &exception_fd_set);
1011 io_command_loop = _io_command_loop;
1012 io_open_display = _io_open_display;
1013 io_redisp = _io_redisp;
1014 io_repaint = _io_repaint;
1015 io_repaint_win = _io_repaint_win;
1016 io_close_display = _io_close_display;
1017 io_input_avail = _io_input_avail;
1018 io_scan_for_input = _io_scan_for_input;
1019 io_wait_for_input = _io_wait_for_input;
1020 io_read_kbd = _io_read_kbd;
1021 io_nodelay = _io_nodelay;
1022 io_getch = _io_getch;
1023 io_bell = _io_bell;
1024 io_get_chr = _io_get_chr;
1025 io_update_status = _io_update_status;
1026 io_fix_input = _io_fix_input;
1027 io_move_cursor = _io_move_cursor;
1028 io_erase = _io_erase;
1029 io_insert = _io_insert;
1030 io_over = _io_over;
1031 io_flush = _io_flush;
1032 io_clear_input_before = _io_clear_input_before;
1033 io_clear_input_after = _io_clear_input_after;
1034 io_pr_cell_win = _io_pr_cell_win;
1035 io_hide_cell_cursor = _io_hide_cell_cursor;
1036 io_cellize_cursor = _io_cellize_cursor;
1037 io_inputize_cursor = _io_inputize_cursor;
1038 io_display_cell_cursor = _io_display_cell_cursor;
1039 }
1040