xref: /original-bsd/usr.bin/window/wwinschar.c (revision a9157423)
1 #ifndef lint
2 static	char *sccsid = "@(#)wwinschar.c	3.6 83/08/17";
3 #endif
4 
5 #include "ww.h"
6 #include "tt.h"
7 
8 wwinschar(w, line, col, c)
9 register struct ww *w;
10 short c;
11 {
12 	register i;
13 	int row = line - w->ww_scroll;
14 	int nvis;
15 
16 	{
17 		register union ww_char *p, *q;
18 
19 		p = &w->ww_buf[line][w->ww_w.nc];
20 		q = p - 1;
21 		for (i = w->ww_w.nc - col - 1; --i >= 0;)
22 			*--p = *--q;
23 		q->c_w = c;
24 	}
25 	if (row < 0 || row >= w->ww_w.nr)
26 		return;
27 	{
28 		register union ww_char *buf;
29 		register char *win;
30 		register union ww_char *ns;
31 		register char *smap;
32 		char *touched;
33 
34 		nvis = 0;
35 		smap = &wwsmap[row + w->ww_w.t][col + w->ww_w.l];
36 		for (i = w->ww_w.nc - col; i > 0; i--)
37 			if (*smap == w->ww_index)
38 				break;
39 			else {
40 				smap++;
41 				col++;
42 			}
43 		if (i <= 0)
44 			return;
45 		buf = &w->ww_buf[line][col];
46 		win = &w->ww_win[row][col];
47 		ns = &wwns[row + w->ww_w.t][col + w->ww_w.l];
48 		touched = &wwtouched[row + w->ww_w.t];
49 		c = buf->c_w ^ *win << WWC_MSHIFT;
50 		for (; --i >= 0;) {
51 			if (*win) {
52 				if ((*win & (WWM_COV|WWM_GLS)) != 0) {
53 					ns++;
54 					buf++;
55 				} else {
56 					*touched = 1;
57 					ns++->c_w = buf++->c_w
58 						^ *win++ << WWC_MSHIFT;
59 				}
60 			} else {
61 				*touched = 1;
62 				*ns++ = *buf++;
63 				win++;
64 				nvis++;
65 			}
66 		}
67 	}
68 	col += w->ww_w.l;
69 	row += w->ww_w.t;
70 	if (tt.tt_setinsert != 0 && nvis > (wwncol - col) / 2
71 	    && col != wwncol - 1) {
72 		register union ww_char *p, *q;
73 
74 		(*tt.tt_setinsert)(1);
75 		(*tt.tt_move)(row, col);
76 		(*tt.tt_setmodes)(c >> WWC_MSHIFT);
77 		(*tt.tt_putc)(c & WWC_CMASK);
78 		(*tt.tt_setinsert)(0);
79 
80 		p = &wwos[row][wwncol];
81 		q = p - 1;
82 		for (i = wwncol - col - 1; --i >= 0;)
83 			*--p = *--q;
84 		q->c_w = c;
85 	}
86 }
87