xref: /netbsd-src/lib/libform/driver.c (revision f1abc9f9db7cee9def548e919032eb259841779b)
1*f1abc9f9Schristos /*	$NetBSD: driver.c,v 1.18 2013/11/26 01:17:00 christos Exp $	*/
241859428Sblymn 
341859428Sblymn /*-
441859428Sblymn  * Copyright (c) 1998-1999 Brett Lymn
541859428Sblymn  *                         (blymn@baea.com.au, brett_lymn@yahoo.com.au)
641859428Sblymn  * All rights reserved.
741859428Sblymn  *
841859428Sblymn  * This code has been donated to The NetBSD Foundation by the Author.
941859428Sblymn  *
1041859428Sblymn  * Redistribution and use in source and binary forms, with or without
1141859428Sblymn  * modification, are permitted provided that the following conditions
1241859428Sblymn  * are met:
1341859428Sblymn  * 1. Redistributions of source code must retain the above copyright
1441859428Sblymn  *    notice, this list of conditions and the following disclaimer.
1541859428Sblymn  * 2. The name of the author may not be used to endorse or promote products
16c03a48d6Swiz  *    derived from this software without specific prior written permission
1741859428Sblymn  *
1841859428Sblymn  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1941859428Sblymn  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2041859428Sblymn  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2141859428Sblymn  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2241859428Sblymn  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2341859428Sblymn  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2441859428Sblymn  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2541859428Sblymn  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2641859428Sblymn  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2741859428Sblymn  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2841859428Sblymn  *
2941859428Sblymn  *
3041859428Sblymn  */
3141859428Sblymn 
32a2ed7b2dSlukem #include <sys/cdefs.h>
33*f1abc9f9Schristos __RCSID("$NetBSD: driver.c,v 1.18 2013/11/26 01:17:00 christos Exp $");
34a2ed7b2dSlukem 
3541859428Sblymn #include <ctype.h>
3641859428Sblymn #include "form.h"
3741859428Sblymn #include "internals.h"
3841859428Sblymn 
3941859428Sblymn static int
4041859428Sblymn traverse_form_links(FORM *form, int direction);
4141859428Sblymn 
4241859428Sblymn /*
4341859428Sblymn  * Traverse the links of the current field in the given direction until
4441859428Sblymn  * either a active & visible field is found or we return to the current
4541859428Sblymn  * field.  Direction is the REQ_{LEFT,RIGHT,UP,DOWN}_FIELD driver commands.
4641859428Sblymn  * The function returns E_OK if a valid field is found, E_REQUEST_DENIED
4741859428Sblymn  * otherwise.
4841859428Sblymn  */
4941859428Sblymn static int
traverse_form_links(FORM * form,int direction)5041859428Sblymn traverse_form_links(FORM *form, int direction)
5141859428Sblymn {
52c64b324aSthorpej 	unsigned idx;
5341859428Sblymn 
54c64b324aSthorpej 	idx = form->cur_field;
5541859428Sblymn 
5641859428Sblymn 	do {
5741859428Sblymn 		switch (direction) {
5841859428Sblymn 		case REQ_LEFT_FIELD:
59c64b324aSthorpej 			if (form->fields[idx]->left == NULL)
6041859428Sblymn 				return E_REQUEST_DENIED;
61c64b324aSthorpej 			idx = form->fields[idx]->left->index;
6241859428Sblymn 			break;
6341859428Sblymn 
6441859428Sblymn 		case REQ_RIGHT_FIELD:
65c64b324aSthorpej 			if (form->fields[idx]->right == NULL)
6641859428Sblymn 				return E_REQUEST_DENIED;
67c64b324aSthorpej 			idx = form->fields[idx]->right->index;
6841859428Sblymn 			break;
6941859428Sblymn 
7041859428Sblymn 		case REQ_UP_FIELD:
71c64b324aSthorpej 			if (form->fields[idx]->up == NULL)
7241859428Sblymn 				return E_REQUEST_DENIED;
73c64b324aSthorpej 			idx = form->fields[idx]->up->index;
7441859428Sblymn 			break;
7541859428Sblymn 
7641859428Sblymn 		case REQ_DOWN_FIELD:
77c64b324aSthorpej 			if (form->fields[idx]->down == NULL)
7841859428Sblymn 				return E_REQUEST_DENIED;
79c64b324aSthorpej 			idx = form->fields[idx]->down->index;
8041859428Sblymn 			break;
8141859428Sblymn 
8241859428Sblymn 		default:
8341859428Sblymn 			return E_REQUEST_DENIED;
8441859428Sblymn 		}
8541859428Sblymn 
86c64b324aSthorpej 		if ((form->fields[idx]->opts & (O_ACTIVE | O_VISIBLE))
8741859428Sblymn 		    == (O_ACTIVE | O_VISIBLE)) {
88c64b324aSthorpej 			form->cur_field = idx;
8941859428Sblymn 			return E_OK;
9041859428Sblymn 		}
91c64b324aSthorpej 	} while (idx != form->cur_field);
9241859428Sblymn 
9341859428Sblymn 	return E_REQUEST_DENIED;
9441859428Sblymn }
9541859428Sblymn 
9641859428Sblymn int
form_driver(FORM * form,int c)9741859428Sblymn form_driver(FORM *form, int c)
9841859428Sblymn {
9941859428Sblymn 	FIELD *fieldp;
10041859428Sblymn 	int update_page, update_field, old_field, old_page, status;
101ab600f6aSblymn 	int start_field;
10241859428Sblymn 	unsigned int pos;
10341859428Sblymn 
10441859428Sblymn 	if (form == NULL)
10541859428Sblymn 		return E_BAD_ARGUMENT;
10641859428Sblymn 
10741859428Sblymn 	if ((form->fields == NULL) || (*(form->fields) == NULL))
10841859428Sblymn 		return E_INVALID_FIELD;
10941859428Sblymn 
11041859428Sblymn 	if (form->posted != 1)
11141859428Sblymn 		return E_NOT_POSTED;
11241859428Sblymn 
11341859428Sblymn 	if (form->in_init == 1)
11441859428Sblymn 		return E_BAD_STATE;
11541859428Sblymn 
11641859428Sblymn 
117ab600f6aSblymn 	old_field = start_field = form->cur_field;
11899af4c10Sblymn 	fieldp = form->fields[form->cur_field];
11941859428Sblymn 	update_page = update_field = 0;
12099af4c10Sblymn 	status = E_OK;
12141859428Sblymn 
12241859428Sblymn 	if (c < REQ_MIN_REQUEST) {
123759e545dSblymn 		if (isprint(c) || isblank(c)) {
12469869e5cSblymn 			do {
12519f07fb2Sblymn 				pos = fieldp->start_char + fieldp->row_xpos;
12641859428Sblymn 
127c0219226Sblymn 			      /* check if we are allowed to edit this field */
128c0219226Sblymn 				if ((fieldp->opts & O_EDIT) != O_EDIT)
129c0219226Sblymn 					return E_REQUEST_DENIED;
130c0219226Sblymn 
13169869e5cSblymn 				if ((status =
13269869e5cSblymn 				     (_formi_add_char(fieldp, pos, c)))
13369869e5cSblymn 				    == E_REQUEST_DENIED) {
13469869e5cSblymn 
13541859428Sblymn 					  /*
13669869e5cSblymn 					   * Need to check here if we
13769869e5cSblymn 					   * want to autoskip.  we
13869869e5cSblymn 					   * call the form driver
13969869e5cSblymn 					   * recursively to pos us on
14069869e5cSblymn 					   * the next field and then
14169869e5cSblymn 					   * we loop back to ensure
14269869e5cSblymn 					   * the next field selected
14369869e5cSblymn 					   * can have data added to it
14441859428Sblymn 					   */
14569869e5cSblymn 					if ((fieldp->opts & O_AUTOSKIP)
14669869e5cSblymn 					    != O_AUTOSKIP)
14741859428Sblymn 						return E_REQUEST_DENIED;
14869869e5cSblymn 					status = form_driver(form,
14969869e5cSblymn 							     REQ_NEXT_FIELD);
15041859428Sblymn 					if (status != E_OK)
15141859428Sblymn 						return status;
152ab600f6aSblymn 
153ab600f6aSblymn 					  /*
154ab600f6aSblymn 					   * check if we have looped
155ab600f6aSblymn                                            * around all the fields.
156ab600f6aSblymn                                            * This can easily happen if
157ab600f6aSblymn                                            * all the fields are full.
158ab600f6aSblymn 					   */
159ab600f6aSblymn 					if (start_field == form->cur_field)
160ab600f6aSblymn 						return E_REQUEST_DENIED;
161ab600f6aSblymn 
16241859428Sblymn 					old_field = form->cur_field;
163043f30d2Sblymn 					fieldp = form->fields[form->cur_field];
164ab600f6aSblymn 					status = _formi_add_char(fieldp,
165ab600f6aSblymn 							fieldp->start_char
166ab600f6aSblymn 							+ fieldp->cursor_xpos,
167ab600f6aSblymn 							c);
16869869e5cSblymn 				} else if (status == E_INVALID_FIELD)
16969869e5cSblymn 					  /* char failed validation, just
17069869e5cSblymn 					   * return the status.
17169869e5cSblymn 					   */
17269869e5cSblymn 					return status;
1733f76420bSblymn 				else if (status == E_NO_ROOM)
1743f76420bSblymn 					  /* we will get this if the line
1753f76420bSblymn 					   * wrapping fails.  Deny the
1763f76420bSblymn 					   * request.
1773f76420bSblymn 					   */
1783f76420bSblymn 					return E_REQUEST_DENIED;
17941859428Sblymn 			}
18069869e5cSblymn 			while (status != E_OK);
18169869e5cSblymn 			update_field = (status == E_OK);
18241859428Sblymn 		} else
18341859428Sblymn 			return E_REQUEST_DENIED;
18441859428Sblymn 	} else {
18541859428Sblymn 		if (c > REQ_MAX_COMMAND)
18641859428Sblymn 			return E_UNKNOWN_COMMAND;
18741859428Sblymn 
18899af4c10Sblymn 		if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
18999af4c10Sblymn 			  /* first check the field we are in is ok */
19099af4c10Sblymn 			if (_formi_validate_field(form) != E_OK)
19199af4c10Sblymn 				return E_INVALID_FIELD;
19299af4c10Sblymn 
19399af4c10Sblymn 			if (form->field_term != NULL)
19499af4c10Sblymn 				form->field_term(form);
19599af4c10Sblymn 
19699af4c10Sblymn 			  /*
19799af4c10Sblymn 			   * if we have a page movement then the form term
19899af4c10Sblymn 			   * needs to be called too
19999af4c10Sblymn 			   */
20099af4c10Sblymn 			if ((c <= REQ_LAST_PAGE) && (form->form_term != NULL))
20199af4c10Sblymn 				form->form_term(form);
20299af4c10Sblymn 		}
20399af4c10Sblymn 
20499af4c10Sblymn 
20541859428Sblymn 		switch (c) {
20641859428Sblymn 		case REQ_NEXT_PAGE:
20741859428Sblymn 			if (form->page < form->max_page) {
20841859428Sblymn 				old_page = form->page;
20941859428Sblymn 				form->page++;
21041859428Sblymn 				update_page = 1;
21141859428Sblymn 				if (_formi_pos_first_field(form) != E_OK) {
21241859428Sblymn 					form->page = old_page;
21399af4c10Sblymn 					status = E_REQUEST_DENIED;
21441859428Sblymn 				}
21541859428Sblymn 			} else
21699af4c10Sblymn 				status = E_REQUEST_DENIED;
21741859428Sblymn 			break;
21841859428Sblymn 
21941859428Sblymn 		case REQ_PREV_PAGE:
22041859428Sblymn 			if (form->page > 0) {
22141859428Sblymn 				old_page = form->page;
22241859428Sblymn 				form->page--;
22341859428Sblymn 				update_page = 1;
22441859428Sblymn 				if (_formi_pos_first_field(form) != E_OK) {
22541859428Sblymn 					form->page = old_page;
22699af4c10Sblymn 					status = E_REQUEST_DENIED;
22741859428Sblymn 				}
22841859428Sblymn 			} else
22999af4c10Sblymn 				status = E_REQUEST_DENIED;
23041859428Sblymn 			break;
23141859428Sblymn 
23241859428Sblymn 		case REQ_FIRST_PAGE:
23341859428Sblymn 			old_page = form->page;
23441859428Sblymn 			form->page = 0;
23541859428Sblymn 			update_page = 1;
23641859428Sblymn 			if (_formi_pos_first_field(form) != E_OK) {
23741859428Sblymn 				form->page = old_page;
23899af4c10Sblymn 				status = E_REQUEST_DENIED;
23941859428Sblymn 			}
24041859428Sblymn 			break;
24141859428Sblymn 
24241859428Sblymn 		case REQ_LAST_PAGE:
24341859428Sblymn 			old_page = form->page;
24441859428Sblymn 			form->page = form->max_page - 1;
24541859428Sblymn 			update_page = 1;
24641859428Sblymn 			if (_formi_pos_first_field(form) != E_OK) {
24741859428Sblymn 				form->page = old_page;
24899af4c10Sblymn 				status = E_REQUEST_DENIED;
24941859428Sblymn 			}
25041859428Sblymn 			break;
25141859428Sblymn 
25241859428Sblymn 		case REQ_NEXT_FIELD:
25341859428Sblymn 			status = _formi_pos_new_field(form, _FORMI_FORWARD,
25441859428Sblymn 						      FALSE);
25541859428Sblymn 			update_field = 1;
25641859428Sblymn 			break;
25741859428Sblymn 
25841859428Sblymn 		case REQ_PREV_FIELD:
25941859428Sblymn 			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
26041859428Sblymn 						      FALSE);
26141859428Sblymn 			update_field = 1;
26241859428Sblymn 			break;
26341859428Sblymn 
26441859428Sblymn 		case REQ_FIRST_FIELD:
26541859428Sblymn 			form->cur_field = 0;
26641859428Sblymn 			update_field = 1;
26741859428Sblymn 			break;
26841859428Sblymn 
26941859428Sblymn 		case REQ_LAST_FIELD:
27041859428Sblymn 			form->cur_field = form->field_count - 1;
27141859428Sblymn 			update_field = 1;
27241859428Sblymn 			break;
27341859428Sblymn 
27441859428Sblymn 		case REQ_SNEXT_FIELD:
27541859428Sblymn 			status = _formi_pos_new_field(form, _FORMI_FORWARD,
27641859428Sblymn 						      TRUE);
27741859428Sblymn 			update_field = 1;
27841859428Sblymn 			break;
27941859428Sblymn 
28041859428Sblymn 		case REQ_SPREV_FIELD:
28141859428Sblymn 			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
28241859428Sblymn 						      TRUE);
28341859428Sblymn 			update_field = 1;
28441859428Sblymn 			break;
28541859428Sblymn 
28641859428Sblymn 		case REQ_SFIRST_FIELD:
287*f1abc9f9Schristos 			fieldp = TAILQ_FIRST(&form->sorted_fields);
28841859428Sblymn 			form->cur_field = fieldp->index;
28941859428Sblymn 			update_field = 1;
29041859428Sblymn 			break;
29141859428Sblymn 
29241859428Sblymn 		case REQ_SLAST_FIELD:
293*f1abc9f9Schristos 			fieldp = TAILQ_LAST(&form->sorted_fields,
294*f1abc9f9Schristos 			    _formi_sort_head);
29541859428Sblymn 			form->cur_field = fieldp->index;
29641859428Sblymn 			update_field = 1;
29741859428Sblymn 			break;
29841859428Sblymn 
29941859428Sblymn 			  /*
30041859428Sblymn 			   * The up, down, left and right field traversals
30141859428Sblymn 			   * are rolled up into a single function, allow a
30241859428Sblymn 			   * fall through to that function.
30341859428Sblymn 			   */
30441859428Sblymn 		case REQ_LEFT_FIELD:
30541859428Sblymn 		case REQ_RIGHT_FIELD:
30641859428Sblymn 		case REQ_UP_FIELD:
30741859428Sblymn 		case REQ_DOWN_FIELD:
30841859428Sblymn 			status = traverse_form_links(form, c);
30941859428Sblymn 			update_field = 1;
31041859428Sblymn 			break;
31141859428Sblymn 
31241859428Sblymn 			  /* the following commands modify the buffer, check if
31341859428Sblymn 			     this is allowed first before falling through. */
31419f07fb2Sblymn 
3156334f191Sblymn 		case REQ_DEL_PREV:
3166334f191Sblymn 			  /*
3176334f191Sblymn 			   * need to check for the overloading of this
3186334f191Sblymn 			   * request.  If overload flag set and we are
3196334f191Sblymn 			   * at the start of field this request turns
3206334f191Sblymn 			   * into a previous field request. Otherwise
3216334f191Sblymn 			   * fallthrough to the field handler.
3226334f191Sblymn 			   */
3236334f191Sblymn 			if ((form->opts & O_BS_OVERLOAD) == O_BS_OVERLOAD) {
3246334f191Sblymn 				if ((fieldp->start_char == 0) &&
3256334f191Sblymn 				    (fieldp->start_line == 0) &&
326d0d41d9fSblymn 				    (fieldp->row_xpos == 0)) {
3276334f191Sblymn 					update_field =
3286334f191Sblymn 						_formi_manipulate_field(form,
3296334f191Sblymn 							REQ_PREV_FIELD);
3306334f191Sblymn 					break;
3316334f191Sblymn 				}
3326334f191Sblymn 			}
3336334f191Sblymn 
3346334f191Sblymn 			  /* FALLTHROUGH */
3356334f191Sblymn 		case REQ_NEW_LINE:
3366334f191Sblymn 			  /*
3376334f191Sblymn 			   * need to check for the overloading of this
3386334f191Sblymn 			   * request.  If overload flag set and we are
3396334f191Sblymn 			   * at the start of field this request turns
3406334f191Sblymn 			   * into a next field request. Otherwise
3416334f191Sblymn 			   * fallthrough to the field handler.
3426334f191Sblymn 			   */
3436334f191Sblymn 			if ((form->opts & O_NL_OVERLOAD) == O_NL_OVERLOAD) {
3446334f191Sblymn 				if ((fieldp->start_char == 0) &&
3456334f191Sblymn 				    (fieldp->start_line == 0) &&
346d0d41d9fSblymn 				    (fieldp->row_xpos == 0)) {
3476334f191Sblymn 					update_field =
3486334f191Sblymn 						_formi_manipulate_field(form,
3496334f191Sblymn 							REQ_NEXT_FIELD);
3506334f191Sblymn 					break;
3516334f191Sblymn 				}
3526334f191Sblymn 			}
3536334f191Sblymn 
3546334f191Sblymn 			  /* FALLTHROUGH */
35541859428Sblymn 		case REQ_INS_CHAR:
35641859428Sblymn 		case REQ_INS_LINE:
35741859428Sblymn 		case REQ_DEL_CHAR:
35841859428Sblymn 		case REQ_DEL_LINE:
35941859428Sblymn 		case REQ_DEL_WORD:
36041859428Sblymn 		case REQ_CLR_EOL:
36141859428Sblymn 		case REQ_CLR_EOF:
36241859428Sblymn 		case REQ_CLR_FIELD:
36341859428Sblymn 		case REQ_OVL_MODE:
36441859428Sblymn 		case REQ_INS_MODE:
36541859428Sblymn 			  /* check if we are allowed to edit the field and fall
36641859428Sblymn 			   * through if we are.
36741859428Sblymn 			   */
36841859428Sblymn 			if ((form->fields[form->cur_field]->opts & O_EDIT) != O_EDIT)
36941859428Sblymn 				return E_REQUEST_DENIED;
37041859428Sblymn 
37141859428Sblymn 			  /* the following manipulate the field contents, bundle
37241859428Sblymn 			     them into one function.... */
37341859428Sblymn 			  /* FALLTHROUGH */
37441859428Sblymn 		case REQ_NEXT_CHAR:
37541859428Sblymn 		case REQ_PREV_CHAR:
37641859428Sblymn 		case REQ_NEXT_LINE:
37741859428Sblymn 		case REQ_PREV_LINE:
37841859428Sblymn 		case REQ_NEXT_WORD:
37941859428Sblymn 		case REQ_PREV_WORD:
38041859428Sblymn 		case REQ_BEG_FIELD:
38141859428Sblymn 		case REQ_END_FIELD:
38241859428Sblymn 		case REQ_BEG_LINE:
38341859428Sblymn 		case REQ_END_LINE:
38441859428Sblymn 		case REQ_LEFT_CHAR:
38541859428Sblymn 		case REQ_RIGHT_CHAR:
38641859428Sblymn 		case REQ_UP_CHAR:
38741859428Sblymn 		case REQ_DOWN_CHAR:
38841859428Sblymn 		case REQ_SCR_FLINE:
38941859428Sblymn 		case REQ_SCR_BLINE:
39041859428Sblymn 		case REQ_SCR_FPAGE:
39141859428Sblymn 		case REQ_SCR_BPAGE:
39241859428Sblymn 		case REQ_SCR_FHPAGE:
39341859428Sblymn 		case REQ_SCR_BHPAGE:
39441859428Sblymn 		case REQ_SCR_FCHAR:
39541859428Sblymn 		case REQ_SCR_BCHAR:
39641859428Sblymn 		case REQ_SCR_HFLINE:
39741859428Sblymn 		case REQ_SCR_HBLINE:
39841859428Sblymn 		case REQ_SCR_HFHALF:
39941859428Sblymn 		case REQ_SCR_HBHALF:
40041859428Sblymn 			update_field = _formi_manipulate_field(form, c);
40141859428Sblymn 			break;
40241859428Sblymn 
40341859428Sblymn 		case REQ_VALIDATION:
40441859428Sblymn 			return _formi_validate_field(form);
40541859428Sblymn 			  /* NOTREACHED */
40641859428Sblymn 			break;
40741859428Sblymn 
40841859428Sblymn 		case REQ_PREV_CHOICE:
40941859428Sblymn 		case REQ_NEXT_CHOICE:
41041859428Sblymn 			update_field = _formi_field_choice(form, c);
411d0d41d9fSblymn 			  /* reinit the cursor pos just in case */
412d0d41d9fSblymn 			if (update_field == 1) {
413d0d41d9fSblymn 				_formi_init_field_xpos(fieldp);
414d0d41d9fSblymn 				fieldp->row_xpos = 0;
415d0d41d9fSblymn 			}
41641859428Sblymn 			break;
41741859428Sblymn 
41841859428Sblymn 		default: /* should not need to do this, but.... */
41941859428Sblymn 			return E_UNKNOWN_COMMAND;
42041859428Sblymn 			  /* NOTREACHED */
42141859428Sblymn 			break;
42241859428Sblymn 		}
42341859428Sblymn 	}
42441859428Sblymn 
42599af4c10Sblymn 	  /* call the field and form init functions if required. */
42699af4c10Sblymn 	if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
42799af4c10Sblymn 		if (form->field_init != NULL)
42899af4c10Sblymn 			form->field_init(form);
42999af4c10Sblymn 
43099af4c10Sblymn 		  /*
43199af4c10Sblymn 		   * if we have a page movement then the form init
43299af4c10Sblymn 		   * needs to be called too
43399af4c10Sblymn 		   */
43499af4c10Sblymn 		if ((c <= REQ_LAST_PAGE) && (form->form_init != NULL))
43599af4c10Sblymn 			form->form_init(form);
43699af4c10Sblymn 
43799af4c10Sblymn 		  /*
43899af4c10Sblymn 		   * if there was an error just return now...
43999af4c10Sblymn 		   */
44099af4c10Sblymn 		if (status != E_OK)
44199af4c10Sblymn 			return status;
442043f30d2Sblymn 
443043f30d2Sblymn 		  /* if we have no error, reset the various offsets */
444043f30d2Sblymn 		fieldp = form->fields[form->cur_field];
445043f30d2Sblymn 		fieldp->start_char = 0;
44698eb8895Sroy 		fieldp->start_line = fieldp->alines;
44798eb8895Sroy 		fieldp->cur_line = fieldp->alines;
448759e545dSblymn 		fieldp->row_xpos = 0;
449043f30d2Sblymn 		fieldp->cursor_ypos = 0;
450d0d41d9fSblymn 		_formi_init_field_xpos(fieldp);
45199af4c10Sblymn 	}
45299af4c10Sblymn 
45341859428Sblymn 	if (update_field < 0)
45441859428Sblymn 		return update_field;
45541859428Sblymn 
45641859428Sblymn 	if (update_field == 1)
45741859428Sblymn 		update_page |= _formi_update_field(form, old_field);
45841859428Sblymn 
45941859428Sblymn 	if (update_page == 1)
46041859428Sblymn 		_formi_draw_page(form);
46141859428Sblymn 
46241859428Sblymn 	pos_form_cursor(form);
463a5ab8107Sblymn 
464a5ab8107Sblymn 	if ((update_page == 1) || (update_field == 1))
465a5ab8107Sblymn 		wrefresh(form->scrwin);
466a5ab8107Sblymn 
46741859428Sblymn 	return E_OK;
46841859428Sblymn }
469