X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fpokey%2Finterface.c;h=950f6596d584d30b956490437ff0bdda6ecd00af;hp=0364dc524b610b90eee7e57c66e1a2f9ca615e85;hb=04d33be4bd102de67bb6dba5c449e12fea0db4d2;hpb=b0a676988a8da3120e64ef0e1a4ea4c28b1511e1 diff --git a/src/pokey/interface.c b/src/pokey/interface.c index 0364dc52..950f6596 100644 --- a/src/pokey/interface.c +++ b/src/pokey/interface.c @@ -1,9 +1,35 @@ +/* + interface.c -- GTK+/GNOME interface functions + Copyright (C) 2002 Guus Sliepen , + 2002 Ivo Timmermans + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id: interface.c,v 1.4 2002/04/28 12:46:26 zarq Exp $ +*/ + #include "config.h" +#include #include #include #include + +#define log mathlog #include +#undef log #include #include @@ -14,10 +40,12 @@ #include #include "node.h" +#include "connection.h" #include "edge.h" #include "interface.h" #include "logging.h" +#include #include #include "system.h" @@ -56,7 +84,7 @@ static int inited = 0; static int number_of_nodes = 0; static GtkWidget *nodetree; -static GtkCTreeNode *subnets_ctn, *hosts_ctn, *conns_ctn; +static GtkCTreeNode *hosts_ctn; static GnomeCanvasGroup *edge_group = NULL; @@ -65,28 +93,34 @@ static int canvas_height; static GtkWidget *canvas = NULL; +static int log_inited = 0; +static int follow_log = 1; + +static int keep_drawing = 1; + +static GtkCList *connlist = NULL; + +static double canvas_zoom = 1.00; + +void if_node_add(const char *hooktype, va_list ap); +void if_node_del(const char *hooktype, va_list ap); +void if_subnet_add(const char *hooktype, va_list ap); +void if_subnet_del(const char *hooktype, va_list ap); +void if_edge_add(const char *hooktype, va_list ap); +void if_edge_del(const char *hooktype, va_list ap); +void if_node_visible(const char *hooktype, va_list ap); +void if_node_invisible(const char *hooktype, va_list ap); + GtkWidget *create_canvas(void) { - GtkWidget *w; - - gtk_widget_push_visual(gdk_rgb_get_visual()); - gtk_widget_push_colormap(gdk_rgb_get_cmap()); - - canvas = gnome_canvas_new_aa(); - - gtk_widget_pop_visual(); - gtk_widget_pop_colormap(); - - gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), -00.0, -00.0, 700, 500); - - w = glade_xml_get_widget(xml, "scrolledwindow3"); - if(!w) + canvas = glade_xml_get_widget(xml, "canvas1"); + if(!canvas) { - fprintf(stderr, "Could not find widget `scrolledwindow3'\n"); + fprintf(stderr, "Could not find widget `canvas1'\n"); return NULL; } - gtk_container_add(GTK_CONTAINER(w), canvas); - gtk_widget_show_all(w); + + gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), -00.0, -00.0, 700, 500); canvas_width = 300.0; canvas_height = 500.0; @@ -103,7 +137,6 @@ void log_gtk(int level, int priority, char *fmt, va_list ap) char *p; struct tm *tm; time_t t; - static int inited = 0; if(!xml) return; @@ -141,56 +174,383 @@ void log_gtk(int level, int priority, char *fmt, va_list ap) gtk_text_freeze(GTK_TEXT(w)); - if(inited) + if(log_inited) gtk_text_insert(GTK_TEXT(w), NULL, NULL, NULL, "\n", 1); gtk_text_insert(GTK_TEXT(w), NULL, &timecolor, NULL, buffer2, strlen(buffer2)); gtk_text_insert(GTK_TEXT(w), NULL, NULL, NULL, buffer1, len); gtk_text_thaw(GTK_TEXT(w)); - inited = 1; + log_inited = 1; + if(follow_log) +/* gtk_text_set_point(GTK_TEXT(w), -1); */ + gtk_editable_set_position(GTK_EDITABLE(w), gtk_text_get_length(GTK_TEXT(w))); +} + +void if_hostinfoclosebutton_clicked(GtkWidget *w, gpointer data) +{ + gtk_widget_destroy(GTK_WIDGET(data)); +} + +void update_hostinfo_dialog(GladeXML *x, node_t *n) +{ + GtkWidget *w; + char s[100]; + avl_node_t *avlnode; + char *l[1]; + + w = glade_xml_get_widget(x, "HostInfoNameEntry"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoNameEntry"); return; } + gtk_entry_set_text(GTK_ENTRY(w), n->name); + + w = glade_xml_get_widget(x, "HostInfoHostnameEntry"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoHostnameEntry"); return; } + gtk_entry_set_text(GTK_ENTRY(w), n->hostname); + + w = glade_xml_get_widget(x, "HostInfoPortEntry"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoPortEntry"); return; } +/* snprintf(s, sizeof(s)-1, "%hd", "0"); */ + gtk_entry_set_text(GTK_ENTRY(w), "port"); + + w = glade_xml_get_widget(x, "HostInfoVersionEntry"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoVersionEntry"); return; } + gtk_entry_set_text(GTK_ENTRY(w), n->name); + + w = glade_xml_get_widget(x, "HostInfoStatusEntry"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoStatusEntry"); return; } +/* snprintf(s, sizeof(s)-1, "%x", n->status); */ + gtk_entry_set_text(GTK_ENTRY(w), "0"); + + w = glade_xml_get_widget(x, "HostInfoActiveCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoActiveCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n->status.active); + + w = glade_xml_get_widget(x, "HostInfoValidkeyCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoValidkeyCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n->status.validkey); + + w = glade_xml_get_widget(x, "HostInfoWaitingforkeyCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoWaitingforkeyCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n->status.waitingforkey); + + w = glade_xml_get_widget(x, "HostInfoVisitedCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoVisitedCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n->status.visited); + + w = glade_xml_get_widget(x, "HostInfoReachableCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoReachableCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n->status.reachable); + + w = glade_xml_get_widget(x, "HostInfoIndirectCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoIndirectCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n->status.indirect); + + w = glade_xml_get_widget(x, "HostInfoVisibleCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoVisibleCheckbutton"); return; } +/* gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), n->status.visible); */ + + w = glade_xml_get_widget(x, "HostInfoTCPOnlyCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoTCPOnlyCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), (n->options & OPTION_TCPONLY) != 0); + + w = glade_xml_get_widget(x, "HostInfoIndirectdataCheckbutton"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoIndirectdataCheckbutton"); return; } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), (n->options & OPTION_INDIRECT) != 0); + +/* w = glade_xml_get_widget(x, "HostInfoWindow"); */ +/* if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostInfoWindow"); return; } */ +/* glade_xml_signal_connect_data(x, "on_HostInfoCloseButton_clicked", if_hostinfoclosebutton_clicked, (gpointer)w); */ + w = glade_xml_get_widget(x, "HostConnectionsCList"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "HostConnectionsCList"); return; } + for(avlnode = n->edge_tree->head; avlnode; avlnode = avlnode->next) + { + if(((edge_t*)(avlnode->data))->to.node == n) + l[0] = ((edge_t*)(avlnode->data))->from.node->name; + else + l[0] = ((edge_t*)(avlnode->data))->to.node->name; + gtk_clist_append(GTK_CLIST(w), l); + } +} + +void on_settings1_activate(GtkMenuItem *mi, gpointer data) +{ + GtkWidget *w; + GladeXML *x; + + x = glade_xml_new(INTERFACE_FILE, "PropertyBox"); + if(x == NULL) + { + log(0, TLOG_ERROR, + _("Could not find widget `%s'"), + "PropertyBox"); + return; + } + + w = glade_xml_get_widget(x, "PropertyBox"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "PropertyBox"); return; } + glade_xml_signal_autoconnect(x); +} + +void on_logcontext_clear_activate(GtkMenuItem *mi, gpointer data) +{ + GtkWidget *l = glade_xml_get_widget(xml, "Messages"); + if(!l) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "Messages"); return; } + gtk_editable_delete_text(GTK_EDITABLE(l), 0, -1); /* Delete from 0 to end of buffer */ + log_inited = 0; +} + +void on_logcontext_follow_activate(GtkMenuItem *mi, gpointer data) +{ + follow_log = !follow_log; +} + +void on_messages_button_press_event(GtkWidget *w, GdkEventButton *event, gpointer data) +{ + GladeXML *x; + GtkWidget *menu; + + if (event->button == 3) + { + x = glade_xml_new(INTERFACE_FILE, "LogContextMenu"); + if(x == NULL) + { + log(0, TLOG_ERROR, + _("Could not find widget `%s'"), + "LogContextMenu"); + return; + } + + menu = glade_xml_get_widget(x, "LogContextMenu"); + if(!menu) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "LogContextMenu"); return; } + + glade_xml_signal_connect_data(x, "on_logcontext_clear_activate", on_logcontext_clear_activate, (gpointer)x); + glade_xml_signal_connect_data(x, "on_logcontext_follow_activate", on_logcontext_follow_activate, (gpointer)x); + w = glade_xml_get_widget(x, "LogContextFollow"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "LogContextFollow"); return; } + GTK_CHECK_MENU_ITEM(w)->active = follow_log; + gnome_popup_menu_do_popup_modal(menu, NULL, NULL, event, NULL); + gtk_widget_destroy(menu); + } +} + +void on_canvascontext_shuffle_activate(GtkMenuItem *mi, gpointer data) +{ + avl_node_t *avlnode; + double newx, newy; + + for(avlnode = node_tree->head; avlnode; avlnode = avlnode->next) + { + newx = ((double)random()) / ((double)RAND_MAX) * 500.0; + newy = ((double)random()) / ((double)RAND_MAX) * 300.0; + ((struct if_node_data*)((node_t *)(avlnode->data))->data)->x = newx; + ((struct if_node_data*)((node_t *)(avlnode->data))->data)->y = newy; + + if(!((struct if_node_data*)((node_t*)(avlnode->data)))->visible) + continue; + + x[((struct if_node_data*)((node_t*)(avlnode->data))->data)->id] = newx; + y[((struct if_node_data*)((node_t*)(avlnode->data))->data)->id] = newy; + } + inited = 0; + build_graph = 1; +} + +void on_canvascontext_keep_drawing_activate(GtkMenuItem *mi, gpointer data) +{ + keep_drawing = !keep_drawing; +} + +void on_canvascontext_minus50_activate(GtkMenuItem *mi, gpointer data) +{ + canvas_zoom *= 0.50; + gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas), canvas_zoom); +} + +void on_canvascontext_minus25_activate(GtkMenuItem *mi, gpointer data) +{ + canvas_zoom *= 0.75; + gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas), canvas_zoom); +} + +void on_canvascontext_minus10_activate(GtkMenuItem *mi, gpointer data) +{ + canvas_zoom *= 0.90; + gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas), canvas_zoom); +} + +void on_canvascontext_default_activate(GtkMenuItem *mi, gpointer data) +{ + canvas_zoom = 1.00; + gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas), 1.00); +} + +void on_canvascontext_plus10_activate(GtkMenuItem *mi, gpointer data) +{ + canvas_zoom *= 1.10; + gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas), canvas_zoom); +} + +void on_canvascontext_plus25_activate(GtkMenuItem *mi, gpointer data) +{ + canvas_zoom *= 1.25; + gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas), canvas_zoom); +} + +void on_canvascontext_plus50_activate(GtkMenuItem *mi, gpointer data) +{ + canvas_zoom *= 1.50; + gnome_canvas_set_pixels_per_unit(GNOME_CANVAS(canvas), canvas_zoom); +} + +void on_canvas_button_press_event(GtkWidget *w, GdkEventButton *event, gpointer data) +{ + GladeXML *x; + GtkWidget *menu; + + if (event->button == 3) + { + x = glade_xml_new(INTERFACE_FILE, "CanvasContextMenu"); + if(x == NULL) + { + log(0, TLOG_ERROR, + _("Could not find widget `%s'"), + "CanvasContextMenu"); + return; + } + + menu = glade_xml_get_widget(x, "CanvasContextMenu"); + if(!menu) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "CanvasContextMenu"); return; } + + glade_xml_signal_autoconnect(x); + glade_xml_signal_connect_data(x, "on_canvascontext_shuffle_activate", on_canvascontext_shuffle_activate, (gpointer)x); + glade_xml_signal_connect_data(x, "on_canvascontext_keep_drawing_activate", on_canvascontext_keep_drawing_activate, (gpointer)x); + w = glade_xml_get_widget(x, "CanvasContextKeepDrawing"); + if(!w) { log(0, TLOG_ERROR, _("Couldn't find widget `%s'"), "CanvasContextKeepDrawing"); return; } + GTK_CHECK_MENU_ITEM(w)->active = keep_drawing; + gnome_popup_menu_do_popup_modal(menu, NULL, NULL, event, NULL); + gtk_widget_destroy(menu); + } +} + +void on_nodetree_button_press_event(GtkWidget *w, GdkEventButton *event, gpointer data) +{ + GtkCTreeNode *node; + int row, col; + gpointer lt; + GladeXML *x; + + gtk_clist_get_selection_info(GTK_CLIST(w), event->x, event->y, + &row, &col); + + node = gtk_ctree_node_nth(GTK_CTREE(w), row); + if(node == NULL) + return; + lt = gtk_ctree_node_get_row_data(GTK_CTREE(w), node); + if(event->type == GDK_2BUTTON_PRESS && event->button == 1) + { + /* Double left click on an item */ + if(lt == NULL) + /* this is only a branch, double click wil (un)expand. */ + return; + + if(GTK_CTREE_ROW(node)->parent == hosts_ctn) + { + x = ((struct if_node_data*)(((node_t*)lt)->data))->hi_xml = glade_xml_new(INTERFACE_FILE, "HostInfoWindow"); + if(x == NULL) + { + log(0, TLOG_ERROR, + _("Could not find widget `%s'"), + "HostInfoWindow"); + return; + } + glade_xml_signal_autoconnect(x); + update_hostinfo_dialog(x, (node_t*)lt); + } + else + { + log(0, TLOG_ERROR, + "WHERE did you click?!"); + } + /* so now we have access to all the data we want. */ +/* gldap_show_details(lt); */ + return; + } +/* else */ +/* if (event->button == 3) */ +/* { */ +/* GtkWidget *temp_menu; */ +/* temp_menu = gnome_popup_menu_new(data); */ +/* gnome_popup_menu_do_popup_modal(temp_menu, NULL, NULL, event, NULL); */ +/* gtk_widget_destroy(temp_menu); */ +/* } */ +} + +void on_exit1_activate(GtkMenuItem *mi, gpointer data) +{ + close_network_connections(); + gtk_exit(0); +} + +void on_info1_activate(GtkMenuItem *mi, gpointer data) +{ + GladeXML *x; + x = glade_xml_new(INTERFACE_FILE, "AboutWindow"); + if(x == NULL) + { + log(0, TLOG_ERROR, + _("Could not find widget `%s'"), + "AboutWindow"); + return; + } } int init_interface(void) { char *l[1]; + glade_gnome_init(); + + xml = glade_xml_new("pokey.glade", "AppWindow"); + if(!xml) - return -1; + { + log(0, TLOG_ERROR, + _("Something bad happened while creating the interface.\n")); + return -1; + } nodetree = glade_xml_get_widget(xml, "NodeTree"); if(!nodetree) { - fprintf(stderr, _("Could not find widget `NodeTree'\n")); + log(0, TLOG_ERROR, + _("Could not find widget `%s'"), + "NodeTree"); return -1; } gtk_clist_freeze(GTK_CLIST(nodetree)); - l[0] = _("Hosts"); hosts_ctn = gtk_ctree_insert_node(GTK_CTREE(nodetree), NULL, NULL, l, 1, NULL, NULL, NULL, NULL, FALSE, TRUE); - l[0] = _("Subnets"); - subnets_ctn = gtk_ctree_insert_node(GTK_CTREE(nodetree), - NULL, NULL, l, 1, - NULL, NULL, NULL, NULL, - FALSE, TRUE); - l[0] = _("Connections"); - conns_ctn = gtk_ctree_insert_node(GTK_CTREE(nodetree), - NULL, NULL, l, 1, - NULL, NULL, NULL, NULL, - FALSE, TRUE); - gtk_clist_thaw(GTK_CLIST(nodetree)); create_canvas(); - gtk_signal_connect(GTK_OBJECT(nodetree), "button_press_event", if_nodetree_button_press_event, NULL); + glade_xml_signal_autoconnect(xml); log_add_hook(log_gtk); log_del_hook(log_default); + + add_hook("node-add", if_node_add); + add_hook("node-del", if_node_del); + add_hook("subnet-add", if_subnet_add); + add_hook("subnet-del", if_subnet_del); + add_hook("edge-add", if_edge_add); + add_hook("edge-del", if_edge_del); + add_hook("node-visible", if_node_visible); + add_hook("node-invisible", if_node_invisible); return 0; } @@ -241,10 +601,10 @@ static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data) gnome_canvas_item_ungrab(item, event->button.time); dragging = FALSE; n = (node_t *)gtk_object_get_user_data(GTK_OBJECT(item)); - n->x = item_x; - n->y = item_y; - x[n->id] = item_x; - y[n->id] = item_y; + ((struct if_node_data*)(n->data))->x = item_x; + ((struct if_node_data*)(n->data))->y = item_y; + x[((struct if_node_data*)(n->data))->id] = item_x; + y[((struct if_node_data*)(n->data))->id] = item_y; build_graph = 1; break; @@ -270,7 +630,7 @@ void if_node_create(node_t *n) "y1", -08.0, "x2", 30.0, "y2", 08.0, - "fill_color_rgba", 0x5f9ea0ff, + "fill_color_rgba", 0x5f9ea080, "outline_color", "black", "width_pixels", 0, NULL); @@ -285,47 +645,48 @@ void if_node_create(node_t *n) "font", "-*-verdana-medium-r-*-*-10-*-*-*-*-*-iso8859-1", NULL); - n->item = GNOME_CANVAS_ITEM(group); - n->x = n->y = 0.0; + ((struct if_node_data*)(n->data))->item = GNOME_CANVAS_ITEM(group); + ((struct if_node_data*)(n->data))->x = ((struct if_node_data*)(n->data))->y = 0.0; gtk_object_set_user_data(GTK_OBJECT(group), (gpointer)n); - gtk_signal_connect(GTK_OBJECT(n->item), "event", (GtkSignalFunc) item_event, NULL); + gtk_signal_connect(GTK_OBJECT(((struct if_node_data*)(n->data))->item), "event", (GtkSignalFunc) item_event, NULL); - gnome_canvas_item_hide(GNOME_CANVAS_ITEM(n->item)); + gnome_canvas_item_hide(GNOME_CANVAS_ITEM(((struct if_node_data*)(n->data))->item)); } -void if_node_visible(node_t *n) +void if_node_visible(const char *hooktype, va_list ap) { int i; avl_node_t *avlnode; double newx, newy; + node_t *n = va_arg(ap, node_t*); - if(!n->item) + if(!((struct if_node_data*)(n->data))->item) return; - if(n->status.visible) + if(((struct if_node_data*)(n->data))->visible) /* This node is already shown */ return; - n->status.visible = 1; + ((struct if_node_data*)(n->data))->visible = 1; newx = 250.0 + 200.0 * sin(number_of_nodes / 10.0 * M_PI); newy = 150.0 - 100.0 * cos(number_of_nodes / 10.0 * M_PI); - gnome_canvas_item_move(GNOME_CANVAS_ITEM(n->item), newx - n->x, newy - n->y); - n->x = newx; - n->y = newy; + gnome_canvas_item_move(GNOME_CANVAS_ITEM(((struct if_node_data*)(n->data))->item), newx - ((struct if_node_data*)(n->data))->x, newy - ((struct if_node_data*)(n->data))->y); + ((struct if_node_data*)(n->data))->x = newx; + ((struct if_node_data*)(n->data))->y = newy; for(i = 0, avlnode = node_tree->head; avlnode; avlnode = avlnode->next, i++) { - if(!((node_t*)(avlnode->data))->status.visible) + if(!((struct if_node_data*)(((node_t*)(avlnode->data))->data))->visible) continue; nodes[i] = (node_t *)(avlnode->data); - nodes[i]->id = i; + ((struct if_node_data*)(nodes[i]->data))->id = i; } number_of_nodes = i; - gnome_canvas_item_show(GNOME_CANVAS_ITEM(n->item)); + gnome_canvas_item_show(GNOME_CANVAS_ITEM(((struct if_node_data*)(n->data))->item)); gnome_canvas_update_now(GNOME_CANVAS(canvas)); /* (Re)start calculations */ @@ -333,31 +694,32 @@ void if_node_visible(node_t *n) build_graph = 1; } -void if_node_invisible(node_t *n) +void if_node_invisible(const char *hooktype, va_list ap) { int i; avl_node_t *avlnode; + node_t *n = va_arg(ap, node_t*); - if(!n->item) + if(!((struct if_node_data*)(n->data))->item) return; - if(!n->status.visible) + if(!((struct if_node_data*)(n->data))->visible) /* This node is already invisible */ return; - n->status.visible = 0; + ((struct if_node_data*)(n->data))->visible = 0; for(i = 0, avlnode = node_tree->head; avlnode; avlnode = avlnode->next, i++) { - if(!((node_t*)(avlnode->data))->status.visible) + if(!((struct if_node_data*)((node_t*)(avlnode->data))->data)->visible) continue; nodes[i] = (node_t *)(avlnode->data); - nodes[i]->id = i; + ((struct if_node_data*)(nodes[i]->data))->id = i; } number_of_nodes = i; - gnome_canvas_item_hide(GNOME_CANVAS_ITEM(n->item)); + gnome_canvas_item_hide(GNOME_CANVAS_ITEM(((struct if_node_data*)(n->data))->item)); gnome_canvas_update_now(GNOME_CANVAS(canvas)); /* (Re)start calculations */ @@ -365,57 +727,89 @@ void if_node_invisible(node_t *n) build_graph = 1; } -GtkCTreeNode *if_node_add(node_t *n) +void if_node_add(const char *hooktype, va_list ap) { + node_t *n = va_arg(ap, node_t*); char *l[1]; - GtkCTreeNode *ctn; + struct if_node_data *nd; if(!xml) - return NULL; + return; + nd = xmalloc(sizeof(*nd)); l[0] = n->name; gtk_clist_freeze(GTK_CLIST(nodetree)); - n->host_ctn = gtk_ctree_insert_node(GTK_CTREE(nodetree), - hosts_ctn, NULL, l, 1, - NULL, NULL, NULL, NULL, - FALSE, FALSE); + nd->ctn = gtk_ctree_insert_node(GTK_CTREE(nodetree), + hosts_ctn, NULL, l, 1, + NULL, NULL, NULL, NULL, + FALSE, FALSE); gtk_clist_thaw(GTK_CLIST(nodetree)); + gtk_ctree_node_set_row_data(GTK_CTREE(nodetree), nd->ctn, n); - if_node_create(n); - if_node_visible(n); + n->data = (void*)nd; - return ctn; + if_node_create(n); + if_node_visible(hooktype, ap); } -void if_node_del(node_t *n) +void if_node_del(const char *hooktype, va_list ap) { - gtk_clist_freeze(GTK_CLIST(nodetree)); - if(n->host_ctn) - gtk_ctree_remove_node(GTK_CTREE(nodetree), n->host_ctn); - if(n->conn_ctn) - gtk_ctree_remove_node(GTK_CTREE(nodetree), n->conn_ctn); - if(n->subnet_ctn) - gtk_ctree_remove_node(GTK_CTREE(nodetree), n->subnet_ctn); - gtk_clist_thaw(GTK_CLIST(nodetree)); + node_t *n = va_arg(ap, node_t*); + struct if_node_data *nd; + + nd = (struct if_node_data*)(n->data); + if(nd &&nd->ctn) + { + gtk_clist_freeze(GTK_CLIST(nodetree)); + gtk_ctree_remove_node(GTK_CTREE(nodetree), nd->ctn); + gtk_clist_thaw(GTK_CLIST(nodetree)); + } + + if_node_invisible(hooktype, ap); - if_node_invisible(n); + free(nd); + n->data = NULL; } -void if_subnet_add(subnet_t *subnet) +void if_subnet_add(const char *hooktype, va_list ap) { char *l[1]; - + subnet_t *subnet = va_arg(ap, subnet_t*); + struct if_subnet_data *sd; + GtkCTreeNode *parent; + + sd = xmalloc(sizeof(*sd)); l[0] = net2str(subnet); + parent = subnet->owner->data ? + ((struct if_subnet_data*)(subnet->owner->data))->ctn + : NULL; + gtk_clist_freeze(GTK_CLIST(nodetree)); - gtk_ctree_insert_node(GTK_CTREE(nodetree), - subnets_ctn, NULL, l, 1, - NULL, NULL, NULL, NULL, - TRUE, FALSE); + sd->ctn = gtk_ctree_insert_node(GTK_CTREE(nodetree), + parent, NULL, l, 1, + NULL, NULL, NULL, NULL, + TRUE, FALSE); gtk_clist_thaw(GTK_CLIST(nodetree)); + gtk_ctree_node_set_row_data(GTK_CTREE(nodetree), sd->ctn, subnet); + + subnet->data = (void*)sd; } -void if_subnet_del(subnet_t *subnet) +void if_subnet_del(const char *hooktype, va_list ap) { + subnet_t *subnet = va_arg(ap, subnet_t*); + struct if_subnet_data *sd; + + sd = (struct if_subnet_data*)(subnet->data); + if(sd && sd->ctn) + { + gtk_clist_freeze(GTK_CLIST(nodetree)); + gtk_ctree_remove_node(GTK_CTREE(nodetree), sd->ctn); + gtk_clist_thaw(GTK_CLIST(nodetree)); + } + + free(sd); + subnet->data = NULL; } void redraw_edges(void) @@ -424,6 +818,7 @@ void redraw_edges(void) GnomeCanvasPoints *points; avl_node_t *avlnode; edge_t *e; + struct if_node_data *fd, *td; if(edge_group) gtk_object_destroy(GTK_OBJECT(edge_group)); @@ -438,22 +833,24 @@ void redraw_edges(void) for(avlnode = edge_tree->head; avlnode; avlnode = avlnode->next) { e = (edge_t *)avlnode->data; + fd = (struct if_node_data*)(e->from.node->data); + td = (struct if_node_data*)(e->to.node->data); - if(!e->from.node->status.visible || - !e->to.node->status.visible) - /* We shouldn't draw this line */ - continue; +/* if(!e->from.node->status.visible || */ +/* !e->to.node->status.visible) */ +/* /\* We shouldn't draw this line *\/ */ +/* continue; */ points = gnome_canvas_points_new(2); - points->coords[0] = e->from.node->x; - points->coords[1] = e->from.node->y; - points->coords[2] = e->to.node->x; - points->coords[3] = e->to.node->y; + points->coords[0] = fd->x; + points->coords[1] = fd->y; + points->coords[2] = td->x; + points->coords[3] = td->y; gnome_canvas_item_new(group, gnome_canvas_line_get_type(), "points", points, - "fill_color_rgba", 0xe080c0ff, + "fill_color_rgba", 0xe080c080, "width_pixels", 2, NULL); gnome_canvas_points_unref(points); @@ -464,7 +861,7 @@ void redraw_edges(void) edge_group = group; } -void if_edge_add(edge_t *e) +void if_edge_add(const char *hooktype, va_list ap) { redraw_edges(); @@ -472,7 +869,7 @@ void if_edge_add(edge_t *e) build_graph = 1; } -void if_edge_del(edge_t *e) +void if_edge_del(const char *hooktype, va_list ap) { redraw_edges(); @@ -484,11 +881,11 @@ void if_move_node(node_t *n, double dx, double dy) { double newx, newy; - newx = n->x + dx; - newy = n->y + dy; - gnome_canvas_item_move(GNOME_CANVAS_ITEM(n->item), newx - n->x, newy - n->y); - n->x = newx; - n->y = newy; + newx = ((struct if_node_data*)(n->data))->x + dx; + newy = ((struct if_node_data*)(n->data))->y + dy; + gnome_canvas_item_move(GNOME_CANVAS_ITEM(((struct if_node_data*)(n->data))->item), newx - ((struct if_node_data*)(n->data))->x, newy - ((struct if_node_data*)(n->data))->y); + ((struct if_node_data*)(n->data))->x = newx; + ((struct if_node_data*)(n->data))->y = newy; } #define X_MARGIN 50.0 @@ -505,17 +902,17 @@ void set_zooming(void) minx = miny = maxx = maxy = 0.0; for(i = 0; i < number_of_nodes; i++) { - if(nodes[i]->x < minx) - minx = nodes[i]->x; + if(((struct if_node_data*)(nodes[i]->data))->x < minx) + minx = ((struct if_node_data*)(nodes[i]->data))->x; else - if(nodes[i]->x > maxx) - maxx = nodes[i]->x; + if(((struct if_node_data*)(nodes[i]->data))->x > maxx) + maxx = ((struct if_node_data*)(nodes[i]->data))->x; - if(nodes[i]->y < miny) - miny = nodes[i]->y; + if(((struct if_node_data*)(nodes[i]->data))->y < miny) + miny = ((struct if_node_data*)(nodes[i]->data))->y; else - if(nodes[i]->y > maxy) - maxy = nodes[i]->y; + if(((struct if_node_data*)(nodes[i]->data))->y > maxy) + maxy = ((struct if_node_data*)(nodes[i]->data))->y; } if(minx > ominx - X_MARGIN_BUFFER && ominx > minx) @@ -595,15 +992,18 @@ void if_build_graph(void) { int i, j, p, max_i; double delta_m, max_delta_m; - double dx, dy, s, L, max_d, old_x, old_y; + double dx, dy, s, L, min_d, old_x, old_y; edge_t *e; + if(!keep_drawing) + return; + if(!inited) { for(i = 0; i < number_of_nodes; i++) { - x[i] = nodes[i]->x; - y[i] = nodes[i]->y; + x[i] = ((struct if_node_data*)(nodes[i]->data))->x; + y[i] = ((struct if_node_data*)(nodes[i]->data))->y; } /* Initialize Floyd */ @@ -645,19 +1045,19 @@ void if_build_graph(void) } } - max_d = 0.0; + min_d = 0.0; for(i = 0; i < number_of_nodes; i++) for(j = i + 1; j < number_of_nodes; j++) - if(d[i][j] > max_d && d[i][j] < INFINITY) - max_d = d[i][j]; + if(d[i][j] < min_d && d[i][j] > 0) + min_d = d[i][j]; - L = 300.0 / log(max_d); + L = 5.0 / sqrt(min_d + 1.0); for(i = 0; i < number_of_nodes; i++) { for(j = i + 1; j < number_of_nodes; j++) { - d[i][j] = d[j][i] = log(d[i][j]+1.0); + d[i][j] = d[j][i] = sqrt(d[i][j]+1.0); l[i][j] = l[j][i] = L * d[i][j]; k[i][j] = k[j][i] = K / (d[i][j] * d[i][j]); } @@ -679,7 +1079,10 @@ void if_build_graph(void) } if(max_delta_m <= epsilon) - build_graph = 0; + { + fprintf(stderr, "Graph building is done; max_delta_m = %f\n", max_delta_m); + build_graph = 0; + } else { int iter = 0, maxiter = 20;