freebsd-dev/lib/libforms/forms.c
1995-05-30 05:51:47 +00:00

268 lines
5.7 KiB
C

/*
* 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 <strhash.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>
#include <forms.h>
#include <err.h>
#include "internal.h"
extern FILE *yyin;
hash_table *root_table, *cbind;
OBJECT *cur_obj;
int done;
/* Default attribute commands */
struct attr_cmnd attr_cmnds[] = {
{"box", ATTR_BOX },
{"center", ATTR_CENTER },
{"right", ATTR_RIGHT }
};
/* Internal bindings */
struct intbind {
char *key;
void *addr;
};
struct intbind internal_bindings[] = {
{"draw_box", &draw_box},
{"draw_shadow", &draw_shadow}
};
/* Bind the internal function addresses */
void
bind_internals(hash_table *table)
{
int i;
for (i=0; i < (sizeof internal_bindings)/(sizeof (struct intbind)); i++)
if (bind_tuple(table, internal_bindings[i].key,
TT_FUNC, internal_bindings[i].addr) == ST_ERROR)
errx(-1, "Failed to bind internal tuples");
}
/*
* Find the default device and open a display on it.
*/
DISPLAY *
default_open(DISPLAY *display)
{
/* XXX -- not implemented, just calls ncurses */
return (ncurses_open(display));
}
int
load_objects(const char *filename)
{
FILE *fd;
root_table = hash_create(0);
if (!root_table)
errx(-1, "Failed to allocate root bindings table");
cbind = root_table;
bind_internals(root_table);
if (!(fd = fopen(filename, "r"))) {
warn("Couldn't open file %s", filename);
return (ST_ERROR);
}
yyin = fd;
yyparse();
if (fclose(fd)) {
warn("Couldn't close file %s", filename);
return (ST_ERROR);
}
return (ST_OK);
}
int
start_object(char *objname)
{
TUPLE *tuple;
OBJECT *object;
tuple = get_tuple(root_table, objname, TT_OBJ_INST);
if (!tuple)
return (ST_NOBIND);
object = (OBJECT *)tuple->addr;
cur_obj = object;
set_display(object->display);
cur_obj->status |= O_VISIBLE;
while (!done) {
hash_traverse(root_table, &display_tuples, root_table);
hash_traverse(root_table, &refresh_displays, root_table);
process_object(cur_obj);
}
return (ST_DONE);
}
int
call_function(char *func, OBJECT *obj)
{
TUPLE *tuple;
tuple = tuple_search(obj, func, TT_FUNC);
if (!tuple)
return (0);
(*tuple->addr)(obj);
return (1);
}
set_display(DISPLAY *display)
{
switch (display->type) {
case DT_NCURSES:
ncurses_set_display(display);
break;
default:
break;
}
}
void
display_object(OBJECT *obj)
{
switch(obj->display->type) {
case DT_NCURSES:
ncurses_display_object(obj);
break;
default:
break;
}
}
void
process_object(OBJECT *obj)
{
TUPLE *tuple;
/* Call user routine, if there is one. */
if (obj->UserProcFunc)
if (call_function(obj->UserProcFunc, obj))
return;
/* Find the first non-compound object or a default override */
while (obj->type == OT_COMPOUND) {
tuple = tuple_search(obj, obj->object.compound->defobj, TT_OBJ_INST);
obj = (OBJECT *)tuple->addr;
}
cur_obj = obj;
switch(obj->display->type) {
case DT_NCURSES:
ncurses_process_object(obj);
break;
default:
break;
}
}
int
refresh_displays(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
DISPLAY *display;
if (tuple->type == TT_DISPLAY)
display = (DISPLAY *)tuple->addr;
switch (display->type) {
case DT_NCURSES:
ncurses_refresh_display(display);
break;
default:
break;
}
return (1);
}
int
display_tuples(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
OBJECT *obj;
void (* fn)();
switch(tuple->type) {
case TT_OBJ_INST:
obj = (OBJECT *)tuple->addr;
/* Call user routine, if there is one. */
if (obj->UserDrawFunc) {
if (!call_function(obj->UserDrawFunc, obj))
display_object(obj);
} else
display_object(obj);
/* Display sub-objects */
if (obj->bind)
hash_traverse(obj->bind, &display_tuples, 0);
break;
default:
break;
}
return (1);
}
AttrType
parse_default_attributes(char *string)
{
int i;
for (i=0; i < (sizeof attr_cmnds) / (sizeof (struct attr_cmnd)); i++)
if (!strcmp(string, attr_cmnds[i].attr_name))
return (attr_cmnds[i].attr_type);
return (ATTR_UNKNOWN);
}