emview_source.c from EmStar at Krugle
Show emview_source.c syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR
* CONTRIBUTORS 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 "emview_i.h"
#include <math.h>
char emview_source_c_id[] = "$Id: emview_source.c,v 1.31 2006/05/30 20:10:52 nithya Exp $";
QUEUE_INST(emview_link_data, ptrs, links, link_data_t, link_source_t);
QUEUE_INST(emview_source_data, ptrs, values, source_data_t, simple_source_t);
QUEUE_INST(emview_source, ptrs, sources, source_t, emview_source_list_t);
/*
* creating a data source
*
* There are several different kinds of source that can be registered
* - simple sources (string and int)
* - link schemes (define arrows between nodes)
* - layout schemes (define node position on screen)
*
*/
static
source_t *emview_source_create(const char *source_name, emview_source_type_t type,
simple_source_attr_t *attr)
{
source_t *src = NULL;
simple_source_t *ss;
link_source_t *ls;
switch (type) {
case EMVIEW_SOURCE_SIMPLE:
ss = g_new0(simple_source_t, 1);
ss->fast_data_lookup = g_hash_table_new(g_direct_hash, g_direct_equal);
if (attr) {
ss->attr = *attr;
if (ss->attr.format_string)
ss->attr.format_string = strdup(ss->attr.format_string);
}
src = (source_t *)ss;
break;
case EMVIEW_SOURCE_LINK:
ls = g_new0(link_source_t, 1);
src = (source_t *)ls;
break;
default:
elog(LOG_CRIT, "source type not implemented yet");
break;
}
if (src) {
src->name = strdup(source_name);
src->type = type;
}
return src;
}
/*
* source lookup
*/
source_t *emview_source_lookup_q(GQuark name)
{
return (source_t *)g_hash_table_lookup(_core.source_list.fast_source_lookup, (void*)name);
}
source_t *emview_source_lookup(const char *name)
{
GQuark q = g_quark_from_string(name);
return emview_source_lookup_q(q);
}
/*
* simple_source data list primitives
*/
source_data_t *emview_source_data_create(simple_source_t *s, node_id_t id)
{
source_data_t *d = g_new0(source_data_t, 1);
/* initialize the data element */
d->parent_source = (source_t*)s;
d->id = id;
d->not_present = 1;
/* add it to the list */
emview_source_data_push(s, d);
g_hash_table_insert(s->fast_data_lookup, (void*)id, d);
return d;
}
source_data_t *emview_source_data_lookup(simple_source_t *s, node_id_t id)
{
source_data_t *d = (source_data_t *)g_hash_table_lookup(s->fast_data_lookup, (void*)id);
if (d == NULL)
d = emview_source_data_create(s, id);
return d;
}
int emview_source_get_int_data(char *source_name, node_id_t id, int *value)
{
source_t *s = emview_source_lookup(source_name);
if (s && s->type == EMVIEW_SOURCE_SIMPLE) {
source_data_t *d = emview_source_data_lookup((simple_source_t *)s, id);
if (d) {
if (value)
*value = d->int_value;
return 0;
}
}
return -1;
}
int emview_source_data_valid(source_data_t *data)
{
return data && !data->not_present;
}
char *emview_source_data_string_value(source_data_t *data)
{
return data->string_value;
}
emview_color_t emview_source_data_bg_color(source_data_t *data)
{
return data->bg_color;
}
emview_color_t emview_source_data_fg_color(source_data_t *data)
{
if (g_timer_isset(data->highlight_timeout))
return EMVIEW_COLOR_RED;
return data->fg_color;
}
/*
* source internal API: activates device dependencies
*/
void emview_source_activate_deps(source_t *src)
{
GList *ptr;
for (ptr=g_list_first(src->device_deps); ptr;
ptr=g_list_next(ptr)) {
emview_device_activate((emview_device_t *)ptr->data);
}
}
void emview_source_links_track_refs(link_source_t *ls)
{
link_data_t *d;
for (d=emview_link_data_top(ls); d; d=emview_link_data_next(d)) {
emview_node_ref(d->src_node, d->src_component);
emview_node_ref(d->dst_node, d->dst_component);
}
}
void emview_draw_line_aux(GdkPixmap *fg_pixmap, GdkGC *gc,
int x1, int y1, int x2, int y2)
{
if (((x1 < 0) && (x2 < 0)) ||
((y1 < 0) && (y2 < 0)) ||
((x1 > _core.gui.width) && (x2 > _core.gui.width)) ||
((y1 > _core.gui.height) && (y2 > _core.gui.height)))
return;
gdk_draw_line(fg_pixmap, gc, x1, y1, x2, y2);
}
void emview_source_links_dump(buf_t *buf, link_source_t *ls)
{
link_data_t *d;
for (d=emview_link_data_top(ls); d; d=emview_link_data_next(d)) {
bufprintf(buf, "Link from %d,%d to %d,%d, attr=%d",
d->src_node, d->src_component,
d->dst_node, d->dst_component,
d->attr.dir);
}
}
void emview_source_links_draw(link_source_t *ls, node_t *n, emview_color_t default_color,
GQuark default_component, int annotations)
{
link_data_t *d;
static GdkGC *gc = NULL;
if (gc == NULL) {
gc = gdk_gc_new(_core.gui.window->window);
gdk_gc_copy(gc, _core.gui.window->style->black_gc);
}
elog(LOG_DEBUG(10), "Drawing links for link source %s, node %d",
ls->super.name, n->id);
for (d=emview_link_data_top(ls); d; d=emview_link_data_next(d)) {
int sx, sy, dx, dy;
int shift_x=0, shift_y=0;
float t;
int status1,status2;
int active;
/* skip links from other nodes */
if (n->id != d->src_node)
goto next;
/* get endpoints */
if ((status1 = emview_node_get_center
(d->src_node, (d->src_component ? d->src_component : default_component), &sx, &sy)) < 0) {
elog(LOG_DEBUG(17), "Unable to get center of component");
goto next;
}
if ((status2 = emview_node_get_center
(d->dst_node, (d->dst_component ? d->dst_component : default_component), &dx, &dy)) < 0) {
elog(LOG_DEBUG(17), "Unable to get center of component");
goto next;
}
/* a link is drawn active if both ends are active */
active = status1 && status2;
/*
* compute line shift
*/
t = atan2(-(dy-sy), (dx-sx));
shift_x = LINK_OFFSET*cos(t + M_PI/2.0);
shift_y = -LINK_OFFSET*sin(t + M_PI/2.0);
#if 0
if ((d->src_node == 3) || (d->dst_node == 3))
elog(LOG_INFO, "ep's %d,%d:%d,%d %d,%d:%d,%d angle=%f deg %d %d",
d->src_node, (d->src_component ? d->src_component : default_component), sx,sy,
d->dst_node, (d->dst_component ? d->dst_component : default_component), dx,dy,
r2d(t), shift_x, shift_y);
#endif
switch (d->attr.dir) {
case EMVIEW_LINKS_TO:
sx -= shift_x;
sy -= shift_y;
dx -= shift_x;
dy -= shift_y;
break;
case EMVIEW_LINKS_FROM:
sx += shift_x;
sy += shift_y;
dx += shift_x;
dy += shift_y;
break;
default:
break;
}
if (annotations) {
float frac=0.5;
int ax,ay;
/* skip if there's no annoation for this link */
if (d->annotation == NULL)
goto next;
/* where does the annotation go? */
switch (d->attr.dir) {
case EMVIEW_LINKS_TO:
frac += NOTE_FRAC;
break;
case EMVIEW_LINKS_FROM:
frac -= NOTE_FRAC;
break;
default:
break;
}
/* determine location */
ax = sx+(dx-sx)*frac;
ay = sy+(dy-sy)*frac;
/* add it */
emview_put_label(ax, ay, 0, 0, d->annotation,
EMVIEW_COLOR_WHITE,
(d->attr.color == EMVIEW_COLOR_NONE) ? default_color : d->attr.color,
(d->attr.color == EMVIEW_COLOR_NONE) ? default_color : d->attr.color,
EMVIEW_CENTER, EMVIEW_CENTER, TEXT_NOTE_PAD,
0, 0, 0, !active);
goto next;
}
/* draw the line */
emview_set_fg_color(gc, (d->attr.color == EMVIEW_COLOR_NONE) ? default_color : d->attr.color,
!active);
gdk_gc_set_line_attributes(gc, d->attr.weight ? d->attr.weight : 1,
d->attr.style, GDK_CAP_BUTT, GDK_JOIN_MITER);
emview_draw_line_aux(_core.gui.fg_pixmap, gc, sx, sy, dx, dy);
/* draw the arrow */
if (d->attr.arrow && (d->attr.dir != EMVIEW_LINKS_BIDIR)) {
float frac=0.5;
int ax,ay,ax2,ay2;
float t2=0;
float t3=0;
/* where does the arrow go? */
switch (d->attr.dir) {
case EMVIEW_LINKS_TO:
frac += ARROW_FRAC;
t2 = t + ARROW_ANGLE;
t3 = t - ARROW_ANGLE;
break;
case EMVIEW_LINKS_FROM:
frac -= ARROW_FRAC;
t2 = t - (M_PI - ARROW_ANGLE);
t3 = t + (M_PI - ARROW_ANGLE);
break;
default:
break;
}
/* determine location */
ax = sx+(dx-sx)*frac;
ay = sy+(dy-sy)*frac;
ax2 = ax+ARROW_LEN*cos(t2);
ay2 = ay-ARROW_LEN*sin(t2);
gdk_gc_set_line_attributes(gc, d->attr.weight ? d->attr.weight : 1,
GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
emview_draw_line_aux(_core.gui.fg_pixmap, gc, ax, ay, ax2, ay2);
ax2 = ax+ARROW_LEN*cos(t3);
ay2 = ay-ARROW_LEN*sin(t3);
emview_draw_line_aux(_core.gui.fg_pixmap, gc, ax, ay, ax2, ay2);
}
next:
continue;
}
}
/*
* source data update API
*/
source_data_t *emview_source_data_lookup_safe(char *source_name, node_id_t id)
{
GQuark q = g_quark_from_string(source_name);
return emview_source_data_lookup_safe_q(q, id);
}
source_data_t *emview_source_data_lookup_safe_q(GQuark source, node_id_t id)
{
source_t *src = emview_source_lookup_q(source);
source_data_t *d = NULL;
if (src == NULL) {
elog(LOG_WARNING, "Unknown source %s", g_quark_to_string(source));
goto out;
}
switch (src->type) {
case EMVIEW_SOURCE_LINK:
/* ignore link sources.. */
break;
case EMVIEW_SOURCE_SIMPLE:
/* lookup data for data sources */
d = emview_source_data_lookup((simple_source_t *)src, id);
break;
default:
elog(LOG_WARNING, "Unknown source type %d", src->type);
break;
}
out:
return d;
}
static
int emview_source_clear_data(void *data, int interval, g_event_t *event)
{
source_data_t *d = (source_data_t *)data;
d->not_present = 1;
return TIMER_DONE;
}
/* updates a simple source with a string value */
int emview_update_source(char *source_name, node_id_t id, char *value)
{
return emview_update_source_q(g_quark_from_string(source_name), id, value);
}
int emview_update_source_q(GQuark source_name, node_id_t id, char *value)
{
source_data_t *d = emview_source_data_lookup_safe_q(source_name, id);
/* heard from this node */
emview_node_heard(id, 0);
if (d) {
simple_source_t *s = (simple_source_t *)d->parent_source;
/* set timer if requested and value changed */
if (s->attr.note_change_timeout &&
(d->string_value && strcmp(d->string_value,value))) {
g_event_destroy(d->highlight_timeout);
g_timer_add(s->attr.note_change_timeout * 1000,
NULL, NULL, NULL, &(d->highlight_timeout));
}
/* if data value is to time out, set the timer */
if (s->attr.data_timeout) {
g_event_destroy(d->data_value_timeout);
g_timer_add(s->attr.data_timeout * 1000,
emview_source_clear_data, d, NULL,
&(d->data_value_timeout));
}
/* replace string value */
if (d->string_value) free(d->string_value);
d->string_value = strdup(value);
/* try to convert to int */
d->int_value = atoi(value);
/* value present */
d->not_present = 0;
/* init colors */
d->bg_color = EMVIEW_COLOR_WHITE;
d->fg_color = EMVIEW_COLOR_BLACK;
return 0;
}
else return -1;
}
/* updates a simple source with an int value */
/* $$$$ more cut and paste nonsense here */
int emview_update_source_int(char *source_name, node_id_t id, int value)
{
return emview_update_source_int_q(g_quark_from_string(source_name), id, value);
}
int emview_update_source_int_q(GQuark source_name, node_id_t id, int value)
{
source_data_t *d = emview_source_data_lookup_safe_q(source_name, id);
/* heard from this node */
emview_node_heard(id, 0);
if (d) {
char str[256];
simple_source_t *s = (simple_source_t *)d->parent_source;
/* set timer if requested and value changed */
if ((d->int_value != value) &&
s->attr.note_change_timeout) {
g_event_destroy(d->highlight_timeout);
g_timer_add(s->attr.note_change_timeout * 1000,
NULL, NULL, NULL, &(d->highlight_timeout));
}
/* if data value is to time out, set the timer */
if (s->attr.data_timeout) {
g_event_destroy(d->data_value_timeout);
g_timer_add(s->attr.data_timeout * 1000,
emview_source_clear_data, d, NULL,
&(d->data_value_timeout));
}
/* set new int value */
d->int_value = value;
/* clear previous string */
if (d->string_value) free(d->string_value);
d->string_value = NULL;
/* convert to string */
sprintf(str, (s->attr.format_string ? s->attr.format_string : "%d"), value);
d->string_value = strdup(str);
/* set present bit */
d->not_present = 0;
/* init colors */
d->bg_color = EMVIEW_COLOR_WHITE;
d->fg_color = EMVIEW_COLOR_BLACK;
return 0;
}
else return -1;
}
/*
* link scheme control methods
*/
static
void emview_link_data_destroy(link_data_t *ld)
{
if (ld->annotation)
free(ld->annotation);
free(ld);
}
int emview_clear_links_q(GQuark source)
{
source_t *src = emview_source_lookup_q(source);
link_source_t *ls = (link_source_t *)src;
link_data_t *ld;
if (src->type != EMVIEW_SOURCE_LINK) {
elog(LOG_WARNING, "Clear links called on non LINK source");
return -1;
}
while ((ld = emview_link_data_pop(ls))) {
emview_link_data_destroy(ld);
}
return 0;
}
/* clear links 'from' node_id, 'to' node_id, or either way */
int emview_clear_links_to_node_q(GQuark source, node_id_t node_id, GQuark component,
emview_link_dir_t from)
{
source_t *src = emview_source_lookup_q(source);
link_source_t *ls = (link_source_t *)src;
link_data_t *ld;
link_data_t *tmp;
int count=0;
if (src == NULL) {
elog(LOG_WARNING, "Source %s not found!", g_quark_to_string(source));
return -1;
}
if (src->type != EMVIEW_SOURCE_LINK) {
elog(LOG_WARNING, "Clear links to node called on non LINK source");
return -1;
}
for (ld = emview_link_data_top(ls); ld; ld = tmp) {
tmp = emview_link_data_next(ld);
switch (from) {
case EMVIEW_LINKS_FROM:
if (((ld->src_node == node_id) &&
(!component || (ld->src_component == component)) &&
(ld->attr.dir != EMVIEW_LINKS_TO)) ||
((ld->dst_node == node_id) &&
(!component || (ld->dst_component == component)) &&
(ld->attr.dir != EMVIEW_LINKS_FROM)))
goto clear;
break;
case EMVIEW_LINKS_TO:
if (((ld->src_node == node_id) &&
(!component || (ld->src_component == component)) &&
(ld->attr.dir != EMVIEW_LINKS_FROM)) ||
((ld->dst_node == node_id) &&
(!component || (ld->dst_component == component)) &&
(ld->attr.dir != EMVIEW_LINKS_TO)))
goto clear;
break;
default:
if (((ld->src_node == node_id) &&
(!component || (ld->src_component == component))) ||
((ld->dst_node == node_id) &&
(!component || (ld->dst_component == component))))
goto clear;
break;
}
continue;
clear:
count++;
emview_link_data_remove(ls, ld);
emview_link_data_destroy(ld);
}
elog(LOG_DEBUG(5), "Cleared %d links", count);
return count;
}
/* clear all links that have a matching private_data attribute.
* (i.e. the attribute passed to this function matches the data
* associated with the link when it was created) */
int emview_clear_links_with_data_q(GQuark source, void *private_data)
{
source_t *src = emview_source_lookup_q(source);
link_source_t *ls = (link_source_t *)src;
link_data_t *ld;
link_data_t *tmp;
int count=0;
if (src->type != EMVIEW_SOURCE_LINK) {
elog(LOG_WARNING, "Clear links to node called on non LINK source");
return -1;
}
for (ld = emview_link_data_top(ls); ld; ld = tmp) {
tmp = emview_link_data_next(ld);
if (ld->attr.private_data != private_data)
continue;
count++;
emview_link_data_remove(ls, ld);
emview_link_data_destroy(ld);
}
elog(LOG_DEBUG(5), "Cleared %d links", count);
return count;
}
/* note: does not remove or replace existing links, just inserts a new one */
int emview_update_link_q(GQuark link_source,
node_id_t src, GQuark src_comp,
node_id_t dst, GQuark dst_comp,
char *note, link_attr_t *attr)
{
link_attr_t defaults = {
weight: 1,
style: GDK_LINE_SOLID,
dir: EMVIEW_LINKS_FROM
};
source_t *l_src = emview_source_lookup_q(link_source);
link_source_t *ls = (link_source_t *)l_src;
link_data_t *ld;
if (l_src->type != EMVIEW_SOURCE_LINK) {
elog(LOG_WARNING, "Update link called on non LINK source");
return -1;
}
ld = g_new0(link_data_t, 1);
/* heard from this node */
emview_node_heard(src, 0);
emview_node_heard(dst, 0);
if (note)
ld->annotation = strdup(note);
if (attr)
ld->attr = *attr;
else
ld->attr = defaults;
ld->src_node = src;
ld->src_component = src_comp;
ld->dst_node = dst;
ld->dst_component = dst_comp;
emview_link_data_push(ls, ld);
return 0;
}
/*
* source registration API
*/
void emview_register_source_q(emview_device_t *dev_dep, GQuark q,
simple_source_attr_t *attr)
{
emview_register_source(dev_dep, g_quark_to_string(q), attr);
}
void emview_register_source(emview_device_t *dev_dep, const char *source_name,
simple_source_attr_t *attr)
{
source_t *src;
/* get quark */
GQuark q = g_quark_from_string(source_name);
/* lookup source and emit error if duplicate */
if (emview_source_lookup(source_name)) {
elog(LOG_CRIT, "Attempt to register duplicate source %s", source_name);
return;
}
/* create a new source of this type */
src = emview_source_create(source_name, EMVIEW_SOURCE_SIMPLE, attr);
/* add to the core */
emview_source_push(&(_core.source_list), src);
g_hash_table_insert(_core.source_list.fast_source_lookup, (void*)q, src);
/* add this device dep */
if (dev_dep)
emview_source_add_dep(source_name, dev_dep);
}
/* $$$ let's get rid of this cut and paste someday!!! */
void emview_register_link_source(emview_device_t *dev_dep, const char *source_name)
{
source_t *src;
/* get quark */
GQuark q = g_quark_from_string(source_name);
/* lookup source and emit error if duplicate */
if (emview_source_lookup(source_name)) {
elog(LOG_CRIT, "Attempt to register duplicate source %s", source_name);
kill(getpid(), SIGSEGV);
exit(1);
}
/* create a new source of this type */
src = emview_source_create(source_name, EMVIEW_SOURCE_LINK, NULL);
/* add to the core */
emview_source_push(&(_core.source_list), src);
g_hash_table_insert(_core.source_list.fast_source_lookup, (void*)q, src);
/* add this device dep */
if (dev_dep)
emview_source_add_dep(source_name, dev_dep);
}
/* adds additional device dependencies to a given component */
void emview_source_add_dep(const char *name, emview_device_t *dev_dep)
{
source_t *src = emview_source_lookup(name);
if (src)
src->device_deps = g_list_prepend(src->device_deps, dev_dep);
}
/* adds a source dependency to this source */
void emview_source_add_source_dep(const char *depender, const char *dependee,
void *update_cb_func, void *data)
{
source_t *dst = emview_source_lookup(depender);
source_t *src = emview_source_lookup(dependee);
GList *ptr;
/* $$$ this is a temporary solution.. !!! */
/* copy the device deps from src to dst */
ptr = g_list_concat(dst->device_deps, g_list_copy(src->device_deps));
/* $$$ future: keep track of source deps and implement cb functions */
}
/* returns the type of source this is (link scheme, source, etc.) */
emview_source_type_t emview_source_get_type(char *name)
{
source_t *src = emview_source_lookup(name);
if (src)
return src->type;
return -1;
}
/* reset all data sources for this node */
void emview_source_reset_node(node_id_t id)
{
source_t *src;
source_data_t *d;
#ifdef CLEAR_REFS_ON_RESET
node_t *n;
/* clear referenced bits */
n = emview_node_lookup_nocreate(id);
if (n) emview_node_clear_refs(n);
#endif
for (src = emview_source_top(&(_core.source_list)); src;
src = emview_source_next(src)) {
switch (src->type) {
case EMVIEW_SOURCE_SIMPLE:
d = emview_source_data_lookup((simple_source_t *)src, id);
d->not_present = 1;
break;
case EMVIEW_SOURCE_LINK:
emview_clear_links_to_node_q(g_quark_from_string(src->name), id, 0, EMVIEW_LINKS_FROM);
break;
default:
elog(LOG_WARNING, "source type %d not implemented", src->type);
}
}
}
/*
* colormaps
*/
emview_color_t emview_assign_color(char *source_name, int value)
{
source_t *src;
int i,j,min_i=-1,min_count=-1;
if (value == 0) return 0;
src = emview_source_lookup(source_name);
for (i=0; i<EMVIEW_MAX_COLORS-2; i++)
for (j=0; j<EMVIEW_MAX_OVERLOAD; j++) {
if (src->colormap[i][j] == 0) {
if (min_count < 0 || j < min_count) {
min_i = i;
min_count = j;
}
break;
}
if (src->colormap[i][j] == value)
return i+1;
}
if (min_i < 0)
return 0;
src->colormap[min_i][min_count] = value;
return min_i+1;
}
emview_color_t emview_query_color(char *source_name, int value)
{
source_t *src;
int i,j;
if (value == 0) return 0;
src = emview_source_lookup(source_name);
for (i=0; i<EMVIEW_MAX_COLORS-2; i++)
for (j=0; j<EMVIEW_MAX_OVERLOAD; j++) {
if (src->colormap[i][j] == 0)
return 0;
if (src->colormap[i][j] == value)
return i+1;
}
return 0;
}
/*
* menus
*/
static int b0rken_gtk = 0;
static
void emview_layout_set_check(link_source_t *ls)
{
if (ls->menu) {
b0rken_gtk = 1;
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ls->menu), (ls == _core.gui.layout_link_source));
b0rken_gtk = 0;
}
}
static
int emview_layout_config(void *data)
{
source_t *src;
link_source_t *ls = (link_source_t*)data;
if (b0rken_gtk) return TRUE;
/* set the layout link source */
_core.gui.layout_link_source = ls;
/* set grid bit if this is reported */
_core.gui.do_grid = (ls == _core.source_list.reported);
emview_layout_set_check(_core.source_list.grid);
emview_layout_set_check(_core.source_list.reported);
for (src = emview_source_top(&(_core.source_list)); src;
src = emview_source_next(src))
if (src->type == EMVIEW_SOURCE_LINK)
emview_layout_set_check((link_source_t *)src);
/* repos now */
emview_repos_nodes();
return TRUE;
}
void emview_build_layout_menu()
{
/* layouts menu */
GtkWidget *menu = emview_toplevel_menu("Layout", NULL);
_core.source_list.grid =
(link_source_t *)emview_source_create(EMVIEW_LAYOUT_GRID, EMVIEW_SOURCE_LINK, NULL);
_core.source_list.grid->menu =
emview_menu_item(menu, gtk_check_menu_item_new_with_label(EMVIEW_LAYOUT_GRID),
emview_layout_config, _core.source_list.grid);
_core.source_list.reported =
(link_source_t *)emview_source_create(EMVIEW_LAYOUT_REPORTED, EMVIEW_SOURCE_LINK, NULL);
_core.source_list.reported->menu =
emview_menu_item(menu, gtk_check_menu_item_new_with_label(EMVIEW_LAYOUT_REPORTED),
emview_layout_config, _core.source_list.reported);
#if 0
{ /* error in this code.. do later $$$$ */
source_t *src;
link_source_t *ls;
GtkWidget *submenu;
submenu = emview_sub_menu(menu, "Logical/Graph");
for (src = emview_source_top(&(_core.source_list)); src;
src = emview_source_next(src))
if (src->type == EMVIEW_SOURCE_LINK) {
ls = (link_source_t *)src;
ls->menu =
emview_menu_item(submenu, gtk_check_menu_item_new_with_label(src->name),
emview_layout_config, ls);
}
}
#endif
_core.source_list.hide_inactive = 0;
_core.source_list.reported->menu =
emview_check_menu_item(menu, "Hide Inactive Nodes",
&(_core.source_list.hide_inactive));
/* default to grid */
_core.gui.layout_link_source = _core.source_list.grid;
emview_layout_set_check(_core.source_list.grid);
}
/*
* status report
*/
static
int emview_sources_status_printable(status_context_t *info, buf_t *buf)
{
source_t *src;
bufprintf(buf, "Sources:\n");
for (src = emview_source_top(&(_core.source_list)); src;
src = emview_source_next(src)) {
//simple_source_t *simple = (simple_source_t *)src;
//link_source_t *link = (link_source_t *)src;
GList *ptr;
bufprintf(buf, " Source '%s', type %d\n Deps: ", src->name, src->type);
for (ptr=g_list_first(src->device_deps); ptr;
ptr=g_list_next(ptr)) {
emview_device_t *dev = (emview_device_t *)(ptr->data);
bufprintf(buf, "%s[%d], ", dev->opts.name, dev->data_id);
}
bufprintf(buf, "\n");
switch (src->type) {
case EMVIEW_SOURCE_SIMPLE:
break;
case EMVIEW_SOURCE_LINK:
break;
default:
elog(LOG_WARNING, "source type %d not implemented", src->type);
}
}
return STATUS_MSG_COMPLETE;
}
void emview_print_source_data(char *field, source_data_t *d, buf_t *buf)
{
bufprintf(buf, " %s: ", field);
if (d == NULL) bufprintf(buf, "Empty\n");
else if (d->parent_source) bufprintf(buf, "%s\n", d->parent_source->name);
else bufprintf(buf, "***non-empty, invalid parent!!!\n");
}
void emview_sources_init()
{
_core.source_list.fast_source_lookup = g_hash_table_new(g_direct_hash, g_direct_equal);
/* configure (optional) status device */
{
status_dev_opts_t opts = {
device: {
devname: "/dev/emview/sources"
},
printable: emview_sources_status_printable
};
g_status_dev(&opts, &(_core.source_list.stat));
}
}
See more files for this project here