FreeNOS
teken_subr.h
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 static void teken_subr_cursor_up(teken_t *, unsigned int);
30 static void teken_subr_erase_line(teken_t *, unsigned int);
33 static void teken_subr_save_cursor(teken_t *);
34 
35 static inline int
36 teken_tab_isset(teken_t *t, unsigned int col)
37 {
38  unsigned int b, o;
39 
40  if (col >= T_NUMCOL)
41  return ((col % 8) == 0);
42 
43  b = col / (sizeof(unsigned int) * 8);
44  o = col % (sizeof(unsigned int) * 8);
45 
46  return (t->t_tabstops[b] & (1 << o));
47 }
48 
49 static inline void
50 teken_tab_clear(teken_t *t, unsigned int col)
51 {
52  unsigned int b, o;
53 
54  if (col >= T_NUMCOL)
55  return;
56 
57  b = col / (sizeof(unsigned int) * 8);
58  o = col % (sizeof(unsigned int) * 8);
59 
60  t->t_tabstops[b] &= ~(1 << o);
61 }
62 
63 static inline void
64 teken_tab_set(teken_t *t, unsigned int col)
65 {
66  unsigned int b, o;
67 
68  if (col >= T_NUMCOL)
69  return;
70 
71  b = col / (sizeof(unsigned int) * 8);
72  o = col % (sizeof(unsigned int) * 8);
73 
74  t->t_tabstops[b] |= 1 << o;
75 }
76 
77 static void
79 {
80  unsigned int i;
81 
82  memset(&t->t_tabstops, 0, T_NUMCOL / 8);
83 
84  for (i = 8; i < T_NUMCOL; i += 8)
85  teken_tab_set(t, i);
86 }
87 
88 static void
90 {
91  teken_rect_t tr;
92  teken_pos_t tp;
93 
96  teken_assert(amount != 0);
97 
98  /* Copy existing data 1 line up. */
99  if (amount > 0) {
100  /* Scroll down. */
101 
102  /* Copy existing data up. */
103  if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
104  tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount;
105  tr.tr_begin.tp_col = 0;
107  tr.tr_end.tp_col = t->t_winsize.tp_col;
108  tp.tp_row = t->t_scrollreg.ts_begin;
109  tp.tp_col = 0;
110  teken_funcs_copy(t, &tr, &tp);
111 
112  tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount;
113  } else {
115  }
116 
117  /* Clear the last lines. */
118  tr.tr_begin.tp_col = 0;
120  tr.tr_end.tp_col = t->t_winsize.tp_col;
121  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
122  } else {
123  /* Scroll up. */
124  amount = -amount;
125 
126  /* Copy existing data down. */
127  if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
129  tr.tr_begin.tp_col = 0;
130  tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount;
131  tr.tr_end.tp_col = t->t_winsize.tp_col;
132  tp.tp_row = t->t_scrollreg.ts_begin + amount;
133  tp.tp_col = 0;
134  teken_funcs_copy(t, &tr, &tp);
135 
136  tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount;
137  } else {
139  }
140 
141  /* Clear the first lines. */
143  tr.tr_begin.tp_col = 0;
144  tr.tr_end.tp_col = t->t_winsize.tp_col;
145  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
146  }
147 }
148 
149 static ssize_t
150 teken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16])
151 {
152 
153  switch (cmd) {
154  case 5: /* Operating status. */
155  strcpy(response, "0n");
156  return (2);
157  case 6: { /* Cursor position. */
158  int len;
159 
160  len = snprintf(response, 16, "%u;%uR",
161  (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1,
162  t->t_cursor.tp_col + 1);
163 
164  if (len >= 16)
165  return (-1);
166  return (len);
167  }
168  case 15: /* Printer status. */
169  strcpy(response, "13n");
170  return (3);
171  case 25: /* UDK status. */
172  strcpy(response, "20n");
173  return (3);
174  case 26: /* Keyboard status. */
175  strcpy(response, "27;1n");
176  return (5);
177  default:
178  teken_printf("Unknown DSR\n");
179  return (-1);
180  }
181 }
182 
183 static void
185 {
186  teken_rect_t tr;
187 
188  t->t_scrollreg.ts_begin = 0;
190 
191  t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
192  t->t_stateflags &= ~TS_WRAPPED;
194 
195  tr.tr_begin.tp_row = 0;
196  tr.tr_begin.tp_col = 0;
197  tr.tr_end = t->t_winsize;
198  teken_funcs_fill(t, &tr, 'E', &t->t_defattr);
199 }
200 
201 static void
203 {
204 
205 #ifdef TEKEN_XTERM
206  if (t->t_cursor.tp_col == 0)
207  return;
208 
209  t->t_cursor.tp_col--;
210  t->t_stateflags &= ~TS_WRAPPED;
211 #else /* !TEKEN_XTERM */
212  if (t->t_cursor.tp_col == 0) {
213  if (t->t_cursor.tp_row == t->t_originreg.ts_begin)
214  return;
215  t->t_cursor.tp_row--;
216  t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
217  } else {
218  t->t_cursor.tp_col--;
219  }
220 #endif /* TEKEN_XTERM */
221 
223 }
224 
225 static void
227 {
228 
229  teken_funcs_bell(t);
230 }
231 
232 static void
234 {
235 
236  t->t_cursor.tp_col = 0;
237  t->t_stateflags &= ~TS_WRAPPED;
239 }
240 
241 static void
242 teken_subr_cursor_backward(teken_t *t, unsigned int ncols)
243 {
244 
245  if (ncols > t->t_cursor.tp_col)
246  t->t_cursor.tp_col = 0;
247  else
248  t->t_cursor.tp_col -= ncols;
249  t->t_stateflags &= ~TS_WRAPPED;
251 }
252 
253 static void
255 {
256 
257  do {
258  /* Stop when we've reached the beginning of the line. */
259  if (t->t_cursor.tp_col == 0)
260  break;
261 
262  t->t_cursor.tp_col--;
263 
264  /* Tab marker set. */
265  if (teken_tab_isset(t, t->t_cursor.tp_col))
266  ntabs--;
267  } while (ntabs > 0);
268 
270 }
271 
272 static void
273 teken_subr_cursor_down(teken_t *t, unsigned int nrows)
274 {
275 
276  if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end)
277  t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
278  else
279  t->t_cursor.tp_row += nrows;
280  t->t_stateflags &= ~TS_WRAPPED;
282 }
283 
284 static void
285 teken_subr_cursor_forward(teken_t *t, unsigned int ncols)
286 {
287 
288  if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
289  t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
290  else
291  t->t_cursor.tp_col += ncols;
292  t->t_stateflags &= ~TS_WRAPPED;
294 }
295 
296 static void
298 {
299 
300  do {
301  /* Stop when we've reached the end of the line. */
302  if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1)
303  break;
304 
305  t->t_cursor.tp_col++;
306 
307  /* Tab marker set. */
308  if (teken_tab_isset(t, t->t_cursor.tp_col))
309  ntabs--;
310  } while (ntabs > 0);
311 
313 }
314 
315 static void
316 teken_subr_cursor_next_line(teken_t *t, unsigned int ncols)
317 {
318 
319  t->t_cursor.tp_col = 0;
320  teken_subr_cursor_down(t, ncols);
321 }
322 
323 static void
324 teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col)
325 {
326 
327  t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
328  if (row >= t->t_originreg.ts_end)
329  t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
330 
331  t->t_cursor.tp_col = col - 1;
332  if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
333  t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
334 
335  t->t_stateflags &= ~TS_WRAPPED;
337 }
338 
339 static void
341 {
342  char response[18] = "\x1B[";
343  ssize_t len;
344 
345  len = teken_subr_do_cpr(t, cmd, response + 2);
346  if (len < 0)
347  return;
348 
349  teken_funcs_respond(t, response, len + 2);
350 }
351 
352 static void
354 {
355 
356  t->t_cursor.tp_col = 0;
357  teken_subr_cursor_up(t, ncols);
358 }
359 
360 static void
361 teken_subr_cursor_up(teken_t *t, unsigned int nrows)
362 {
363 
364  if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row)
366  else
367  t->t_cursor.tp_row -= nrows;
368  t->t_stateflags &= ~TS_WRAPPED;
370 }
371 
372 static void
373 teken_subr_delete_character(teken_t *t, unsigned int ncols)
374 {
375  teken_rect_t tr;
376 
377  tr.tr_begin.tp_row = t->t_cursor.tp_row;
378  tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
379  tr.tr_end.tp_col = t->t_winsize.tp_col;
380 
381  if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
382  tr.tr_begin.tp_col = t->t_cursor.tp_col;
383  } else {
384  /* Copy characters to the left. */
385  tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols;
386  teken_funcs_copy(t, &tr, &t->t_cursor);
387 
388  tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols;
389  }
390 
391  /* Blank trailing columns. */
392  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
393 }
394 
395 static void
396 teken_subr_delete_line(teken_t *t, unsigned int nrows)
397 {
398  teken_rect_t tr;
399 
400  tr.tr_begin.tp_col = 0;
402  tr.tr_end.tp_col = t->t_winsize.tp_col;
403 
404  if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
405  tr.tr_begin.tp_row = t->t_cursor.tp_row;
406  } else {
407  teken_pos_t tp;
408 
409  /* Copy rows up. */
410  tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows;
411  tp.tp_row = t->t_cursor.tp_row;
412  tp.tp_col = 0;
413  teken_funcs_copy(t, &tr, &tp);
414 
415  tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows;
416  }
417 
418  /* Blank trailing rows. */
419  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
420 }
421 
422 static void
424 {
425 
426  teken_printf("device control string???\n");
427 }
428 
429 static void
431 {
432  char response[19] = "\x1B[?";
433  ssize_t len;
434 
435  len = teken_subr_do_cpr(t, cmd, response + 3);
436  if (len < 0)
437  return;
438 
439  teken_funcs_respond(t, response, len + 3);
440 }
441 
442 static void
444 {
445 
446  teken_printf("double height double width top\n");
447 }
448 
449 static void
451 {
452 
453  teken_printf("double height double width bottom\n");
454 }
455 
456 static void
457 teken_subr_erase_character(teken_t *t, unsigned int ncols)
458 {
459  teken_rect_t tr;
460 
461  tr.tr_begin = t->t_cursor;
462  tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
463 
464  if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
465  tr.tr_end.tp_col = t->t_winsize.tp_col;
466  else
467  tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
468 
469  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
470 }
471 
472 static void
473 teken_subr_erase_display(teken_t *t, unsigned int mode)
474 {
475  teken_rect_t r;
476 
477  r.tr_begin.tp_col = 0;
478  r.tr_end.tp_col = t->t_winsize.tp_col;
479 
480  switch (mode) {
481  case 1: /* Erase from the top to the cursor. */
482  teken_subr_erase_line(t, 1);
483 
484  /* Erase lines above. */
485  if (t->t_cursor.tp_row == 0)
486  return;
487  r.tr_begin.tp_row = 0;
488  r.tr_end.tp_row = t->t_cursor.tp_row;
489  break;
490  case 2: /* Erase entire display. */
491  r.tr_begin.tp_row = 0;
492  r.tr_end.tp_row = t->t_winsize.tp_row;
493  break;
494  default: /* Erase from cursor to the bottom. */
495  teken_subr_erase_line(t, 0);
496 
497  /* Erase lines below. */
498  if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1)
499  return;
500  r.tr_begin.tp_row = t->t_cursor.tp_row + 1;
501  r.tr_end.tp_row = t->t_winsize.tp_row;
502  break;
503  }
504 
505  teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
506 }
507 
508 static void
509 teken_subr_erase_line(teken_t *t, unsigned int mode)
510 {
511  teken_rect_t r;
512 
514  r.tr_end.tp_row = t->t_cursor.tp_row + 1;
515 
516  switch (mode) {
517  case 1: /* Erase from the beginning of the line to the cursor. */
518  r.tr_begin.tp_col = 0;
519  r.tr_end.tp_col = t->t_cursor.tp_col + 1;
520  break;
521  case 2: /* Erase entire line. */
522  r.tr_begin.tp_col = 0;
523  r.tr_end.tp_col = t->t_winsize.tp_col;
524  break;
525  default: /* Erase from cursor to the end of the line. */
527  r.tr_end.tp_col = t->t_winsize.tp_col;
528  break;
529  }
530 
531  teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
532 }
533 
534 static void
536 {
537 
539 }
540 
541 static void
543 {
544 
546 }
547 
548 static void
550 {
551 
553 }
554 
555 static void
557 {
558 
560 }
561 
562 static void
564 {
565 
567 }
568 
569 static void
571 {
572 
574 }
575 
576 static void
578 {
579 
580  t->t_cursor.tp_col = col - 1;
581  if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
582  t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
583 
584  t->t_stateflags &= ~TS_WRAPPED;
586 }
587 
588 static void
590 {
591 #ifdef TEKEN_XTERM
592  teken_rect_t tr;
593 
594  tr.tr_begin = t->t_cursor;
596  tr.tr_end.tp_row = tr.tr_begin.tp_row + 1;
597  tr.tr_end.tp_col = t->t_cursor.tp_col;
598 
599  /* Blank region that we skipped. */
600  if (tr.tr_end.tp_col > tr.tr_begin.tp_col)
601  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
602 #else /* !TEKEN_XTERM */
603 
605 #endif /* TEKEN_XTERM */
606 }
607 
608 static void
610 {
611 
613 }
614 
615 static void
617 {
618 
619  if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) {
620  t->t_cursor.tp_row++;
621  t->t_stateflags &= ~TS_WRAPPED;
623  } else {
624  teken_subr_do_scroll(t, 1);
625  }
626 }
627 
628 static void
629 teken_subr_insert_character(teken_t *t, unsigned int ncols)
630 {
631  teken_rect_t tr;
632 
633  tr.tr_begin = t->t_cursor;
634  tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
635 
636  if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
637  tr.tr_end.tp_col = t->t_winsize.tp_col;
638  } else {
639  teken_pos_t tp;
640 
641  /* Copy characters to the right. */
642  tr.tr_end.tp_col = t->t_winsize.tp_col - ncols;
643  tp.tp_row = t->t_cursor.tp_row;
644  tp.tp_col = t->t_cursor.tp_col + ncols;
645  teken_funcs_copy(t, &tr, &tp);
646 
647  tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
648  }
649 
650  /* Blank current location. */
651  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
652 }
653 
654 static void
655 teken_subr_insert_line(teken_t *t, unsigned int nrows)
656 {
657  teken_rect_t tr;
658 
659  tr.tr_begin.tp_row = t->t_cursor.tp_row;
660  tr.tr_begin.tp_col = 0;
661  tr.tr_end.tp_col = t->t_winsize.tp_col;
662 
663  if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
665  } else {
666  teken_pos_t tp;
667 
668  /* Copy lines down. */
669  tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows;
670  tp.tp_row = t->t_cursor.tp_row + nrows;
671  tp.tp_col = 0;
672  teken_funcs_copy(t, &tr, &tp);
673 
674  tr.tr_end.tp_row = t->t_cursor.tp_row + nrows;
675  }
676 
677  /* Blank current location. */
678  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
679 }
680 
681 static void
683 {
684 
686 }
687 
688 static void
690 {
691 
693 }
694 
695 static void
697 {
698 
699  t->t_cursor.tp_row++;
700 
701  if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) {
702  teken_subr_do_scroll(t, 1);
703  t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
704  }
705 
706  t->t_stateflags &= ~TS_WRAPPED;
708 }
709 
710 static void
712 {
713 #ifdef TEKEN_XTERM
714 
716 #else /* !TEKEN_XTERM */
717  teken_rect_t tr;
718 
719  tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0;
720  tr.tr_end = t->t_winsize;
721  teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
722 
723  t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
725 #endif /* TEKEN_XTERM */
726 }
727 
728 static void
730 {
731 
732  t->t_cursor.tp_col = 0;
734 }
735 
736 static void
737 teken_subr_pan_down(teken_t *t, unsigned int nrows)
738 {
739 
740  teken_subr_do_scroll(t, (int)nrows);
741 }
742 
743 static void
744 teken_subr_pan_up(teken_t *t, unsigned int nrows)
745 {
746 
747  teken_subr_do_scroll(t, -(int)nrows);
748 }
749 
750 static void
752 {
753 
754  if (request == 0) {
755  const char response[] = "\x1B[?1;2c";
756 
757  teken_funcs_respond(t, response, sizeof response - 1);
758  } else {
759  teken_printf("Unknown DA1\n");
760  }
761 }
762 
763 static void
765  int width)
766 {
767 
768  if (t->t_stateflags & TS_INSERT &&
769  tp->tp_col < t->t_winsize.tp_col - width) {
770  teken_rect_t ctr;
771  teken_pos_t ctp;
772 
773  /* Insert mode. Move existing characters to the right. */
774  ctr.tr_begin = *tp;
775  ctr.tr_end.tp_row = tp->tp_row + 1;
776  ctr.tr_end.tp_col = t->t_winsize.tp_col - width;
777  ctp.tp_row = tp->tp_row;
778  ctp.tp_col = tp->tp_col + width;
779  teken_funcs_copy(t, &ctr, &ctp);
780  }
781 
782  teken_funcs_putchar(t, tp, c, &t->t_curattr);
783 }
784 
785 static void
787 {
788  int width;
789 
790  c = teken_scs_process(t, c);
791 
792  /* XXX: Don't process zero-width characters yet. */
793  width = teken_wcwidth(c);
794  if (width <= 0)
795  return;
796 
797 #ifdef TEKEN_XTERM
798  if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 &&
801  teken_pos_t tp;
802 
803  /* Perform line wrapping. */
804 
805  if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
806  /* Perform scrolling. */
807  teken_subr_do_scroll(t, 1);
808  tp.tp_row = t->t_scrollreg.ts_end - 1;
809  } else {
810  /* No scrolling needed. */
811  tp.tp_row = t->t_cursor.tp_row + 1;
812  if (tp.tp_row == t->t_winsize.tp_row) {
813  /*
814  * Corner case: regular character
815  * outside scrolling region, but at the
816  * bottom of the screen.
817  */
819  c, width);
820  return;
821  }
822  }
823 
824  tp.tp_col = 0;
825  teken_subr_do_putchar(t, &tp, c, width);
826 
827  t->t_cursor.tp_row = tp.tp_row;
828  t->t_cursor.tp_col = width;
829  t->t_stateflags &= ~TS_WRAPPED;
830  } else {
831  /* No line wrapping needed. */
832  teken_subr_do_putchar(t, &t->t_cursor, c, width);
833  t->t_cursor.tp_col += width;
834 
835  if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
836  t->t_stateflags |= TS_WRAPPED;
837  t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
838  } else {
839  t->t_stateflags &= ~TS_WRAPPED;
840  }
841  }
842 #else /* !TEKEN_XTERM */
843  teken_subr_do_putchar(t, &t->t_cursor, c, width);
844  t->t_cursor.tp_col += width;
845 
846  if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
847  if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
848  /* Perform scrolling. */
849  teken_subr_do_scroll(t, 1);
850  } else {
851  /* No scrolling needed. */
852  if (t->t_cursor.tp_row < t->t_winsize.tp_row - 1)
853  t->t_cursor.tp_row++;
854  }
855  t->t_cursor.tp_col = 0;
856  }
857 #endif /* TEKEN_XTERM */
858 
860 }
861 
862 static void
863 teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
864 {
865 
866  switch (cmd) {
867  case 1: /* Cursor keys mode. */
869  break;
870  case 2: /* DECANM: ANSI/VT52 mode. */
871  teken_printf("DECRST VT52\n");
872  break;
873  case 3: /* 132 column mode. */
876  break;
877  case 5: /* Inverse video. */
878  teken_printf("DECRST inverse video\n");
879  break;
880  case 6: /* Origin mode. */
881  t->t_stateflags &= ~TS_ORIGIN;
882  t->t_originreg.ts_begin = 0;
884  t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
885  t->t_stateflags &= ~TS_WRAPPED;
887  break;
888  case 7: /* Autowrap mode. */
889  t->t_stateflags &= ~TS_AUTOWRAP;
890  break;
891  case 8: /* Autorepeat mode. */
893  break;
894  case 25: /* Hide cursor. */
896  break;
897  case 40: /* Disallow 132 columns. */
898  teken_printf("DECRST allow 132\n");
899  break;
900  case 45: /* Disable reverse wraparound. */
901  teken_printf("DECRST reverse wraparound\n");
902  break;
903  case 47: /* Switch to alternate buffer. */
904  teken_printf("Switch to alternate buffer\n");
905  break;
906  default:
907  teken_printf("Unknown DECRST: %u\n", cmd);
908  }
909 }
910 
911 static void
912 teken_subr_reset_mode(teken_t *t, unsigned int cmd)
913 {
914 
915  switch (cmd) {
916  case 4:
917  t->t_stateflags &= ~TS_INSERT;
918  break;
919  default:
920  teken_printf("Unknown reset mode: %u\n", cmd);
921  }
922 }
923 
924 static void
926 {
927 
928  t->t_curattr = t->t_defattr;
929  t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
931 
934  teken_scs_switch(t, 0);
935 
938 }
939 
940 static void
942 {
943 
948 }
949 
950 static void
952 {
953 
954  t->t_cursor = t->t_saved_cursor;
955  t->t_curattr = t->t_saved_curattr;
956  t->t_stateflags &= ~TS_WRAPPED;
959 }
960 
961 static void
963 {
964 
965  if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) {
966  t->t_cursor.tp_row--;
967  t->t_stateflags &= ~TS_WRAPPED;
969  } else {
970  teken_subr_do_scroll(t, -1);
971  }
972 }
973 
974 static void
976 {
977 
978  t->t_saved_cursor = t->t_cursor;
979  t->t_saved_curattr = t->t_curattr;
980  teken_scs_save(t);
981 }
982 
983 static void
985 {
986 
987  if (request == 0) {
988  const char response[] = "\x1B[>0;10;0c";
989  teken_funcs_respond(t, response, sizeof response - 1);
990  } else {
991  teken_printf("Unknown DA2\n");
992  }
993 }
994 
995 static void
996 teken_subr_set_dec_mode(teken_t *t, unsigned int cmd)
997 {
998 
999  switch (cmd) {
1000  case 1: /* Cursor keys mode. */
1002  break;
1003  case 2: /* DECANM: ANSI/VT52 mode. */
1004  teken_printf("DECSET VT52\n");
1005  break;
1006  case 3: /* 132 column mode. */
1009  break;
1010  case 5: /* Inverse video. */
1011  teken_printf("DECSET inverse video\n");
1012  break;
1013  case 6: /* Origin mode. */
1014  t->t_stateflags |= TS_ORIGIN;
1015  t->t_originreg = t->t_scrollreg;
1017  t->t_cursor.tp_col = 0;
1018  t->t_stateflags &= ~TS_WRAPPED;
1019  teken_funcs_cursor(t);
1020  break;
1021  case 7: /* Autowrap mode. */
1022  t->t_stateflags |= TS_AUTOWRAP;
1023  break;
1024  case 8: /* Autorepeat mode. */
1026  break;
1027  case 25: /* Display cursor. */
1029  break;
1030  case 40: /* Allow 132 columns. */
1031  teken_printf("DECSET allow 132\n");
1032  break;
1033  case 45: /* Enable reverse wraparound. */
1034  teken_printf("DECSET reverse wraparound\n");
1035  break;
1036  case 47: /* Switch to alternate buffer. */
1037  teken_printf("Switch away from alternate buffer\n");
1038  break;
1039  default:
1040  teken_printf("Unknown DECSET: %u\n", cmd);
1041  }
1042 }
1043 
1044 static void
1045 teken_subr_set_mode(teken_t *t, unsigned int cmd)
1046 {
1047 
1048  switch (cmd) {
1049  case 4:
1050  teken_printf("Insert mode\n");
1051  t->t_stateflags |= TS_INSERT;
1052  break;
1053  default:
1054  teken_printf("Unknown set mode: %u\n", cmd);
1055  }
1056 }
1057 
1058 static void
1060  unsigned int cmds[])
1061 {
1062  unsigned int i, n;
1063 
1064  /* No attributes means reset. */
1065  if (ncmds == 0) {
1066  t->t_curattr = t->t_defattr;
1067  return;
1068  }
1069 
1070  for (i = 0; i < ncmds; i++) {
1071  n = cmds[i];
1072 
1073  switch (n) {
1074  case 0: /* Reset. */
1075  t->t_curattr = t->t_defattr;
1076  break;
1077  case 1: /* Bold. */
1078  t->t_curattr.ta_format |= TF_BOLD;
1079  break;
1080  case 4: /* Underline. */
1082  break;
1083  case 5: /* Blink. */
1085  break;
1086  case 7: /* Reverse. */
1088  break;
1089  case 22: /* Remove bold. */
1090  t->t_curattr.ta_format &= ~TF_BOLD;
1091  break;
1092  case 24: /* Remove underline. */
1094  break;
1095  case 25: /* Remove blink. */
1096  t->t_curattr.ta_format &= ~TF_BLINK;
1097  break;
1098  case 27: /* Remove reverse. */
1100  break;
1101  case 30: /* Set foreground color: black */
1102  case 31: /* Set foreground color: red */
1103  case 32: /* Set foreground color: green */
1104  case 33: /* Set foreground color: brown */
1105  case 34: /* Set foreground color: blue */
1106  case 35: /* Set foreground color: magenta */
1107  case 36: /* Set foreground color: cyan */
1108  case 37: /* Set foreground color: white */
1109  t->t_curattr.ta_fgcolor = n - 30;
1110  break;
1111  case 39: /* Set default foreground color. */
1113  break;
1114  case 40: /* Set background color: black */
1115  case 41: /* Set background color: red */
1116  case 42: /* Set background color: green */
1117  case 43: /* Set background color: brown */
1118  case 44: /* Set background color: blue */
1119  case 45: /* Set background color: magenta */
1120  case 46: /* Set background color: cyan */
1121  case 47: /* Set background color: white */
1122  t->t_curattr.ta_bgcolor = n - 40;
1123  break;
1124  case 49: /* Set default background color. */
1126  break;
1127  default:
1128  teken_printf("unsupported attribute %u\n", n);
1129  }
1130  }
1131 }
1132 
1133 static void
1135  unsigned int bottom)
1136 {
1137 
1138  /* Adjust top row number. */
1139  if (top > 0)
1140  top--;
1141  /* Adjust bottom row number. */
1142  if (bottom == 0 || bottom > t->t_winsize.tp_row)
1143  bottom = t->t_winsize.tp_row;
1144 
1145  /* Invalid arguments. */
1146  if (top >= bottom - 1) {
1147  top = 0;
1148  bottom = t->t_winsize.tp_row;
1149  }
1150 
1151  t->t_scrollreg.ts_begin = top;
1152  t->t_scrollreg.ts_end = bottom;
1153  if (t->t_stateflags & TS_ORIGIN) {
1154  /* XXX: home cursor? */
1155  t->t_originreg = t->t_scrollreg;
1157  t->t_cursor.tp_col = 0;
1158  t->t_stateflags &= ~TS_WRAPPED;
1159  teken_funcs_cursor(t);
1160  }
1161 }
1162 
1163 static void
1165 {
1166 
1167  teken_printf("single height double width???\n");
1168 }
1169 
1170 static void
1172 {
1173 
1174  teken_printf("single height single width???\n");
1175 }
1176 
1177 static void
1179 {
1180 
1181  teken_printf("string terminator???\n");
1182 }
1183 
1184 static void
1185 teken_subr_tab_clear(teken_t *t, unsigned int cmd)
1186 {
1187 
1188  switch (cmd) {
1189  case 0:
1191  break;
1192  case 3:
1193  memset(&t->t_tabstops, 0, T_NUMCOL / 8);
1194  break;
1195  }
1196 }
1197 
1198 static void
1200 {
1201 
1202  t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
1203  if (row >= t->t_originreg.ts_end)
1204  t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
1205 
1206 
1207  t->t_stateflags &= ~TS_WRAPPED;
1208  teken_funcs_cursor(t);
1209 }
teken_subr_device_status_report
static void teken_subr_device_status_report(teken_t *t, unsigned int cmd)
Definition: teken_subr.h:430
teken_attr_t::ta_format
teken_format_t ta_format
Definition: teken.h:77
teken_subr_reset_to_initial_state
static void teken_subr_reset_to_initial_state(teken_t *)
Definition: teken_subr.h:941
teken_funcs_fill
static void teken_funcs_fill(teken_t *t, const teken_rect_t *r, const teken_char_t c, const teken_attr_t *a)
Definition: teken.c:125
teken_scs_uk_national
static teken_char_t teken_scs_uk_national(teken_char_t c)
Definition: teken_scs.h:83
teken_subr_g0_scs_special_graphics
static void teken_subr_g0_scs_special_graphics(teken_t *t __unused)
Definition: teken_subr.h:535
teken_subr_carriage_return
static void teken_subr_carriage_return(teken_t *t)
Definition: teken_subr.h:233
teken_subr_insert_character
static void teken_subr_insert_character(teken_t *t, unsigned int ncols)
Definition: teken_subr.h:629
__teken::t_scrollreg
teken_span_t t_scrollreg
Definition: teken.h:151
teken_subr_newpage
static void teken_subr_newpage(teken_t *t)
Definition: teken_subr.h:711
teken_subr_do_reset
static void teken_subr_do_reset(teken_t *t)
Definition: teken_subr.h:925
TF_BLINK
#define TF_BLINK
Definition: teken.h:55
teken_funcs_copy
static void teken_funcs_copy(teken_t *t, const teken_rect_t *r, const teken_pos_t *p)
Definition: teken.c:138
teken_scs_save
#define teken_scs_save(t)
Definition: teken.c:71
teken_tab_set
static void teken_tab_set(teken_t *t, unsigned int col)
Definition: teken_subr.h:64
TP_CURSORKEYS
#define TP_CURSORKEYS
Definition: teken.h:103
teken_scs_restore
#define teken_scs_restore(t)
Definition: teken.c:70
teken_span_t::ts_begin
teken_unit_t ts_begin
Definition: teken.h:82
teken_funcs_param
static void teken_funcs_param(teken_t *t, int cmd, unsigned int value)
Definition: teken.c:152
teken_tab_isset
static int teken_tab_isset(teken_t *t, unsigned int col)
Definition: teken_subr.h:36
TF_REVERSE
#define TF_REVERSE
Definition: teken.h:56
teken_attr_t::ta_fgcolor
teken_color_t ta_fgcolor
Definition: teken.h:78
teken_subr_do_putchar
static void teken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, int width)
Definition: teken_subr.h:764
teken_subr_g1_scs_uk_national
static void teken_subr_g1_scs_uk_national(teken_t *t __unused)
Definition: teken_subr.h:563
TP_132COLS
#define TP_132COLS
Definition: teken.h:107
teken_subr_vertical_position_absolute
static void teken_subr_vertical_position_absolute(teken_t *t, unsigned int row)
Definition: teken_subr.h:1199
teken_subr_double_height_double_width_line_bottom
static void teken_subr_double_height_double_width_line_bottom(teken_t *t __unused)
Definition: teken_subr.h:450
teken_tab_clear
static void teken_tab_clear(teken_t *t, unsigned int col)
Definition: teken_subr.h:50
teken_subr_regular_character
static void teken_subr_regular_character(teken_t *, teken_char_t)
Definition: teken_subr.h:786
TP_AUTOREPEAT
#define TP_AUTOREPEAT
Definition: teken.h:105
teken_subr_insert_line
static void teken_subr_insert_line(teken_t *t, unsigned int nrows)
Definition: teken_subr.h:655
teken_subr_string_terminator
static void teken_subr_string_terminator(teken_t *t __unused)
Definition: teken_subr.h:1178
teken_subr_g1_scs_us_ascii
static void teken_subr_g1_scs_us_ascii(teken_t *t __unused)
Definition: teken_subr.h:570
teken_subr_backspace
static void teken_subr_backspace(teken_t *t)
Definition: teken_subr.h:202
teken_subr_g0_scs_us_ascii
static void teken_subr_g0_scs_us_ascii(teken_t *t __unused)
Definition: teken_subr.h:549
teken_funcs_bell
static void teken_funcs_bell(teken_t *t)
Definition: teken.c:97
__teken::t_cursor
teken_pos_t t_cursor
Definition: teken.h:142
__teken::t_winsize
teken_pos_t t_winsize
Definition: teken.h:148
teken_subr_cursor_down
static void teken_subr_cursor_down(teken_t *t, unsigned int nrows)
Definition: teken_subr.h:273
teken_subr_cursor_position
static void teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col)
Definition: teken_subr.h:324
teken_funcs_putchar
static void teken_funcs_putchar(teken_t *t, const teken_pos_t *p, teken_char_t c, const teken_attr_t *a)
Definition: teken.c:114
teken_subr_keypad_numeric_mode
static void teken_subr_keypad_numeric_mode(teken_t *t)
Definition: teken_subr.h:689
teken_printf
#define teken_printf(x,...)
Definition: teken.c:46
TS_ORIGIN
#define TS_ORIGIN
Definition: teken.c:80
teken_subr_newline
static void teken_subr_newline(teken_t *t)
Definition: teken_subr.h:696
teken_subr_erase_display
static void teken_subr_erase_display(teken_t *t, unsigned int mode)
Definition: teken_subr.h:473
teken_rect_t::tr_end
teken_pos_t tr_end
Definition: teken.h:74
TP_KEYPADAPP
#define TP_KEYPADAPP
Definition: teken.h:104
teken_subr_cursor_backward
static void teken_subr_cursor_backward(teken_t *t, unsigned int ncols)
Definition: teken_subr.h:242
strcpy
int strcpy(char *dest, const char *src)
Copy a string.
Definition: strcpy.cpp:20
teken_subr_cursor_next_line
static void teken_subr_cursor_next_line(teken_t *t, unsigned int ncols)
Definition: teken_subr.h:316
teken_subr_cursor_position_report
static void teken_subr_cursor_position_report(teken_t *t, unsigned int cmd)
Definition: teken_subr.h:340
teken_subr_set_mode
static void teken_subr_set_mode(teken_t *t, unsigned int cmd)
Definition: teken_subr.h:1045
teken_subr_reset_dec_mode
static void teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
Definition: teken_subr.h:863
__teken::t_stateflags
unsigned int t_stateflags
Definition: teken.h:136
__teken::t_tabstops
unsigned int t_tabstops[T_NUMCOL/(sizeof(unsigned int) *8)]
Definition: teken.h:156
teken_subr_single_height_single_width_line
static void teken_subr_single_height_single_width_line(teken_t *t __unused)
Definition: teken_subr.h:1171
teken_subr_keypad_application_mode
static void teken_subr_keypad_application_mode(teken_t *t)
Definition: teken_subr.h:682
teken_subr_do_scroll
static void teken_subr_do_scroll(teken_t *t, int amount)
Definition: teken_subr.h:89
teken_subr_cursor_previous_line
static void teken_subr_cursor_previous_line(teken_t *t, unsigned int ncols)
Definition: teken_subr.h:353
teken_subr_horizontal_tab_set
static void teken_subr_horizontal_tab_set(teken_t *t)
Definition: teken_subr.h:609
teken_attr_t::ta_bgcolor
teken_color_t ta_bgcolor
Definition: teken.h:79
teken_subr_cursor_forward_tabulation
static void teken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs)
Definition: teken_subr.h:297
teken_subr_next_line
static void teken_subr_next_line(teken_t *t)
Definition: teken_subr.h:729
teken_pos_t::tp_col
teken_unit_t tp_col
Definition: teken.h:70
teken_funcs_respond
static void teken_funcs_respond(teken_t *t, const void *buf, size_t len)
Definition: teken.c:159
teken_subr_double_height_double_width_line_top
static void teken_subr_double_height_double_width_line_top(teken_t *t __unused)
Definition: teken_subr.h:443
teken_subr_pan_up
static void teken_subr_pan_up(teken_t *t, unsigned int nrows)
Definition: teken_subr.h:744
teken_subr_cursor_up
static void teken_subr_cursor_up(teken_t *, unsigned int)
Definition: teken_subr.h:361
teken_subr_bell
static void teken_subr_bell(teken_t *t)
Definition: teken_subr.h:226
teken_subr_delete_line
static void teken_subr_delete_line(teken_t *t, unsigned int nrows)
Definition: teken_subr.h:396
teken_subr_secondary_device_attributes
static void teken_subr_secondary_device_attributes(teken_t *t, unsigned int request)
Definition: teken_subr.h:984
teken_subr_reverse_index
static void teken_subr_reverse_index(teken_t *t)
Definition: teken_subr.h:962
teken_subr_save_cursor
static void teken_subr_save_cursor(teken_t *)
Definition: teken_subr.h:975
teken_subr_horizontal_tab
static void teken_subr_horizontal_tab(teken_t *t)
Definition: teken_subr.h:589
teken_scs_set
#define teken_scs_set(t, g, ts)
Definition: teken.c:72
teken_funcs_cursor
static void teken_funcs_cursor(teken_t *t)
Definition: teken.c:104
teken_scs_special_graphics
static teken_char_t teken_scs_special_graphics(teken_char_t c)
Definition: teken_scs.h:73
TF_UNDERLINE
#define TF_UNDERLINE
Definition: teken.h:54
teken_scs_process
#define teken_scs_process(t, c)
Definition: teken.c:69
__unused
#define __unused
Definition: teken.c:29
__teken::t_saved_cursor
teken_pos_t t_saved_cursor
Definition: teken.h:144
teken_subr_pan_down
static void teken_subr_pan_down(teken_t *t, unsigned int nrows)
Definition: teken_subr.h:737
teken_scs_us_ascii
static teken_char_t teken_scs_us_ascii(teken_char_t c)
Definition: teken_scs.h:93
teken_assert
#define teken_assert(x)
Definition: teken.c:43
teken_subr_erase_character
static void teken_subr_erase_character(teken_t *t, unsigned int ncols)
Definition: teken_subr.h:457
TS_AUTOWRAP
#define TS_AUTOWRAP
Definition: teken.c:79
teken_char_t
unsigned char teken_char_t
Definition: teken.h:49
teken_pos_t::tp_row
teken_unit_t tp_row
Definition: teken.h:69
teken_subr_horizontal_position_absolute
static void teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col)
Definition: teken_subr.h:577
TS_WRAPPED
#define TS_WRAPPED
Definition: teken.c:84
TF_BOLD
#define TF_BOLD
Definition: teken.h:53
teken_rect_t::tr_begin
teken_pos_t tr_begin
Definition: teken.h:73
T_NUMCOL
#define T_NUMCOL
Definition: teken.h:155
teken_wcwidth
#define teken_wcwidth(c)
Definition: teken.c:62
BLANK
#define BLANK
Definition: teken.c:88
__teken
Definition: teken.h:131
teken_subr_do_cpr
static ssize_t teken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16])
Definition: teken_subr.h:150
teken_subr_cursor_backward_tabulation
static void teken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs)
Definition: teken_subr.h:254
TS_INSERT
#define TS_INSERT
Definition: teken.c:78
teken_tab_default
static void teken_tab_default(teken_t *t)
Definition: teken_subr.h:78
TP_SHOWCURSOR
#define TP_SHOWCURSOR
Definition: teken.h:102
__teken::t_saved_curattr
teken_attr_t t_saved_curattr
Definition: teken.h:145
__teken::t_originreg
teken_span_t t_originreg
Definition: teken.h:153
teken_subr_tab_clear
static void teken_subr_tab_clear(teken_t *t, unsigned int cmd)
Definition: teken_subr.h:1185
ssize_t
slong ssize_t
Used for a count of bytes or an error indication.
Definition: types.h:38
memset
void * memset(void *dest, int ch, size_t count)
Fill memory with a constant byte.
Definition: memset.cpp:20
teken_subr_set_graphic_rendition
static void teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, unsigned int cmds[])
Definition: teken_subr.h:1059
teken_subr_index
static void teken_subr_index(teken_t *t)
Definition: teken_subr.h:616
teken_pos_t
Definition: teken.h:68
teken_subr_primary_device_attributes
static void teken_subr_primary_device_attributes(teken_t *t, unsigned int request)
Definition: teken_subr.h:751
teken_subr_alignment_test
static void teken_subr_alignment_test(teken_t *t)
Definition: teken_subr.h:184
teken_subr_set_top_and_bottom_margins
static void teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, unsigned int bottom)
Definition: teken_subr.h:1134
__teken::t_defattr
teken_attr_t t_defattr
Definition: teken.h:147
teken_subr_g0_scs_uk_national
static void teken_subr_g0_scs_uk_national(teken_t *t __unused)
Definition: teken_subr.h:542
teken_subr_g1_scs_special_graphics
static void teken_subr_g1_scs_special_graphics(teken_t *t __unused)
Definition: teken_subr.h:556
teken_scs_switch
#define teken_scs_switch(t, g)
Definition: teken.c:73
teken_subr_set_dec_mode
static void teken_subr_set_dec_mode(teken_t *t, unsigned int cmd)
Definition: teken_subr.h:996
teken_span_t::ts_end
teken_unit_t ts_end
Definition: teken.h:83
snprintf
int snprintf(char *buffer, unsigned int size, const char *fmt,...)
Write a formatted string into a buffer.
Definition: snprintf.cpp:22
teken_subr_device_control_string
static void teken_subr_device_control_string(teken_t *t __unused)
Definition: teken_subr.h:423
teken_subr_restore_cursor
static void teken_subr_restore_cursor(teken_t *t)
Definition: teken_subr.h:951
__teken::t_curattr
teken_attr_t t_curattr
Definition: teken.h:143
teken_subr_cursor_forward
static void teken_subr_cursor_forward(teken_t *t, unsigned int ncols)
Definition: teken_subr.h:285
teken_subr_reset_mode
static void teken_subr_reset_mode(teken_t *t, unsigned int cmd)
Definition: teken_subr.h:912
teken_subr_erase_line
static void teken_subr_erase_line(teken_t *, unsigned int)
Definition: teken_subr.h:509
teken_subr_delete_character
static void teken_subr_delete_character(teken_t *t, unsigned int ncols)
Definition: teken_subr.h:373
teken_rect_t
Definition: teken.h:72
teken_subr_single_height_double_width_line
static void teken_subr_single_height_double_width_line(teken_t *t __unused)
Definition: teken_subr.h:1164