xref: /original-bsd/usr.bin/window/wwinschar.c (revision 81a135f6)
1 #ifndef lint
2 static char sccsid[] = "@(#)wwinschar.c	3.13 05/23/84";
3 #endif
4 
5 #include "ww.h"
6 #include "tt.h"
7 
8 wwinschar(w, row, col, c)
9 register struct ww *w;
10 short c;
11 {
12 	register i;
13 	int nvis;
14 
15 	/*
16 	 * First, shift the line.
17 	 */
18 	{
19 		register union ww_char *p, *q;
20 
21 		p = &w->ww_buf[row][w->ww_b.r];
22 		q = p - 1;
23 		for (i = w->ww_b.r - col; --i > 0;)
24 			*--p = *--q;
25 		q->c_w = c;
26 	}
27 
28 	/*
29 	 * If can't see it, just return.
30 	 */
31 	if (row < w->ww_i.t || row >= w->ww_i.b
32 	    || w->ww_i.r <= 0 || w->ww_i.r <= col)
33 		return;
34 
35 	if (col < w->ww_i.l)
36 		col = w->ww_i.l;
37 
38 	/*
39 	 * Now find out how much is actually changed, and fix wwns.
40 	 */
41 	{
42 		register union ww_char *buf;
43 		register char *win;
44 		register union ww_char *ns;
45 		register char *smap;
46 		char touched;
47 
48 		nvis = 0;
49 		smap = &wwsmap[row][col];
50 		for (i = col; i < w->ww_i.r && *smap++ != w->ww_index; i++)
51 			;
52 		if (i >= w->ww_i.r)
53 			return;
54 		col = i;
55 		buf = w->ww_buf[row];
56 		win = w->ww_win[row];
57 		ns = wwns[row];
58 		smap = &wwsmap[row][i];
59 		touched = wwtouched[row];
60 		for (; i < w->ww_i.r; i++) {
61 			if (*smap++ != w->ww_index)
62 				continue;
63 			touched |= WWU_TOUCHED;
64 			if (win[i])
65 				ns[i].c_w =
66 					buf[i].c_w ^ win[i] << WWC_MSHIFT;
67 			else {
68 				nvis++;
69 				ns[i] = buf[i];
70 			}
71 		}
72 		wwtouched[row] = touched;
73 	}
74 
75 	/*
76 	 * Can/Should we use delete character?
77 	 */
78 	if (tt.tt_hasinsert && nvis > (wwncol - col) / 2) {
79 		register union ww_char *p, *q;
80 
81 		tt.tt_ninsert = 1;
82 		tt.tt_nmodes = c >> WWC_MSHIFT & tt.tt_availmodes;
83 		(*tt.tt_move)(row, col);
84 		(*tt.tt_putc)(c & WWC_CMASK);
85 		tt.tt_ninsert = 0;
86 
87 		p = &wwos[row][wwncol];
88 		q = p - 1;
89 		for (i = wwncol - col; --i > 0;)
90 			*--p = *--q;
91 		q->c_w = c;
92 	}
93 }
94