1995-03-01 08:19:06 +00:00
|
|
|
|
/*-
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
1995-03-26 10:25:00 +00:00
|
|
|
|
#include <strhash.h>
|
1995-03-01 08:19:06 +00:00
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <err.h>
|
|
|
|
|
#include <ncurses.h>
|
|
|
|
|
#include <forms.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
extern hash_table *global_bindings;
|
|
|
|
|
|
|
|
|
|
struct attr_cmd {
|
|
|
|
|
char *name;
|
|
|
|
|
int attr;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct attr_cmd attr_cmds[] = {
|
|
|
|
|
{ "standout", 0x00010000},
|
|
|
|
|
{ "underline", 0x00020000},
|
|
|
|
|
{ "reverse", 0x00040000},
|
|
|
|
|
{ "blink", 0x00080000},
|
|
|
|
|
{ "bold", 0x00200000 }
|
|
|
|
|
};
|
|
|
|
|
|
1995-03-01 08:19:06 +00:00
|
|
|
|
int done=0;
|
|
|
|
|
|
|
|
|
|
int
|
1995-03-26 07:44:33 +00:00
|
|
|
|
init_field(char *key, void *data, void *arg)
|
1995-03-01 08:19:06 +00:00
|
|
|
|
{
|
1995-03-26 07:44:33 +00:00
|
|
|
|
struct Tuple *tuple = (struct Tuple *)data;
|
|
|
|
|
struct Tuple *def_tuple;
|
|
|
|
|
struct Field *def, *field;
|
1995-03-01 08:19:06 +00:00
|
|
|
|
int i;
|
|
|
|
|
int len, lim;
|
1995-03-26 07:44:33 +00:00
|
|
|
|
int strwidth;
|
1995-03-01 08:19:06 +00:00
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
field = (struct Field *)tuple->addr;
|
|
|
|
|
|
|
|
|
|
/* Field definitions are global, at least for now */
|
|
|
|
|
def_tuple = form_get_tuple(global_bindings, field->defname, FT_FIELD_DEF);
|
|
|
|
|
if (!def_tuple) {
|
1995-03-01 08:19:06 +00:00
|
|
|
|
warnx("Field definition not found -- skipping field");
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
def = (struct Field *)def_tuple->addr;
|
1995-03-01 08:19:06 +00:00
|
|
|
|
field->height = def->height;
|
|
|
|
|
field->width = def->width;
|
|
|
|
|
field->attr = def->attr;
|
|
|
|
|
field->selattr = def->selattr;
|
|
|
|
|
field->type = def->type;
|
|
|
|
|
switch (field->type) {
|
|
|
|
|
case FF_INPUT:
|
|
|
|
|
field->field.input = malloc(sizeof (struct InputField));
|
|
|
|
|
if (!field->field.input) {
|
|
|
|
|
warnx("Couldn't allocate memory for input field");
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
field->field.input->limit = def->field.input->limit;
|
|
|
|
|
|
|
|
|
|
/* Force height to one regardless, at least for now :-) */
|
|
|
|
|
field->height = 1;
|
|
|
|
|
if (!field->width && !field->field.input->limit) {
|
1995-03-26 07:44:33 +00:00
|
|
|
|
field->width = calc_string_width(def->field.input->label);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
field->field.input->limit = field->width;
|
|
|
|
|
} else if (!field->width)
|
|
|
|
|
field->width = field->field.input->limit;
|
|
|
|
|
else if (!field->field.input->limit)
|
|
|
|
|
field->field.input->limit = field->width;
|
|
|
|
|
if (field->field.input->limit < field->width)
|
|
|
|
|
field->width = field->field.input->limit;
|
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
strwidth = strlen(def->field.input->label);
|
|
|
|
|
field->field.input->input = malloc(strwidth + 1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!field->field.input->input) {
|
|
|
|
|
warnx("Couldn't allocate memory for input field text");
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
1995-03-26 07:44:33 +00:00
|
|
|
|
field->field.input->label = malloc(strwidth + 1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!field->field.input->label) {
|
|
|
|
|
warnx("Couldn't allocate memory for input field label");
|
|
|
|
|
return (-1);
|
|
|
|
|
}
|
|
|
|
|
strncpy(field->field.input->label,
|
|
|
|
|
def->field.input->label,
|
1995-03-26 07:44:33 +00:00
|
|
|
|
strwidth + 1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
field->field.input->lbl_flag = def->field.input->lbl_flag;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If it's a label then clear the input string
|
|
|
|
|
* otherwise copy the default there.
|
|
|
|
|
*/
|
|
|
|
|
if (field->field.input->lbl_flag)
|
|
|
|
|
field->field.input->input[0] = '\0';
|
|
|
|
|
else if (field->field.input->label) {
|
|
|
|
|
strncpy(field->field.input->input,
|
1995-03-26 07:44:33 +00:00
|
|
|
|
field->field.input->label,
|
|
|
|
|
strwidth + 1);
|
|
|
|
|
field->field.input->input[strwidth] = 0;
|
1995-03-01 08:19:06 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case FF_TEXT:
|
|
|
|
|
field->field.text = malloc(sizeof (struct TextField));
|
|
|
|
|
if (!field->field.text) {
|
|
|
|
|
warnx("Couldn't allocate memory for text field");
|
|
|
|
|
return (FS_ERROR);
|
|
|
|
|
}
|
1995-03-26 07:44:33 +00:00
|
|
|
|
strwidth = strlen(def->field.text->text);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!field->width)
|
1995-03-26 07:44:33 +00:00
|
|
|
|
field->width = calc_string_width(def->field.text->text);
|
|
|
|
|
field->field.text->text = malloc(strwidth + 1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!field->field.text->text) {
|
|
|
|
|
warnx("Couldn't allocate memory for text field text");
|
|
|
|
|
return (FS_ERROR);
|
|
|
|
|
} else
|
|
|
|
|
strncpy(field->field.text->text,
|
|
|
|
|
def->field.text->text,
|
1995-03-26 07:44:33 +00:00
|
|
|
|
strwidth + 1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!field->height)
|
|
|
|
|
calc_field_height(field, field->field.text->text);
|
|
|
|
|
break;
|
|
|
|
|
case FF_MENU:
|
|
|
|
|
field->field.menu = malloc(sizeof (struct MenuField));
|
|
|
|
|
if (!field->field.menu) {
|
|
|
|
|
warnx("Couldn't allocate memory for menu field");
|
|
|
|
|
return (FS_ERROR);
|
|
|
|
|
}
|
|
|
|
|
field->field.menu->no_options = 0;
|
|
|
|
|
field->height = 1;
|
|
|
|
|
lim = 0;
|
|
|
|
|
for (i=0; i < def->field.menu->no_options; i++) {
|
|
|
|
|
field->field.menu->no_options =
|
|
|
|
|
add_menu_option(field->field.menu,
|
|
|
|
|
def->field.menu->options[i]);
|
|
|
|
|
if (!field->field.menu->no_options) {
|
|
|
|
|
warnx("Couldn't add menu option");
|
|
|
|
|
return (FS_ERROR);
|
|
|
|
|
}
|
1995-03-26 07:44:33 +00:00
|
|
|
|
len = calc_string_width(def->field.menu->options[i]);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (len > lim)
|
|
|
|
|
lim = len;
|
|
|
|
|
}
|
|
|
|
|
if (!field->width)
|
|
|
|
|
field->width = lim;
|
|
|
|
|
break;
|
|
|
|
|
case FF_ACTION:
|
|
|
|
|
field->field.action = malloc(sizeof (struct ActionField));
|
|
|
|
|
if (!field->field.action) {
|
|
|
|
|
warnx("Couldn't allocate memory for action field");
|
|
|
|
|
return (FS_ERROR);
|
|
|
|
|
}
|
|
|
|
|
if (!field->width)
|
1995-03-26 07:44:33 +00:00
|
|
|
|
field->width = calc_string_width(def->field.action->text);
|
|
|
|
|
strwidth = strlen(def->field.action->text);
|
|
|
|
|
field->field.action->text = malloc(strwidth + 1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!field->field.action->text) {
|
|
|
|
|
warnx("Couldn't allocate memory for text field text");
|
|
|
|
|
return (FS_ERROR);
|
|
|
|
|
} else
|
|
|
|
|
strncpy(field->field.action->text,
|
|
|
|
|
def->field.action->text,
|
1995-03-26 07:44:33 +00:00
|
|
|
|
strwidth + 1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!field->height)
|
|
|
|
|
calc_field_height(field, field->field.action->text);
|
|
|
|
|
field->field.action->fn = def->field.action->fn;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
1995-03-26 07:44:33 +00:00
|
|
|
|
return (1);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
display_field(WINDOW *window, struct Field *field)
|
|
|
|
|
{
|
|
|
|
|
wattrset(window, field->attr);
|
|
|
|
|
wmove(window, field->y, field->x);
|
|
|
|
|
switch (field->type) {
|
|
|
|
|
case FF_TEXT:
|
|
|
|
|
display_text(window, field);
|
|
|
|
|
break;
|
|
|
|
|
case FF_MENU:
|
|
|
|
|
display_menu(window, field);
|
|
|
|
|
break;
|
|
|
|
|
case FF_INPUT:
|
|
|
|
|
display_input(window, field);
|
|
|
|
|
break;
|
|
|
|
|
case FF_ACTION:
|
|
|
|
|
display_action(window, field);
|
|
|
|
|
break;
|
|
|
|
|
case FF_UNKNOWN:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
wattrset(window, 0);
|
|
|
|
|
wrefresh(window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
display_text(WINDOW *window, struct Field *field)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (print_string(window, field->y, field->x, field->height,
|
|
|
|
|
field->width, field->field.text->text) == ERR)
|
|
|
|
|
print_status("Illegal scroll in print_string");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
display_input(WINDOW *window, struct Field *field)
|
|
|
|
|
{
|
|
|
|
|
if (field->field.input->lbl_flag) {
|
|
|
|
|
if (print_string(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(window, field->y, field->x, field->height,
|
|
|
|
|
field->width, field->field.input->input) == ERR)
|
|
|
|
|
print_status("Illegal scroll in print_string");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
display_menu(WINDOW *window, struct Field *field)
|
|
|
|
|
{
|
|
|
|
|
if (print_string(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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
display_action(WINDOW *window, struct Field *field)
|
|
|
|
|
{
|
|
|
|
|
if (print_string(window, field->y, field->x, field->height,
|
|
|
|
|
field->width,
|
|
|
|
|
field->field.action->text) == ERR)
|
|
|
|
|
print_status("Illegal scroll in print_string");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
do_action(struct Form *form)
|
|
|
|
|
{
|
|
|
|
|
struct Field *field = form->current_field;
|
|
|
|
|
struct Tuple *tuple;
|
|
|
|
|
int ch;
|
|
|
|
|
void (* fn)();
|
|
|
|
|
|
|
|
|
|
display_action(form->window, field);
|
|
|
|
|
wmove(form->window, field->y, field->x);
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
|
|
ch = wgetch(form->window);
|
|
|
|
|
|
|
|
|
|
if (ch == FK_ACCEPT) {
|
1995-03-26 07:44:33 +00:00
|
|
|
|
tuple = form_get_tuple(form->bindings, field->field.action->fn, FT_FUNC);
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (!tuple) {
|
|
|
|
|
print_status("No function bound to action");
|
|
|
|
|
beep();
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
fn = tuple->addr;
|
|
|
|
|
(*fn)(form);
|
|
|
|
|
return (FS_OK);
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
ch = do_key_bind(form, ch);
|
|
|
|
|
|
|
|
|
|
if (ch == FS_OK)
|
|
|
|
|
return (FS_OK);
|
|
|
|
|
else if (ch == FS_ERROR)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
do_menu(struct Form *form)
|
|
|
|
|
{
|
|
|
|
|
struct Field *field = form->current_field;
|
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
|
|
display_menu(form->window, field);
|
|
|
|
|
wmove(form->window, field->y, field->x);
|
|
|
|
|
|
|
|
|
|
ch = wgetch(form->window);
|
|
|
|
|
|
|
|
|
|
switch (ch) {
|
|
|
|
|
case ' ':
|
|
|
|
|
print_status("");
|
|
|
|
|
field->field.menu->selected++;
|
|
|
|
|
if (field->field.menu->selected >= field->field.menu->no_options)
|
|
|
|
|
field->field.menu->selected = 0;
|
1995-03-26 07:44:33 +00:00
|
|
|
|
ch = FS_OK;
|
1995-03-01 08:19:06 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
ch = do_key_bind(form, ch);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ch == FS_OK)
|
|
|
|
|
return (FS_OK);
|
|
|
|
|
else if (ch == FS_ERROR) {
|
|
|
|
|
beep();
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
print_status("Hit the space bar to toggle through options");
|
|
|
|
|
beep();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
do_field(struct Form *form)
|
|
|
|
|
{
|
1995-03-26 07:44:33 +00:00
|
|
|
|
struct Tuple *tuple;
|
1995-03-01 08:19:06 +00:00
|
|
|
|
struct Field *field = form->current_field;
|
1995-03-26 07:44:33 +00:00
|
|
|
|
void (* fn)();
|
1995-03-01 08:19:06 +00:00
|
|
|
|
int status;
|
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
/* Do field entry tasks */
|
|
|
|
|
if (field->enter) {
|
|
|
|
|
tuple = form_get_tuple(form->bindings, field->enter, FT_FUNC);
|
|
|
|
|
|
|
|
|
|
if (tuple) {
|
|
|
|
|
fn = tuple->addr;
|
|
|
|
|
(*fn)(form);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-01 08:19:06 +00:00
|
|
|
|
switch (field->type) {
|
|
|
|
|
case FF_TEXT:
|
|
|
|
|
status = FS_OK;
|
|
|
|
|
display_text(form->window, field);
|
|
|
|
|
break;
|
|
|
|
|
case FF_INPUT:
|
|
|
|
|
status = do_input(form);
|
|
|
|
|
break;
|
|
|
|
|
case FF_MENU:
|
|
|
|
|
status = do_menu(form);
|
|
|
|
|
break;
|
|
|
|
|
case FF_ACTION:
|
|
|
|
|
status = do_action(form);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
status = FF_UNKNOWN;
|
|
|
|
|
beep();
|
|
|
|
|
print_status("Unknown field type");
|
|
|
|
|
form->current_field = form->prev_field;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
/* Do field leave tasks */
|
|
|
|
|
if (field->leave) {
|
|
|
|
|
tuple = form_get_tuple(form->bindings, field->leave, FT_FUNC);
|
|
|
|
|
|
|
|
|
|
if (tuple) {
|
|
|
|
|
fn = tuple->addr;
|
|
|
|
|
(*fn)(form);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-01 08:19:06 +00:00
|
|
|
|
return (status);
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
int
|
|
|
|
|
parse_attr(WINDOW *window, char *string)
|
|
|
|
|
{
|
|
|
|
|
int inc = 0;
|
|
|
|
|
struct attr_cmd *attr;
|
|
|
|
|
|
|
|
|
|
if (*(string) == '\\')
|
|
|
|
|
return (1);
|
|
|
|
|
|
|
|
|
|
while (!isspace(*(string + inc))) {
|
|
|
|
|
inc++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (attr = attr_cmds; attr->name; attr++) {
|
|
|
|
|
if (strncmp(attr->name, string, inc))
|
|
|
|
|
continue;
|
|
|
|
|
else {
|
|
|
|
|
wattron(window, attr->attr);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Skip trailing space after the attribute string */
|
|
|
|
|
while (isspace(*(string + inc)))
|
|
|
|
|
inc++;
|
|
|
|
|
|
|
|
|
|
return (inc);
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-01 08:19:06 +00:00
|
|
|
|
int
|
|
|
|
|
print_string(WINDOW *window, int y, int x,
|
|
|
|
|
int height, int fwidth, char *string)
|
|
|
|
|
{
|
1995-03-26 07:44:33 +00:00
|
|
|
|
int len, skip;
|
1995-03-01 08:19:06 +00:00
|
|
|
|
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) {
|
1995-03-26 07:44:33 +00:00
|
|
|
|
if (*string == '\\') {
|
|
|
|
|
string++;
|
|
|
|
|
len--;
|
|
|
|
|
skip = parse_attr(window, string);
|
|
|
|
|
len -= skip;
|
|
|
|
|
string += skip;
|
|
|
|
|
}
|
1995-03-01 08:19:06 +00:00
|
|
|
|
if (waddch(window, *string++) == ERR)
|
|
|
|
|
return (ERR);
|
1995-03-26 07:44:33 +00:00
|
|
|
|
} else if (waddch(window, ' ') == ERR)
|
1995-03-01 08:19:06 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
do_input(struct Form *form)
|
|
|
|
|
{
|
|
|
|
|
struct Field *field = form->current_field;
|
|
|
|
|
int len;
|
|
|
|
|
int disp_off=0, abspos=0, cursor = 0;
|
|
|
|
|
unsigned int ch;
|
|
|
|
|
|
|
|
|
|
#define DISPOFF ((len < field->width) ? 0 : len - field->width)
|
|
|
|
|
#define CURSPOS ((len < field->width) ? len : field->width)
|
|
|
|
|
|
|
|
|
|
len = strlen(field->field.input->input);
|
|
|
|
|
display_input(form->window, field);
|
|
|
|
|
|
|
|
|
|
cursor = CURSPOS;
|
|
|
|
|
abspos = cursor;
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
|
|
wmove(form->window, field->y, field->x+cursor);
|
|
|
|
|
wrefresh(form->window);
|
|
|
|
|
|
|
|
|
|
ch = wgetch(form->window);
|
|
|
|
|
ch = do_key_bind(form, ch);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If there was a valid motion command then we've
|
|
|
|
|
* moved to a new field so just return. If the motion
|
|
|
|
|
* command was invalid then just go around and get another
|
|
|
|
|
* keystroke. Otherwise, it was not a motion command.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (ch == FS_OK)
|
|
|
|
|
return (FS_OK);
|
|
|
|
|
else if (ch == FS_ERROR)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
print_status("");
|
|
|
|
|
|
|
|
|
|
if (field->field.input->lbl_flag) {
|
|
|
|
|
field->field.input->lbl_flag = 0;
|
|
|
|
|
}
|
|
|
|
|
if ((ch == FK_CHOME) || (ch == '')) {
|
|
|
|
|
disp_off = 0;
|
|
|
|
|
cursor = 0;
|
|
|
|
|
abspos = 0;
|
|
|
|
|
} else if ((ch == FK_CEND) || (ch == '')) {
|
|
|
|
|
disp_off = DISPOFF;
|
|
|
|
|
abspos = len;
|
|
|
|
|
cursor = CURSPOS;
|
|
|
|
|
} else if (ch == FK_CDEL) {
|
|
|
|
|
if (!(len-abspos))
|
|
|
|
|
beep();
|
|
|
|
|
else {
|
|
|
|
|
bcopy(field->field.input->input+abspos+1,
|
|
|
|
|
field->field.input->input+abspos,
|
|
|
|
|
len - abspos);
|
|
|
|
|
--len;
|
|
|
|
|
}
|
|
|
|
|
} else if ((ch == FK_CLEFT) || (ch == FK_CBS) || (ch == '')) {
|
|
|
|
|
if (!abspos)
|
|
|
|
|
beep();
|
|
|
|
|
else {
|
|
|
|
|
if (ch == FK_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 == FK_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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-26 07:44:33 +00:00
|
|
|
|
/*
|
|
|
|
|
* Calculate length of printable part of the string,
|
|
|
|
|
* stripping out the attribute modifiers.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
calc_string_width(char *string)
|
|
|
|
|
{
|
|
|
|
|
int len, width=0;
|
|
|
|
|
|
|
|
|
|
if (!string)
|
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
|
|
len = strlen(string);
|
|
|
|
|
|
|
|
|
|
while (len) {
|
|
|
|
|
if (*string != '\\') {
|
|
|
|
|
width++;
|
|
|
|
|
len--;
|
|
|
|
|
string++;
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
string++;
|
|
|
|
|
len--;
|
|
|
|
|
if (*string == '\\') {
|
|
|
|
|
string++;
|
|
|
|
|
width++;
|
|
|
|
|
len--;
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
while (!isspace(*string)) {
|
|
|
|
|
string++;
|
|
|
|
|
len--;
|
|
|
|
|
}
|
|
|
|
|
while (isspace(*string)) {
|
|
|
|
|
string ++;
|
|
|
|
|
len--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Calculate a default height for a field */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
calc_field_height(struct Field *field, char *string)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int len;
|
|
|
|
|
|
|
|
|
|
len = calc_string_width(string);
|
|
|
|
|
|
|
|
|
|
if (!field->width) {
|
|
|
|
|
/*
|
|
|
|
|
* This is a failsafe, this routine shouldn't be called
|
|
|
|
|
* with a width of 0, the width should be determined
|
|
|
|
|
* first.
|
|
|
|
|
*/
|
|
|
|
|
field->height = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (len < field->width) {
|
|
|
|
|
field->height = 1;
|
|
|
|
|
return;
|
|
|
|
|
} else
|
|
|
|
|
field->height = len / field->width;
|
|
|
|
|
|
|
|
|
|
if ((field->height*field->width) < len)
|
|
|
|
|
field->height++;
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
1995-03-01 08:19:06 +00:00
|
|
|
|
void
|
|
|
|
|
exit_form(struct Form *form)
|
|
|
|
|
{
|
|
|
|
|
form->status = FS_EXIT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
cancel_form(struct Form *form)
|
|
|
|
|
{
|
|
|
|
|
form->status = FS_CANCEL;
|
|
|
|
|
}
|