xref: /original-bsd/usr.bin/window/wwinschar.c (revision 2bd07fe6)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)wwinschar.c	3.18 (Berkeley) 08/24/89";
20 #endif /* not lint */
21 
22 #include "ww.h"
23 #include "tt.h"
24 
25 wwinschar(w, row, col, c, m)
26 register struct ww *w;
27 char c, m;
28 {
29 	register i;
30 	int nvis;
31 	short x = c | m << WWC_MSHIFT;
32 
33 	/*
34 	 * First, shift the line.
35 	 */
36 	{
37 		register union ww_char *p, *q;
38 
39 		p = &w->ww_buf[row][w->ww_b.r];
40 		q = p - 1;
41 		for (i = w->ww_b.r - col; --i > 0;)
42 			*--p = *--q;
43 		q->c_w = x;
44 	}
45 
46 	/*
47 	 * If can't see it, just return.
48 	 */
49 	if (row < w->ww_i.t || row >= w->ww_i.b
50 	    || w->ww_i.r <= 0 || w->ww_i.r <= col)
51 		return;
52 
53 	if (col < w->ww_i.l)
54 		col = w->ww_i.l;
55 
56 	/*
57 	 * Now find out how much is actually changed, and fix wwns.
58 	 */
59 	{
60 		register union ww_char *buf;
61 		register char *win;
62 		register union ww_char *ns;
63 		register char *smap;
64 		char touched;
65 
66 		nvis = 0;
67 		smap = &wwsmap[row][col];
68 		for (i = col; i < w->ww_i.r && *smap++ != w->ww_index; i++)
69 			;
70 		if (i >= w->ww_i.r)
71 			return;
72 		col = i;
73 		buf = w->ww_buf[row];
74 		win = w->ww_win[row];
75 		ns = wwns[row];
76 		smap = &wwsmap[row][i];
77 		touched = wwtouched[row];
78 		for (; i < w->ww_i.r; i++) {
79 			if (*smap++ != w->ww_index)
80 				continue;
81 			touched |= WWU_TOUCHED;
82 			if (win[i])
83 				ns[i].c_w =
84 					buf[i].c_w ^ win[i] << WWC_MSHIFT;
85 			else {
86 				nvis++;
87 				ns[i] = buf[i];
88 			}
89 		}
90 		wwtouched[row] = touched;
91 	}
92 
93 	/*
94 	 * Can/Should we use delete character?
95 	 */
96 	if ((tt.tt_inschar || tt.tt_insspace) && nvis > (wwncol - col) / 2) {
97 		register union ww_char *p, *q;
98 
99 		if (tt.tt_inschar)
100 			xxinschar(row, col, c, m);
101 		else {
102 			xxinsspace(row, col);
103 			x = ' ';
104 		}
105 		p = &wwos[row][wwncol];
106 		q = p - 1;
107 		for (i = wwncol - col; --i > 0;)
108 			*--p = *--q;
109 		q->c_w = x;
110 	}
111 }
112