Home | History | Annotate | Line # | Download | only in libform
driver.c revision 1.15
      1  1.15    lukem /*	$NetBSD: driver.c,v 1.15 2003/03/09 00:57:17 lukem Exp $	*/
      2   1.1    blymn 
      3   1.1    blymn /*-
      4   1.1    blymn  * Copyright (c) 1998-1999 Brett Lymn
      5   1.1    blymn  *                         (blymn (at) baea.com.au, brett_lymn (at) yahoo.com.au)
      6   1.1    blymn  * All rights reserved.
      7   1.1    blymn  *
      8   1.1    blymn  * This code has been donated to The NetBSD Foundation by the Author.
      9   1.1    blymn  *
     10   1.1    blymn  * Redistribution and use in source and binary forms, with or without
     11   1.1    blymn  * modification, are permitted provided that the following conditions
     12   1.1    blymn  * are met:
     13   1.1    blymn  * 1. Redistributions of source code must retain the above copyright
     14   1.1    blymn  *    notice, this list of conditions and the following disclaimer.
     15   1.1    blymn  * 2. The name of the author may not be used to endorse or promote products
     16  1.10      wiz  *    derived from this software without specific prior written permission
     17   1.1    blymn  *
     18   1.1    blymn  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19   1.1    blymn  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20   1.1    blymn  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21   1.1    blymn  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22   1.1    blymn  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23   1.1    blymn  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24   1.1    blymn  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25   1.1    blymn  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26   1.1    blymn  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27   1.1    blymn  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28   1.1    blymn  *
     29   1.1    blymn  *
     30   1.1    blymn  */
     31  1.15    lukem 
     32  1.15    lukem #include <sys/cdefs.h>
     33  1.15    lukem __RCSID("$NetBSD: driver.c,v 1.15 2003/03/09 00:57:17 lukem Exp $");
     34   1.1    blymn 
     35   1.1    blymn #include <ctype.h>
     36   1.1    blymn #include "form.h"
     37   1.1    blymn #include "internals.h"
     38   1.1    blymn 
     39   1.1    blymn static int
     40   1.1    blymn traverse_form_links(FORM *form, int direction);
     41   1.1    blymn 
     42   1.1    blymn /*
     43   1.1    blymn  * Traverse the links of the current field in the given direction until
     44   1.1    blymn  * either a active & visible field is found or we return to the current
     45   1.1    blymn  * field.  Direction is the REQ_{LEFT,RIGHT,UP,DOWN}_FIELD driver commands.
     46   1.1    blymn  * The function returns E_OK if a valid field is found, E_REQUEST_DENIED
     47   1.1    blymn  * otherwise.
     48   1.1    blymn  */
     49   1.1    blymn static int
     50   1.1    blymn traverse_form_links(FORM *form, int direction)
     51   1.1    blymn {
     52  1.11  thorpej 	unsigned idx;
     53   1.1    blymn 
     54  1.11  thorpej 	idx = form->cur_field;
     55   1.1    blymn 
     56   1.1    blymn 	do {
     57   1.1    blymn 		switch (direction) {
     58   1.1    blymn 		case REQ_LEFT_FIELD:
     59  1.11  thorpej 			if (form->fields[idx]->left == NULL)
     60   1.1    blymn 				return E_REQUEST_DENIED;
     61  1.11  thorpej 			idx = form->fields[idx]->left->index;
     62   1.1    blymn 			break;
     63   1.1    blymn 
     64   1.1    blymn 		case REQ_RIGHT_FIELD:
     65  1.11  thorpej 			if (form->fields[idx]->right == NULL)
     66   1.1    blymn 				return E_REQUEST_DENIED;
     67  1.11  thorpej 			idx = form->fields[idx]->right->index;
     68   1.1    blymn 			break;
     69   1.1    blymn 
     70   1.1    blymn 		case REQ_UP_FIELD:
     71  1.11  thorpej 			if (form->fields[idx]->up == NULL)
     72   1.1    blymn 				return E_REQUEST_DENIED;
     73  1.11  thorpej 			idx = form->fields[idx]->up->index;
     74   1.1    blymn 			break;
     75   1.1    blymn 
     76   1.1    blymn 		case REQ_DOWN_FIELD:
     77  1.11  thorpej 			if (form->fields[idx]->down == NULL)
     78   1.1    blymn 				return E_REQUEST_DENIED;
     79  1.11  thorpej 			idx = form->fields[idx]->down->index;
     80   1.1    blymn 			break;
     81   1.1    blymn 
     82   1.1    blymn 		default:
     83   1.1    blymn 			return E_REQUEST_DENIED;
     84   1.1    blymn 		}
     85   1.1    blymn 
     86  1.11  thorpej 		if ((form->fields[idx]->opts & (O_ACTIVE | O_VISIBLE))
     87   1.1    blymn 		    == (O_ACTIVE | O_VISIBLE)) {
     88  1.11  thorpej 			form->cur_field = idx;
     89   1.1    blymn 			return E_OK;
     90   1.1    blymn 		}
     91  1.11  thorpej 	} while (idx != form->cur_field);
     92   1.1    blymn 
     93   1.1    blymn 	return E_REQUEST_DENIED;
     94   1.1    blymn }
     95   1.1    blymn 
     96   1.1    blymn int
     97   1.1    blymn form_driver(FORM *form, int c)
     98   1.1    blymn {
     99   1.1    blymn 	FIELD *fieldp;
    100   1.1    blymn 	int update_page, update_field, old_field, old_page, status;
    101   1.7    blymn 	int start_field;
    102   1.1    blymn 	unsigned int pos;
    103   1.1    blymn 
    104   1.1    blymn 	if (form == NULL)
    105   1.1    blymn 		return E_BAD_ARGUMENT;
    106   1.1    blymn 
    107   1.1    blymn 	if ((form->fields == NULL) || (*(form->fields) == NULL))
    108   1.1    blymn 		return E_INVALID_FIELD;
    109   1.1    blymn 
    110   1.1    blymn 	if (form->posted != 1)
    111   1.1    blymn 		return E_NOT_POSTED;
    112   1.1    blymn 
    113   1.1    blymn 	if (form->in_init == 1)
    114   1.1    blymn 		return E_BAD_STATE;
    115   1.1    blymn 
    116   1.1    blymn 
    117   1.7    blymn 	old_field = start_field = form->cur_field;
    118   1.4    blymn 	fieldp = form->fields[form->cur_field];
    119   1.1    blymn 	update_page = update_field = 0;
    120   1.4    blymn 	status = E_OK;
    121   1.1    blymn 
    122   1.1    blymn 	if (c < REQ_MIN_REQUEST) {
    123  1.12    blymn 		if (isprint(c) || isblank(c)) {
    124   1.6    blymn 			do {
    125  1.12    blymn 				pos = fieldp->start_char + fieldp->row_xpos
    126   1.8    blymn 	       + fieldp->lines[fieldp->start_line + fieldp->cursor_ypos].start;
    127   1.1    blymn 
    128   1.7    blymn 			      /* check if we are allowed to edit this field */
    129   1.6    blymn 				if ((fieldp->opts & O_EDIT) != O_EDIT)
    130   1.1    blymn 					return E_REQUEST_DENIED;
    131   1.6    blymn 
    132   1.6    blymn 				if ((status =
    133   1.6    blymn 				     (_formi_add_char(fieldp, pos, c)))
    134   1.6    blymn 				    == E_REQUEST_DENIED) {
    135   1.6    blymn 
    136   1.6    blymn 					  /*
    137   1.6    blymn 					   * Need to check here if we
    138   1.6    blymn 					   * want to autoskip.  we
    139   1.6    blymn 					   * call the form driver
    140   1.6    blymn 					   * recursively to pos us on
    141   1.6    blymn 					   * the next field and then
    142   1.6    blymn 					   * we loop back to ensure
    143   1.6    blymn 					   * the next field selected
    144   1.6    blymn 					   * can have data added to it
    145   1.6    blymn 					   */
    146   1.6    blymn 					if ((fieldp->opts & O_AUTOSKIP)
    147   1.6    blymn 					    != O_AUTOSKIP)
    148   1.6    blymn 						return E_REQUEST_DENIED;
    149   1.6    blymn 					status = form_driver(form,
    150   1.6    blymn 							     REQ_NEXT_FIELD);
    151   1.6    blymn 					if (status != E_OK)
    152   1.6    blymn 						return status;
    153   1.7    blymn 
    154   1.7    blymn 					  /*
    155   1.7    blymn 					   * check if we have looped
    156   1.7    blymn                                            * around all the fields.
    157   1.7    blymn                                            * This can easily happen if
    158   1.7    blymn                                            * all the fields are full.
    159   1.7    blymn 					   */
    160   1.7    blymn 					if (start_field == form->cur_field)
    161   1.7    blymn 						return E_REQUEST_DENIED;
    162   1.7    blymn 
    163   1.6    blymn 					old_field = form->cur_field;
    164   1.6    blymn 					fieldp = form->fields[form->cur_field];
    165   1.7    blymn 					status = _formi_add_char(fieldp,
    166   1.7    blymn 							fieldp->start_char
    167   1.7    blymn 							+ fieldp->cursor_xpos,
    168   1.7    blymn 							c);
    169   1.6    blymn 				} else if (status == E_INVALID_FIELD)
    170   1.6    blymn 					  /* char failed validation, just
    171   1.6    blymn 					   * return the status.
    172   1.6    blymn 					   */
    173   1.1    blymn 					return status;
    174   1.9    blymn 				else if (status == E_NO_ROOM)
    175   1.9    blymn 					  /* we will get this if the line
    176   1.9    blymn 					   * wrapping fails.  Deny the
    177   1.9    blymn 					   * request.
    178   1.9    blymn 					   */
    179   1.9    blymn 					return E_REQUEST_DENIED;
    180   1.1    blymn 			}
    181   1.6    blymn 			while (status != E_OK);
    182   1.6    blymn 			update_field = (status == E_OK);
    183   1.1    blymn 		} else
    184   1.1    blymn 			return E_REQUEST_DENIED;
    185   1.1    blymn 	} else {
    186   1.1    blymn 		if (c > REQ_MAX_COMMAND)
    187   1.1    blymn 			return E_UNKNOWN_COMMAND;
    188   1.1    blymn 
    189   1.4    blymn 		if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
    190   1.4    blymn 			  /* first check the field we are in is ok */
    191   1.4    blymn 			if (_formi_validate_field(form) != E_OK)
    192   1.4    blymn 				return E_INVALID_FIELD;
    193   1.4    blymn 
    194   1.4    blymn 			if (form->field_term != NULL)
    195   1.4    blymn 				form->field_term(form);
    196   1.4    blymn 
    197   1.4    blymn 			  /*
    198   1.4    blymn 			   * if we have a page movement then the form term
    199   1.4    blymn 			   * needs to be called too
    200   1.4    blymn 			   */
    201   1.4    blymn 			if ((c <= REQ_LAST_PAGE) && (form->form_term != NULL))
    202   1.4    blymn 				form->form_term(form);
    203   1.4    blymn 		}
    204   1.4    blymn 
    205   1.4    blymn 
    206   1.1    blymn 		switch (c) {
    207   1.1    blymn 		case REQ_NEXT_PAGE:
    208   1.1    blymn 			if (form->page < form->max_page) {
    209   1.1    blymn 				old_page = form->page;
    210   1.1    blymn 				form->page++;
    211   1.1    blymn 				update_page = 1;
    212   1.1    blymn 				if (_formi_pos_first_field(form) != E_OK) {
    213   1.1    blymn 					form->page = old_page;
    214   1.4    blymn 					status = E_REQUEST_DENIED;
    215   1.1    blymn 				}
    216   1.1    blymn 			} else
    217   1.4    blymn 				status = E_REQUEST_DENIED;
    218   1.1    blymn 			break;
    219   1.1    blymn 
    220   1.1    blymn 		case REQ_PREV_PAGE:
    221   1.1    blymn 			if (form->page > 0) {
    222   1.1    blymn 				old_page = form->page;
    223   1.1    blymn 				form->page--;
    224   1.1    blymn 				update_page = 1;
    225   1.1    blymn 				if (_formi_pos_first_field(form) != E_OK) {
    226   1.1    blymn 					form->page = old_page;
    227   1.4    blymn 					status = E_REQUEST_DENIED;
    228   1.1    blymn 				}
    229   1.1    blymn 			} else
    230   1.4    blymn 				status = E_REQUEST_DENIED;
    231   1.1    blymn 			break;
    232   1.1    blymn 
    233   1.1    blymn 		case REQ_FIRST_PAGE:
    234   1.1    blymn 			old_page = form->page;
    235   1.1    blymn 			form->page = 0;
    236   1.1    blymn 			update_page = 1;
    237   1.1    blymn 			if (_formi_pos_first_field(form) != E_OK) {
    238   1.1    blymn 				form->page = old_page;
    239   1.4    blymn 				status = E_REQUEST_DENIED;
    240   1.1    blymn 			}
    241   1.1    blymn 			break;
    242   1.1    blymn 
    243   1.1    blymn 		case REQ_LAST_PAGE:
    244   1.1    blymn 			old_page = form->page;
    245   1.1    blymn 			form->page = form->max_page - 1;
    246   1.1    blymn 			update_page = 1;
    247   1.1    blymn 			if (_formi_pos_first_field(form) != E_OK) {
    248   1.1    blymn 				form->page = old_page;
    249   1.4    blymn 				status = E_REQUEST_DENIED;
    250   1.1    blymn 			}
    251   1.1    blymn 			break;
    252   1.1    blymn 
    253   1.1    blymn 		case REQ_NEXT_FIELD:
    254   1.1    blymn 			status = _formi_pos_new_field(form, _FORMI_FORWARD,
    255   1.1    blymn 						      FALSE);
    256   1.1    blymn 			update_field = 1;
    257   1.1    blymn 			break;
    258   1.1    blymn 
    259   1.1    blymn 		case REQ_PREV_FIELD:
    260   1.1    blymn 			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
    261   1.1    blymn 						      FALSE);
    262   1.1    blymn 			update_field = 1;
    263   1.1    blymn 			break;
    264   1.1    blymn 
    265   1.1    blymn 		case REQ_FIRST_FIELD:
    266   1.1    blymn 			form->cur_field = 0;
    267   1.1    blymn 			update_field = 1;
    268   1.1    blymn 			break;
    269   1.1    blymn 
    270   1.1    blymn 		case REQ_LAST_FIELD:
    271   1.1    blymn 			form->cur_field = form->field_count - 1;
    272   1.1    blymn 			update_field = 1;
    273   1.1    blymn 			break;
    274   1.1    blymn 
    275   1.1    blymn 		case REQ_SNEXT_FIELD:
    276   1.1    blymn 			status = _formi_pos_new_field(form, _FORMI_FORWARD,
    277   1.1    blymn 						      TRUE);
    278   1.1    blymn 			update_field = 1;
    279   1.1    blymn 			break;
    280   1.1    blymn 
    281   1.1    blymn 		case REQ_SPREV_FIELD:
    282   1.1    blymn 			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
    283   1.1    blymn 						      TRUE);
    284   1.1    blymn 			update_field = 1;
    285   1.1    blymn 			break;
    286   1.1    blymn 
    287   1.1    blymn 		case REQ_SFIRST_FIELD:
    288   1.1    blymn 			fieldp = CIRCLEQ_FIRST(&form->sorted_fields);
    289   1.1    blymn 			form->cur_field = fieldp->index;
    290   1.1    blymn 			update_field = 1;
    291   1.1    blymn 			break;
    292   1.1    blymn 
    293   1.1    blymn 		case REQ_SLAST_FIELD:
    294   1.1    blymn 			fieldp = CIRCLEQ_LAST(&form->sorted_fields);
    295   1.1    blymn 			form->cur_field = fieldp->index;
    296   1.1    blymn 			update_field = 1;
    297   1.1    blymn 			break;
    298   1.1    blymn 
    299   1.1    blymn 			  /*
    300   1.1    blymn 			   * The up, down, left and right field traversals
    301   1.1    blymn 			   * are rolled up into a single function, allow a
    302   1.1    blymn 			   * fall through to that function.
    303   1.1    blymn 			   */
    304   1.1    blymn 			  /* FALLTHROUGH */
    305   1.1    blymn 		case REQ_LEFT_FIELD:
    306   1.1    blymn 		case REQ_RIGHT_FIELD:
    307   1.1    blymn 		case REQ_UP_FIELD:
    308   1.1    blymn 		case REQ_DOWN_FIELD:
    309   1.1    blymn 			status = traverse_form_links(form, c);
    310   1.1    blymn 			update_field = 1;
    311   1.1    blymn 			break;
    312   1.1    blymn 
    313   1.1    blymn 			  /* the following commands modify the buffer, check if
    314   1.1    blymn 			     this is allowed first before falling through. */
    315   1.1    blymn 			  /* FALLTHROUGH */
    316   1.3    blymn 		case REQ_DEL_PREV:
    317   1.3    blymn 			  /*
    318   1.3    blymn 			   * need to check for the overloading of this
    319   1.3    blymn 			   * request.  If overload flag set and we are
    320   1.3    blymn 			   * at the start of field this request turns
    321   1.3    blymn 			   * into a previous field request. Otherwise
    322   1.3    blymn 			   * fallthrough to the field handler.
    323   1.3    blymn 			   */
    324   1.3    blymn 			if ((form->opts & O_BS_OVERLOAD) == O_BS_OVERLOAD) {
    325   1.3    blymn 				if ((fieldp->start_char == 0) &&
    326   1.3    blymn 				    (fieldp->start_line == 0) &&
    327  1.13    blymn 				    (fieldp->row_xpos == 0)) {
    328   1.3    blymn 					update_field =
    329   1.3    blymn 						_formi_manipulate_field(form,
    330   1.3    blymn 							REQ_PREV_FIELD);
    331   1.3    blymn 					break;
    332   1.3    blymn 				}
    333   1.3    blymn 			}
    334   1.3    blymn 
    335   1.3    blymn 			  /* FALLTHROUGH */
    336   1.3    blymn 		case REQ_NEW_LINE:
    337   1.3    blymn 			  /*
    338   1.3    blymn 			   * need to check for the overloading of this
    339   1.3    blymn 			   * request.  If overload flag set and we are
    340   1.3    blymn 			   * at the start of field this request turns
    341   1.3    blymn 			   * into a next field request. Otherwise
    342   1.3    blymn 			   * fallthrough to the field handler.
    343   1.3    blymn 			   */
    344   1.3    blymn 			if ((form->opts & O_NL_OVERLOAD) == O_NL_OVERLOAD) {
    345   1.3    blymn 				if ((fieldp->start_char == 0) &&
    346   1.3    blymn 				    (fieldp->start_line == 0) &&
    347  1.13    blymn 				    (fieldp->row_xpos == 0)) {
    348   1.3    blymn 					update_field =
    349   1.3    blymn 						_formi_manipulate_field(form,
    350   1.3    blymn 							REQ_NEXT_FIELD);
    351   1.3    blymn 					break;
    352   1.3    blymn 				}
    353   1.3    blymn 			}
    354   1.3    blymn 
    355   1.3    blymn 			  /* FALLTHROUGH */
    356   1.1    blymn 		case REQ_INS_CHAR:
    357   1.1    blymn 		case REQ_INS_LINE:
    358   1.1    blymn 		case REQ_DEL_CHAR:
    359   1.1    blymn 		case REQ_DEL_LINE:
    360   1.1    blymn 		case REQ_DEL_WORD:
    361   1.1    blymn 		case REQ_CLR_EOL:
    362   1.1    blymn 		case REQ_CLR_EOF:
    363   1.1    blymn 		case REQ_CLR_FIELD:
    364   1.1    blymn 		case REQ_OVL_MODE:
    365   1.1    blymn 		case REQ_INS_MODE:
    366   1.1    blymn 			  /* check if we are allowed to edit the field and fall
    367   1.1    blymn 			   * through if we are.
    368   1.1    blymn 			   */
    369   1.1    blymn 			if ((form->fields[form->cur_field]->opts & O_EDIT) != O_EDIT)
    370   1.1    blymn 				return E_REQUEST_DENIED;
    371   1.1    blymn 
    372   1.1    blymn 			  /* the following manipulate the field contents, bundle
    373   1.1    blymn 			     them into one function.... */
    374   1.1    blymn 			  /* FALLTHROUGH */
    375   1.1    blymn 		case REQ_NEXT_CHAR:
    376   1.1    blymn 		case REQ_PREV_CHAR:
    377   1.1    blymn 		case REQ_NEXT_LINE:
    378   1.1    blymn 		case REQ_PREV_LINE:
    379   1.1    blymn 		case REQ_NEXT_WORD:
    380   1.1    blymn 		case REQ_PREV_WORD:
    381   1.1    blymn 		case REQ_BEG_FIELD:
    382   1.1    blymn 		case REQ_END_FIELD:
    383   1.1    blymn 		case REQ_BEG_LINE:
    384   1.1    blymn 		case REQ_END_LINE:
    385   1.1    blymn 		case REQ_LEFT_CHAR:
    386   1.1    blymn 		case REQ_RIGHT_CHAR:
    387   1.1    blymn 		case REQ_UP_CHAR:
    388   1.1    blymn 		case REQ_DOWN_CHAR:
    389   1.1    blymn 		case REQ_SCR_FLINE:
    390   1.1    blymn 		case REQ_SCR_BLINE:
    391   1.1    blymn 		case REQ_SCR_FPAGE:
    392   1.1    blymn 		case REQ_SCR_BPAGE:
    393   1.1    blymn 		case REQ_SCR_FHPAGE:
    394   1.1    blymn 		case REQ_SCR_BHPAGE:
    395   1.1    blymn 		case REQ_SCR_FCHAR:
    396   1.1    blymn 		case REQ_SCR_BCHAR:
    397   1.1    blymn 		case REQ_SCR_HFLINE:
    398   1.1    blymn 		case REQ_SCR_HBLINE:
    399   1.1    blymn 		case REQ_SCR_HFHALF:
    400   1.1    blymn 		case REQ_SCR_HBHALF:
    401   1.1    blymn 			update_field = _formi_manipulate_field(form, c);
    402   1.1    blymn 			break;
    403   1.1    blymn 
    404   1.1    blymn 		case REQ_VALIDATION:
    405   1.1    blymn 			return _formi_validate_field(form);
    406   1.1    blymn 			  /* NOTREACHED */
    407   1.1    blymn 			break;
    408   1.1    blymn 
    409   1.1    blymn 		case REQ_PREV_CHOICE:
    410   1.1    blymn 		case REQ_NEXT_CHOICE:
    411   1.1    blymn 			update_field = _formi_field_choice(form, c);
    412  1.13    blymn 			  /* reinit the cursor pos just in case */
    413  1.13    blymn 			if (update_field == 1) {
    414  1.13    blymn 				_formi_init_field_xpos(fieldp);
    415  1.13    blymn 				fieldp->row_xpos = 0;
    416  1.13    blymn 			}
    417   1.1    blymn 			break;
    418   1.1    blymn 
    419   1.1    blymn 		default: /* should not need to do this, but.... */
    420   1.1    blymn 			return E_UNKNOWN_COMMAND;
    421   1.1    blymn 			  /* NOTREACHED */
    422   1.1    blymn 			break;
    423   1.1    blymn 		}
    424   1.4    blymn 	}
    425   1.4    blymn 
    426   1.4    blymn 	  /* call the field and form init functions if required. */
    427   1.4    blymn 	if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
    428   1.4    blymn 		if (form->field_init != NULL)
    429   1.4    blymn 			form->field_init(form);
    430   1.4    blymn 
    431   1.4    blymn 		  /*
    432   1.4    blymn 		   * if we have a page movement then the form init
    433   1.4    blymn 		   * needs to be called too
    434   1.4    blymn 		   */
    435   1.4    blymn 		if ((c <= REQ_LAST_PAGE) && (form->form_init != NULL))
    436   1.4    blymn 			form->form_init(form);
    437   1.4    blymn 
    438   1.4    blymn 		  /*
    439   1.4    blymn 		   * if there was an error just return now...
    440   1.4    blymn 		   */
    441   1.4    blymn 		if (status != E_OK)
    442   1.4    blymn 			return status;
    443   1.5    blymn 
    444   1.5    blymn 		  /* if we have no error, reset the various offsets */
    445   1.5    blymn 		fieldp = form->fields[form->cur_field];
    446   1.5    blymn 		fieldp->start_char = 0;
    447   1.5    blymn 		fieldp->start_line = 0;
    448  1.12    blymn 		fieldp->row_xpos = 0;
    449   1.5    blymn 		fieldp->cursor_ypos = 0;
    450  1.13    blymn 		_formi_init_field_xpos(fieldp);
    451   1.1    blymn 	}
    452   1.1    blymn 
    453   1.1    blymn 	if (update_field < 0)
    454   1.1    blymn 		return update_field;
    455   1.1    blymn 
    456   1.1    blymn 	if (update_field == 1)
    457   1.1    blymn 		update_page |= _formi_update_field(form, old_field);
    458   1.1    blymn 
    459   1.1    blymn 	if (update_page == 1)
    460   1.1    blymn 		_formi_draw_page(form);
    461   1.1    blymn 
    462   1.1    blymn 	pos_form_cursor(form);
    463  1.14    blymn 
    464  1.14    blymn 	if ((update_page == 1) || (update_field == 1))
    465  1.14    blymn 		wrefresh(form->scrwin);
    466  1.14    blymn 
    467   1.1    blymn 	return E_OK;
    468   1.1    blymn }
    469