summaryrefslogtreecommitdiff
path: root/usr.bin/vi/svi/svi_screen.h
blob: 3b4643dc10d1ffe4bf82718c5c7a85f390e3cd50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/*-
 * Copyright (c) 1993, 1994
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)svi_screen.h	8.52 (Berkeley) 7/20/94
 */

/*
 * Structure for mapping lines to the screen.  An SMAP is an array, with one
 * structure element per screen line, which holds information describing the
 * physical line which is displayed in the screen line.  The first two fields
 * (lno and off) are all that are necessary to describe a line.  The rest of
 * the information is useful to keep information from being re-calculated.
 *
 * Lno is the line number.  Off is the screen offset into the line.  For
 * example, the pair 2:1 would be the first screen of line 2, and 2:2 would
 * be the second.  If doing left-right scrolling, all of the offsets will be
 * the same, i.e. for the second screen, 1:2, 2:2, 3:2, etc.  If doing the
 * standard vi scrolling, it will be staggered, i.e. 1:1, 1:2, 1:3, 2:1, 3:1,
 * etc.
 *
 * The SMAP is always as large as the physical screen, plus a slot for the
 * info line, so that there is room to add any screen into another one at
 * screen exit.
 */
typedef struct _smap {
	recno_t  lno;		/* 1-N: Physical file line number. */
	size_t	 off;		/* 1-N: Screen offset in the line. */

				/* svi_line() cache information. */
	size_t	 c_sboff;	/* 0-N: offset of first character byte. */
	size_t	 c_eboff;	/* 0-N: offset of  last character byte. */
	u_char	 c_scoff;	/* 0-N: offset into the first character. */
	u_char	 c_eclen;	/* 1-N: columns from the last character. */
	u_char	 c_ecsize;	/* 1-N: size of the  last character. */
} SMAP;

				/* Macros to flush/test cached information. */
#define	SMAP_CACHE(smp)		((smp)->c_ecsize != 0)
#define	SMAP_FLUSH(smp)		((smp)->c_ecsize = 0)

typedef struct _svi_private {
/* INITIALIZED AT SCREEN CREATE. */
	SMAP	*h_smap;	/* First slot of the line map. */
	SMAP	*t_smap;	/*  Last slot of the line map. */

	size_t	 exlinecount;	/* Ex overwrite count. */
	size_t	 extotalcount;	/* Ex overwrite count. */
	size_t	 exlcontinue;	/* Ex line continue value. */

				/* svi_opt_screens() cache information. */
#define	SVI_SCR_CFLUSH(svp)	svp->ss_lno = OOBLNO
	recno_t	 ss_lno;	/* 1-N: Line number. */
	size_t	 ss_screens;	/* Return value. */

	recno_t	 olno;		/* 1-N: old cursor file line. */
	size_t	 ocno;		/* 0-N: old file cursor column. */
	size_t	 sc_col;	/* 0-N: LOGICAL screen column. */

/* PARTIALLY OR COMPLETELY COPIED FROM PREVIOUS SCREEN. */
	size_t	 srows;		/* 1-N: Rows in the terminal/window. */

	char	*VB;		/* Visual bell termcap string. */

#define	SVI_CURSES_INIT	0x001	/* Curses/termcap initialized. */
#define	SVI_CUR_INVALID	0x002	/* Cursor position is unknown. */
#define	SVI_DIVIDER	0x004	/* Screen divider is displayed. */
#define	SVI_INFOLINE	0x008	/* The infoline is being used by v_ntext(). */
#define	SVI_SCREENDIRTY	0x010	/* Screen needs refreshing. */
	u_int8_t flags;
} SVI_PRIVATE;

#define	SVP(sp)		((SVI_PRIVATE *)((sp)->svi_private))
#define	 HMAP		(SVP(sp)->h_smap)
#define	 TMAP		(SVP(sp)->t_smap)
#define	_HMAP(sp)	(SVP(sp)->h_smap)
#define	_TMAP(sp)	(SVP(sp)->t_smap)

/*
 * One extra slot is always allocated for the map so that we can use
 * it to do vi :colon command input; see svi_get().
 */
#define	SIZE_HMAP(sp)	(SVP(sp)->srows + 1)

#define	O_NUMBER_FMT	"%7lu "			/* O_NUMBER format, length. */
#define	O_NUMBER_LENGTH	8
						/* Columns on a screen. */
#define	SCREEN_COLS(sp)							\
	((O_ISSET(sp, O_NUMBER) ? (sp)->cols - O_NUMBER_LENGTH : (sp)->cols))

#define	HALFSCREEN(sp)	((sp)->t_maxrows / 2)	/* Half the screen. */
#define	HALFTEXT(sp)	((sp)->t_rows / 2)	/* Half the text. */

#define	INFOLINE(sp)	((sp)->t_maxrows)	/* Info line test, offset. */
#define	ISINFOLINE(sp, smp)	(((smp) - HMAP) == INFOLINE(sp))

						/* Small screen test. */
#define	ISSMALLSCREEN(sp)	((sp)->t_minrows != (sp)->t_maxrows)

/*
 * Next tab offset.
 *
 * !!!
 * There are problems with how the historical vi handled tabs.  For example,
 * by doing "set ts=3" and building lines that fold, you can get it to step
 * through tabs as if they were spaces and move inserted characters to new
 * positions when <esc> is entered.  I think that nvi does tabs correctly,
 * but there may be some historical incompatibilities.
 */
#define	TAB_OFF(sp, c)	(O_VAL(sp, O_TABSTOP) - (c) % O_VAL(sp, O_TABSTOP))

/* Move in a screen (absolute), and fail if it doesn't work. */
#ifdef DEBUG
#define	MOVEA(sp, lno, cno) {						\
	if (move(lno, cno) == ERR) {					\
		msgq(sp, M_ERR,						\
		    "Error: %s/%d: move:l(%u), c(%u), abs",		\
		    tail(__FILE__), __LINE__, lno, cno);		\
		return (1);						\
	}								\
}
#else
#define	MOVEA(sp, lno, cno)	(void)move(lno, cno)
#endif

/* Move in a window, and fail if it doesn't work. */
#ifdef DEBUG
#define	MOVE(sp, lno, cno) {						\
	size_t __lno = (sp)->woff + (lno);				\
	if (move(__lno, cno) == ERR) {					\
		msgq(sp, M_ERR,						\
		    "Error: %s/%d: move:l(%u), c(%u), o(%u)",		\
		    tail(__FILE__), __LINE__, lno, cno, sp->woff);	\
		return (1);						\
	}								\
}
#else
#define	MOVE(sp, lno, cno)	(void)move((sp)->woff + (lno), cno)
#endif

/* Add a character. */
#define	ADDCH(ch) {							\
	CHAR_T __ch = ch;						\
	ADDNSTR(KEY_NAME(sp, __ch), KEY_LEN(sp, __ch));			\
}

/* Add a string len bytes long. */
#ifdef DEBUG
#define	ADDNSTR(str, len) {						\
	if (addnstr(str, len) == ERR) {					\
		int __x, __y;						\
		getyx(stdscr, __y, __x);				\
		msgq(sp, M_ERR, "Error: %s/%d: addnstr: (%d/%u)",	\
		    tail(__FILE__), __LINE__, __y, __x);		\
		return (1);						\
	}								\
}
#else
#define	ADDNSTR(str, len)	(void)addnstr(str, len)
#endif

/* Add a string. */
#ifdef DEBUG
#define	ADDSTR(str) {							\
	if (addstr(str) == ERR) {					\
		int __x, __y;						\
		getyx(stdscr, __y, __x);				\
		msgq(sp, M_ERR, "Error: %s/%d: addstr: (%d/%u)",	\
		    tail(__FILE__), __LINE__, __y, __x);		\
		return (1);						\
	}								\
}
#else
#define	ADDSTR(str)	(void)addstr(str);
#endif

/* Public routines. */
void	svi_bell __P((SCR *));
int	svi_bg __P((SCR *));
int	svi_busy __P((SCR *, char const *));
int	svi_change __P((SCR *, EXF *, recno_t, enum operation));
size_t	svi_cm_public __P((SCR *, EXF *, recno_t, size_t));
int	svi_column __P((SCR *, EXF *, size_t *));
enum confirm
	svi_confirm __P((SCR *, EXF *, MARK *, MARK *));
int	svi_clear __P((SCR *));
int	svi_crel __P((SCR *, long));
int	svi_ex_cmd __P((SCR *, EXF *, struct _excmdarg *, MARK *));
int	svi_ex_run __P((SCR *, EXF *, MARK *));
int	svi_ex_write __P((void *, const char *, int));
int	svi_fg __P((SCR *, CHAR_T *));
int	svi_fmap __P((SCR *, enum seqtype, CHAR_T *, size_t, CHAR_T *, size_t));
enum input
	svi_get __P((SCR *, EXF *, TEXTH *, ARG_CHAR_T, u_int));
int	svi_optchange __P((SCR *, int));
int	svi_rabs __P((SCR *, long, enum adjust));
size_t	svi_rcm __P((SCR *, EXF *, recno_t));
int	svi_refresh __P((SCR *, EXF *));
int	svi_screen_copy __P((SCR *, SCR *));
int	svi_screen_edit __P((SCR *, EXF *));
int	svi_screen_end __P((SCR *));
int	svi_sm_fill __P((SCR *, EXF *, recno_t, enum position));
int	svi_sm_position __P((SCR *, EXF *, MARK *, u_long, enum position));
int	svi_sm_scroll __P((SCR *, EXF *, MARK *, recno_t, enum sctype));
int	svi_split __P((SCR *, ARGS *[], int));
int	svi_suspend __P((SCR *));
int	svi_swap __P((SCR *, SCR **, char *));

/* Private routines. */
size_t	svi_cm_private __P((SCR *, EXF *, recno_t, size_t, size_t));
int	svi_curses_end __P((SCR *));
int	svi_curses_init __P((SCR *));
void	svi_dtoh __P((SCR *, char *));
int	svi_init __P((SCR *));
int	svi_join __P((SCR *, SCR **));
void	svi_keypad __P((SCR *, int));
int	svi_line __P((SCR *, EXF *, SMAP *, size_t *, size_t *));
int	svi_msgflush __P((SCR *));
int	svi_number __P((SCR *, EXF *));
size_t	svi_opt_screens __P((SCR *, EXF *, recno_t, size_t *));
int	svi_paint __P((SCR *, EXF *));
int	svi_sm_1down __P((SCR *, EXF *));
int	svi_sm_1up __P((SCR *, EXF *));
int	svi_sm_cursor __P((SCR *, EXF *, SMAP **));
int	svi_sm_next __P((SCR *, EXF *, SMAP *, SMAP *));
recno_t	svi_sm_nlines __P((SCR *, EXF *, SMAP *, recno_t, size_t));
int	svi_sm_prev __P((SCR *, EXF *, SMAP *, SMAP *));
int	svi_term_end __P((SCR *sp));
int	svi_term_init __P((SCR *sp));

/* Private debugging routines. */
#ifdef DEBUG
int	svi_gdbrefresh __P((void));
#endif