blob: ab06a6b9abd474578ee82fd814dfd4d8a16cef1d [file] [log] [blame]
Dave Barach3e07a4a2020-04-04 10:05:48 -04001/*
Dave Barach52642c32016-02-11 19:28:19 -05002 *------------------------------------------------------------------
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:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#include <stdio.h>
18#include <gtk/gtk.h>
19#define GTK_ENABLE_BROKEN // DGMS
20#include <gtk/gtktext.h>
21#include <stdlib.h>
22#include "g2.h"
23#include <string.h>
24
25/*
26 * locals
27 */
28static GtkWidget *s_mainmenubar;
29static GtkWidget *s_filemenu;
30static GtkWidget *s_readdefs;
31static GtkWidget *s_readevents;
32static GtkWidget *s_readeventsclock;
33static GtkWidget *s_readcpel;
34static GtkWidget *s_readclib;
35static GtkWidget *s_print;
36static GtkWidget *s_quit;
37
38static GtkWidget *s_mainfilemenu;
39static GtkWidget *s_help_general;
40static GtkWidget *s_help_about;
41static GtkWidget *s_mainhelpmenu;
42static GtkWidget *s_helpmenu;
43
44static GtkWidget *s_filesel;
45static GtkWidget *s_eventsel;
46
47typedef struct md_ {
48 GtkWidget *entry;
49 GtkWidget *label;
50 GtkWidget *dialog;
51 boolean (*callback)(char *);
52 char *retry_text;
53} md_t;
54
55char *general_help = "\n"
56"G2 is a performance event visualization tool.\n"
57"\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"
61"\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"
65"\n"
66"To toggle event detail boxes, left-mouse-click on an event.\n"
67"\n"
68"To zoom to an area, depress the left mouse button. Move the\n"
69"mouse. Release the mouse.\n"
70"\n"
71"To use the time ruler, depress the right mouse button. Move the\n"
72"mouse. Release when done.\n"
73"\n"
74"To push a track to the bottom, <ctrl><left-mouse>\n"
75"\n"
76"To pull a track to the top, <shift><left-mouse>\n"
77"\n"
78"To selectively color/uncolor a track, <ctrl><shift><left-mouse>\n"
79"\n"
80"To make the mouse scrollwheel faster, press <shift>\n"
81"\n"
82"Hotkeys, supposedly Quake-like:\n"
83" w - zoom-in\n"
84" s - zoom-out\n"
85" a - pan-left\n"
86" d - pan-right\n"
87" r - pan-up\n"
88" f - pan-down\n"
89" t - less traces\n"
90" g - more traces\n"
91"\n"
92" e - toggle summary-mode\n"
93" c - toggle color-mode\n"
94"\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"
99"\n"
100"<ctrl>q - quit\n"
101"Send comments / bug reports to the \"fd.io\" mailing list.\n";
102
103/****************************************************************************
104* debug_dialog_callback
105****************************************************************************/
106
107boolean debug_dialog_callback (char *s)
108{
109 g_print("Dialog result: %s", s);
110 return (TRUE);
111}
112
113/****************************************************************************
114* get_dialog_value
115****************************************************************************/
116
117static void get_dialog_value (GtkWidget *dialog, gpointer user_data)
118{
119 md_t *md = (md_t *)user_data;
120 char * cb_arg;
Dave Barach3e07a4a2020-04-04 10:05:48 -0400121
Dave Barach52642c32016-02-11 19:28:19 -0500122 cb_arg = (char *) gtk_entry_get_text(GTK_ENTRY(md->entry));
123
124 if ((*md->callback)(cb_arg)) {
125 gtk_grab_remove(md->dialog);
126 gtk_widget_destroy(md->dialog);
127 } else {
128 gtk_label_set_text (GTK_LABEL(md->label), md->retry_text);
129 }
130}
131
132/****************************************************************************
133* modal_dialog
134****************************************************************************/
135
Dave Barach3e07a4a2020-04-04 10:05:48 -0400136void modal_dialog (char *label_text, char *retry_text, char *default_value,
Dave Barach52642c32016-02-11 19:28:19 -0500137 boolean (*cb)(char *))
138{
139 GtkWidget *dialog, *label, *ok_button, *entry;
140 static md_t dlg;
141 md_t *md = &dlg;
142
143 dialog = gtk_dialog_new();
144 label = gtk_label_new(label_text);
145
146 entry = gtk_entry_new();
147 if (default_value)
148 gtk_entry_set_text(GTK_ENTRY(entry), default_value);
149
150 ok_button = gtk_button_new_with_label("OK");
151
152 md->entry = entry;
153 md->label = label;
154 md->retry_text = retry_text;
155 md->dialog = dialog;
156 if (cb)
157 md->callback = cb;
158 else
159 md->callback = debug_dialog_callback;
160
Dave Barach3e07a4a2020-04-04 10:05:48 -0400161 gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500162 GTK_SIGNAL_FUNC(get_dialog_value), (gpointer) md);
163
Dave Barach3e07a4a2020-04-04 10:05:48 -0400164 gtk_signal_connect (GTK_OBJECT (entry), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500165 GTK_SIGNAL_FUNC(get_dialog_value), (gpointer) md);
166
167 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
168 entry);
169
170 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
171 ok_button);
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);
176}
177
178/****************************************************************************
179* get_eventdef_name
180****************************************************************************/
181
182static void get_eventdef_name (GtkFileSelection *sel, gpointer user_data)
183{
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);
188}
189
190/****************************************************************************
191* read_eventdef_callback
192****************************************************************************/
193
194static void read_eventdef_callback(GtkToggleButton *item, gpointer data)
195{
Dave Barach3e07a4a2020-04-04 10:05:48 -0400196
Dave Barach52642c32016-02-11 19:28:19 -0500197 s_filesel = gtk_file_selection_new("Read Event Definitions From...");
Dave Barach3e07a4a2020-04-04 10:05:48 -0400198
199 gtk_file_selection_set_filename(GTK_FILE_SELECTION(s_filesel),
Dave Barach52642c32016-02-11 19:28:19 -0500200 "../h/elog.h");
201
202 gtk_signal_connect (GTK_OBJECT (
203 GTK_FILE_SELECTION(s_filesel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400204 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500205 GTK_SIGNAL_FUNC(get_eventdef_name), NULL);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400206
Dave Barach52642c32016-02-11 19:28:19 -0500207 gtk_signal_connect_object (GTK_OBJECT (
208 GTK_FILE_SELECTION(s_filesel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400209 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500210 GTK_SIGNAL_FUNC (gtk_widget_destroy),
211 (gpointer) s_filesel);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400212
Dave Barach52642c32016-02-11 19:28:19 -0500213 gtk_signal_connect_object (GTK_OBJECT (
214 GTK_FILE_SELECTION(s_filesel)->cancel_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400215 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500216 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);
220}
221
222/****************************************************************************
223* get_events_name
224****************************************************************************/
225
226static void get_events_name (GtkFileSelection *sel, gpointer user_data)
227{
228 char *filename = (char *) gtk_file_selection_get_filename (
229 GTK_FILE_SELECTION(s_eventsel));
230 read_events(filename);
231 view1_display_when_idle();
232}
233
234
235/****************************************************************************
236* get_ticks_per_ns
237****************************************************************************/
238
239static boolean get_ticks_per_ns (char *value)
240{
241 double rv;
242
243 rv = atof (value);
244
245 if (rv == 0.0 || rv > 100000)
246 return(FALSE);
247
248 ticks_per_ns = rv;
249 ticks_per_ns_set = TRUE;
250
251 gtk_widget_show(s_eventsel);
252 return(TRUE);
253}
254
255/****************************************************************************
256* read_events_callback
257****************************************************************************/
258
259static void read_events_callback(GtkToggleButton *item, gpointer data)
260{
261 char tmpbuf [32];
262
263 s_eventsel = gtk_file_selection_new("Read Events From...");
Dave Barach3e07a4a2020-04-04 10:05:48 -0400264
Dave Barach52642c32016-02-11 19:28:19 -0500265 gtk_signal_connect (GTK_OBJECT (
266 GTK_FILE_SELECTION(s_eventsel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400267 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500268 GTK_SIGNAL_FUNC(get_events_name), NULL);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400269
Dave Barach52642c32016-02-11 19:28:19 -0500270 gtk_signal_connect_object (GTK_OBJECT (
271 GTK_FILE_SELECTION(s_eventsel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400272 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500273 GTK_SIGNAL_FUNC (gtk_widget_destroy),
274 (gpointer) s_eventsel);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400275
Dave Barach52642c32016-02-11 19:28:19 -0500276 gtk_signal_connect_object (GTK_OBJECT (
277 GTK_FILE_SELECTION(s_eventsel)->cancel_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400278 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500279 GTK_SIGNAL_FUNC (gtk_widget_destroy),
280 (gpointer) s_eventsel);
281 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(s_eventsel));
282
283 if (ticks_per_ns_set)
284 gtk_widget_show (s_eventsel);
285 else {
Dave Barach3e07a4a2020-04-04 10:05:48 -0400286 snprintf(tmpbuf, sizeof(tmpbuf), "%.3f", ticks_per_ns);
Dave Barach52642c32016-02-11 19:28:19 -0500287 modal_dialog ("Please enter clock ticks per nanosecond",
288 "Invalid: Please enter clock ticks per nanosecond",
289 tmpbuf, get_ticks_per_ns);
290 }
291}
292
293/****************************************************************************
294* read_eventclock_callback
295****************************************************************************/
296
297static void read_eventsclock_callback(GtkToggleButton *item, gpointer data)
298{
299 ticks_per_ns_set = FALSE;
300 read_events_callback(item, data);
301}
302
303/****************************************************************************
304* infobox_size_request
305****************************************************************************/
306
307void infobox_size_request (GtkWidget *widget, GtkRequisition *req,
308 gpointer user_data)
309{
310 char *text = (char *)user_data;
311 char *cp;
312 int widest_line_in_chars;
313 int w;
314 int nlines;
Dave Barach3e07a4a2020-04-04 10:05:48 -0400315
Dave Barach52642c32016-02-11 19:28:19 -0500316 /*
317 * You'd think that the string extent function would work here.
Dave Barach3e07a4a2020-04-04 10:05:48 -0400318 * You'd be wrong.
Dave Barach52642c32016-02-11 19:28:19 -0500319 */
320 nlines = w = widest_line_in_chars = 0;
321 for (cp = text; *cp; cp++) {
322 if (*cp == '\n') {
323 if (w > widest_line_in_chars) {
324 widest_line_in_chars = w;
325 }
326 w = 0;
327 nlines++;
328 }
329 w++;
330 }
331
332 nlines++;
333
334 req->width = (widest_line_in_chars * 8) + 20;
335 req->height = (nlines * 13) + 10;
336}
337
338/****************************************************************************
339* infobox
340****************************************************************************/
341
342void infobox(char *label_text, char *text)
343{
344 GtkWidget *dialog, *label, *ok_button, *entry;
345 GtkWidget *box;
346
347 dialog = gtk_dialog_new();
348 label = gtk_label_new(label_text);
349
350 entry = gtk_text_new(NULL, NULL);
351
Dave Barach3e07a4a2020-04-04 10:05:48 -0400352 gtk_signal_connect (GTK_OBJECT (entry), "size-request",
353 GTK_SIGNAL_FUNC(infobox_size_request),
Dave Barach52642c32016-02-11 19:28:19 -0500354 (gpointer) text);
355
356 gtk_text_insert(GTK_TEXT(entry), g_font, &fg_black, &bg_white,
357 text, -1);
358
359 gtk_text_set_editable(GTK_TEXT(entry), FALSE);
360
361 ok_button = gtk_button_new_with_label("OK");
362
Dave Barach3e07a4a2020-04-04 10:05:48 -0400363 gtk_signal_connect_object (GTK_OBJECT (ok_button), "clicked",
364 GTK_SIGNAL_FUNC(gtk_widget_destroy),
Dave Barach52642c32016-02-11 19:28:19 -0500365 (gpointer) GTK_OBJECT(dialog));
366
367 box = gtk_vbox_new(FALSE, 5);
368
369
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);
372
373 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
374 box);
375
376 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
377 gtk_widget_show_all(dialog);
378}
379
380/****************************************************************************
381* help_general_callback
382****************************************************************************/
383
384static void help_general_callback(GtkToggleButton *item, gpointer data)
385{
386 infobox("General Help", general_help);
387}
388
389/****************************************************************************
390* help_about_callback
391****************************************************************************/
392
393static void help_about_callback(GtkToggleButton *item, gpointer data)
394{
395 char tmpbuf [1024];
Dave Barach3e07a4a2020-04-04 10:05:48 -0400396 snprintf (tmpbuf, sizeof(tmpbuf), "G2 -- Graphical Event Viewer\n\n");
Dave Barach52642c32016-02-11 19:28:19 -0500397 view1_about(tmpbuf);
398 pointsel_about(tmpbuf);
399 events_about(tmpbuf);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400400 snprintf (tmpbuf+strlen(tmpbuf), sizeof(tmpbuf) - strlen(tmpbuf),
401 "\n%s\n", version_string);
402 snprintf (tmpbuf+strlen(tmpbuf), sizeof(tmpbuf) - strlen(tmpbuf),
403 "%s\n", minor_v_string);
Dave Barach52642c32016-02-11 19:28:19 -0500404 infobox("About", tmpbuf);
405}
406
407
408/****************************************************************************
409* get_cpel_name
410****************************************************************************/
411
412static void get_cpel_name (GtkFileSelection *sel, gpointer user_data)
413{
414 char *filename = (char *)gtk_file_selection_get_filename (
415 GTK_FILE_SELECTION(s_filesel));
416 read_cpel_file(filename);
417 set_window_title(filename);
418}
419
420/****************************************************************************
421* get_clib_name
422****************************************************************************/
423
424static void get_clib_name (GtkFileSelection *sel, gpointer user_data)
425{
426 char *filename = (char *) gtk_file_selection_get_filename (
427 GTK_FILE_SELECTION(s_filesel));
428 read_clib_file(filename);
429 set_window_title(filename);
430}
431
432/****************************************************************************
433* read_cpel_callback
434****************************************************************************/
435
436static void read_cpel_callback(GtkToggleButton *item, gpointer data)
437{
Dave Barach3e07a4a2020-04-04 10:05:48 -0400438
Dave Barach52642c32016-02-11 19:28:19 -0500439 s_filesel = gtk_file_selection_new("Read CPEL data from...");
Dave Barach3e07a4a2020-04-04 10:05:48 -0400440
441 gtk_file_selection_set_filename(GTK_FILE_SELECTION(s_filesel),
Dave Barach52642c32016-02-11 19:28:19 -0500442 "cpel.out");
443
444 gtk_signal_connect (GTK_OBJECT (
445 GTK_FILE_SELECTION(s_filesel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400446 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500447 GTK_SIGNAL_FUNC(get_cpel_name), NULL);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400448
Dave Barach52642c32016-02-11 19:28:19 -0500449 gtk_signal_connect_object (GTK_OBJECT (
450 GTK_FILE_SELECTION(s_filesel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400451 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500452 GTK_SIGNAL_FUNC (gtk_widget_destroy),
453 (gpointer) s_filesel);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400454
Dave Barach52642c32016-02-11 19:28:19 -0500455 gtk_signal_connect_object (GTK_OBJECT (
456 GTK_FILE_SELECTION(s_filesel)->cancel_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400457 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500458 GTK_SIGNAL_FUNC (gtk_widget_destroy),
459 (gpointer) s_filesel);
460 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(s_filesel));
461 gtk_widget_show (s_filesel);
462}
463
464/****************************************************************************
465* read_clib_callback
466****************************************************************************/
467
468static void read_clib_callback(GtkToggleButton *item, gpointer data)
469{
Dave Barach3e07a4a2020-04-04 10:05:48 -0400470
Dave Barach52642c32016-02-11 19:28:19 -0500471 s_filesel = gtk_file_selection_new("Read clib data From...");
Dave Barach3e07a4a2020-04-04 10:05:48 -0400472
473 gtk_file_selection_set_filename(GTK_FILE_SELECTION(s_filesel),
Dave Barach52642c32016-02-11 19:28:19 -0500474 "clib.out");
475
476 gtk_signal_connect (GTK_OBJECT (
477 GTK_FILE_SELECTION(s_filesel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400478 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500479 GTK_SIGNAL_FUNC(get_clib_name), NULL);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400480
Dave Barach52642c32016-02-11 19:28:19 -0500481 gtk_signal_connect_object (GTK_OBJECT (
482 GTK_FILE_SELECTION(s_filesel)->ok_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400483 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500484 GTK_SIGNAL_FUNC (gtk_widget_destroy),
485 (gpointer) s_filesel);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400486
Dave Barach52642c32016-02-11 19:28:19 -0500487 gtk_signal_connect_object (GTK_OBJECT (
488 GTK_FILE_SELECTION(s_filesel)->cancel_button),
Dave Barach3e07a4a2020-04-04 10:05:48 -0400489 "clicked",
Dave Barach52642c32016-02-11 19:28:19 -0500490 GTK_SIGNAL_FUNC (gtk_widget_destroy),
491 (gpointer) s_filesel);
492 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(s_filesel));
493 gtk_widget_show (s_filesel);
494}
495
496/****************************************************************************
497* menu1_init
498****************************************************************************/
499
500void menu1_init(void)
501{
502
503 s_filemenu = gtk_menu_new();
504
Dave Barach3e07a4a2020-04-04 10:05:48 -0400505 s_readcpel = gtk_menu_item_new_with_label
Dave Barach52642c32016-02-11 19:28:19 -0500506 ("Read CPEL file");
507 gtk_menu_append(GTK_MENU(s_filemenu), s_readcpel);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400508 gtk_signal_connect(GTK_OBJECT(s_readcpel), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500509 GTK_SIGNAL_FUNC(read_cpel_callback), 0);
510
Dave Barach3e07a4a2020-04-04 10:05:48 -0400511 s_readclib = gtk_menu_item_new_with_label
Dave Barach52642c32016-02-11 19:28:19 -0500512 ("Read CLIB file");
513 gtk_menu_append(GTK_MENU(s_filemenu), s_readclib);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400514 gtk_signal_connect(GTK_OBJECT(s_readclib), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500515 GTK_SIGNAL_FUNC(read_clib_callback), 0);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400516
Dave Barach52642c32016-02-11 19:28:19 -0500517 s_readdefs = gtk_menu_item_new_with_label ("Read Event Definitions");
518 gtk_menu_append(GTK_MENU(s_filemenu), s_readdefs);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400519 gtk_signal_connect(GTK_OBJECT(s_readdefs), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500520 GTK_SIGNAL_FUNC(read_eventdef_callback), 0);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400521
Dave Barach52642c32016-02-11 19:28:19 -0500522 s_readevents = gtk_menu_item_new_with_label ("Read Event Log");
523 gtk_menu_append(GTK_MENU(s_filemenu), s_readevents);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400524 gtk_signal_connect(GTK_OBJECT(s_readevents), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500525 GTK_SIGNAL_FUNC(read_events_callback), 0);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400526
527 s_readeventsclock = gtk_menu_item_new_with_label
Dave Barach52642c32016-02-11 19:28:19 -0500528 ("Read Event Log with Different Clock Rate");
529 gtk_menu_append(GTK_MENU(s_filemenu), s_readeventsclock);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400530 gtk_signal_connect(GTK_OBJECT(s_readeventsclock), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500531 GTK_SIGNAL_FUNC(read_eventsclock_callback), 0);
532
533 s_print = gtk_menu_item_new_with_label ("Print");
534 gtk_menu_append(GTK_MENU(s_filemenu), s_print);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400535 gtk_signal_connect(GTK_OBJECT(s_print), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500536 GTK_SIGNAL_FUNC(view1_print_callback), 0);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400537
Dave Barach52642c32016-02-11 19:28:19 -0500538 s_quit = gtk_menu_item_new_with_label ("Exit");
539 gtk_menu_append(GTK_MENU(s_filemenu), s_quit);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400540 gtk_signal_connect(GTK_OBJECT(s_quit), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500541 GTK_SIGNAL_FUNC(gtk_main_quit), 0);
542
543 s_mainfilemenu = gtk_menu_item_new_with_label("File");
544 gtk_menu_item_set_submenu(GTK_MENU_ITEM(s_mainfilemenu), s_filemenu);
545
546 s_helpmenu = gtk_menu_new();
547
548 s_help_general = gtk_menu_item_new_with_label ("General");
549 gtk_menu_append(GTK_MENU(s_helpmenu), s_help_general);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400550 gtk_signal_connect(GTK_OBJECT(s_help_general), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500551 GTK_SIGNAL_FUNC(help_general_callback), 0);
552
553 s_help_about = gtk_menu_item_new_with_label ("About");
554 gtk_menu_append(GTK_MENU(s_helpmenu), s_help_about);
Dave Barach3e07a4a2020-04-04 10:05:48 -0400555 gtk_signal_connect(GTK_OBJECT(s_help_about), "activate",
Dave Barach52642c32016-02-11 19:28:19 -0500556 GTK_SIGNAL_FUNC(help_about_callback), 0);
557
558 s_mainhelpmenu = gtk_menu_item_new_with_label("Help");
559 gtk_menu_item_set_submenu(GTK_MENU_ITEM(s_mainhelpmenu), s_helpmenu);
560
561 s_mainmenubar = gtk_menu_bar_new();
562 gtk_menu_bar_append(GTK_MENU_BAR(s_mainmenubar), s_mainfilemenu);
563 gtk_menu_bar_append(GTK_MENU_BAR(s_mainmenubar), s_mainhelpmenu);
564 gtk_widget_show_all(s_mainmenubar);
565
566 gtk_box_pack_start(GTK_BOX(g_mainvbox), s_mainmenubar, FALSE, FALSE, 0);
567}