1*a0e6850fSThomas Cort /* $NetBSD: form.c,v 1.15 2004/11/24 11:57:09 blymn Exp $ */
2*a0e6850fSThomas Cort
3*a0e6850fSThomas Cort /*-
4*a0e6850fSThomas Cort * Copyright (c) 1998-1999 Brett Lymn
5*a0e6850fSThomas Cort * (blymn@baea.com.au, brett_lymn@yahoo.com.au)
6*a0e6850fSThomas Cort * All rights reserved.
7*a0e6850fSThomas Cort *
8*a0e6850fSThomas Cort * This code has been donated to The NetBSD Foundation by the Author.
9*a0e6850fSThomas Cort *
10*a0e6850fSThomas Cort * Redistribution and use in source and binary forms, with or without
11*a0e6850fSThomas Cort * modification, are permitted provided that the following conditions
12*a0e6850fSThomas Cort * are met:
13*a0e6850fSThomas Cort * 1. Redistributions of source code must retain the above copyright
14*a0e6850fSThomas Cort * notice, this list of conditions and the following disclaimer.
15*a0e6850fSThomas Cort * 2. The name of the author may not be used to endorse or promote products
16*a0e6850fSThomas Cort * derived from this software without specific prior written permission
17*a0e6850fSThomas Cort *
18*a0e6850fSThomas Cort * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19*a0e6850fSThomas Cort * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20*a0e6850fSThomas Cort * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21*a0e6850fSThomas Cort * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22*a0e6850fSThomas Cort * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23*a0e6850fSThomas Cort * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*a0e6850fSThomas Cort * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*a0e6850fSThomas Cort * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*a0e6850fSThomas Cort * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27*a0e6850fSThomas Cort * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*a0e6850fSThomas Cort *
29*a0e6850fSThomas Cort *
30*a0e6850fSThomas Cort */
31*a0e6850fSThomas Cort
32*a0e6850fSThomas Cort #include <sys/cdefs.h>
33*a0e6850fSThomas Cort __RCSID("$NetBSD: form.c,v 1.15 2004/11/24 11:57:09 blymn Exp $");
34*a0e6850fSThomas Cort
35*a0e6850fSThomas Cort #include <stdlib.h>
36*a0e6850fSThomas Cort #include <strings.h>
37*a0e6850fSThomas Cort #include <form.h>
38*a0e6850fSThomas Cort #include "internals.h"
39*a0e6850fSThomas Cort
40*a0e6850fSThomas Cort extern FIELD _formi_default_field;
41*a0e6850fSThomas Cort
42*a0e6850fSThomas Cort FORM _formi_default_form = {
43*a0e6850fSThomas Cort FALSE, /* true if performing a init or term function */
44*a0e6850fSThomas Cort FALSE, /* the form is posted */
45*a0e6850fSThomas Cort FALSE, /* make field list circular if true */
46*a0e6850fSThomas Cort NULL, /* window for the form */
47*a0e6850fSThomas Cort NULL, /* subwindow for the form */
48*a0e6850fSThomas Cort NULL, /* use this window for output */
49*a0e6850fSThomas Cort NULL, /* user defined pointer */
50*a0e6850fSThomas Cort 0, /* options for the form */
51*a0e6850fSThomas Cort NULL, /* function called when form posted and
52*a0e6850fSThomas Cort after page change */
53*a0e6850fSThomas Cort NULL, /* function called when form is unposted and
54*a0e6850fSThomas Cort before page change */
55*a0e6850fSThomas Cort NULL, /* function called when form posted and after
56*a0e6850fSThomas Cort current field changes */
57*a0e6850fSThomas Cort NULL, /* function called when form unposted and
58*a0e6850fSThomas Cort before current field changes */
59*a0e6850fSThomas Cort 0, /* number of fields attached */
60*a0e6850fSThomas Cort 0, /* current field */
61*a0e6850fSThomas Cort 0, /* current page of form */
62*a0e6850fSThomas Cort 0, /* number of pages in the form */
63*a0e6850fSThomas Cort NULL, /* dynamic array of fields that start
64*a0e6850fSThomas Cort the pages */
65*a0e6850fSThomas Cort {NULL, NULL}, /* sorted field list */
66*a0e6850fSThomas Cort NULL /* array of fields attached to this form. */
67*a0e6850fSThomas Cort };
68*a0e6850fSThomas Cort
69*a0e6850fSThomas Cort /*
70*a0e6850fSThomas Cort * Set the window associated with the form
71*a0e6850fSThomas Cort */
72*a0e6850fSThomas Cort int
set_form_win(FORM * form,WINDOW * win)73*a0e6850fSThomas Cort set_form_win(FORM *form, WINDOW *win)
74*a0e6850fSThomas Cort {
75*a0e6850fSThomas Cort if (form == NULL) {
76*a0e6850fSThomas Cort _formi_default_form.win = win;
77*a0e6850fSThomas Cort _formi_default_form.scrwin = win;
78*a0e6850fSThomas Cort } else {
79*a0e6850fSThomas Cort if (form->posted == TRUE)
80*a0e6850fSThomas Cort return E_POSTED;
81*a0e6850fSThomas Cort else {
82*a0e6850fSThomas Cort form->win = win;
83*a0e6850fSThomas Cort form->scrwin = win;
84*a0e6850fSThomas Cort }
85*a0e6850fSThomas Cort }
86*a0e6850fSThomas Cort
87*a0e6850fSThomas Cort return E_OK;
88*a0e6850fSThomas Cort }
89*a0e6850fSThomas Cort
90*a0e6850fSThomas Cort /*
91*a0e6850fSThomas Cort * Return the window used by the given form
92*a0e6850fSThomas Cort */
93*a0e6850fSThomas Cort WINDOW *
form_win(FORM * form)94*a0e6850fSThomas Cort form_win(FORM *form)
95*a0e6850fSThomas Cort {
96*a0e6850fSThomas Cort if (form == NULL)
97*a0e6850fSThomas Cort return _formi_default_form.win;
98*a0e6850fSThomas Cort else
99*a0e6850fSThomas Cort return form->win;
100*a0e6850fSThomas Cort }
101*a0e6850fSThomas Cort
102*a0e6850fSThomas Cort /*
103*a0e6850fSThomas Cort * Set the subwindow for the form.
104*a0e6850fSThomas Cort */
105*a0e6850fSThomas Cort int
set_form_sub(FORM * form,WINDOW * window)106*a0e6850fSThomas Cort set_form_sub(FORM *form, WINDOW *window)
107*a0e6850fSThomas Cort {
108*a0e6850fSThomas Cort if (form == NULL) {
109*a0e6850fSThomas Cort _formi_default_form.subwin = window;
110*a0e6850fSThomas Cort _formi_default_form.scrwin = window;
111*a0e6850fSThomas Cort } else {
112*a0e6850fSThomas Cort if (form->posted == TRUE)
113*a0e6850fSThomas Cort return E_POSTED;
114*a0e6850fSThomas Cort else {
115*a0e6850fSThomas Cort form->subwin = window;
116*a0e6850fSThomas Cort form->scrwin = window;
117*a0e6850fSThomas Cort }
118*a0e6850fSThomas Cort }
119*a0e6850fSThomas Cort
120*a0e6850fSThomas Cort return E_OK;
121*a0e6850fSThomas Cort }
122*a0e6850fSThomas Cort
123*a0e6850fSThomas Cort /*
124*a0e6850fSThomas Cort * Return the subwindow for the given form.
125*a0e6850fSThomas Cort */
126*a0e6850fSThomas Cort WINDOW *
form_sub(FORM * form)127*a0e6850fSThomas Cort form_sub(FORM *form)
128*a0e6850fSThomas Cort {
129*a0e6850fSThomas Cort if (form == NULL)
130*a0e6850fSThomas Cort return _formi_default_form.subwin;
131*a0e6850fSThomas Cort else
132*a0e6850fSThomas Cort return form->subwin;
133*a0e6850fSThomas Cort }
134*a0e6850fSThomas Cort
135*a0e6850fSThomas Cort /*
136*a0e6850fSThomas Cort * Return the minimum size required to contain the form.
137*a0e6850fSThomas Cort */
138*a0e6850fSThomas Cort int
scale_form(FORM * form,int * rows,int * cols)139*a0e6850fSThomas Cort scale_form(FORM *form, int *rows, int *cols)
140*a0e6850fSThomas Cort {
141*a0e6850fSThomas Cort int i, max_row, max_col, temp;
142*a0e6850fSThomas Cort
143*a0e6850fSThomas Cort if ((form->fields == NULL) || (form->fields[0] == NULL))
144*a0e6850fSThomas Cort return E_NOT_CONNECTED;
145*a0e6850fSThomas Cort
146*a0e6850fSThomas Cort max_row = 0;
147*a0e6850fSThomas Cort max_col = 0;
148*a0e6850fSThomas Cort
149*a0e6850fSThomas Cort for (i = 0; i < form->field_count; i++) {
150*a0e6850fSThomas Cort temp = form->fields[i]->form_row + form->fields[i]->rows;
151*a0e6850fSThomas Cort max_row = (temp > max_row)? temp : max_row;
152*a0e6850fSThomas Cort temp = form->fields[i]->form_col + form->fields[i]->cols;
153*a0e6850fSThomas Cort max_col = (temp > max_col)? temp : max_col;
154*a0e6850fSThomas Cort }
155*a0e6850fSThomas Cort
156*a0e6850fSThomas Cort (*rows) = max_row;
157*a0e6850fSThomas Cort (*cols) = max_col;
158*a0e6850fSThomas Cort
159*a0e6850fSThomas Cort return E_OK;
160*a0e6850fSThomas Cort }
161*a0e6850fSThomas Cort
162*a0e6850fSThomas Cort /*
163*a0e6850fSThomas Cort * Set the user defined pointer for the form given.
164*a0e6850fSThomas Cort */
165*a0e6850fSThomas Cort int
set_form_userptr(FORM * form,void * ptr)166*a0e6850fSThomas Cort set_form_userptr(FORM *form, void *ptr)
167*a0e6850fSThomas Cort {
168*a0e6850fSThomas Cort if (form == NULL)
169*a0e6850fSThomas Cort _formi_default_form.userptr = ptr;
170*a0e6850fSThomas Cort else
171*a0e6850fSThomas Cort form->userptr = ptr;
172*a0e6850fSThomas Cort
173*a0e6850fSThomas Cort return E_OK;
174*a0e6850fSThomas Cort }
175*a0e6850fSThomas Cort
176*a0e6850fSThomas Cort /*
177*a0e6850fSThomas Cort * Return the user defined pointer associated with the given form.
178*a0e6850fSThomas Cort */
179*a0e6850fSThomas Cort void *
form_userptr(FORM * form)180*a0e6850fSThomas Cort form_userptr(FORM *form)
181*a0e6850fSThomas Cort {
182*a0e6850fSThomas Cort
183*a0e6850fSThomas Cort if (form == NULL)
184*a0e6850fSThomas Cort return _formi_default_form.userptr;
185*a0e6850fSThomas Cort else
186*a0e6850fSThomas Cort return form->userptr;
187*a0e6850fSThomas Cort }
188*a0e6850fSThomas Cort
189*a0e6850fSThomas Cort /*
190*a0e6850fSThomas Cort * Set the form options to the given ones.
191*a0e6850fSThomas Cort */
192*a0e6850fSThomas Cort int
set_form_opts(FORM * form,Form_Options options)193*a0e6850fSThomas Cort set_form_opts(FORM *form, Form_Options options)
194*a0e6850fSThomas Cort {
195*a0e6850fSThomas Cort if (form == NULL)
196*a0e6850fSThomas Cort _formi_default_form.opts = options;
197*a0e6850fSThomas Cort else
198*a0e6850fSThomas Cort form->opts = options;
199*a0e6850fSThomas Cort
200*a0e6850fSThomas Cort return E_OK;
201*a0e6850fSThomas Cort }
202*a0e6850fSThomas Cort
203*a0e6850fSThomas Cort /*
204*a0e6850fSThomas Cort * Turn the given options on for the form.
205*a0e6850fSThomas Cort */
206*a0e6850fSThomas Cort int
form_opts_on(FORM * form,Form_Options options)207*a0e6850fSThomas Cort form_opts_on(FORM *form, Form_Options options)
208*a0e6850fSThomas Cort {
209*a0e6850fSThomas Cort if (form == NULL)
210*a0e6850fSThomas Cort _formi_default_form.opts |= options;
211*a0e6850fSThomas Cort else
212*a0e6850fSThomas Cort form->opts |= options;
213*a0e6850fSThomas Cort
214*a0e6850fSThomas Cort return E_OK;
215*a0e6850fSThomas Cort }
216*a0e6850fSThomas Cort
217*a0e6850fSThomas Cort /*
218*a0e6850fSThomas Cort * Turn the given options off for the form.
219*a0e6850fSThomas Cort */
220*a0e6850fSThomas Cort int
form_opts_off(FORM * form,Form_Options options)221*a0e6850fSThomas Cort form_opts_off(FORM *form, Form_Options options)
222*a0e6850fSThomas Cort {
223*a0e6850fSThomas Cort if (form == NULL)
224*a0e6850fSThomas Cort _formi_default_form.opts &= ~options;
225*a0e6850fSThomas Cort else
226*a0e6850fSThomas Cort form->opts &= ~options;
227*a0e6850fSThomas Cort
228*a0e6850fSThomas Cort
229*a0e6850fSThomas Cort return E_OK;
230*a0e6850fSThomas Cort }
231*a0e6850fSThomas Cort
232*a0e6850fSThomas Cort /*
233*a0e6850fSThomas Cort * Return the options set for the given form.
234*a0e6850fSThomas Cort */
235*a0e6850fSThomas Cort Form_Options
form_opts(FORM * form)236*a0e6850fSThomas Cort form_opts(FORM *form)
237*a0e6850fSThomas Cort {
238*a0e6850fSThomas Cort if (form == NULL)
239*a0e6850fSThomas Cort return _formi_default_form.opts;
240*a0e6850fSThomas Cort else
241*a0e6850fSThomas Cort return form->opts;
242*a0e6850fSThomas Cort }
243*a0e6850fSThomas Cort
244*a0e6850fSThomas Cort /*
245*a0e6850fSThomas Cort * Set the form init function for the given form
246*a0e6850fSThomas Cort */
247*a0e6850fSThomas Cort int
set_form_init(FORM * form,Form_Hook func)248*a0e6850fSThomas Cort set_form_init(FORM *form, Form_Hook func)
249*a0e6850fSThomas Cort {
250*a0e6850fSThomas Cort if (form == NULL)
251*a0e6850fSThomas Cort _formi_default_form.form_init = func;
252*a0e6850fSThomas Cort else
253*a0e6850fSThomas Cort form->form_init = func;
254*a0e6850fSThomas Cort
255*a0e6850fSThomas Cort return E_OK;
256*a0e6850fSThomas Cort }
257*a0e6850fSThomas Cort
258*a0e6850fSThomas Cort /*
259*a0e6850fSThomas Cort * Return the init function associated with the given form.
260*a0e6850fSThomas Cort */
261*a0e6850fSThomas Cort Form_Hook
form_init(FORM * form)262*a0e6850fSThomas Cort form_init(FORM *form)
263*a0e6850fSThomas Cort {
264*a0e6850fSThomas Cort if (form == NULL)
265*a0e6850fSThomas Cort return _formi_default_form.form_init;
266*a0e6850fSThomas Cort else
267*a0e6850fSThomas Cort return form->form_init;
268*a0e6850fSThomas Cort }
269*a0e6850fSThomas Cort
270*a0e6850fSThomas Cort /*
271*a0e6850fSThomas Cort * Set the function to be called on form termination.
272*a0e6850fSThomas Cort */
273*a0e6850fSThomas Cort int
set_form_term(FORM * form,Form_Hook function)274*a0e6850fSThomas Cort set_form_term(FORM *form, Form_Hook function)
275*a0e6850fSThomas Cort {
276*a0e6850fSThomas Cort if (form == NULL)
277*a0e6850fSThomas Cort _formi_default_form.form_term = function;
278*a0e6850fSThomas Cort else
279*a0e6850fSThomas Cort form->form_term = function;
280*a0e6850fSThomas Cort
281*a0e6850fSThomas Cort return E_OK;
282*a0e6850fSThomas Cort }
283*a0e6850fSThomas Cort
284*a0e6850fSThomas Cort /*
285*a0e6850fSThomas Cort * Return the function defined for the termination function.
286*a0e6850fSThomas Cort */
287*a0e6850fSThomas Cort Form_Hook
form_term(FORM * form)288*a0e6850fSThomas Cort form_term(FORM *form)
289*a0e6850fSThomas Cort {
290*a0e6850fSThomas Cort
291*a0e6850fSThomas Cort if (form == NULL)
292*a0e6850fSThomas Cort return _formi_default_form.form_term;
293*a0e6850fSThomas Cort else
294*a0e6850fSThomas Cort return form->form_term;
295*a0e6850fSThomas Cort }
296*a0e6850fSThomas Cort
297*a0e6850fSThomas Cort
298*a0e6850fSThomas Cort /*
299*a0e6850fSThomas Cort * Attach the given fields to the form.
300*a0e6850fSThomas Cort */
301*a0e6850fSThomas Cort int
set_form_fields(FORM * form,FIELD ** fields)302*a0e6850fSThomas Cort set_form_fields(FORM *form, FIELD **fields)
303*a0e6850fSThomas Cort {
304*a0e6850fSThomas Cort int num_fields = 0, i, maxpg = 1, status;
305*a0e6850fSThomas Cort
306*a0e6850fSThomas Cort if (form == NULL)
307*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
308*a0e6850fSThomas Cort
309*a0e6850fSThomas Cort if (form->posted == TRUE)
310*a0e6850fSThomas Cort return E_POSTED;
311*a0e6850fSThomas Cort
312*a0e6850fSThomas Cort if (fields == NULL)
313*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
314*a0e6850fSThomas Cort
315*a0e6850fSThomas Cort while (fields[num_fields] != NULL) {
316*a0e6850fSThomas Cort if ((fields[num_fields]->parent != NULL) &&
317*a0e6850fSThomas Cort (fields[num_fields]->parent != form))
318*a0e6850fSThomas Cort return E_CONNECTED;
319*a0e6850fSThomas Cort num_fields++;
320*a0e6850fSThomas Cort }
321*a0e6850fSThomas Cort
322*a0e6850fSThomas Cort /* disconnect old fields, if any */
323*a0e6850fSThomas Cort if (form->fields != NULL) {
324*a0e6850fSThomas Cort for (i = 0; i < form->field_count; i++) {
325*a0e6850fSThomas Cort form->fields[i]->parent = NULL;
326*a0e6850fSThomas Cort form->fields[i]->index = -1;
327*a0e6850fSThomas Cort }
328*a0e6850fSThomas Cort }
329*a0e6850fSThomas Cort
330*a0e6850fSThomas Cort /* kill old page pointers if any */
331*a0e6850fSThomas Cort if (form->page_starts != NULL)
332*a0e6850fSThomas Cort free(form->page_starts);
333*a0e6850fSThomas Cort
334*a0e6850fSThomas Cort form->field_count = num_fields;
335*a0e6850fSThomas Cort
336*a0e6850fSThomas Cort /* now connect the new fields to the form */
337*a0e6850fSThomas Cort for (i = 0; i < num_fields; i++) {
338*a0e6850fSThomas Cort fields[i]->parent = form;
339*a0e6850fSThomas Cort fields[i]->index = i;
340*a0e6850fSThomas Cort /* set the page number of the field */
341*a0e6850fSThomas Cort if (fields[i]->page_break == 1)
342*a0e6850fSThomas Cort maxpg++;
343*a0e6850fSThomas Cort fields[i]->page = maxpg;
344*a0e6850fSThomas Cort }
345*a0e6850fSThomas Cort
346*a0e6850fSThomas Cort form->fields = fields;
347*a0e6850fSThomas Cort form->cur_field = 0;
348*a0e6850fSThomas Cort form->max_page = maxpg;
349*a0e6850fSThomas Cort if ((status = _formi_find_pages(form)) != E_OK)
350*a0e6850fSThomas Cort return status;
351*a0e6850fSThomas Cort
352*a0e6850fSThomas Cort /* sort the fields and set the navigation pointers */
353*a0e6850fSThomas Cort _formi_sort_fields(form);
354*a0e6850fSThomas Cort _formi_stitch_fields(form);
355*a0e6850fSThomas Cort
356*a0e6850fSThomas Cort return E_OK;
357*a0e6850fSThomas Cort }
358*a0e6850fSThomas Cort
359*a0e6850fSThomas Cort /*
360*a0e6850fSThomas Cort * Return the fields attached to the form given.
361*a0e6850fSThomas Cort */
362*a0e6850fSThomas Cort FIELD **
form_fields(FORM * form)363*a0e6850fSThomas Cort form_fields(FORM *form)
364*a0e6850fSThomas Cort {
365*a0e6850fSThomas Cort if (form == NULL)
366*a0e6850fSThomas Cort return NULL;
367*a0e6850fSThomas Cort
368*a0e6850fSThomas Cort return form->fields;
369*a0e6850fSThomas Cort }
370*a0e6850fSThomas Cort
371*a0e6850fSThomas Cort /*
372*a0e6850fSThomas Cort * Return the number of fields attached to the given form.
373*a0e6850fSThomas Cort */
374*a0e6850fSThomas Cort int
field_count(FORM * form)375*a0e6850fSThomas Cort field_count(FORM *form)
376*a0e6850fSThomas Cort {
377*a0e6850fSThomas Cort if (form == NULL)
378*a0e6850fSThomas Cort return -1;
379*a0e6850fSThomas Cort
380*a0e6850fSThomas Cort return form->field_count;
381*a0e6850fSThomas Cort }
382*a0e6850fSThomas Cort
383*a0e6850fSThomas Cort /*
384*a0e6850fSThomas Cort * Move the given field to the row and column given.
385*a0e6850fSThomas Cort */
386*a0e6850fSThomas Cort int
move_field(FIELD * fptr,int frow,int fcol)387*a0e6850fSThomas Cort move_field(FIELD *fptr, int frow, int fcol)
388*a0e6850fSThomas Cort {
389*a0e6850fSThomas Cort FIELD *field = (fptr == NULL) ? &_formi_default_field : fptr;
390*a0e6850fSThomas Cort
391*a0e6850fSThomas Cort if (field->parent != NULL)
392*a0e6850fSThomas Cort return E_CONNECTED;
393*a0e6850fSThomas Cort
394*a0e6850fSThomas Cort field->form_row = frow;
395*a0e6850fSThomas Cort field->form_col = fcol;
396*a0e6850fSThomas Cort
397*a0e6850fSThomas Cort return E_OK;
398*a0e6850fSThomas Cort }
399*a0e6850fSThomas Cort
400*a0e6850fSThomas Cort /*
401*a0e6850fSThomas Cort * Set the page of the form to the given page.
402*a0e6850fSThomas Cort */
403*a0e6850fSThomas Cort int
set_form_page(FORM * form,int page)404*a0e6850fSThomas Cort set_form_page(FORM *form, int page)
405*a0e6850fSThomas Cort {
406*a0e6850fSThomas Cort if (form == NULL)
407*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
408*a0e6850fSThomas Cort
409*a0e6850fSThomas Cort if (form->in_init == TRUE)
410*a0e6850fSThomas Cort return E_BAD_STATE;
411*a0e6850fSThomas Cort
412*a0e6850fSThomas Cort if (page > form->max_page)
413*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
414*a0e6850fSThomas Cort
415*a0e6850fSThomas Cort form->page = page;
416*a0e6850fSThomas Cort return E_OK;
417*a0e6850fSThomas Cort }
418*a0e6850fSThomas Cort
419*a0e6850fSThomas Cort /*
420*a0e6850fSThomas Cort * Return the maximum page of the form.
421*a0e6850fSThomas Cort */
422*a0e6850fSThomas Cort int
form_max_page(FORM * form)423*a0e6850fSThomas Cort form_max_page(FORM *form)
424*a0e6850fSThomas Cort {
425*a0e6850fSThomas Cort if (form == NULL)
426*a0e6850fSThomas Cort return _formi_default_form.max_page;
427*a0e6850fSThomas Cort else
428*a0e6850fSThomas Cort return form->max_page;
429*a0e6850fSThomas Cort }
430*a0e6850fSThomas Cort
431*a0e6850fSThomas Cort /*
432*a0e6850fSThomas Cort * Return the current page of the form.
433*a0e6850fSThomas Cort */
434*a0e6850fSThomas Cort int
form_page(FORM * form)435*a0e6850fSThomas Cort form_page(FORM *form)
436*a0e6850fSThomas Cort {
437*a0e6850fSThomas Cort if (form == NULL)
438*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
439*a0e6850fSThomas Cort
440*a0e6850fSThomas Cort return form->page;
441*a0e6850fSThomas Cort }
442*a0e6850fSThomas Cort
443*a0e6850fSThomas Cort /*
444*a0e6850fSThomas Cort * Set the current field to the field given.
445*a0e6850fSThomas Cort */
446*a0e6850fSThomas Cort int
set_current_field(FORM * form,FIELD * field)447*a0e6850fSThomas Cort set_current_field(FORM *form, FIELD *field)
448*a0e6850fSThomas Cort {
449*a0e6850fSThomas Cort if (form == NULL)
450*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
451*a0e6850fSThomas Cort
452*a0e6850fSThomas Cort if (form->in_init == TRUE)
453*a0e6850fSThomas Cort return E_BAD_STATE;
454*a0e6850fSThomas Cort
455*a0e6850fSThomas Cort if (field == NULL)
456*a0e6850fSThomas Cort return E_INVALID_FIELD;
457*a0e6850fSThomas Cort
458*a0e6850fSThomas Cort if ((field->parent == NULL) || (field->parent != form))
459*a0e6850fSThomas Cort return E_INVALID_FIELD; /* field is not of this form */
460*a0e6850fSThomas Cort
461*a0e6850fSThomas Cort form->cur_field = field->index;
462*a0e6850fSThomas Cort
463*a0e6850fSThomas Cort /* XXX update page if posted??? */
464*a0e6850fSThomas Cort return E_OK;
465*a0e6850fSThomas Cort }
466*a0e6850fSThomas Cort
467*a0e6850fSThomas Cort /*
468*a0e6850fSThomas Cort * Return the current field of the given form.
469*a0e6850fSThomas Cort */
470*a0e6850fSThomas Cort FIELD *
current_field(FORM * form)471*a0e6850fSThomas Cort current_field(FORM *form)
472*a0e6850fSThomas Cort {
473*a0e6850fSThomas Cort if (form == NULL)
474*a0e6850fSThomas Cort return NULL;
475*a0e6850fSThomas Cort
476*a0e6850fSThomas Cort if (form->fields == NULL)
477*a0e6850fSThomas Cort return NULL;
478*a0e6850fSThomas Cort
479*a0e6850fSThomas Cort return form->fields[form->cur_field];
480*a0e6850fSThomas Cort }
481*a0e6850fSThomas Cort
482*a0e6850fSThomas Cort /*
483*a0e6850fSThomas Cort * Allocate a new form with the given fields.
484*a0e6850fSThomas Cort */
485*a0e6850fSThomas Cort FORM *
new_form(FIELD ** fields)486*a0e6850fSThomas Cort new_form(FIELD **fields)
487*a0e6850fSThomas Cort {
488*a0e6850fSThomas Cort FORM *new;
489*a0e6850fSThomas Cort
490*a0e6850fSThomas Cort if ((new = (FORM *) malloc(sizeof(FORM))) == NULL)
491*a0e6850fSThomas Cort return NULL;
492*a0e6850fSThomas Cort
493*a0e6850fSThomas Cort
494*a0e6850fSThomas Cort /* copy in the defaults... */
495*a0e6850fSThomas Cort bcopy(&_formi_default_form, new, sizeof(FORM));
496*a0e6850fSThomas Cort
497*a0e6850fSThomas Cort if (new->win == NULL)
498*a0e6850fSThomas Cort new->scrwin = stdscr; /* something for curses to write to */
499*a0e6850fSThomas Cort
500*a0e6850fSThomas Cort if (fields != NULL) { /* attach the fields, if any */
501*a0e6850fSThomas Cort if (set_form_fields(new, fields) < 0) {
502*a0e6850fSThomas Cort free(new); /* field attach failed, back out */
503*a0e6850fSThomas Cort return NULL;
504*a0e6850fSThomas Cort }
505*a0e6850fSThomas Cort }
506*a0e6850fSThomas Cort
507*a0e6850fSThomas Cort return new;
508*a0e6850fSThomas Cort }
509*a0e6850fSThomas Cort
510*a0e6850fSThomas Cort /*
511*a0e6850fSThomas Cort * Free the given form.
512*a0e6850fSThomas Cort */
513*a0e6850fSThomas Cort int
free_form(FORM * form)514*a0e6850fSThomas Cort free_form(FORM *form)
515*a0e6850fSThomas Cort {
516*a0e6850fSThomas Cort int i;
517*a0e6850fSThomas Cort
518*a0e6850fSThomas Cort if (form == NULL)
519*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
520*a0e6850fSThomas Cort
521*a0e6850fSThomas Cort if (form->posted == TRUE)
522*a0e6850fSThomas Cort return E_POSTED;
523*a0e6850fSThomas Cort
524*a0e6850fSThomas Cort for (i = 0; i < form->field_count; i++) {
525*a0e6850fSThomas Cort /* detach all the fields from the form */
526*a0e6850fSThomas Cort form->fields[i]->parent = NULL;
527*a0e6850fSThomas Cort form->fields[i]->index = -1;
528*a0e6850fSThomas Cort }
529*a0e6850fSThomas Cort
530*a0e6850fSThomas Cort free(form);
531*a0e6850fSThomas Cort
532*a0e6850fSThomas Cort return E_OK;
533*a0e6850fSThomas Cort }
534*a0e6850fSThomas Cort
535*a0e6850fSThomas Cort /*
536*a0e6850fSThomas Cort * Tell if the current field of the form has offscreen data ahead
537*a0e6850fSThomas Cort */
538*a0e6850fSThomas Cort int
data_ahead(FORM * form)539*a0e6850fSThomas Cort data_ahead(FORM *form)
540*a0e6850fSThomas Cort {
541*a0e6850fSThomas Cort FIELD *cur;
542*a0e6850fSThomas Cort
543*a0e6850fSThomas Cort if ((form == NULL) || (form->fields == NULL)
544*a0e6850fSThomas Cort || (form->fields[0] == NULL))
545*a0e6850fSThomas Cort return FALSE;
546*a0e6850fSThomas Cort
547*a0e6850fSThomas Cort cur = form->fields[form->cur_field];
548*a0e6850fSThomas Cort
549*a0e6850fSThomas Cort /*XXXX wrong */
550*a0e6850fSThomas Cort if (cur->cur_line->expanded > cur->cols)
551*a0e6850fSThomas Cort return TRUE;
552*a0e6850fSThomas Cort
553*a0e6850fSThomas Cort return FALSE;
554*a0e6850fSThomas Cort }
555*a0e6850fSThomas Cort
556*a0e6850fSThomas Cort /*
557*a0e6850fSThomas Cort * Tell if current field of the form has offscreen data behind
558*a0e6850fSThomas Cort */
559*a0e6850fSThomas Cort int
data_behind(FORM * form)560*a0e6850fSThomas Cort data_behind(FORM *form)
561*a0e6850fSThomas Cort {
562*a0e6850fSThomas Cort FIELD *cur;
563*a0e6850fSThomas Cort
564*a0e6850fSThomas Cort if ((form == NULL) || (form->fields == NULL)
565*a0e6850fSThomas Cort || (form->fields[0] == NULL))
566*a0e6850fSThomas Cort return FALSE;
567*a0e6850fSThomas Cort
568*a0e6850fSThomas Cort cur = form->fields[form->cur_field];
569*a0e6850fSThomas Cort
570*a0e6850fSThomas Cort if (cur->start_char > 0)
571*a0e6850fSThomas Cort return TRUE;
572*a0e6850fSThomas Cort
573*a0e6850fSThomas Cort return FALSE;
574*a0e6850fSThomas Cort }
575*a0e6850fSThomas Cort
576*a0e6850fSThomas Cort /*
577*a0e6850fSThomas Cort * Position the form cursor.
578*a0e6850fSThomas Cort */
579*a0e6850fSThomas Cort int
pos_form_cursor(FORM * form)580*a0e6850fSThomas Cort pos_form_cursor(FORM *form)
581*a0e6850fSThomas Cort {
582*a0e6850fSThomas Cort FIELD *cur;
583*a0e6850fSThomas Cort int row, col;
584*a0e6850fSThomas Cort
585*a0e6850fSThomas Cort if ((form == NULL) || (form->fields == NULL) ||
586*a0e6850fSThomas Cort (form->fields[0] == NULL))
587*a0e6850fSThomas Cort return E_BAD_ARGUMENT;
588*a0e6850fSThomas Cort
589*a0e6850fSThomas Cort if (form->posted != 1)
590*a0e6850fSThomas Cort return E_NOT_POSTED;
591*a0e6850fSThomas Cort
592*a0e6850fSThomas Cort cur = form->fields[form->cur_field];
593*a0e6850fSThomas Cort row = cur->form_row;
594*a0e6850fSThomas Cort col = cur->form_col;
595*a0e6850fSThomas Cort
596*a0e6850fSThomas Cort /* if the field is public then show the cursor pos */
597*a0e6850fSThomas Cort if ((cur->opts & O_PUBLIC) == O_PUBLIC) {
598*a0e6850fSThomas Cort row += cur->cursor_ypos;
599*a0e6850fSThomas Cort col += cur->cursor_xpos;
600*a0e6850fSThomas Cort if (cur->cursor_xpos >= cur->cols) {
601*a0e6850fSThomas Cort col = cur->form_col;
602*a0e6850fSThomas Cort row++;
603*a0e6850fSThomas Cort }
604*a0e6850fSThomas Cort }
605*a0e6850fSThomas Cort
606*a0e6850fSThomas Cort #ifdef DEBUG
607*a0e6850fSThomas Cort fprintf(dbg, "pos_cursor: row=%d, col=%d\n", row, col);
608*a0e6850fSThomas Cort #endif
609*a0e6850fSThomas Cort
610*a0e6850fSThomas Cort wmove(form->scrwin, row, col);
611*a0e6850fSThomas Cort
612*a0e6850fSThomas Cort return E_OK;
613*a0e6850fSThomas Cort }
614