📄 vis.c
字号:
#include <gtk/gtk.h>#include <gdk/gdk.h>#include "chord.h"#include "math.h"#include "rxx.h"#include "async.h"#include "misc_utils.h"#include "vis.h"#define WINX 700#define WINY 700#define PI 3.14159#define TIMEOUT 10#define NELEM(x) (sizeof (x)/ sizeof ((x)[0]))bool accordion = false;// Interesting things to draw and their handlers.static const unsigned int DRAW_IMMED_SUCC = 1 << 0;static const unsigned int DRAW_SUCC_LIST = 1 << 1;static const unsigned int DRAW_IMMED_PRED = 1 << 2;// static const unsigned int DRAW_DEBRUIJN = 1 << 3;static const unsigned int DRAW_FINGERS = 1 << 4;// static const unsigned int DRAW_TOES = 1 << 5;static const unsigned int DRAW_TOP_FINGERS = 1 << 6;static const unsigned int DRAW_PRED_LIST = 1 << 7;struct handler_info { unsigned int flag; char *name; GtkWidget *widget; GtkSignalFunc handler;};void draw_toggle_cb (GtkWidget *widget, gpointer data);// widgets will be initialized later, by initgraf.static handler_info handlers[] = { { DRAW_IMMED_SUCC, "immed. succ", NULL, GTK_SIGNAL_FUNC (draw_toggle_cb) }, { DRAW_SUCC_LIST, "succ. list", NULL, GTK_SIGNAL_FUNC (draw_toggle_cb) }, { DRAW_PRED_LIST, "pred. list", NULL, GTK_SIGNAL_FUNC (draw_toggle_cb) }, { DRAW_IMMED_PRED, "immed. pred", NULL, GTK_SIGNAL_FUNC (draw_toggle_cb) }, { DRAW_FINGERS, "fingers", NULL, GTK_SIGNAL_FUNC (draw_toggle_cb) }, { DRAW_TOP_FINGERS, "top fingers", NULL, GTK_SIGNAL_FUNC (draw_toggle_cb) }};/* GTK stuff */static GdkPixmap *pixmap = NULL;static GtkWidget *window = NULL;static GtkWidget *drawing_area = NULL;static GtkWidget *drawing_area_r = NULL;static GtkWidget *drawing_area_g = NULL;static GdkGC *draw_gc = NULL;static GdkColormap *cmap = NULL;static GdkFont *courier10 = NULL;static int glevel = 1;static char *color_file;static bool drawids = false;bool simulated_input (false);static GdkColor highlight_color;static char *highlight = "cyan4"; // consistent with old presentationsstatic int xindex = 0;static int yindex = 1;static float zoomx = 1.0;static float zoomy = 1.0;static float centerx = 0.0;static float centery = 0.0;static bool ggeo = false;static bool dual = false;struct color_pair { GdkColor c; unsigned long lat;};vec<color_pair> lat_map;char last_clicked[128] = "";static GdkColor search_color;void recenter ();void setup ();ptr<aclnt> get_aclnt (str host, unsigned short port);void initgraf ();void init_color_list (char *filename);static gint configure_event (GtkWidget *widget, GdkEventConfigure *event);static gint expose_event (GtkWidget *widget, GdkEventExpose *event);static gint delete_event (GtkWidget *widget, GdkEvent *event, gpointer data);static gint key_release_event (GtkWidget *widget, GdkEventKey *event, gpointer data);static gint button_down_event (GtkWidget *widget, GdkEventButton *event, gpointer data);void select_all_cb (GtkWidget *widget, gpointer data);void select_none_cb (GtkWidget *widget, gpointer data);void quit_cb (GtkWidget *widget, gpointer data);void redraw_cb (GtkWidget *widget, gpointer data);void update_cb (GtkWidget *widget, gpointer data);void zoom_in_cb (GtkWidget *widget, gpointer data);void geo_cb (GtkWidget *widget, gpointer data);void dump_cb (GtkWidget *widget, gpointer data);void redraw();chordID xy_to_ID (int sx, int sy);void xy_to_coord (int x, int y, float *cx, float *cy);void ID_to_string (chordID ID, char *str);double ID_to_angle (chordID ID);void set_foreground_lat (unsigned long lat);void gtk_poll ();ptr<axprt_dgram> dgram_xprt;voidsetup () { int dgram_fd = inetsocket (SOCK_DGRAM); if (dgram_fd < 0) fatal << "Failed to allocate dgram socket\n"; dgram_xprt = axprt_dgram::alloc (dgram_fd, sizeof(sockaddr), 230000); if (!dgram_xprt) fatal << "Failed to allocate dgram xprt\n";}ptr<aclnt>get_aclnt (str host, unsigned short port){ sockaddr_in saddr; bzero(&saddr, sizeof(sockaddr_in)); saddr.sin_family = AF_INET; inet_aton (host.cstr (), &saddr.sin_addr); saddr.sin_port = htons (port); ptr<aclnt> c = aclnt::alloc (dgram_xprt, transport_program_1, (sockaddr *)&(saddr)); return c;}voiddoRPCcb (chordID ID, xdrproc_t outproc, dorpc_res *res, void *out, aclnt_cb cb, clnt_stat err){ f_node *nu = nodes[ID]; // If we've already removed a node, then there's no reason to even // notify the cb of anything in this program. if (!nu) { delete res; return; } if (err || res->status == DORPC_UNKNOWNNODE) { if (!err) warn << "status: " << res->status << "\n"; warn << "deleting " << ID << ":" << nu->host << "\n"; nodes.remove (nu); char nodess[1024]; sprintf (nodess, "%zd nodes", nodes.size ()); gtk_label_set_text (GTK_LABEL (total_nodes), nodess); delete nu; delete res; return; } // Don't have good results here, so just ignore it. if (res->status != DORPC_OK) { delete res; return; } nu->coords.clear (); for (unsigned int i = 0; i < 3; i++) nu->coords.push_back (((float)res->resok->src.coords[i])); xdrmem x ((char *)res->resok->results.base (), res->resok->results.size (), XDR_DECODE); if (!outproc (x.xdrp (), out)) { fatal << "failed to unmarshall result.\n"; cb (RPC_CANTSEND); } else cb (err); delete res;}voiddoRPC (f_node *nu, const rpc_program &prog, int procno, const void *in, void *out, aclnt_cb cb){ ptr<aclnt> c = get_aclnt (nu->host, nu->port); if (c == NULL) fatal << "doRPC: couldn't aclnt::alloc\n"; //form the transport RPC ptr<dorpc_arg> arg = New refcounted<dorpc_arg> (); //header struct sockaddr_in saddr; bzero(&saddr, sizeof (sockaddr_in)); saddr.sin_family = AF_INET; inet_aton (nu->host.cstr (), &saddr.sin_addr); arg->dest.machine_order_ipv4_addr = ntohl (saddr.sin_addr.s_addr); arg->dest.machine_order_port_vnnum = (nu->port << 16) | nu->vnode_num; //leave coords as random. bzero (&arg->src, sizeof (arg->src)); arg->progno = prog.progno; arg->procno = procno; //marshall the args ourself xdrproc_t inproc = prog.tbl[procno].xdr_arg; xdrproc_t outproc = prog.tbl[procno].xdr_res; xdrsuio x (XDR_ENCODE); if ((!inproc) || (!inproc (x.xdrp (), (void *)in))) { fatal << "failed to marshall args\n"; } else { int args_len = x.uio ()->resid (); arg->args.setsize (args_len); x.uio ()->copyout (arg->args.base ()); dorpc_res *res = New dorpc_res (DORPC_OK); c->timedcall (TIMEOUT, TRANSPORTPROC_DORPC, arg, res, wrap (&doRPCcb, nu->ID, outproc, res, out, cb)); }} voidget_fingers (str file) { int i = 0; char s[1024]; strbuf data = strbuf () << file2str (file); chord_nodelistextres *nfingers = NULL; while (str line = suio_getline(data.tosuio ())) { f_node *n; switch (i) { case 0: { int ID = atoi (line); n = New f_node (bigint (ID) * (bigint(1) << (160-24)), file, 0); nodes.insert (n); nfingers = New chord_nodelistextres (CHORD_OK); n->fingers = nfingers; } break; case 1: { vec<int> ids; vec<int> lats; const char *cs = line.cstr (); strcpy (s, cs); char *start = s; char *end = s; while ((end = strchr(start, ' '))) { *end = 0; end++; char *sid = start; char *latency = strchr(sid, '|'); *latency = 0; latency++; ids.push_back (atoi (sid)); lats.push_back (atoi (latency)); start = end; } nfingers->resok->nlist.setsize (ids.size ()); for (unsigned int i = 0; i < ids.size (); i++) { nfingers->resok->nlist[i].a_lat = lats[i] * 1000; } } break; } i = (i + 1) % 2; } draw_ring ();}// ------- graphics and UI handlers -------------------------------------voidinitgraf (){ courier10 = gdk_font_load ("-*-courier-*-r-*-*-*-*-*-*-*-*-*-*"); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); drawing_area = drawing_area_r = gtk_drawing_area_new(); gtk_drawing_area_size ((GtkDrawingArea *)drawing_area_r, WINX, WINY); if (dual) { drawing_area_g = gtk_drawing_area_new(); gtk_drawing_area_size ((GtkDrawingArea *)drawing_area_g, WINX, WINY); } GtkWidget *select_all = gtk_button_new_with_label ("Select All"); GtkWidget *select_none = gtk_button_new_with_label ("Select None"); GtkWidget *hsep1 = gtk_hseparator_new (); GtkWidget *draw_nothing = gtk_button_new_with_label ("Reset"); GtkWidget *hsep2 = gtk_hseparator_new (); total_nodes = gtk_label_new (" "); for (size_t i = 0; i < NELEM (handlers); i++) handlers[i].widget = gtk_check_button_new_with_label (handlers[i].name); GtkWidget *hsep3 = gtk_hseparator_new (); GtkWidget *in = gtk_button_new_with_label ("Recenter"); GtkWidget *refresh = gtk_button_new_with_label ("Refresh All"); GtkWidget *quit = gtk_button_new_with_label ("Quit"); GtkWidget *sep = gtk_vseparator_new (); GtkWidget *geo = gtk_button_new_with_label ("Geo. View"); GtkWidget *dump_to_file = gtk_button_new_with_label ("Save..."); //organize things into boxes GtkWidget *vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), select_all, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), select_none, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hsep1, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), draw_nothing, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hsep2, FALSE, TRUE, 0); for (size_t i = 0; i < NELEM (handlers); i++) gtk_box_pack_start (GTK_BOX (vbox), handlers[i].widget, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hsep3, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), total_nodes, FALSE, TRUE, 0); gtk_box_pack_end (GTK_BOX (vbox), quit, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), refresh, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), dump_to_file, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), geo, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (vbox), in, FALSE, FALSE, 0); GtkWidget *hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), drawing_area_r, TRUE, FALSE, 0); if (dual) gtk_box_pack_start (GTK_BOX (hbox), drawing_area_g, TRUE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), sep, FALSE, TRUE, 5); gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, FALSE, 0); gtk_container_add(GTK_CONTAINER (window), hbox); gtk_signal_connect_object (GTK_OBJECT (select_all), "clicked", GTK_SIGNAL_FUNC (select_all_cb), NULL); gtk_signal_connect_object (GTK_OBJECT (select_none), "clicked", GTK_SIGNAL_FUNC (select_none_cb), NULL); gtk_signal_connect_object (GTK_OBJECT (draw_nothing), "clicked", GTK_SIGNAL_FUNC (draw_nothing_cb), NULL); gtk_signal_connect_object (GTK_OBJECT (refresh), "clicked", GTK_SIGNAL_FUNC (update_cb), NULL); gtk_signal_connect_object (GTK_OBJECT (dump_to_file), "clicked", GTK_SIGNAL_FUNC (dump_cb), NULL); gtk_signal_connect_object (GTK_OBJECT (in), "clicked", GTK_SIGNAL_FUNC (zoom_in_cb), NULL); gtk_signal_connect_object (GTK_OBJECT (quit), "clicked", GTK_SIGNAL_FUNC (quit_cb), NULL); gtk_signal_connect_object (GTK_OBJECT (geo), "clicked", GTK_SIGNAL_FUNC (geo_cb), NULL); for (size_t i = 0; i < NELEM (handlers); i++) gtk_signal_connect_object (GTK_OBJECT (handlers[i].widget), "toggled", GTK_SIGNAL_FUNC (handlers[i].handler), NULL); gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL); gtk_signal_connect (GTK_OBJECT (window), "key_release_event", GTK_SIGNAL_FUNC (key_release_event), NULL); gtk_widget_set_events (window, GDK_KEY_RELEASE_MASK); gtk_signal_connect (GTK_OBJECT (drawing_area_r), "expose_event", (GtkSignalFunc) expose_event, NULL); gtk_signal_connect (GTK_OBJECT(drawing_area_r),"configure_event", (GtkSignalFunc) configure_event, NULL); gtk_signal_connect (GTK_OBJECT (drawing_area_r), "button_press_event", (GtkSignalFunc) button_down_event, NULL); gtk_widget_set_events (drawing_area_r, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); gtk_widget_show (drawing_area_r); if (dual) { gtk_signal_connect (GTK_OBJECT (drawing_area_g), "expose_event", (GtkSignalFunc) expose_event, NULL); gtk_signal_connect (GTK_OBJECT(drawing_area_g),"configure_event", (GtkSignalFunc) configure_event, NULL); gtk_signal_connect (GTK_OBJECT (drawing_area_g), "button_press_event", (GtkSignalFunc) button_down_event, NULL); gtk_widget_set_events (drawing_area_g, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); gtk_widget_show (drawing_area_g); } gtk_widget_show (select_all); gtk_widget_show (select_none); gtk_widget_show (draw_nothing); for (size_t i = 0; i < NELEM (handlers); i++) gtk_widget_show (handlers[i].widget); gtk_widget_show (total_nodes);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -