summaryrefslogtreecommitdiff
path: root/lib/libforms/forms.c.orig
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libforms/forms.c.orig')
-rw-r--r--lib/libforms/forms.c.orig502
1 files changed, 502 insertions, 0 deletions
diff --git a/lib/libforms/forms.c.orig b/lib/libforms/forms.c.orig
new file mode 100644
index 000000000000..6787d8ecb1da
--- /dev/null
+++ b/lib/libforms/forms.c.orig
@@ -0,0 +1,502 @@
+/*-
+ * Copyright (c) 1995
+ * Paul Richards. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * verbatim and that no modifications are made prior to this
+ * point in the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Richards.
+ * 4. The name Paul Richards may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL PAUL RICHARDS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <forms.h>
+#include <ncurses.h>
+
+#include "internal.h"
+
+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 */
+};
+
+int done=0;
+
+int
+initfrm(struct form *form)
+{
+
+ struct field *field = &form->field[0];
+ int i;
+
+ 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);
+ }
+ }
+ cbreak();
+ noecho();
+
+ if (!form->height)
+ form->height = LINES;
+ if (!form->width)
+ form->width = COLS;
+
+ 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];
+ }
+ form->current_field = form->start_field;
+ show_form(form);
+ return (OK);
+}
+
+void
+endfrm(struct form *form)
+{
+
+ struct field *field = &form->field[0];
+ int i;
+
+ delwin(form->window);
+
+ for (i=0; i < form->no_fields; i++) {
+ if (field->type == F_INPUT)
+ free(field->field.input->input);
+ field = &form->field[i];
+ }
+}
+
+int
+update_form(struct form *form)
+{
+ 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);
+
+ return (done);
+}
+
+static void
+show_form(struct form *form)
+{
+ int i;
+ int y, x;
+
+ 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;
+ }
+ }
+ 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");
+}
+
+static void
+disp_input(struct form *form, int index)
+{
+
+ 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");
+}
+
+static void
+disp_menu(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.menu->options[field->field.menu->selected]) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+static void
+disp_action(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.action->text) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+static void
+field_action(struct form *form)
+{
+
+ 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;
+ }
+}
+
+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;
+ }
+ }
+}
+
+static int
+next_field(struct form *form, int ch)
+{
+
+ struct field *field = &form->field[form->current_field];
+
+ if (ch == F_UP) {
+ if (field->up == -1) {
+ print_status("Can't go up from here");
+ return (0);
+ } 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);
+ } 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);
+ } 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);
+ } 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);
+ } else
+ form->current_field = field->left;
+ } 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);
+
+ }
+ return (OK);
+}
+
+void
+print_status(char *msg)
+{
+ if (wmove(stdscr, LINES-1, 0) == ERR) {
+ endwin();
+ exit(1);
+ }
+
+ wclrtoeol(stdscr);
+
+ wstandout(stdscr);
+ if (wprintw(stdscr, "%s",
+ msg) == ERR) {
+ endwin();
+ exit(1);
+ }
+ wstandend(stdscr);
+ wrefresh(stdscr);
+}
+
+
+void
+field_input(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);
+
+ cursor = CURSPOS;
+ abspos = cursor;
+
+ 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);
+ }
+ /* Not Reached */
+}
+
+void
+exit_form(void)
+{
+ done = F_DONE;
+}
+
+void
+cancel_form(void)
+{
+ done = F_CANCEL;
+}