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