diff options
Diffstat (limited to 'lib/libforms/forms.c')
| -rw-r--r-- | lib/libforms/forms.c | 574 |
1 files changed, 183 insertions, 391 deletions
diff --git a/lib/libforms/forms.c b/lib/libforms/forms.c index 6787d8ecb1da..a51c95e28932 100644 --- a/lib/libforms/forms.c +++ b/lib/libforms/forms.c @@ -1,4 +1,4 @@ -/*- +/* * Copyright (c) 1995 * Paul Richards. All rights reserved. * @@ -32,48 +32,72 @@ * */ -#include <string.h> +#include <stdio.h> #include <stdlib.h> -#include <ctype.h> #include <forms.h> +#include <err.h> #include <ncurses.h> #include "internal.h" +extern FILE *yyin; + +struct Tuple *fbind_first; +struct Tuple *fbind_last; + unsigned int f_keymap[] = { - KEY_UP, /* F_UP */ - KEY_DOWN, /* F_DOWN */ - 9, /* F_RIGHT */ - 8, /* F_LEFT */ - 10, /* F_NEXT */ - KEY_LEFT, /* F_CLEFT */ - KEY_RIGHT, /* F_CRIGHT */ - KEY_HOME, /* F_CHOME */ - KEY_END, /* F_CEND */ - 263, /* F_CBS */ - 330, /* F_CDEL */ - 10 /* F_ACCEPT */ + KEY_UP, /* F_UP */ + KEY_DOWN, /* F_DOWN */ + 9, /* F_RIGHT */ + 8, /* F_LEFT */ + 10, /* F_NEXT */ + KEY_LEFT, /* F_CLEFT */ + KEY_RIGHT, /* F_CRIGHT */ + KEY_HOME, /* F_CHOME */ + KEY_END, /* F_CEND */ + 263, /* F_CBS */ + 330, /* F_CDEL */ + 10 /* F_ACCEPT */ }; -int done=0; - int -initfrm(struct form *form) +form_load(const char *filename) +{ + FILE *fd; + + if (!(fd = fopen(filename, "r"))) { + warn("Couldn't open forms file %s", filename); + return (FS_ERROR); + } + + yyin = fd; + yyparse(); + + if (fclose(fd)) { + warn("Couldn't close forms file %s", filename); + return (FS_ERROR); + } + + return (FS_OK); +} + +struct Form * +form_start(const char *formname) { + struct Tuple *tuple; + struct Form *form; + struct Field *field; - struct field *field = &form->field[0]; - int i; + tuple = form_get_tuple(formname, FT_FORM); - if (has_colors()) { - start_color(); - if (form->color_table) - for (i=0; form->color_table[i].f != -1; i++) { - init_pair(i+1, form->color_table[i].f, form->color_table[i].b); - } + if (!tuple) { + warnx("No such form"); + return (0); } - cbreak(); - noecho(); + form = tuple->addr; + + /* Initialise form */ if (!form->height) form->height = LINES; if (!form->width) @@ -81,422 +105,190 @@ initfrm(struct form *form) form->window = newwin(form->height, form->width, form->y, form->x); if (!form->window) { - print_status("Couldn't open window, closing form"); - return (ERR); - } - form->no_fields = 0; - - keypad(form->window, TRUE); - - - while (field->type != F_END) { - if (field->type == F_INPUT) { - field->field.input->input = malloc(field->field.input->limit); - if (!field->field.input->input){ - print_status("Couldn't allocate memory, closing form"); - endfrm(form); - return (ERR); - } - /* - * If it's a label then clear the input string - * otherwise copy the default string to the input string. - */ - if (field->field.input->lbl_flag) - field->field.input->input[0] = '\0'; - else if (field->field.input->label) { - strncpy(field->field.input->input, - field->field.input->label, - field->field.input->limit); - field->field.input->input[field->field.input->limit] = 0; - } - } else if ((field->type != F_TEXT) && (field->type != F_MENU) && - (field->type != F_ACTION)) { - print_status("Unknown field type, closing form"); - endfrm(form); - return (ERR); - } - form->no_fields++; - field = &form->field[form->no_fields]; + warnx("Couldn't open window, closing form"); + return (0); } - form->current_field = form->start_field; - show_form(form); - return (OK); -} -void -endfrm(struct form *form) -{ + tuple = form_get_tuple(form->startfield, FT_FIELD_INST); + + if (!tuple) { + warnx("No start field specified"); + /* XXX should search for better default start */ + form->current_field = form->fieldlist; + } else + form->current_field = (struct Field *)tuple->addr; - struct field *field = &form->field[0]; - int i; + form->prev_field = form->current_field; - delwin(form->window); + /* Initialise the field instances */ - for (i=0; i < form->no_fields; i++) { - if (field->type == F_INPUT) - free(field->field.input->input); - field = &form->field[i]; + for (field = form->fieldlist; field; field = field->next) { + init_field(field); } + + form->status = FS_RUNNING; + + return (form); } int -update_form(struct form *form) +form_bind_tuple(char *name, TupleType type, void *addr) { - show_form(form); - - if (form->current_field == -1) - return (F_CANCEL); - - wattrset(form->window, form->field[form->current_field].selattr); - switch (form->field[form->current_field].type) { - case F_MENU: - field_menu(form); - break; - case F_INPUT: - field_input(form); - break; - case F_ACTION: - field_action(form); - break; - case F_TEXT: - default: - print_status("Error, current field is invalid"); - return (F_CANCEL); - } - wattrset(form->window, 0); + struct Tuple *tuple; - return (done); -} + tuple = malloc(sizeof (struct Tuple)); + if (!tuple) { + warn("Couldn't allocate memory for new tuple"); + return (FS_ERROR); + } -static void -show_form(struct form *form) -{ - int i; - int y, x; + tuple->name = name; + tuple->type = type; + tuple->addr = addr; + tuple->next = 0; - wattrset(form->window, form->attr); - for (y = 0; y < form->height; y++) - for (x = 0; x < form->width; x++) - mvwaddch(form->window, y, x, ' '); - for (i=0; i < form->no_fields; i++) { - wattrset(form->window, form->field[i].attr); - wmove(form->window, form->field[i].y, form->field[i].x); - switch (form->field[i].type) { - case F_TEXT: - disp_text(form, i); - break; - case F_MENU: - disp_menu(form, i); - break; - case F_INPUT: - disp_input(form,i); - break; - case F_ACTION: - disp_action(form,i); - break; - case F_END: - default: - break; + if (!fbind_first) { + fbind_first = tuple; + fbind_last = tuple; + } else { + /* Check there isn't already a tuple of this type with this name */ + if (form_get_tuple(name, type)) { + warn("Duplicate tuple name, %s, skipping", name); + return (FS_ERROR); } + fbind_last->next = tuple; + fbind_last = tuple; } - wattrset(form->window, 0); - wrefresh(form->window); -} - -static void -disp_text(struct form *form, int index) -{ - - struct field *field = &form->field[index]; - if (print_string(form->window, field->y, field->x, field->height, - field->width, field->field.text->text) == ERR) - print_status("Illegal scroll in print_string"); + return (0); } -static void -disp_input(struct form *form, int index) +struct Tuple * +form_get_tuple(const char *name, TupleType type) { - - struct field *field = &form->field[index]; - - if (field->field.input->lbl_flag) { - if (print_string(form->window, field->y, field->x, field->height, - field->width, field->field.input->label) == ERR) - print_status("Illegal scroll in print_string"); - } else - if (print_string(form->window, field->y, field->x, field->height, - field->width, field->field.input->input) == ERR) - print_status("Illegal scroll in print_string"); + return (form_next_tuple(name, type, fbind_first)); } -static void -disp_menu(struct form *form, int index) +struct Tuple * +form_next_tuple(const char *name, TupleType type, struct Tuple *tuple) { - struct field *field = &form->field[index]; + for (; tuple; tuple = tuple->next) { + if (type != FT_ANY) + if (tuple->type != type) + continue; + if (name) + if (strcmp(name, tuple->name)) + continue; + return (tuple); + } - if (print_string(form->window, field->y, field->x, field->height, - field->width, - field->field.menu->options[field->field.menu->selected]) == ERR) - print_status("Illegal scroll in print_string"); + return (0); } -static void -disp_action(struct form *form, int index) +int +form_show(const char *formname) { - struct field *field = &form->field[index]; + struct Tuple *tuple; + struct Form *form; + struct Field *field; + int x, y; - if (print_string(form->window, field->y, field->x, field->height, - field->width, - field->field.action->text) == ERR) - print_status("Illegal scroll in print_string"); -} + tuple = form_get_tuple(formname, FT_FORM); + if (!tuple) + return (FS_NOBIND); -static void -field_action(struct form *form) -{ + form = tuple->addr; - struct field *field = &form->field[form->current_field]; - int ch; - - for (;;) { - disp_action(form, form->current_field); - wmove(form->window, field->y, field->x); - ch = wgetch(form->window); - if (ch == F_ACCEPT) { - (*field->field.action->fn)(); - return; - } else if (!next_field(form, ch)) - beep(); - else - return; - } -} + /* Clear form */ + wattrset(form->window, form->attr); + for (y=0; y < form->height; y++) + for (x=0; x < form->width; x++) + mvwaddch(form->window, y, x, ' '); -static void -field_menu(struct form *form) -{ - struct field *field = &form->field[form->current_field]; - int ch; - - for (;;) { - disp_menu(form, form->current_field); - wmove(form->window, field->y, field->x); - switch (ch = wgetch(form->window)) { - case ' ': - print_status(""); - field->field.menu->selected++; - if (field->field.menu->selected >= field->field.menu->no_options) - field->field.menu->selected = 0; - break; - default: - if (!next_field(form, ch)) { - print_status("Hit the space bar to toggle through options"); - beep(); - } else - return; - } + for (field = form->fieldlist; field; field = field->next) { + display_field(form->window, field); } + + return (FS_OK); } -static int -next_field(struct form *form, int ch) +unsigned int +do_key_bind(struct Form *form, unsigned int ch) { + struct Field *field = form->current_field; + struct Tuple *tuple=0; - struct field *field = &form->field[form->current_field]; + /* XXX -- check for keymappings here --- not yet done */ - if (ch == F_UP) { - if (field->up == -1) { - print_status("Can't go up from here"); - return (0); + if (ch == FK_UP) { + if (field->fup) { + tuple = form_get_tuple(field->fup, FT_FIELD_INST); + if (!tuple) + print_status("Field to move up to does not exist"); } else - form->current_field = field->up; - } else if (ch == F_DOWN) { - if (field->down == -1) { - print_status("Can't go down from here"); - return (0); + print_status("Can't move up from this field"); + } else if (ch == FK_DOWN) { + if (field->fdown) { + tuple = form_get_tuple(field->fdown, FT_FIELD_INST); + if (!tuple) + print_status("Field to move down to does not exist"); } else - form->current_field = field->down; - } else if (ch == F_NEXT) { - if (field->next == -1) { - print_status("Can't go to next from here"); - return (0); + print_status("Can't move down from this field"); + } else if (ch == FK_LEFT) { + if (field->fleft) { + tuple = form_get_tuple(field->fleft, FT_FIELD_INST); + if (!tuple) + print_status("Field to move left to does not exist"); } else - form->current_field = field->next; - } else if (ch == F_RIGHT) { - if (field->right == -1) { - print_status("Can't go right from here"); - return (0); + print_status("Can't move left from this field"); + } else if (ch == FK_RIGHT) { + if (field->fright) { + tuple = form_get_tuple(field->fright, FT_FIELD_INST); + if (!tuple) + print_status("Field to move right to does not exist"); } else - form->current_field = field->right; - } else if (ch == F_LEFT) { - if (field->left == -1) { - print_status("Can't go left from here"); - return (0); + print_status("Can't move right from this field"); + } else if (ch == FK_NEXT) { + if (field->fnext) { + tuple = form_get_tuple(field->fnext, FT_FIELD_INST); + if (!tuple) + print_status("Field to move to next does not exist"); } else - form->current_field = field->left; + print_status("Can't move next from this field"); } else - return (0); - - print_status(""); - return (1); -} - -static int -print_string(WINDOW *window, int y, int x, - int height, int fwidth, char *string) -{ - int len; - int width; - - if (!string) - len = -1; - - len = strlen(string); - - if (wmove(window, y, x) == ERR) - return (ERR); - while (height--) { - width = fwidth; - while (width--) { - if (len-- > 0) { - if (waddch(window, *string++) == ERR) - return (ERR); - } else - if (waddch(window, ' ') == ERR) - return (ERR); - } - if (wmove(window, ++y, x) == ERR) - return (ERR); - + /* No motion keys pressed */ + return (ch); + + if (tuple) { + form->prev_field = form->current_field; + form->current_field = tuple->addr; + return (FS_OK); + } else { + beep(); + return (FS_ERROR); } - return (OK); -} +} void -print_status(char *msg) +debug_dump_bindings() { - if (wmove(stdscr, LINES-1, 0) == ERR) { - endwin(); - exit(1); - } + struct Tuple *binds; - wclrtoeol(stdscr); - - wstandout(stdscr); - if (wprintw(stdscr, "%s", - msg) == ERR) { - endwin(); - exit(1); + binds = form_get_tuple(0, FT_ANY); + while (binds) { + printf("%s, %d, %x\n", binds->name, binds->type, (int)binds->addr); + binds = form_next_tuple(0, FT_ANY, binds->next); } - wstandend(stdscr); - wrefresh(stdscr); } - -void -field_input(struct form *form) +void debug_dump_form(struct Form *form) { - struct field *field = &form->field[form->current_field]; - int len; - int ch; - int disp_off=0, abspos=0, cursor = 0; - -#define DISPOFF ((len < field->width) ? 0 : len - field->width) -#define CURSPOS ((len < field->width) ? len : field->width) - - len = strlen(field->field.input->input); - disp_input(form, form->current_field); + struct Field *field; - cursor = CURSPOS; - abspos = cursor; + field = form->fieldlist; - for(;;) { - - wmove(form->window, field->y, field->x+cursor); - wrefresh(form->window); - - ch = wgetch(form->window); - if (next_field(form, ch)) { - print_string(form->window, field->y, field->x, - field->height, field->width, - field->field.input->input+DISPOFF); - return; - } - if (field->field.input->lbl_flag) { - field->field.input->lbl_flag = 0; - } - if ((ch == F_CHOME) || (ch == '')) { - disp_off = 0; - cursor = 0; - abspos = 0; - } else if ((ch == F_CEND) || (ch == '')) { - disp_off = DISPOFF; - abspos = len; - cursor = CURSPOS; - } else if (ch == F_CDEL) { - if (!(len-abspos)) - beep(); - else { - bcopy(field->field.input->input+abspos+1, - field->field.input->input+abspos, - len - abspos); - --len; - } - } else if ((ch == F_CLEFT) || (ch == F_CBS) || (ch == '')) { - if (!abspos) - beep(); - else { - if (ch == F_CBS) { - bcopy(field->field.input->input+abspos, - field->field.input->input+abspos-1, - len-abspos+1); - --len; - } - --abspos; - --cursor; - if ((disp_off) && (cursor < 0)) { - --disp_off; - ++cursor; - } - } - } else if ((ch == F_CRIGHT) || (ch == '')) { - if (abspos == len) - beep(); - else { - ++abspos; - if (++cursor == field->width) { - ++disp_off; - --cursor; - } - } - } else if ((isprint(ch)) && (len < field->field.input->limit)){ - bcopy(field->field.input->input+abspos, - field->field.input->input+abspos+1, len-abspos+1); - field->field.input->input[abspos++] = ch; - len++; - if (++cursor > field->width) { - ++disp_off; - --cursor; - } - } else { - beep(); - } - print_string(form->window, field->y, field->x, field->height, - field->width, field->field.input->input+disp_off); + for ( ; field; field = field->next) { + printf("%s, %x, next = %x\n", field->defname, (int)field, (int)field->next); } - /* Not Reached */ -} - -void -exit_form(void) -{ - done = F_DONE; -} - -void -cancel_form(void) -{ - done = F_CANCEL; } |
