/* * Post the form to the screen. */ int post_form(FORM *form) { int rows, cols, status; if (form == NULL) return E_BAD_ARGUMENT; if (form->posted == 1) return E_POSTED; if ((form->fields == NULL) || (form->fields[0] == NULL)) return E_NOT_CONNECTED; if (form->in_init == 1) return E_BAD_STATE; if (scale_form(form, &rows, &cols) != E_OK) return E_SYSTEM_ERROR; if ((form->scrwin != NULL) && ((rows > getmaxy(form->scrwin)) || (cols > getmaxx(form->scrwin)))) { return E_NO_ROOM; } form->in_init = 1; if (form->form_init != NULL) form->form_init(form); if (form->field_init != NULL) form->field_init(form); form->in_init = 0; _formi_pos_first_field(form); if ((status = _formi_draw_page(form)) != E_OK) return status; form->posted = 1; pos_form_cursor(form); return E_OK; }
int form_driver(FORM *form, int c) { FIELD *fieldp; int update_page, update_field, old_field, old_page, status; int start_field; unsigned int pos; if (form == NULL) return E_BAD_ARGUMENT; if ((form->fields == NULL) || (*(form->fields) == NULL)) return E_INVALID_FIELD; if (form->posted != 1) return E_NOT_POSTED; if (form->in_init == 1) return E_BAD_STATE; old_field = start_field = form->cur_field; fieldp = form->fields[form->cur_field]; update_page = update_field = 0; status = E_OK; if (c < REQ_MIN_REQUEST) { if (isprint(c) || isblank(c)) { do { pos = fieldp->start_char + fieldp->row_xpos; /* check if we are allowed to edit this field */ if ((fieldp->opts & O_EDIT) != O_EDIT) return E_REQUEST_DENIED; if ((status = (_formi_add_char(fieldp, pos, c))) == E_REQUEST_DENIED) { /* * Need to check here if we * want to autoskip. we * call the form driver * recursively to pos us on * the next field and then * we loop back to ensure * the next field selected * can have data added to it */ if ((fieldp->opts & O_AUTOSKIP) != O_AUTOSKIP) return E_REQUEST_DENIED; status = form_driver(form, REQ_NEXT_FIELD); if (status != E_OK) return status; /* * check if we have looped * around all the fields. * This can easily happen if * all the fields are full. */ if (start_field == form->cur_field) return E_REQUEST_DENIED; old_field = form->cur_field; fieldp = form->fields[form->cur_field]; status = _formi_add_char(fieldp, fieldp->start_char + fieldp->cursor_xpos, c); } else if (status == E_INVALID_FIELD) /* char failed validation, just * return the status. */ return status; else if (status == E_NO_ROOM) /* we will get this if the line * wrapping fails. Deny the * request. */ return E_REQUEST_DENIED; } while (status != E_OK); update_field = (status == E_OK); } else return E_REQUEST_DENIED; } else { if (c > REQ_MAX_COMMAND) return E_UNKNOWN_COMMAND; if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) { /* first check the field we are in is ok */ if (_formi_validate_field(form) != E_OK) return E_INVALID_FIELD; if (form->field_term != NULL) form->field_term(form); /* * if we have a page movement then the form term * needs to be called too */ if ((c <= REQ_LAST_PAGE) && (form->form_term != NULL)) form->form_term(form); } switch (c) { case REQ_NEXT_PAGE: if (form->page < form->max_page) { old_page = form->page; form->page++; update_page = 1; if (_formi_pos_first_field(form) != E_OK) { form->page = old_page; status = E_REQUEST_DENIED; } } else status = E_REQUEST_DENIED; break; case REQ_PREV_PAGE: if (form->page > 0) { old_page = form->page; form->page--; update_page = 1; if (_formi_pos_first_field(form) != E_OK) { form->page = old_page; status = E_REQUEST_DENIED; } } else status = E_REQUEST_DENIED; break; case REQ_FIRST_PAGE: old_page = form->page; form->page = 0; update_page = 1; if (_formi_pos_first_field(form) != E_OK) { form->page = old_page; status = E_REQUEST_DENIED; } break; case REQ_LAST_PAGE: old_page = form->page; form->page = form->max_page - 1; update_page = 1; if (_formi_pos_first_field(form) != E_OK) { form->page = old_page; status = E_REQUEST_DENIED; } break; case REQ_NEXT_FIELD: status = _formi_pos_new_field(form, _FORMI_FORWARD, FALSE); update_field = 1; break; case REQ_PREV_FIELD: status = _formi_pos_new_field(form, _FORMI_BACKWARD, FALSE); update_field = 1; break; case REQ_FIRST_FIELD: form->cur_field = 0; update_field = 1; break; case REQ_LAST_FIELD: form->cur_field = form->field_count - 1; update_field = 1; break; case REQ_SNEXT_FIELD: status = _formi_pos_new_field(form, _FORMI_FORWARD, TRUE); update_field = 1; break; case REQ_SPREV_FIELD: status = _formi_pos_new_field(form, _FORMI_BACKWARD, TRUE); update_field = 1; break; case REQ_SFIRST_FIELD: fieldp = TAILQ_FIRST(&form->sorted_fields); form->cur_field = fieldp->index; update_field = 1; break; case REQ_SLAST_FIELD: fieldp = TAILQ_LAST(&form->sorted_fields, _formi_sort_head); form->cur_field = fieldp->index; update_field = 1; break; /* * The up, down, left and right field traversals * are rolled up into a single function, allow a * fall through to that function. */ case REQ_LEFT_FIELD: case REQ_RIGHT_FIELD: case REQ_UP_FIELD: case REQ_DOWN_FIELD: status = traverse_form_links(form, c); update_field = 1; break; /* the following commands modify the buffer, check if this is allowed first before falling through. */ case REQ_DEL_PREV: /* * need to check for the overloading of this * request. If overload flag set and we are * at the start of field this request turns * into a previous field request. Otherwise * fallthrough to the field handler. */ if ((form->opts & O_BS_OVERLOAD) == O_BS_OVERLOAD) { if ((fieldp->start_char == 0) && (fieldp->start_line == 0) && (fieldp->row_xpos == 0)) { update_field = _formi_manipulate_field(form, REQ_PREV_FIELD); break; } } /* FALLTHROUGH */ case REQ_NEW_LINE: /* * need to check for the overloading of this * request. If overload flag set and we are * at the start of field this request turns * into a next field request. Otherwise * fallthrough to the field handler. */ if ((form->opts & O_NL_OVERLOAD) == O_NL_OVERLOAD) { if ((fieldp->start_char == 0) && (fieldp->start_line == 0) && (fieldp->row_xpos == 0)) { update_field = _formi_manipulate_field(form, REQ_NEXT_FIELD); break; } } /* FALLTHROUGH */ case REQ_INS_CHAR: case REQ_INS_LINE: case REQ_DEL_CHAR: case REQ_DEL_LINE: case REQ_DEL_WORD: case REQ_CLR_EOL: case REQ_CLR_EOF: case REQ_CLR_FIELD: case REQ_OVL_MODE: case REQ_INS_MODE: /* check if we are allowed to edit the field and fall * through if we are. */ if ((form->fields[form->cur_field]->opts & O_EDIT) != O_EDIT) return E_REQUEST_DENIED; /* the following manipulate the field contents, bundle them into one function.... */ /* FALLTHROUGH */ case REQ_NEXT_CHAR: case REQ_PREV_CHAR: case REQ_NEXT_LINE: case REQ_PREV_LINE: case REQ_NEXT_WORD: case REQ_PREV_WORD: case REQ_BEG_FIELD: case REQ_END_FIELD: case REQ_BEG_LINE: case REQ_END_LINE: case REQ_LEFT_CHAR: case REQ_RIGHT_CHAR: case REQ_UP_CHAR: case REQ_DOWN_CHAR: case REQ_SCR_FLINE: case REQ_SCR_BLINE: case REQ_SCR_FPAGE: case REQ_SCR_BPAGE: case REQ_SCR_FHPAGE: case REQ_SCR_BHPAGE: case REQ_SCR_FCHAR: case REQ_SCR_BCHAR: case REQ_SCR_HFLINE: case REQ_SCR_HBLINE: case REQ_SCR_HFHALF: case REQ_SCR_HBHALF: update_field = _formi_manipulate_field(form, c); break; case REQ_VALIDATION: return _formi_validate_field(form); /* NOTREACHED */ break; case REQ_PREV_CHOICE: case REQ_NEXT_CHOICE: update_field = _formi_field_choice(form, c); /* reinit the cursor pos just in case */ if (update_field == 1) { _formi_init_field_xpos(fieldp); fieldp->row_xpos = 0; } break; default: /* should not need to do this, but.... */ return E_UNKNOWN_COMMAND; /* NOTREACHED */ break; } } /* call the field and form init functions if required. */ if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) { if (form->field_init != NULL) form->field_init(form); /* * if we have a page movement then the form init * needs to be called too */ if ((c <= REQ_LAST_PAGE) && (form->form_init != NULL)) form->form_init(form); /* * if there was an error just return now... */ if (status != E_OK) return status; /* if we have no error, reset the various offsets */ fieldp = form->fields[form->cur_field]; fieldp->start_char = 0; fieldp->start_line = fieldp->alines; fieldp->cur_line = fieldp->alines; fieldp->row_xpos = 0; fieldp->cursor_ypos = 0; _formi_init_field_xpos(fieldp); } if (update_field < 0) return update_field; if (update_field == 1) update_page |= _formi_update_field(form, old_field); if (update_page == 1) _formi_draw_page(form); pos_form_cursor(form); if ((update_page == 1) || (update_field == 1)) wrefresh(form->scrwin); return E_OK; }