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