1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1988 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  *      Copyright (c) 1997, by Sun Microsystems, Inc.
28  *      All rights reserved.
29  */
30 
31 /*LINTLIBRARY*/
32 
33 #include <sys/types.h>
34 #include "utility.h"
35 
36 #define	SizePrev(f, v)	((v) - Buf(f))		/* from beginning to v	*/
37 #define	SizeNext(f, v)	(BufSize(f) - SizePrev(f, v))
38 					/* from v through end	*/
39 #define	OffscreenRows(c)	((c)->drows - (c)->rows)
40 #define	OffscreenCols(c)	((c)->dcols - (c)->cols)
41 
42 /* _next_char move to next char with wrap to next line at end of line */
43 int
_next_char(FORM * f)44 _next_char(FORM *f)
45 {
46 	if (++X(f) == Xmax(f)) {
47 		if (++Y(f) == Ymax(f)) {
48 			--X(f);
49 			--Y(f);
50 			return (E_REQUEST_DENIED);	/* at last char */
51 		}
52 		X(f) = 0;
53 	}
54 	return (E_OK);
55 }
56 
57 /*
58  * _prev_char - move to previous char with
59  * wrap to previous line at beginning of line
60  */
61 int
_prev_char(FORM * f)62 _prev_char(FORM *f)
63 {
64 	if (--X(f) < 0) {
65 		if (--Y(f) < 0) {
66 			++X(f);
67 			++Y(f);
68 			return (E_REQUEST_DENIED);	/* at first char */
69 		}
70 		X(f) = Xmax(f) - 1;
71 	}
72 	return (E_OK);
73 }
74 
75 /* _next_line - move to beginning of next line */
76 int
_next_line(FORM * f)77 _next_line(FORM *f)
78 {
79 	if (++Y(f) == Ymax(f)) {
80 		--Y(f);
81 		return (E_REQUEST_DENIED);	/* at last line */
82 	}
83 	X(f) = 0;
84 	return (E_OK);
85 }
86 
87 /* _prev_line - move to beginning of previous line */
88 int
_prev_line(FORM * f)89 _prev_line(FORM *f)
90 {
91 	if (--Y(f) < 0) {
92 		++Y(f);
93 		return (E_REQUEST_DENIED);	/* at first line */
94 	}
95 	X(f) = 0;
96 	return (E_OK);
97 }
98 
99 /* _next_word - move to beginning of next word */
100 int
_next_word(FORM * f)101 _next_word(FORM *f)
102 {
103 	FIELD *		c = C(f);
104 	char *		v = LineBuf(c, Y(f)) + X(f);	/* position in buffer */
105 	char *		t;
106 
107 	_sync_buffer(f);
108 
109 	t = _whsp_beg(v, (int) SizeNext(c, v));
110 	v = _data_beg(t, (int) SizeNext(c, t));
111 
112 	if (v == t)
113 		return (E_REQUEST_DENIED);	/* at last word */
114 
115 	if (OneRow(c) && c->dcols != c->cols) {
116 	/* one row and field has grown */
117 		t = v;
118 
119 		while (*t != ' ' && *t != '\0')  /* find end of word + 1 */
120 			t++;
121 
122 		if (t - (Buf(c) + B(f)) > c->cols) {
123 			if (t - v > c->cols) {
124 			/* word longer than visible field */
125 				B(f) = (int) (v - Buf(c));
126 			} else {
127 				B(f) = (int) (t - (Buf(c) + c->cols));
128 			}
129 
130 			X(f) = (int) (v - Buf(c));
131 			return (E_OK);
132 		}
133 	}
134 
135 	_adjust_cursor(f, v);
136 	return (E_OK);
137 }
138 
139 /* _prev_word - move to beginning of previous word */
140 int
_prev_word(FORM * f)141 _prev_word(FORM *f)
142 {
143 	FIELD *		c = C(f);
144 	char *		v = LineBuf(c, Y(f)) + X(f);	/* position in buffer */
145 	char *		t;
146 
147 	_sync_buffer(f);
148 
149 	t = _data_end(Buf(c), (int) SizePrev(c, v));
150 	v = _whsp_end(Buf(c), (int) SizePrev(c, t));
151 
152 	if (v == t)
153 		return (E_REQUEST_DENIED);	/* at first word */
154 
155 	_adjust_cursor(f, v);
156 	return (E_OK);
157 }
158 
159 /* _beg_field - move to first non-pad char in field */
160 int
_beg_field(FORM * f)161 _beg_field(FORM *f)
162 {
163 	FIELD *	c = C(f);
164 
165 	_sync_buffer(f);
166 	_adjust_cursor(f, _data_beg(Buf(c), BufSize(c)));
167 	return (E_OK);
168 }
169 
170 /* _end_field - move after last non-pad char in field */
171 int
_end_field(FORM * f)172 _end_field(FORM *f)
173 {
174 	FIELD *	c = C(f);
175 	char *	end;
176 
177 	_sync_buffer(f);
178 	end = _data_end(Buf(c), BufSize(c));
179 
180 	if (end == Buf(c) + BufSize(c))
181 		end--;
182 
183 	_adjust_cursor(f, end);
184 	return (E_OK);
185 }
186 
187 /* _beg_line - move to first non-pad char on current line */
188 int
_beg_line(FORM * f)189 _beg_line(FORM *f)
190 {
191 	FIELD *c = C(f);
192 
193 	_sync_buffer(f);
194 	_adjust_cursor(f, _data_beg(LineBuf(c, Y(f)), Xmax(f)));
195 	return (E_OK);
196 }
197 
198 /* _end_line - move after last non-pad char on current line */
199 int
_end_line(FORM * f)200 _end_line(FORM *f)
201 {
202 	FIELD	*c = C(f);
203 	char	*end;
204 
205 	_sync_buffer(f);
206 	end = _data_end(LineBuf(c, Y(f)), Xmax(f));
207 
208 	if (end == LineBuf(c, Y(f)) + Xmax(f))
209 		end--;
210 
211 	_adjust_cursor(f, end);
212 	return (E_OK);
213 }
214 
215 /* _left_char - move left */
216 int
_left_char(FORM * f)217 _left_char(FORM *f)
218 {
219 	if (--X(f) < 0) {
220 		++X(f);
221 		return (E_REQUEST_DENIED);	/* at left side */
222 	}
223 	return (E_OK);
224 }
225 
226 /* _right_char - move right */
227 int
_right_char(FORM * f)228 _right_char(FORM *f)
229 {
230 	if (++X(f) == Xmax(f)) {
231 		--X(f);
232 		return (E_REQUEST_DENIED);	/* at right side */
233 	}
234 	return (E_OK);
235 }
236 
237 /* _up_char - move up */
238 int
_up_char(FORM * f)239 _up_char(FORM *f)
240 {
241 	if (--Y(f) < 0) {
242 		++Y(f);
243 		return (E_REQUEST_DENIED);	/* at top */
244 	}
245 	return (E_OK);
246 }
247 
248 /* _down_char - move down */
249 int
_down_char(FORM * f)250 _down_char(FORM *f)
251 {
252 	if (++Y(f) == Ymax(f)) {
253 		--Y(f);
254 		return (E_REQUEST_DENIED);	/* at bottom */
255 	}
256 	return (E_OK);
257 }
258 
259 /* _scr_fline - scroll forward one line */
260 int
_scr_fline(FORM * f)261 _scr_fline(FORM *f)
262 {
263 	FIELD	*c = C(f);
264 
265 	if (++T(f) > OffscreenRows(c)) {
266 		--T(f);
267 		return (E_REQUEST_DENIED);	/* at bottom */
268 	}
269 	++Y(f);
270 	Set(c, TOP_CHG);
271 	return (E_OK);
272 }
273 
274 /* _scr_bline - scroll backward one line */
275 int
_scr_bline(FORM * f)276 _scr_bline(FORM *f)
277 {
278 	FIELD	*c = C(f);
279 
280 	if (--T(f) < 0) {
281 		++T(f);
282 		return (E_REQUEST_DENIED);	/* at top */
283 	}
284 	--Y(f);
285 	Set(c, TOP_CHG);
286 	return (E_OK);
287 }
288 
289 /* _scr_fpage - scroll forward one page(C(f) -> rows) */
290 int
_scr_fpage(FORM * f)291 _scr_fpage(FORM *f)
292 {
293 	FIELD *		c = C(f);
294 	int		m = OffscreenRows(c) - T(f);
295 	int		n = c -> rows < m ? c -> rows : m;
296 
297 	if (n) {
298 		Y(f) += n;
299 		T(f) += n;
300 		Set(c, TOP_CHG);
301 		return (E_OK);
302 	}
303 	return (E_REQUEST_DENIED);	/* at bottom */
304 }
305 
306 /* _scr_bpage - scroll backward one page(C(f) -> rows) */
307 int
_scr_bpage(FORM * f)308 _scr_bpage(FORM *f)
309 {
310 	FIELD *		c = C(f);
311 	int		m = T(f);
312 	int		n = c -> rows < m ? c -> rows : m;
313 
314 	if (n) {
315 		Y(f) -= n;
316 		T(f) -= n;
317 		Set(c, TOP_CHG);
318 		return (E_OK);
319 	}
320 	return (E_REQUEST_DENIED);	/* at top */
321 }
322 
323 /* _scr_fhpage - scroll forward one half page(C(f)->rows + 1)/2) */
324 int
_scr_fhpage(FORM * f)325 _scr_fhpage(FORM *f)
326 {
327 	FIELD *		c = C(f);
328 	int		m = OffscreenRows(c) - T(f);
329 	int		h = (c->rows + 1)/2;
330 	int		n = h < m ? h : m;
331 
332 	if (n) {
333 		Y(f) += n;
334 		T(f) += n;
335 		Set(c, TOP_CHG);
336 		return (E_OK);
337 	}
338 	return (E_REQUEST_DENIED);	/* at bottom */
339 }
340 
341 /* _scr_bhpage - scroll backward one half page(C(f)->rows + 1)/2) */
342 int
_scr_bhpage(FORM * f)343 _scr_bhpage(FORM *f)
344 {
345 	FIELD *		c = C(f);
346 	int		m = T(f);
347 	int		h = (c->rows + 1)/2;
348 	int		n = h < m ? h : m;
349 
350 	if (n) {
351 		Y(f) -= n;
352 		T(f) -= n;
353 		Set(c, TOP_CHG);
354 		return (E_OK);
355 	}
356 	return (E_REQUEST_DENIED);	/* at top */
357 }
358 
359 /* _scr_fchar - horizontal scroll forward one char */
360 int
_scr_fchar(FORM * f)361 _scr_fchar(FORM *f)
362 {
363 	FIELD	*c = C(f);
364 
365 	if (++B(f) > OffscreenCols(c)) {
366 		--B(f);
367 		return (E_REQUEST_DENIED);	/* at end */
368 	}
369 	++X(f);
370 	return (E_OK);
371 }
372 
373 /* _scr_bchar - horizontal scroll backward one char */
374 int
_scr_bchar(FORM * f)375 _scr_bchar(FORM *f)
376 {
377 
378 	if (--B(f) < 0) {
379 		++B(f);
380 		return (E_REQUEST_DENIED);	/* at beginning */
381 	}
382 	--X(f);
383 	return (E_OK);
384 }
385 
386 /* _scr_hfline - horizontal scroll forward one line(C(f)->cols) */
387 int
_scr_hfline(FORM * f)388 _scr_hfline(FORM *f)
389 {
390 	FIELD	*c = C(f);
391 	int	m = OffscreenCols(c) - B(f);
392 	int	n = c -> cols < m ? c -> cols : m;
393 
394 	if (n) {
395 		X(f) += n;
396 		B(f) += n;
397 		return (E_OK);
398 	}
399 	return (E_REQUEST_DENIED);	/* at end */
400 }
401 
402 /* _scr_hbline - horizontal scroll backward one line(C(f)->cols) */
403 int
_scr_hbline(FORM * f)404 _scr_hbline(FORM *f)
405 {
406 	FIELD	*c = C(f);
407 	int	m = B(f);
408 	int	n = c -> cols < m ? c -> cols : m;
409 
410 	if (n) {
411 		X(f) -= n;
412 		B(f) -= n;
413 		return (E_OK);
414 	}
415 	return (E_REQUEST_DENIED);	/* at end */
416 }
417 
418 /* _scr_hfhalf - horizontal scroll forward one half line(C(f)->cols/2) */
419 int
_scr_hfhalf(FORM * f)420 _scr_hfhalf(FORM *f)
421 {
422 	FIELD	*c = C(f);
423 	int	m = OffscreenCols(c) - B(f);
424 	int	h = (c->cols + 1)/2;
425 	int	n = h < m ? h : m;
426 
427 	if (n) {
428 		X(f) += n;
429 		B(f) += n;
430 		return (E_OK);
431 	}
432 	return (E_REQUEST_DENIED);	/* at end */
433 }
434 
435 /* _scr_hbhalf - horizontal scroll backward one half line(C(f)->cols/2) */
436 int
_scr_hbhalf(FORM * f)437 _scr_hbhalf(FORM *f)
438 {
439 	FIELD	*c = C(f);
440 	int	m = B(f);
441 	int	h = (c->cols + 1)/2;
442 	int	n = h < m ? h : m;
443 
444 	if (n) {
445 		X(f) -= n;
446 		B(f) -= n;
447 		return (E_OK);
448 	}
449 	return (E_REQUEST_DENIED);	/* at top */
450 }
451