89e255f52c
Bumped major number. Ncurses backend still needs improving. Other back-ends need to be written.
268 lines
5.7 KiB
C
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);
|
|
}
|