Index: main/form2.c
===================================================================
--- main/form2.c	(revision main,4)
+++ main/form2.c	(revision main,4)
@@ -0,0 +1,194 @@
+#include <form.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+#define _MAX_FORMS 16
+#define _MAX_FIELDS 16
+
+#define _KEY_BITS 4
+#define _IDX_MASK (~(0u) << _KEY_BITS)
+#define _KEY_MASK (~_IDX_MASK)
+
+
+
+#define DC(v, c) const int v = c
+
+DC(req_next_field, REQ_NEXT_FIELD);
+DC(req_del_prev, REQ_DEL_PREV);
+DC(key_backspace, KEY_BACKSPACE);
+DC(req_end_line, REQ_END_LINE);
+DC(req_end_field, REQ_END_FIELD);
+DC(req_beg_field, REQ_BEG_FIELD);
+DC(key_left, KEY_LEFT);
+DC(key_right, KEY_RIGHT);
+DC(req_left_char, REQ_LEFT_CHAR);
+DC(req_right_char, REQ_RIGHT_CHAR);
+
+
+
+typedef unsigned form2_h;
+
+struct form2_t {
+	unsigned key;
+
+	FIELD *fields[_MAX_FIELDS + 1];
+	int field_count;
+
+	FORM *form_struct; /* Only set when posted. */
+};
+
+static struct form2_t *_forms[_MAX_FORMS];
+
+
+static form2_h _form2_init(unsigned i)
+{
+	_forms[i] = calloc(1, sizeof(struct form2_t));
+	if(!_forms[i]) return 0;
+
+	do {
+		_forms[i]->key = rand() & _KEY_MASK;
+	} while(i == 0 && _forms[i]->key == 0);
+
+	return (i << _KEY_BITS) | _forms[i]->key;
+}
+
+static struct form2_t **_check_ptr(form2_h form)
+{
+	unsigned i, k;
+	struct form2_t **f;
+
+	if(!form) return NULL;
+
+	i = form >> _KEY_BITS;
+	k = form & _KEY_MASK;
+
+	if(i >= _MAX_FORMS) return NULL;
+
+	f = _forms + i;
+
+	if(!*f) return NULL;
+	if((*f)->key != k) return NULL;
+
+	return f;
+}
+
+static struct form2_t *_check(form2_h form)
+{
+	struct form2_t **f = _check_ptr(form);
+	if(!f) return NULL;
+	return *f;
+}
+
+form2_h form2_create(void)
+{
+	int i;
+
+	for(i = 0; i < _MAX_FORMS; i++)
+		if(!_forms[i]) return _form2_init(i);
+
+	return 0;
+}
+
+int form2_add_field(form2_h form, int row, int col, int width, int height,
+		int data_height)
+{
+	struct form2_t *f = _check(form);
+	int *i;
+
+	if(!f) return 0;
+
+	i = &(f->field_count);
+	if(*i == _MAX_FIELDS) return 0;
+
+	init_pair(1, COLOR_WHITE, COLOR_BLUE);
+
+	f->fields[*i] = new_field(height, width, row, col, data_height, 0);
+	set_field_back(f->fields[*i], A_UNDERLINE | COLOR_PAIR(1));
+	field_opts_off(f->fields[*i], O_AUTOSKIP);
+
+	++(*i);
+
+	return 1;
+}
+
+int form2_destroy(form2_h form)
+{
+	struct form2_t **f = _check_ptr(form);
+	int i;
+
+	if(!f) return 0;
+
+	for(i = 0; i < (*f)->field_count; i++) {
+		free_field((*f)->fields[i]);
+	}
+
+	free(*f);
+	*f = NULL;
+
+	return 1;
+}
+
+int form2_post(form2_h form)
+{
+	struct form2_t *f = _check(form);
+
+	if(!f) return 0;
+	if(f->form_struct) return 0;
+
+	f->form_struct = new_form(f->fields);
+
+	post_form(f->form_struct);
+
+	return 1;
+}
+
+int form2_drive(form2_h form, int c)
+{
+	struct form2_t *f = _check(form);
+
+	if(!f) return 0;
+	if(!f->form_struct) return 0;
+
+	form_driver(f->form_struct, c);
+
+	return 1;
+}
+
+int form2_unpost(form2_h form)
+{
+	struct form2_t *f = _check(form);
+
+	if(!f) return 0;
+	if(!f->form_struct) return 0;
+
+	unpost_form(f->form_struct);
+	free_form(f->form_struct);
+	f->form_struct = NULL;
+
+	return 1;
+}
+
+int form2_field_len(form2_h form, int i)
+{
+	struct form2_t *f = _check(form);
+
+	if(!f) return -1;
+	if(!f->form_struct) return -1;
+
+	return strlen(field_buffer(f->fields[i], 0));
+}
+
+int form2_copy_field(form2_h form, int i, char *buff, int len)
+{
+	struct form2_t *f = _check(form);
+
+	if(!f) return -1;
+	if(!f->form_struct) return -1;
+
+	strncpy(buff, field_buffer(f->fields[i], 0), len);
+	buff[len - 1] = '\0';
+
+	return 1;
+}
