2 *------------------------------------------------------------------
3 * Copyright (c) 2006-2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #define GTK_ENABLE_BROKEN // DGMS
20 #include <gtk/gtktext.h>
28 static GtkWidget *s_mainmenubar;
29 static GtkWidget *s_filemenu;
30 static GtkWidget *s_readdefs;
31 static GtkWidget *s_readevents;
32 static GtkWidget *s_readeventsclock;
33 static GtkWidget *s_readcpel;
34 static GtkWidget *s_readclib;
35 static GtkWidget *s_print;
36 static GtkWidget *s_quit;
38 static GtkWidget *s_mainfilemenu;
39 static GtkWidget *s_help_general;
40 static GtkWidget *s_help_about;
41 static GtkWidget *s_mainhelpmenu;
42 static GtkWidget *s_helpmenu;
44 static GtkWidget *s_filesel;
45 static GtkWidget *s_eventsel;
51 boolean (*callback)(char *);
55 char *general_help = "\n"
56 "G2 is a performance event visualization tool.\n"
58 "To view CPEL-format event data:\n"
59 "g2 --cpel <filename>\n"
60 "or use the File Menu->Read CPEL file option.\n"
62 "To view vppinfra-format (.../open-repo/vppinfra/vppinfra/elog.h) event data:\n"
63 "g2 --clib <filename>\n"
64 "or use the File Menu->Read clib file option.\n"
66 "To toggle event detail boxes, left-mouse-click on an event.\n"
68 "To zoom to an area, depress the left mouse button. Move the\n"
69 "mouse. Release the mouse.\n"
71 "To use the time ruler, depress the right mouse button. Move the\n"
72 "mouse. Release when done.\n"
74 "To push a track to the bottom, <ctrl><left-mouse>\n"
76 "To pull a track to the top, <shift><left-mouse>\n"
78 "To selectively color/uncolor a track, <ctrl><shift><left-mouse>\n"
80 "To make the mouse scrollwheel faster, press <shift>\n"
82 "Hotkeys, supposedly Quake-like:\n"
92 " e - toggle summary-mode\n"
93 " c - toggle color-mode\n"
95 " x - take snapshot\n"
96 " z - go to next snapshot\n"
97 " p - put snapshots to snapshots.g2 \n"
98 " l - load snapshots from snapshots.g2\n"
101 "Send comments / bug reports to the \"fd.io\" mailing list.\n";
103 /****************************************************************************
104 * debug_dialog_callback
105 ****************************************************************************/
107 boolean debug_dialog_callback (char *s)
109 g_print("Dialog result: %s", s);
113 /****************************************************************************
115 ****************************************************************************/
117 static void get_dialog_value (GtkWidget *dialog, gpointer user_data)
119 md_t *md = (md_t *)user_data;
122 cb_arg = (char *) gtk_entry_get_text(GTK_ENTRY(md->entry));
124 if ((*md->callback)(cb_arg)) {
125 gtk_grab_remove(md->dialog);
126 gtk_widget_destroy(md->dialog);
128 gtk_label_set_text (GTK_LABEL(md->label), md->retry_text);
132 /****************************************************************************
134 ****************************************************************************/
136 void modal_dialog (char *label_text, char *retry_text, char *default_value,
137 boolean (*cb)(char *))
139 GtkWidget *dialog, *label, *ok_button, *entry;
143 dialog = gtk_dialog_new();
144 label = gtk_label_new(label_text);
146 entry = gtk_entry_new();
148 gtk_entry_set_text(GTK_ENTRY(entry), default_value);
150 ok_button = gtk_button_new_with_label("OK");
154 md->retry_text = retry_text;
159 md->callback = debug_dialog_callback;
161 gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
162 GTK_SIGNAL_FUNC(get_dialog_value), (gpointer) md);
164 gtk_signal_connect (GTK_OBJECT (entry), "activate",
165 GTK_SIGNAL_FUNC(get_dialog_value), (gpointer) md);
167 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
170 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
172 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
173 gtk_widget_show_all(dialog);
174 gtk_widget_grab_focus(entry);
175 gtk_grab_add(dialog);
178 /****************************************************************************
180 ****************************************************************************/
182 static void get_eventdef_name (GtkFileSelection *sel, gpointer user_data)
184 char *filename = (char *) gtk_file_selection_get_filename (
185 GTK_FILE_SELECTION(s_filesel));
186 read_event_definitions(filename);
187 set_window_title(filename);
190 /****************************************************************************
191 * read_eventdef_callback
192 ****************************************************************************/
194 static void read_eventdef_callback(GtkToggleButton *item, gpointer data)
197 s_filesel = gtk_file_selection_new("Read Event Definitions From...");
199 gtk_file_selection_set_filename(GTK_FILE_SELECTION(s_filesel),
202 gtk_signal_connect (GTK_OBJECT (
203 GTK_FILE_SELECTION(s_filesel)->ok_button),
205 GTK_SIGNAL_FUNC(get_eventdef_name), NULL);
207 gtk_signal_connect_object (GTK_OBJECT (
208 GTK_FILE_SELECTION(s_filesel)->ok_button),
210 GTK_SIGNAL_FUNC (gtk_widget_destroy),
211 (gpointer) s_filesel);
213 gtk_signal_connect_object (GTK_OBJECT (
214 GTK_FILE_SELECTION(s_filesel)->cancel_button),
216 GTK_SIGNAL_FUNC (gtk_widget_destroy),
217 (gpointer) s_filesel);
218 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(s_filesel));
219 gtk_widget_show (s_filesel);
222 /****************************************************************************
224 ****************************************************************************/
226 static void get_events_name (GtkFileSelection *sel, gpointer user_data)
228 char *filename = (char *) gtk_file_selection_get_filename (
229 GTK_FILE_SELECTION(s_eventsel));
230 read_events(filename);
231 view1_display_when_idle();
235 /****************************************************************************
237 ****************************************************************************/
239 static boolean get_ticks_per_ns (char *value)
245 if (rv == 0.0 || rv > 100000)
249 ticks_per_ns_set = TRUE;
251 gtk_widget_show(s_eventsel);
255 /****************************************************************************
256 * read_events_callback
257 ****************************************************************************/
259 static void read_events_callback(GtkToggleButton *item, gpointer data)
263 s_eventsel = gtk_file_selection_new("Read Events From...");
265 gtk_signal_connect (GTK_OBJECT (
266 GTK_FILE_SELECTION(s_eventsel)->ok_button),
268 GTK_SIGNAL_FUNC(get_events_name), NULL);
270 gtk_signal_connect_object (GTK_OBJECT (
271 GTK_FILE_SELECTION(s_eventsel)->ok_button),
273 GTK_SIGNAL_FUNC (gtk_widget_destroy),
274 (gpointer) s_eventsel);
276 gtk_signal_connect_object (GTK_OBJECT (
277 GTK_FILE_SELECTION(s_eventsel)->cancel_button),
279 GTK_SIGNAL_FUNC (gtk_widget_destroy),
280 (gpointer) s_eventsel);
281 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(s_eventsel));
283 if (ticks_per_ns_set)
284 gtk_widget_show (s_eventsel);
286 sprintf(tmpbuf, "%.3f", ticks_per_ns);
287 modal_dialog ("Please enter clock ticks per nanosecond",
288 "Invalid: Please enter clock ticks per nanosecond",
289 tmpbuf, get_ticks_per_ns);
293 /****************************************************************************
294 * read_eventclock_callback
295 ****************************************************************************/
297 static void read_eventsclock_callback(GtkToggleButton *item, gpointer data)
299 ticks_per_ns_set = FALSE;
300 read_events_callback(item, data);
303 /****************************************************************************
304 * infobox_size_request
305 ****************************************************************************/
307 void infobox_size_request (GtkWidget *widget, GtkRequisition *req,
310 char *text = (char *)user_data;
312 int widest_line_in_chars;
317 * You'd think that the string extent function would work here.
320 nlines = w = widest_line_in_chars = 0;
321 for (cp = text; *cp; cp++) {
323 if (w > widest_line_in_chars) {
324 widest_line_in_chars = w;
334 req->width = (widest_line_in_chars * 8) + 20;
335 req->height = (nlines * 13) + 10;
338 /****************************************************************************
340 ****************************************************************************/
342 void infobox(char *label_text, char *text)
344 GtkWidget *dialog, *label, *ok_button, *entry;
347 dialog = gtk_dialog_new();
348 label = gtk_label_new(label_text);
350 entry = gtk_text_new(NULL, NULL);
352 gtk_signal_connect (GTK_OBJECT (entry), "size-request",
353 GTK_SIGNAL_FUNC(infobox_size_request),
356 gtk_text_insert(GTK_TEXT(entry), g_font, &fg_black, &bg_white,
359 gtk_text_set_editable(GTK_TEXT(entry), FALSE);
361 ok_button = gtk_button_new_with_label("OK");
363 gtk_signal_connect_object (GTK_OBJECT (ok_button), "clicked",
364 GTK_SIGNAL_FUNC(gtk_widget_destroy),
365 (gpointer) GTK_OBJECT(dialog));
367 box = gtk_vbox_new(FALSE, 5);
370 gtk_box_pack_start(GTK_BOX(box), entry, TRUE, TRUE, 0);
371 gtk_box_pack_start(GTK_BOX(box), ok_button, FALSE, FALSE, 0);
373 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
376 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
377 gtk_widget_show_all(dialog);
380 /****************************************************************************
381 * help_general_callback
382 ****************************************************************************/
384 static void help_general_callback(GtkToggleButton *item, gpointer data)
386 infobox("General Help", general_help);
389 /****************************************************************************
390 * help_about_callback
391 ****************************************************************************/
393 static void help_about_callback(GtkToggleButton *item, gpointer data)
396 sprintf (tmpbuf, "G2 -- Graphical Event Viewer\n\n");
398 pointsel_about(tmpbuf);
399 events_about(tmpbuf);
400 sprintf (tmpbuf+strlen(tmpbuf), "\n%s\n", version_string);
401 sprintf (tmpbuf+strlen(tmpbuf), "%s\n", minor_v_string);
402 infobox("About", tmpbuf);
406 /****************************************************************************
408 ****************************************************************************/
410 static void get_cpel_name (GtkFileSelection *sel, gpointer user_data)
412 char *filename = (char *)gtk_file_selection_get_filename (
413 GTK_FILE_SELECTION(s_filesel));
414 read_cpel_file(filename);
415 set_window_title(filename);
418 /****************************************************************************
420 ****************************************************************************/
422 static void get_clib_name (GtkFileSelection *sel, gpointer user_data)
424 char *filename = (char *) gtk_file_selection_get_filename (
425 GTK_FILE_SELECTION(s_filesel));
426 read_clib_file(filename);
427 set_window_title(filename);
430 /****************************************************************************
432 ****************************************************************************/
434 static void read_cpel_callback(GtkToggleButton *item, gpointer data)
437 s_filesel = gtk_file_selection_new("Read CPEL data from...");
439 gtk_file_selection_set_filename(GTK_FILE_SELECTION(s_filesel),
442 gtk_signal_connect (GTK_OBJECT (
443 GTK_FILE_SELECTION(s_filesel)->ok_button),
445 GTK_SIGNAL_FUNC(get_cpel_name), NULL);
447 gtk_signal_connect_object (GTK_OBJECT (
448 GTK_FILE_SELECTION(s_filesel)->ok_button),
450 GTK_SIGNAL_FUNC (gtk_widget_destroy),
451 (gpointer) s_filesel);
453 gtk_signal_connect_object (GTK_OBJECT (
454 GTK_FILE_SELECTION(s_filesel)->cancel_button),
456 GTK_SIGNAL_FUNC (gtk_widget_destroy),
457 (gpointer) s_filesel);
458 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(s_filesel));
459 gtk_widget_show (s_filesel);
462 /****************************************************************************
464 ****************************************************************************/
466 static void read_clib_callback(GtkToggleButton *item, gpointer data)
469 s_filesel = gtk_file_selection_new("Read clib data From...");
471 gtk_file_selection_set_filename(GTK_FILE_SELECTION(s_filesel),
474 gtk_signal_connect (GTK_OBJECT (
475 GTK_FILE_SELECTION(s_filesel)->ok_button),
477 GTK_SIGNAL_FUNC(get_clib_name), NULL);
479 gtk_signal_connect_object (GTK_OBJECT (
480 GTK_FILE_SELECTION(s_filesel)->ok_button),
482 GTK_SIGNAL_FUNC (gtk_widget_destroy),
483 (gpointer) s_filesel);
485 gtk_signal_connect_object (GTK_OBJECT (
486 GTK_FILE_SELECTION(s_filesel)->cancel_button),
488 GTK_SIGNAL_FUNC (gtk_widget_destroy),
489 (gpointer) s_filesel);
490 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(s_filesel));
491 gtk_widget_show (s_filesel);
494 /****************************************************************************
496 ****************************************************************************/
498 void menu1_init(void)
501 s_filemenu = gtk_menu_new();
503 s_readcpel = gtk_menu_item_new_with_label
505 gtk_menu_append(GTK_MENU(s_filemenu), s_readcpel);
506 gtk_signal_connect(GTK_OBJECT(s_readcpel), "activate",
507 GTK_SIGNAL_FUNC(read_cpel_callback), 0);
509 s_readclib = gtk_menu_item_new_with_label
511 gtk_menu_append(GTK_MENU(s_filemenu), s_readclib);
512 gtk_signal_connect(GTK_OBJECT(s_readclib), "activate",
513 GTK_SIGNAL_FUNC(read_clib_callback), 0);
515 s_readdefs = gtk_menu_item_new_with_label ("Read Event Definitions");
516 gtk_menu_append(GTK_MENU(s_filemenu), s_readdefs);
517 gtk_signal_connect(GTK_OBJECT(s_readdefs), "activate",
518 GTK_SIGNAL_FUNC(read_eventdef_callback), 0);
520 s_readevents = gtk_menu_item_new_with_label ("Read Event Log");
521 gtk_menu_append(GTK_MENU(s_filemenu), s_readevents);
522 gtk_signal_connect(GTK_OBJECT(s_readevents), "activate",
523 GTK_SIGNAL_FUNC(read_events_callback), 0);
525 s_readeventsclock = gtk_menu_item_new_with_label
526 ("Read Event Log with Different Clock Rate");
527 gtk_menu_append(GTK_MENU(s_filemenu), s_readeventsclock);
528 gtk_signal_connect(GTK_OBJECT(s_readeventsclock), "activate",
529 GTK_SIGNAL_FUNC(read_eventsclock_callback), 0);
531 s_print = gtk_menu_item_new_with_label ("Print");
532 gtk_menu_append(GTK_MENU(s_filemenu), s_print);
533 gtk_signal_connect(GTK_OBJECT(s_print), "activate",
534 GTK_SIGNAL_FUNC(view1_print_callback), 0);
536 s_quit = gtk_menu_item_new_with_label ("Exit");
537 gtk_menu_append(GTK_MENU(s_filemenu), s_quit);
538 gtk_signal_connect(GTK_OBJECT(s_quit), "activate",
539 GTK_SIGNAL_FUNC(gtk_main_quit), 0);
541 s_mainfilemenu = gtk_menu_item_new_with_label("File");
542 gtk_menu_item_set_submenu(GTK_MENU_ITEM(s_mainfilemenu), s_filemenu);
544 s_helpmenu = gtk_menu_new();
546 s_help_general = gtk_menu_item_new_with_label ("General");
547 gtk_menu_append(GTK_MENU(s_helpmenu), s_help_general);
548 gtk_signal_connect(GTK_OBJECT(s_help_general), "activate",
549 GTK_SIGNAL_FUNC(help_general_callback), 0);
551 s_help_about = gtk_menu_item_new_with_label ("About");
552 gtk_menu_append(GTK_MENU(s_helpmenu), s_help_about);
553 gtk_signal_connect(GTK_OBJECT(s_help_about), "activate",
554 GTK_SIGNAL_FUNC(help_about_callback), 0);
556 s_mainhelpmenu = gtk_menu_item_new_with_label("Help");
557 gtk_menu_item_set_submenu(GTK_MENU_ITEM(s_mainhelpmenu), s_helpmenu);
559 s_mainmenubar = gtk_menu_bar_new();
560 gtk_menu_bar_append(GTK_MENU_BAR(s_mainmenubar), s_mainfilemenu);
561 gtk_menu_bar_append(GTK_MENU_BAR(s_mainmenubar), s_mainhelpmenu);
562 gtk_widget_show_all(s_mainmenubar);
564 gtk_box_pack_start(GTK_BOX(g_mainvbox), s_mainmenubar, FALSE, FALSE, 0);