Annotation of embedaddon/mtr/gtk.c, revision 1.1
1.1 ! misho 1: /*
! 2: mtr -- a network diagnostic tool
! 3: Copyright (C) 1997,1998 Matt Kimball
! 4: Changes/additions Copyright (C) 1998 R.E.Wolff@BitWizard.nl
! 5:
! 6: This program is free software; you can redistribute it and/or modify
! 7: it under the terms of the GNU General Public License version 2 as
! 8: published by the Free Software Foundation.
! 9:
! 10: This program is distributed in the hope that it will be useful,
! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 13: GNU General Public License for more details.
! 14:
! 15: You should have received a copy of the GNU General Public License
! 16: along with this program; if not, write to the Free Software
! 17: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 18: */
! 19:
! 20: #include <config.h>
! 21:
! 22: #include <stdio.h>
! 23: #include <stdlib.h>
! 24: #include <unistd.h>
! 25: #include <sys/time.h>
! 26: #include <sys/types.h>
! 27:
! 28: #ifndef NO_GTK
! 29: #include <string.h>
! 30: #include <sys/types.h>
! 31: #include <gtk/gtk.h>
! 32:
! 33: #include "mtr.h"
! 34: #include "net.h"
! 35: #include "dns.h"
! 36: #include "mtr-gtk.h"
! 37: #include "version.h"
! 38:
! 39: #include "img/mtr_icon.xpm"
! 40: #endif
! 41:
! 42: gint gtk_ping(gpointer data);
! 43: gint Copy_activate(GtkWidget *widget, gpointer data);
! 44: gint NewDestination_activate(GtkWidget *widget, gpointer data);
! 45: gboolean ReportTreeView_clicked(GtkWidget *Tree, GdkEventButton *event);
! 46: gchar* getSelectedHost(GtkTreePath *path);
! 47:
! 48:
! 49:
! 50: extern char *Hostname;
! 51: extern float WaitTime;
! 52: extern int af;
! 53: static int tag;
! 54: static GtkWidget *Pause_Button;
! 55: static GtkWidget *Entry;
! 56: static GtkWidget *main_window;
! 57:
! 58: void gtk_add_ping_timeout (void)
! 59: {
! 60: int dt;
! 61:
! 62: dt = calc_deltatime (WaitTime);
! 63: tag = g_timeout_add(dt / 1000, gtk_ping, NULL);
! 64: }
! 65:
! 66:
! 67: void gtk_do_init(int *argc, char ***argv)
! 68: {
! 69: static int done = 0;
! 70:
! 71: if(!done) {
! 72: gtk_init(argc, argv);
! 73:
! 74: done = 1;
! 75: }
! 76: }
! 77:
! 78:
! 79: int gtk_detect(UNUSED int *argc, UNUSED char ***argv)
! 80: {
! 81: if(getenv("DISPLAY") != NULL) {
! 82: /* If we do this here, gtk_init exits on an error. This happens
! 83: BEFORE the user has had a chance to tell us not to use the
! 84: display... */
! 85: return TRUE;
! 86: } else {
! 87: return FALSE;
! 88: }
! 89: }
! 90:
! 91:
! 92: gint Window_destroy(UNUSED GtkWidget *Window, UNUSED gpointer data)
! 93: {
! 94: gtk_main_quit();
! 95:
! 96: return FALSE;
! 97: }
! 98:
! 99:
! 100: gint Restart_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data)
! 101: {
! 102: net_reset();
! 103: gtk_redraw();
! 104:
! 105: return FALSE;
! 106: }
! 107:
! 108:
! 109: gint Pause_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data)
! 110: {
! 111: static int paused = 0;
! 112:
! 113: if (paused) {
! 114: gtk_add_ping_timeout ();
! 115: } else {
! 116: g_source_remove (tag);
! 117: }
! 118: paused = ! paused;
! 119: gtk_redraw();
! 120:
! 121: return FALSE;
! 122: }
! 123:
! 124: gint About_clicked(UNUSED GtkWidget *Button, UNUSED gpointer data)
! 125: {
! 126: gchar *authors[] = {
! 127: "Matt Kimball <mkimball@xmission.com>",
! 128: "Roger Wolff <R.E.Wolff@BitWizard.nl>",
! 129: "Bohdan Vlasyuk <bohdan@cec.vstu.vinnica.ua>",
! 130: "Evgeniy Tretyak <evtr@ukr.net>",
! 131: "John Thacker <thacker@math.cornell.edu>",
! 132: "Juha Takala",
! 133: "David Sward <sward@clark.net>",
! 134: "David Stone <stone@AsIf.com>",
! 135: "Andrew Stesin",
! 136: "Greg Stark <gsstark@mit.edu>",
! 137: "Robert Sparks <rjsparks@nostrum.com>",
! 138: "Mike Simons <msimons@moria.simons-clan.com>",
! 139: "Aaron Scarisbrick,",
! 140: "Craig Milo Rogers <Rogers@ISI.EDU>",
! 141: "Antonio Querubin <tony@aloha.net>",
! 142: "Russell Nelson <rn-mtr@crynwr.com>",
! 143: "Davin Milun <milun@acm.org>",
! 144: "Josh Martin <jmartin@columbiaservices.net>",
! 145: "Alexander V. Lukyanov <lav@yars.free.net>",
! 146: "Charles Levert <charles@comm.polymtl.ca> ",
! 147: "Bertrand Leconte <B.Leconte@mail.dotcom.fr>",
! 148: "Anand Kumria",
! 149: "Olav Kvittem <Olav.Kvittem@uninett.no>",
! 150: "Adam Kramer <l3zqc@qcunix1.acc.qc.edu> ",
! 151: "Philip Kizer <pckizer@nostrum.com>",
! 152: "Simon Kirby",
! 153: "Christophe Kalt",
! 154: "Steve Kann <stevek@spheara.horizonlive.com>",
! 155: "Brett Johnson <brett@jdacareers.com>",
! 156: "Roland Illig <roland.illig@gmx.de>",
! 157: "Damian Gryski <dgryski@uwaterloo.ca>",
! 158: "Rob Foehl <rwf@loonybin.net>",
! 159: "Mircea Damian",
! 160: "Cougar <cougar@random.ee>",
! 161: "Travis Cross <tc@traviscross.com>",
! 162: "Brian Casey",
! 163: "Andrew Brown <atatat@atatdot.net>",
! 164: "Bill Bogstad <bogstad@pobox.com> ",
! 165: "Marc Bejarano <marc.bejarano@openwave.com>",
! 166: "Moritz Barsnick <barsnick@gmx.net>",
! 167: "Thomas Klausner <wiz@NetBSD.org>",
! 168: NULL
! 169: };
! 170:
! 171: gtk_show_about_dialog(GTK_WINDOW(main_window)
! 172: , "version", MTR_VERSION
! 173: , "copyright", "Copyright \xc2\xa9 1997,1998 Matt Kimball"
! 174: , "website", "http://www.bitwizard.nl/mtr/"
! 175: , "authors", authors
! 176: , "comments", "The 'traceroute' and 'ping' programs in a single network diagnostic tool."
! 177: , "license",
! 178: "This program is free software; you can redistribute it and/or modify\n"
! 179: "it under the terms of the GNU General Public License version 2 as\n"
! 180: "published by the Free Software Foundation.\n"
! 181: "\n"
! 182: "This program is distributed in the hope that it will be useful,\n"
! 183: "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
! 184: "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
! 185: "GNU General Public License for more details."
! 186: , NULL);
! 187: return TRUE;
! 188: }
! 189:
! 190: /*
! 191: * There is a small problem with the following code:
! 192: * The timeout is canceled and removed in order to ensure that
! 193: * it takes effect (consider what happens if you set the timeout to 999,
! 194: * then try to undo the change); is a better approach possible?
! 195: *
! 196: * What's the problem with this? (-> "I don't think so)
! 197: */
! 198:
! 199: gint WaitTime_changed(UNUSED GtkAdjustment *Adj, UNUSED GtkWidget *Button)
! 200: {
! 201: WaitTime = gtk_spin_button_get_value(GTK_SPIN_BUTTON(Button));
! 202: g_source_remove (tag);
! 203: gtk_add_ping_timeout ();
! 204: gtk_redraw();
! 205:
! 206: return FALSE;
! 207: }
! 208:
! 209:
! 210: gint Host_activate(GtkWidget *Entry, UNUSED gpointer data)
! 211: {
! 212: struct hostent * addr;
! 213:
! 214: addr = dns_forward(gtk_entry_get_text(GTK_ENTRY(Entry)));
! 215: if(addr) {
! 216: net_reopen(addr);
! 217: /* If we are "Paused" at this point it is usually because someone
! 218: entered a non-existing host. Therefore do the go-ahead... */
! 219: gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( Pause_Button ) , 0);
! 220: } else {
! 221: int pos = strlen(gtk_entry_get_text( GTK_ENTRY(Entry)));
! 222: gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( Pause_Button ) , 1);
! 223: gtk_editable_insert_text( GTK_EDITABLE(Entry), ": not found", -1, &pos);
! 224: }
! 225:
! 226: return FALSE;
! 227: }
! 228:
! 229:
! 230: GdkPixmap *gtk_load_pixmap(char **pixmap)
! 231: {
! 232: return gdk_pixmap_colormap_create_from_xpm_d(NULL,
! 233: gdk_colormap_get_system(),
! 234: NULL, NULL, pixmap);
! 235: }
! 236:
! 237:
! 238: void Toolbar_fill(GtkWidget *Toolbar)
! 239: {
! 240: GtkWidget *Button;
! 241: GtkWidget *Label;
! 242: GtkAdjustment *Adjustment;
! 243:
! 244: Button = gtk_button_new_from_stock(GTK_STOCK_QUIT);
! 245: gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
! 246: g_signal_connect(GTK_OBJECT(Button), "clicked",
! 247: GTK_SIGNAL_FUNC(Window_destroy), NULL);
! 248:
! 249: Button = gtk_button_new_from_stock(GTK_STOCK_ABOUT);
! 250: gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
! 251: g_signal_connect(GTK_OBJECT(Button), "clicked",
! 252: GTK_SIGNAL_FUNC(About_clicked), NULL);
! 253:
! 254: Button = gtk_button_new_with_mnemonic("_Restart");
! 255: gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
! 256: g_signal_connect(GTK_OBJECT(Button), "clicked",
! 257: GTK_SIGNAL_FUNC(Restart_clicked), NULL);
! 258:
! 259: Pause_Button = gtk_toggle_button_new_with_mnemonic("_Pause");
! 260: gtk_box_pack_end(GTK_BOX(Toolbar), Pause_Button, FALSE, FALSE, 0);
! 261: g_signal_connect(GTK_OBJECT(Pause_Button), "clicked",
! 262: GTK_SIGNAL_FUNC(Pause_clicked), NULL);
! 263:
! 264: /* allow root only to set zero delay */
! 265: Adjustment = (GtkAdjustment *)gtk_adjustment_new(WaitTime,
! 266: getuid()==0 ? 0.01:1.00,
! 267: 999.99,
! 268: 1.0, 10.0,
! 269: 0.0);
! 270: Button = gtk_spin_button_new(Adjustment, 0.5, 2);
! 271: gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(Button), TRUE);
! 272: /* gtk_spin_button_set_snap_to_ticks(GTK_SPIN_BUTTON(Button), FALSE); */
! 273: /* gtk_spin_button_set_set_update_policy(GTK_SPIN_BUTTON(Button),
! 274: GTK_UPDATE_IF_VALID); */
! 275: gtk_box_pack_end(GTK_BOX(Toolbar), Button, FALSE, FALSE, 0);
! 276: g_signal_connect(GTK_OBJECT(Adjustment), "value_changed",
! 277: GTK_SIGNAL_FUNC(WaitTime_changed), Button);
! 278:
! 279: Label = gtk_label_new_with_mnemonic("_Hostname:");
! 280: gtk_box_pack_start(GTK_BOX(Toolbar), Label, FALSE, FALSE, 0);
! 281:
! 282: Entry = gtk_entry_new();
! 283: gtk_entry_set_text(GTK_ENTRY(Entry), Hostname);
! 284: g_signal_connect(GTK_OBJECT(Entry), "activate",
! 285: GTK_SIGNAL_FUNC(Host_activate), NULL);
! 286: gtk_box_pack_start(GTK_BOX(Toolbar), Entry, TRUE, TRUE, 0);
! 287:
! 288: gtk_label_set_mnemonic_widget(GTK_LABEL(Label), Entry);
! 289: }
! 290:
! 291: static GtkWidget *ReportTreeView;
! 292: static GtkListStore *ReportStore;
! 293:
! 294: enum {
! 295: COL_HOSTNAME,
! 296: COL_LOSS,
! 297: COL_RCV,
! 298: COL_SNT,
! 299: COL_LAST,
! 300: COL_BEST,
! 301: COL_AVG,
! 302: COL_WORST,
! 303: COL_STDEV,
! 304: COL_COLOR,
! 305: N_COLS
! 306: };
! 307:
! 308: // Trick to cast a pointer to integer.....
! 309: // We are mis-using a pointer as a single integer. On 64-bit
! 310: // architectures, the pointer is 64 bits and the integer only 32.
! 311: // The compiler warns us of loss of precision. However we know we
! 312: // casted a normal 32-bit integer into this pointer a few microseconds
! 313: // earlier, so it is ok. Nothing to worry about....
! 314: #define POINTER_TO_INT(p) ((int)(long)(p))
! 315:
! 316: void float_formatter(GtkTreeViewColumn *tree_column,
! 317: GtkCellRenderer *cell,
! 318: GtkTreeModel *tree_model,
! 319: GtkTreeIter *iter,
! 320: gpointer data)
! 321: {
! 322: gfloat f;
! 323: gchar text[64];
! 324: gtk_tree_model_get(tree_model, iter, POINTER_TO_INT(data), &f, -1);
! 325: sprintf(text, "%.2f", f);
! 326: g_object_set(cell, "text", text, NULL);
! 327: }
! 328:
! 329: void percent_formatter(GtkTreeViewColumn *tree_column,
! 330: GtkCellRenderer *cell,
! 331: GtkTreeModel *tree_model,
! 332: GtkTreeIter *iter,
! 333: gpointer data)
! 334: {
! 335: gfloat f;
! 336: gchar text[64];
! 337: gtk_tree_model_get(tree_model, iter, POINTER_TO_INT(data), &f, -1);
! 338: sprintf(text, "%.1f%%", f);
! 339: g_object_set(cell, "text", text, NULL);
! 340: }
! 341:
! 342: void TreeViewCreate(void)
! 343: {
! 344: GtkCellRenderer *renderer;
! 345: GtkTreeViewColumn *column;
! 346:
! 347: ReportStore = gtk_list_store_new(N_COLS,
! 348: G_TYPE_STRING,
! 349: G_TYPE_FLOAT,
! 350: G_TYPE_INT,
! 351: G_TYPE_INT,
! 352: G_TYPE_INT,
! 353: G_TYPE_INT,
! 354: G_TYPE_INT,
! 355: G_TYPE_INT,
! 356: G_TYPE_FLOAT,
! 357: G_TYPE_STRING
! 358: );
! 359:
! 360: ReportTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ReportStore));
! 361:
! 362: g_signal_connect(GTK_OBJECT(ReportTreeView), "button_press_event",
! 363: G_CALLBACK(ReportTreeView_clicked),NULL);
! 364:
! 365: renderer = gtk_cell_renderer_text_new ();
! 366: column = gtk_tree_view_column_new_with_attributes ("Hostname",
! 367: renderer,
! 368: "text", COL_HOSTNAME,
! 369: "foreground", COL_COLOR,
! 370: NULL);
! 371: gtk_tree_view_column_set_expand(column, TRUE);
! 372: gtk_tree_view_column_set_resizable(column, TRUE);
! 373: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 374:
! 375: renderer = gtk_cell_renderer_text_new ();
! 376: g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
! 377: column = gtk_tree_view_column_new_with_attributes ("Loss",
! 378: renderer,
! 379: "text", COL_LOSS,
! 380: "foreground", COL_COLOR,
! 381: NULL);
! 382: gtk_tree_view_column_set_resizable(column, TRUE);
! 383: gtk_tree_view_column_set_cell_data_func(column, renderer, percent_formatter, (void*)COL_LOSS, NULL);
! 384: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 385:
! 386: renderer = gtk_cell_renderer_text_new ();
! 387: g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
! 388: column = gtk_tree_view_column_new_with_attributes ("Snt",
! 389: renderer,
! 390: "text", 3,
! 391: "foreground", COL_COLOR,
! 392: NULL);
! 393: gtk_tree_view_column_set_resizable(column, TRUE);
! 394: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 395:
! 396: renderer = gtk_cell_renderer_text_new ();
! 397: g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
! 398: column = gtk_tree_view_column_new_with_attributes ("Last",
! 399: renderer,
! 400: "text", 4,
! 401: "foreground", COL_COLOR,
! 402: NULL);
! 403: gtk_tree_view_column_set_resizable(column, TRUE);
! 404: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 405:
! 406: renderer = gtk_cell_renderer_text_new ();
! 407: g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
! 408: column = gtk_tree_view_column_new_with_attributes ("Avg",
! 409: renderer,
! 410: "text", 6,
! 411: "foreground", COL_COLOR,
! 412: NULL);
! 413: gtk_tree_view_column_set_resizable(column, TRUE);
! 414: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 415:
! 416: renderer = gtk_cell_renderer_text_new ();
! 417: g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
! 418: column = gtk_tree_view_column_new_with_attributes ("Best",
! 419: renderer,
! 420: "text", 5,
! 421: "foreground", COL_COLOR,
! 422: NULL);
! 423: gtk_tree_view_column_set_resizable(column, TRUE);
! 424: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 425:
! 426: renderer = gtk_cell_renderer_text_new ();
! 427: g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
! 428: column = gtk_tree_view_column_new_with_attributes ("Worst",
! 429: renderer,
! 430: "text", 7,
! 431: "foreground", COL_COLOR,
! 432: NULL);
! 433: gtk_tree_view_column_set_resizable(column, TRUE);
! 434: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 435:
! 436: renderer = gtk_cell_renderer_text_new ();
! 437: g_object_set (G_OBJECT(renderer), "xalign", 1.0, NULL);
! 438: column = gtk_tree_view_column_new_with_attributes ("StDev",
! 439: renderer,
! 440: "text", 8,
! 441: "foreground", COL_COLOR,
! 442: NULL);
! 443: gtk_tree_view_column_set_resizable(column, TRUE);
! 444: gtk_tree_view_column_set_cell_data_func(column, renderer, float_formatter, (void*)COL_STDEV, NULL);
! 445: gtk_tree_view_append_column (GTK_TREE_VIEW(ReportTreeView), column);
! 446:
! 447: }
! 448:
! 449: void update_tree_row(int row, GtkTreeIter *iter)
! 450: {
! 451: ip_t *addr;
! 452: char str[256]="???", *name=str;
! 453:
! 454: addr = net_addr(row);
! 455: if (addrcmp( (void *) addr, (void *) &unspec_addr, af)) {
! 456: if ((name = dns_lookup(addr))) {
! 457: if (show_ips) {
! 458: snprintf(str, sizeof(str), "%s (%s)", name, strlongip(addr));
! 459: name = str;
! 460: }
! 461: } else name = strlongip(addr);
! 462: }
! 463:
! 464: gtk_list_store_set(ReportStore, iter,
! 465: COL_HOSTNAME, name,
! 466: COL_LOSS, (float)(net_loss(row)/1000.0),
! 467:
! 468: COL_RCV, net_returned(row),
! 469: COL_SNT, net_xmit(row),
! 470:
! 471: COL_LAST, net_last(row)/1000,
! 472: COL_BEST, net_best(row)/1000,
! 473: COL_AVG, net_avg(row)/1000,
! 474: COL_WORST, net_worst(row)/1000,
! 475: COL_STDEV, (float)(net_stdev(row)/1000.0),
! 476:
! 477: COL_COLOR, net_up(row) ? "black" : "red",
! 478:
! 479: -1);
! 480: }
! 481:
! 482: void gtk_redraw(void)
! 483: {
! 484: int max = net_max();
! 485:
! 486: GtkTreeIter iter;
! 487: int row = net_min();
! 488: gboolean valid;
! 489:
! 490: valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(ReportStore), &iter);
! 491:
! 492: while(valid) {
! 493: if(row < max) {
! 494: update_tree_row(row++, &iter);
! 495: valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(ReportStore), &iter);
! 496: } else {
! 497: valid = gtk_list_store_remove(ReportStore, &iter);
! 498: }
! 499: }
! 500: while(row < max) {
! 501: gtk_list_store_append(ReportStore, &iter);
! 502: update_tree_row(row++, &iter);
! 503: }
! 504: }
! 505:
! 506:
! 507: void Window_fill(GtkWidget *Window)
! 508: {
! 509: GtkWidget *VBox;
! 510: GtkWidget *Toolbar;
! 511: GtkWidget *scroll;
! 512:
! 513: gtk_window_set_title(GTK_WINDOW(Window), "My traceroute");
! 514: gtk_window_set_default_size(GTK_WINDOW(Window), 650, 400);
! 515: gtk_container_set_border_width(GTK_CONTAINER(Window), 10);
! 516: VBox = gtk_vbox_new(FALSE, 10);
! 517:
! 518: Toolbar = gtk_hbox_new(FALSE, 10);
! 519: Toolbar_fill(Toolbar);
! 520: gtk_box_pack_start(GTK_BOX(VBox), Toolbar, FALSE, FALSE, 0);
! 521:
! 522: TreeViewCreate();
! 523: scroll = gtk_scrolled_window_new(NULL, NULL);
! 524: gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
! 525: gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN);
! 526: gtk_container_add(GTK_CONTAINER(scroll), ReportTreeView);
! 527: gtk_box_pack_start(GTK_BOX(VBox), scroll, TRUE, TRUE, 0);
! 528:
! 529: gtk_container_add(GTK_CONTAINER(Window), VBox);
! 530: }
! 531:
! 532:
! 533: void gtk_open(void)
! 534: {
! 535: GdkPixbuf *icon;
! 536:
! 537: int argc;
! 538: char *args[2];
! 539: char **argv;
! 540: argc = 1;
! 541: argv = args;
! 542: argv[0] = "";
! 543: argv[1] = NULL;
! 544: gtk_do_init(&argc, &argv);
! 545:
! 546: icon = gdk_pixbuf_new_from_xpm_data((const char**)mtr_icon);
! 547: gtk_window_set_default_icon(icon);
! 548:
! 549: main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
! 550:
! 551: g_set_application_name("My traceroute");
! 552:
! 553: Window_fill(main_window);
! 554:
! 555: g_signal_connect(GTK_OBJECT(main_window), "delete_event",
! 556: GTK_SIGNAL_FUNC(Window_destroy), NULL);
! 557: g_signal_connect(GTK_OBJECT(main_window), "destroy",
! 558: GTK_SIGNAL_FUNC(Window_destroy), NULL);
! 559:
! 560: gtk_widget_show_all(main_window);
! 561: }
! 562:
! 563:
! 564: void gtk_close(void)
! 565: {
! 566: }
! 567:
! 568:
! 569: int gtk_keyaction(void)
! 570: {
! 571: return 0;
! 572: }
! 573:
! 574:
! 575: gint gtk_ping(UNUSED gpointer data)
! 576: {
! 577: gtk_redraw();
! 578: net_send_batch();
! 579: net_harvest_fds();
! 580: g_source_remove (tag);
! 581: gtk_add_ping_timeout ();
! 582: return TRUE;
! 583: }
! 584:
! 585:
! 586: gboolean gtk_net_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
! 587: {
! 588: net_process_return();
! 589: return TRUE;
! 590: }
! 591:
! 592:
! 593: gboolean gtk_dns_data(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
! 594: {
! 595: dns_ack();
! 596: gtk_redraw();
! 597: return TRUE;
! 598: }
! 599: #ifdef ENABLE_IPV6
! 600: gboolean gtk_dns_data6(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, UNUSED gpointer data)
! 601: {
! 602: dns_ack6();
! 603: gtk_redraw();
! 604: return TRUE;
! 605: }
! 606: #endif
! 607:
! 608:
! 609: void gtk_loop(void)
! 610: {
! 611: GIOChannel *net_iochannel, *dns_iochannel;
! 612:
! 613: gtk_add_ping_timeout ();
! 614:
! 615: net_iochannel = g_io_channel_unix_new(net_waitfd());
! 616: g_io_add_watch(net_iochannel, G_IO_IN, gtk_net_data, NULL);
! 617: #ifdef ENABLE_IPV6
! 618: dns_iochannel = g_io_channel_unix_new(dns_waitfd6());
! 619: g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data6, NULL);
! 620: #endif
! 621: dns_iochannel = g_io_channel_unix_new(dns_waitfd());
! 622: g_io_add_watch(dns_iochannel, G_IO_IN, gtk_dns_data, NULL);
! 623:
! 624: gtk_main();
! 625: }
! 626:
! 627: gboolean NewDestination_activate(GtkWidget *widget, gpointer data)
! 628: {
! 629: gchar *hostname;
! 630: GtkTreePath *path = (GtkTreePath*)data;
! 631:
! 632: hostname = getSelectedHost(path);
! 633: if (hostname) {
! 634: gtk_entry_set_text (GTK_ENTRY(Entry), hostname);
! 635: Host_activate(Entry, NULL);
! 636: g_free(hostname);
! 637: }
! 638: return TRUE;
! 639: }
! 640:
! 641:
! 642: gboolean Copy_activate(GtkWidget *widget, gpointer data)
! 643: {
! 644: gchar *hostname;
! 645: GtkTreePath *path = (GtkTreePath*)data;
! 646:
! 647: hostname = getSelectedHost(path);
! 648: if (hostname != NULL) {
! 649: GtkClipboard *clipboard;
! 650:
! 651: clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
! 652: gtk_clipboard_set_text(clipboard, hostname, -1);
! 653:
! 654: clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
! 655: gtk_clipboard_set_text(clipboard, hostname, -1);
! 656:
! 657: g_free(hostname);
! 658: }
! 659:
! 660: return TRUE;
! 661: }
! 662:
! 663: gchar *getSelectedHost(GtkTreePath *path)
! 664: {
! 665: GtkTreeIter iter;
! 666: gchar *name = NULL;
! 667:
! 668: if (gtk_tree_model_get_iter(GTK_TREE_MODEL(ReportStore), &iter, path)) {
! 669: gtk_tree_model_get (GTK_TREE_MODEL(ReportStore), &iter, COL_HOSTNAME, &name, -1);
! 670: }
! 671: gtk_tree_path_free(path);
! 672: return name;
! 673: }
! 674:
! 675:
! 676: gboolean ReportTreeView_clicked(GtkWidget *Tree, GdkEventButton *event)
! 677: {
! 678: GtkWidget* popup_menu;
! 679: GtkWidget* copy_item;
! 680: GtkWidget* newdestination_item;
! 681: GtkTreePath *path;
! 682:
! 683: if (event->type != GDK_BUTTON_PRESS || event->button != 3)
! 684: return FALSE;
! 685:
! 686: if(!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(ReportTreeView),
! 687: event->x, event->y, &path, NULL, NULL, NULL))
! 688: return FALSE;
! 689:
! 690: gtk_tree_view_set_cursor(GTK_TREE_VIEW(ReportTreeView), path, NULL, FALSE);
! 691:
! 692: // Single right click: prepare and show the popup menu
! 693: popup_menu = gtk_menu_new ();
! 694:
! 695: copy_item = gtk_menu_item_new_with_label ("Copy to clipboard");
! 696: newdestination_item = gtk_menu_item_new_with_label ("Set as new destination");
! 697:
! 698: gtk_menu_append (GTK_MENU (popup_menu), copy_item);
! 699: gtk_menu_append (GTK_MENU (popup_menu), newdestination_item);
! 700:
! 701: g_signal_connect(GTK_OBJECT(copy_item),"activate",
! 702: GTK_SIGNAL_FUNC(Copy_activate), path);
! 703:
! 704: g_signal_connect(GTK_OBJECT(newdestination_item),"activate",
! 705: GTK_SIGNAL_FUNC(NewDestination_activate), path);
! 706:
! 707: gtk_widget_show (copy_item);
! 708: gtk_widget_show (newdestination_item);
! 709:
! 710: gtk_menu_popup (GTK_MENU(popup_menu), NULL, NULL, NULL, NULL,
! 711: 0, event->time);
! 712: return TRUE;
! 713: }
! 714:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>