1 /*
2 * Copyright (c) Tony Bybell 1999-2017.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 */
9
10 /* AIX may need this for alloca to work */
11 #if defined _AIX
12 #pragma alloca
13 #endif
14
15 #include "globals.h"
16 #include <config.h>
17 #include <gtk/gtk.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #ifdef __MINGW32__
21 #include <windows.h>
22 #endif
23 #include "fsdb_wrapper_api.h"
24
25 /*
26 #define WAVE_CRASH_ON_GTK_WARNING
27 */
28
29 #include "wave_locale.h"
30
31 #if !defined _MSC_VER && !defined __MINGW32__
32 #include <signal.h>
33 #include <sys/types.h>
34 #include <sys/wait.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #endif
38
39 #if !defined _MSC_VER && defined WAVE_USE_GTK2
40 #define WAVE_USE_XID
41 #else
42 #undef WAVE_USE_XID
43 #endif
44
45 #ifdef HAVE_GETOPT_LONG
46 #include <getopt.h>
47 #else
48 #include "gnu-getopt.h"
49 #ifndef _MSC_VER
50 #include <unistd.h>
51 #else
52 #define strcasecmp _stricmp
53 #endif
54 #endif
55
56 #include "symbol.h"
57 #include "lx2.h"
58 #include "ae2.h"
59 #include "vzt.h"
60 #include "ghw.h"
61 #include "fst.h"
62 #include "main.h"
63 #include "menu.h"
64 #include "vcd.h"
65 #include "lxt.h"
66 #include "lxt2_read.h"
67 #include "vzt_read.h"
68 #include "pixmaps.h"
69 #include "currenttime.h"
70 #include "fgetdynamic.h"
71 #include "rc.h"
72 #include "translate.h"
73 #include "ptranslate.h"
74 #include "ttranslate.h"
75
76 #include "tcl_helper.h"
77 #if defined(HAVE_LIBTCL)
78 #include <tcl.h>
79 #include <tk.h>
80 #endif
81
82 #ifdef MAC_INTEGRATION
83 #include <gtkosxapplication.h>
84 #endif
85
86 char *gtkwave_argv0_cached = NULL;
87
switch_page(GtkNotebook * notebook,GtkNotebookPage * page,guint page_num,gpointer user_data)88 static void switch_page(GtkNotebook *notebook,
89 GtkNotebookPage *page,
90 guint page_num,
91 gpointer user_data)
92 {
93 (void)notebook;
94 (void)page;
95 (void)user_data;
96
97 char timestr[32];
98 struct Global *g_old = GLOBALS;
99
100 set_GLOBALS((*GLOBALS->contexts)[page_num]);
101
102 GLOBALS->lxt_clock_compress_to_z = g_old->lxt_clock_compress_to_z;
103 GLOBALS->autoname_bundles = g_old->autoname_bundles;
104 GLOBALS->autocoalesce_reversal = g_old->autocoalesce_reversal;
105 GLOBALS->autocoalesce = g_old->autocoalesce;
106 GLOBALS->hier_grouping = g_old->hier_grouping;
107 GLOBALS->wave_scrolling = g_old->wave_scrolling;
108 GLOBALS->constant_marker_update = g_old->constant_marker_update;
109 GLOBALS->do_zoom_center = g_old->do_zoom_center;
110 GLOBALS->use_roundcaps = g_old->use_roundcaps;
111 GLOBALS->do_resize_signals = g_old->do_resize_signals;
112 GLOBALS->alt_wheel_mode = g_old->alt_wheel_mode;
113 GLOBALS->initial_signal_window_width = g_old->initial_signal_window_width;
114 GLOBALS->scale_to_time_dimension = g_old->scale_to_time_dimension;
115 GLOBALS->use_full_precision = g_old->use_full_precision;
116 GLOBALS->show_base = g_old->show_base;
117 GLOBALS->display_grid = g_old->display_grid;
118 GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow;
119 GLOBALS->fill_waveform = g_old->fill_waveform;
120 GLOBALS->use_standard_trace_select = g_old->use_standard_trace_select;
121 GLOBALS->disable_mouseover = g_old->disable_mouseover;
122 GLOBALS->clipboard_mouseover = g_old->clipboard_mouseover;
123 GLOBALS->keep_xz_colors = g_old->keep_xz_colors;
124 GLOBALS->zoom_pow10_snap = g_old->zoom_pow10_snap;
125 GLOBALS->zoom_dyn = g_old->zoom_dyn;
126 GLOBALS->zoom_dyne = g_old->zoom_dyne;
127 GLOBALS->hier_ignore_escapes = g_old->hier_ignore_escapes;
128 GLOBALS->sst_dbl_action_type = g_old->sst_dbl_action_type;
129 GLOBALS->save_on_exit = g_old->save_on_exit;
130
131 reformat_time(timestr, GLOBALS->tims.first + GLOBALS->global_time_offset, GLOBALS->time_dimension);
132 gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),timestr);
133 reformat_time(timestr, GLOBALS->tims.last + GLOBALS->global_time_offset, GLOBALS->time_dimension);
134 gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),timestr);
135
136 update_maxmarker_labels();
137 update_basetime(GLOBALS->tims.baseline);
138
139 GLOBALS->keypress_handler_id = g_old->keypress_handler_id;
140
141 if(GLOBALS->second_page_created)
142 {
143 wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0);
144
145 MaxSignalLength();
146 signalarea_configure_event(GLOBALS->signalarea, NULL);
147 wavearea_configure_event(GLOBALS->wavearea, NULL);
148 }
149
150 }
151
152
kill_stems_browser_single(void * V)153 void kill_stems_browser_single(void *V)
154 {
155 struct Global *G = (struct Global *)V;
156 #if !defined _MSC_VER
157 if(G && G->anno_ctx)
158 {
159 #ifdef __MINGW32__
160 if(G->anno_ctx->browser_process)
161 {
162 TerminateProcess(G->anno_ctx->browser_process, 0);
163 CloseHandle(G->anno_ctx->browser_process);
164 G->anno_ctx->browser_process = 0;
165 }
166 #else
167 if(G->anno_ctx->browser_process)
168 {
169 #ifdef __CYGWIN__
170 G->anno_ctx->cygwin_remote_kill = 1; /* let cygwin child exit() on its own */
171 #else
172 kill(G->anno_ctx->browser_process, SIGKILL);
173 #endif
174 G->anno_ctx->browser_process = (pid_t)0;
175 }
176 #endif
177 G->anno_ctx = NULL;
178 }
179 #endif
180 }
181
182 #if !defined _MSC_VER
kill_stems_browser(void)183 void kill_stems_browser(void)
184 {
185 unsigned int ix;
186
187 for(ix=0;ix<GLOBALS->num_notebook_pages;ix++)
188 {
189 struct Global *G = (*GLOBALS->contexts)[ix];
190 kill_stems_browser_single(G);
191 }
192 }
193 #endif
194
195
196 #ifdef WAVE_USE_XID
plug_destroy(GtkWidget * widget,gpointer data)197 static int plug_destroy (GtkWidget *widget, gpointer data)
198 {
199 (void)widget;
200 (void)data;
201
202 exit(0);
203
204 return(FALSE);
205 }
206 #endif
207
208 #if defined __MINGW32__
close_all_fst_files(void)209 static void close_all_fst_files(void) /* so mingw does delete of reader tempfiles */
210 {
211 unsigned int i;
212 for(i=0;i<GLOBALS->num_notebook_pages;i++)
213 {
214 if((*GLOBALS->contexts)[i]->fst_fst_c_1)
215 {
216 fstReaderClose((*GLOBALS->contexts)[i]->fst_fst_c_1);
217 (*GLOBALS->contexts)[i]->fst_fst_c_1 = NULL;
218 }
219 }
220 }
221 #endif
222
223
224 #ifdef WAVE_FSDB_READER_IS_PRESENT
close_all_fsdb_files(void)225 static void close_all_fsdb_files(void) /* otherwise fsdb can leave around stray files if .gz/.bz2 was in use */
226 {
227 unsigned int i;
228 for(i=0;i<GLOBALS->num_notebook_pages;i++)
229 {
230 if((*GLOBALS->contexts)[i]->extload_ffr_ctx)
231 {
232 fsdbReaderClose((*GLOBALS->contexts)[i]->extload_ffr_ctx);
233 (*GLOBALS->contexts)[i]->extload_ffr_ctx = NULL;
234 }
235 }
236 }
237 #endif
238
239
print_help(char * nam)240 static void print_help(char *nam)
241 {
242 #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH)
243 int slen = strlen(EXTLOAD_SUFFIX);
244 char *ucase_ext = wave_alloca(slen+1);
245 int i;
246
247 for(i=0;i<slen;i++)
248 {
249 ucase_ext[i] = toupper(EXTLOAD_SUFFIX[i]);
250 }
251 ucase_ext[i] = 0;
252 #endif
253
254
255 #if !defined _MSC_VER && !defined __MINGW32__ && !defined __FreeBSD__ && !defined __CYGWIN__
256 #define WAVE_GETOPT_CPUS " -c, --cpu=NUMCPUS specify number of CPUs for parallelizable ops\n"
257 #else
258 #define WAVE_GETOPT_CPUS
259 #endif
260
261 #if !defined _MSC_VER && !defined __MINGW32__
262 #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH)
263 #define VCD_GETOPT " -o, --optimize optimize VCD/%s to FST\n"
264 #else
265 #define VCD_GETOPT " -o, --optimize optimize VCD to FST\n"
266 #endif
267 #else
268 #define VCD_GETOPT
269 #endif
270
271 #if !defined _MSC_VER
272 #define STEMS_GETOPT " -t, --stems=FILE specify stems file for source code annotation\n"
273 #define DUAL_GETOPT " -D, --dualid=WHICH specify multisession identifier\n"
274 #define INTR_GETOPT " -I, --interactive interactive VCD mode (filename is shared mem ID)\n"
275 #else
276 #define STEMS_GETOPT
277 #define DUAL_GETOPT
278 #define INTR_GETOPT
279 #endif
280
281 #ifdef WAVE_USE_XID
282 #define XID_GETOPT " -X, --xid=XID specify XID of window for GtkPlug to connect to\n"
283 #else
284 #define XID_GETOPT
285 #endif
286
287 #if defined(WIN32) && defined(USE_TCL_STUBS)
288 #define WISH_GETOPT
289 #else
290 #define WISH_GETOPT " -T, --tcl_init=FILE specify Tcl command script file to be loaded on startup\n" \
291 " -W, --wish enable Tcl command line on stdio\n"
292 #endif
293
294 #if defined(HAVE_LIBTCL)
295 #define REPSCRIPT_GETOPT WISH_GETOPT \
296 " -R, --repscript=FILE specify timer-driven Tcl command script file\n" \
297 " -P, --repperiod=VALUE specify repscript period in msec (default: 500)\n"
298 #else
299 #define REPSCRIPT_GETOPT
300 #endif
301
302 #if !defined _MSC_VER && !defined __MINGW32__
303 #define OUTPUT_GETOPT " -O, --output=FILE specify filename for stdout/stderr redirect\n"
304 #define CHDIR_GETOPT " -2, --chdir=DIR specify new current working directory\n"
305 #else
306 #define OUTPUT_GETOPT
307 #define CHDIR_GETOPT
308 #endif
309
310 #if defined(WAVE_HAVE_GCONF) || defined(WAVE_HAVE_GSETTINGS)
311 #define RPC_GETOPT " -1, --rpcid=RPCID specify RPCID of GConf session\n"
312 #if defined(WAVE_HAVE_GCONF)
313 #define RPC_GETOPT3 " -3, --restore restore previous RPCID numbered session\n"
314 #else
315 #define RPC_GETOPT3 " -3, --restore restore previous session\n"
316 #endif
317 #else
318 #define RPC_GETOPT
319 #define RPC_GETOPT3
320 #endif
321
322 #if defined(WAVE_USE_GTK2)
323 #define SLIDEZOOM_OPT " -z, --slider-zoom enable horizontal slider stretch zoom\n"
324 #else
325 #define SLIDEZOOM_OPT
326 #endif
327
328 printf(
329 "Usage: %s [OPTION]... [DUMPFILE] [SAVEFILE] [RCFILE]\n\n"
330 " -n, --nocli=DIRPATH use file requester for dumpfile name\n"
331 " -f, --dump=FILE specify dumpfile name\n"
332 " -F, --fastload generate/use VCD recoder fastload files\n"
333 VCD_GETOPT
334 " -a, --save=FILE specify savefile name\n"
335 " -A, --autosavename assume savefile is suffix modified dumpfile name\n"
336 " -r, --rcfile=FILE specify override .rcfile name\n"
337 " -d, --defaultskip if missing .rcfile, do not use useful defaults\n"
338 DUAL_GETOPT
339 " -l, --logfile=FILE specify simulation logfile name for time values\n"
340 " -s, --start=TIME specify start time for LXT2/VZT block skip\n"
341 " -e, --end=TIME specify end time for LXT2/VZT block skip\n"
342 STEMS_GETOPT
343 WAVE_GETOPT_CPUS
344 " -N, --nowm disable window manager for most windows\n"
345 " -M, --nomenus do not render menubar (for making applets)\n"
346 " -S, --script=FILE specify Tcl command script file for execution\n"
347 REPSCRIPT_GETOPT
348 XID_GETOPT
349 RPC_GETOPT
350 CHDIR_GETOPT
351 RPC_GETOPT3
352 " -4, --rcvar specify single rc variable values individually\n"
353 " -5, --sstexclude specify sst exclusion filter filename\n"
354 INTR_GETOPT
355 " -C, --comphier use compressed hierarchy names (slower)\n"
356 " -g, --giga use gigabyte mempacking when recoding (slower)\n"
357 " -L, --legacy use legacy VCD mode rather than the VCD recoder\n"
358 " -v, --vcd use stdin as a VCD dumpfile\n"
359 OUTPUT_GETOPT
360 SLIDEZOOM_OPT
361 " -V, --version display version banner then exit\n"
362 " -h, --help display this help then exit\n"
363 " -x, --exit exit after loading trace (for loader benchmarks)\n\n"
364
365 "VCD files and save files may be compressed with zip or gzip.\n"
366 "GHW files may be compressed with gzip or bzip2.\n"
367 "Other formats must remain uncompressed due to their non-linear access.\n"
368 "Note that DUMPFILE is optional if the --dump or --nocli options are specified.\n"
369 "SAVEFILE and RCFILE are always optional.\n\n"
370
371 "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam
372 #if !defined _MSC_VER && !defined __MINGW32__
373 #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH)
374 ,ucase_ext
375 #endif
376 #endif
377 );
378
379 #ifdef __MINGW32__
380 fflush(stdout); /* fix for possible problem with mingw/msys shells */
381 #endif
382
383 exit(0);
384 }
385
386
387 /*
388 * file selection for -n/--nocli flag
389 */
390
wave_get_filename_cleanup(GtkWidget * widget,gpointer data)391 static void wave_get_filename_cleanup(GtkWidget *widget, gpointer data)
392 {
393 (void)widget;
394 (void)data;
395
396 gtk_main_quit(); /* do nothing but exit gtk loop */
397 }
398
wave_get_filename(char * dfile)399 static char *wave_get_filename(char *dfile)
400 {
401 if(dfile)
402 {
403 int len = strlen(dfile);
404 GLOBALS->ftext_main_main_c_1 = malloc_2(strlen(dfile)+2);
405 strcpy(GLOBALS->ftext_main_main_c_1, dfile);
406 #if !defined _MSC_VER && !defined __MINGW32__
407 if((len)&&(dfile[len-1]!='/'))
408 {
409 strcpy(GLOBALS->ftext_main_main_c_1 + len, "/");
410 }
411 #else
412 if((len)&&(dfile[len-1]!='\\'))
413 {
414 strcpy(GLOBALS->ftext_main_main_c_1 + len, "\\");
415 }
416 #endif
417 }
418 fileselbox_old("GTKWave: Select a dumpfile...",&GLOBALS->ftext_main_main_c_1,GTK_SIGNAL_FUNC(wave_get_filename_cleanup), GTK_SIGNAL_FUNC(wave_get_filename_cleanup), NULL, 0);
419 gtk_main();
420
421 return(GLOBALS->ftext_main_main_c_1);
422 }
423
424 /*
425 * Modify the name of the executable (argv[0]) handed to Tk_MainEx;
426 * The new executable name has _[pid] appended. This gives a unique
427 * (and known) name to the interpreter (for use with send).
428 */
addPidToExecutableName(int argc,char * argv[],char * argv_mod[])429 void addPidToExecutableName(int argc, char* argv[], char* argv_mod[])
430 {
431 char* pos;
432 char* buffer;
433
434 int i;
435 for(i=0;i<argc;i++)
436 {
437 argv_mod[i] = argv[i];
438 }
439
440 buffer = malloc_2(strlen(argv[0])+1+10);
441 pos = buffer;
442 strcpy(pos, argv[0]);
443 pos = buffer + strlen(buffer);
444 strcpy(pos, "_");
445 pos = buffer + strlen(buffer);
446 sprintf(pos, "%d", getpid());
447
448 argv_mod[0] = buffer;
449 }
450
451
main(int argc,char * argv[])452 int main(int argc, char *argv[])
453 {
454 return(main_2(0, argc, argv));
455 }
456
main_2(int opt_vcd,int argc,char * argv[])457 int main_2(int opt_vcd, int argc, char *argv[])
458 {
459 static char *winprefix="GTKWave - ";
460 static char *winstd="GTKWave (stdio) ";
461 static char *vcd_autosave_name="vcd_autosave.sav";
462 char *output_name = NULL;
463 char *chdir_cache = NULL;
464
465 int magic_word_filetype = G_FT_UNKNOWN;
466
467 int i;
468 int c;
469 char is_vcd=0;
470 char is_wish=0;
471 char is_interactive=0;
472 char is_smartsave = 0;
473 char is_legacy = 0;
474 char is_fastload = VCD_FSL_NONE;
475 char is_giga = 0;
476 char fast_exit=0;
477 char opt_errors_encountered=0;
478 char is_missing_file = 0;
479
480 char *wname=NULL;
481 char *override_rc=NULL;
482 char *scriptfile=NULL;
483 FILE *wave = NULL;
484 FILE *vcd_save_handle_cached = NULL;
485
486 GtkWidget *main_vbox = NULL, *top_table = NULL, *whole_table = NULL;
487 GtkWidget *menubar;
488 GtkWidget *text1;
489 GtkWidget *zoombuttons;
490 GtkWidget *pagebuttons;
491 GtkWidget *fetchbuttons;
492 GtkWidget *discardbuttons;
493 GtkWidget *shiftbuttons;
494 GtkWidget *edgebuttons;
495 GtkWidget *entry;
496 GtkWidget *timebox;
497 GtkWidget *panedwindow;
498 GtkWidget *dummy1, *dummy2;
499 GtkWidget *toolhandle=NULL;
500 int tcl_interpreter_needs_making = 0;
501 struct Global *old_g = NULL;
502
503 int splash_disable_rc_override = 0;
504 int mainwindow_already_built = 0;
505 #ifdef MAC_INTEGRATION
506 GdkPixbuf *dock_pb;
507 #endif
508
509 struct rc_override *rc_override_head = NULL, *rc_override_curr = NULL;
510
511 WAVE_LOCALE_FIX
512
513 /* Initialize the GLOBALS structure for the first time... */
514
515 if(!GLOBALS)
516 {
517 set_GLOBALS(initialize_globals());
518 mainwindow_already_built = 0;
519 tcl_interpreter_needs_making = 1;
520
521 GLOBALS->logfiles = calloc(1, sizeof(void *)); /* calloc is deliberate! */
522 }
523 else
524 {
525 old_g = GLOBALS;
526
527 set_GLOBALS(initialize_globals());
528
529 GLOBALS->second_page_created = old_g->second_page_created = 1;
530
531 GLOBALS->notebook = old_g->notebook;
532 GLOBALS->num_notebook_pages = old_g->num_notebook_pages;
533 GLOBALS->num_notebook_pages_cumulative = old_g->num_notebook_pages_cumulative;
534 GLOBALS->contexts = old_g->contexts;
535
536 GLOBALS->mainwindow = old_g->mainwindow;
537 splash_disable_rc_override = 1;
538
539 /* busy.c */
540 GLOBALS->busycursor_busy_c_1 = old_g->busycursor_busy_c_1;
541
542 /* logfiles.c */
543 GLOBALS->logfiles = old_g->logfiles;
544
545 /* menu.c */
546 #if defined(HAVE_LIBTCL)
547 GLOBALS->interp = old_g->interp;
548 #endif
549 #ifndef WAVE_USE_MLIST_T
550 GLOBALS->item_factory_menu_c_1 = old_g->item_factory_menu_c_1;
551 #endif
552 GLOBALS->vcd_jmp_buf = old_g->vcd_jmp_buf;
553
554 /* currenttime.c */
555 GLOBALS->max_or_marker_label_currenttime_c_1 = old_g->max_or_marker_label_currenttime_c_1;
556 GLOBALS->maxtext_currenttime_c_1=(char *)malloc_2(40);
557 GLOBALS->maxtimewid_currenttime_c_1 = old_g->maxtimewid_currenttime_c_1;
558 GLOBALS->curtext_currenttime_c_1 = old_g->curtext_currenttime_c_1;
559 GLOBALS->base_or_curtime_label_currenttime_c_1 = old_g->base_or_curtime_label_currenttime_c_1;
560 GLOBALS->curtimewid_currenttime_c_1 = old_g->curtimewid_currenttime_c_1;
561
562 /* status.c */
563 GLOBALS->text_status_c_2 = old_g->text_status_c_2;
564 GLOBALS->vscrollbar_status_c_2 = old_g->vscrollbar_status_c_2;
565 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
566 GLOBALS->iter_status_c_3 = old_g->iter_status_c_3;
567 GLOBALS->bold_tag_status_c_3 = old_g->bold_tag_status_c_3;
568 #endif
569
570 /* timeentry.c */
571 GLOBALS->from_entry = old_g->from_entry;
572 GLOBALS->to_entry = old_g->to_entry;
573
574 /* rc.c */
575 GLOBALS->possibly_use_rc_defaults = old_g->possibly_use_rc_defaults;
576 GLOBALS->ignore_savefile_pane_pos = old_g->ignore_savefile_pane_pos;
577 GLOBALS->ignore_savefile_pos = old_g->ignore_savefile_pos;
578 GLOBALS->ignore_savefile_size = old_g->ignore_savefile_size;
579
580 GLOBALS->color_back = old_g->color_back;
581 GLOBALS->color_baseline = old_g->color_baseline;
582 GLOBALS->color_grid = old_g->color_grid;
583 GLOBALS->color_grid2 = old_g->color_grid2;
584 GLOBALS->color_high = old_g->color_high;
585 GLOBALS->color_highfill = old_g->color_highfill;
586 GLOBALS->color_low = old_g->color_low;
587 GLOBALS->color_1 = old_g->color_1;
588 GLOBALS->color_1fill = old_g->color_1fill;
589 GLOBALS->color_0 = old_g->color_0;
590 GLOBALS->color_mark = old_g->color_mark;
591 GLOBALS->color_mid = old_g->color_mid;
592 GLOBALS->color_time = old_g->color_time;
593 GLOBALS->color_timeb = old_g->color_timeb;
594 GLOBALS->color_trans = old_g->color_trans;
595 GLOBALS->color_umark = old_g->color_umark;
596 GLOBALS->color_value = old_g->color_value;
597 GLOBALS->color_vbox = old_g->color_vbox;
598 GLOBALS->color_vtrans = old_g->color_vtrans;
599 GLOBALS->color_x = old_g->color_x;
600 GLOBALS->color_xfill = old_g->color_xfill;
601 GLOBALS->color_u = old_g->color_u;
602 GLOBALS->color_ufill = old_g->color_ufill;
603 GLOBALS->color_w = old_g->color_w;
604 GLOBALS->color_wfill = old_g->color_wfill;
605 GLOBALS->color_dash = old_g->color_dash;
606 GLOBALS->color_dashfill = old_g->color_dashfill;
607 GLOBALS->color_white = old_g->color_white;
608 GLOBALS->color_black = old_g->color_black;
609 GLOBALS->color_ltgray = old_g->color_ltgray;
610 GLOBALS->color_normal = old_g->color_normal;
611 GLOBALS->color_mdgray = old_g->color_mdgray;
612 GLOBALS->color_dkgray = old_g->color_dkgray;
613 GLOBALS->color_dkblue = old_g->color_dkblue;
614 GLOBALS->color_brkred = old_g->color_brkred;
615 GLOBALS->color_ltblue = old_g->color_ltblue;
616 GLOBALS->color_gmstrd = old_g->color_gmstrd;
617
618 GLOBALS->atomic_vectors = old_g->atomic_vectors;
619 GLOBALS->autoname_bundles = old_g->autoname_bundles;
620 GLOBALS->autocoalesce = old_g->autocoalesce;
621 GLOBALS->autocoalesce_reversal = old_g->autocoalesce_reversal;
622 GLOBALS->constant_marker_update = old_g->constant_marker_update;
623 GLOBALS->convert_to_reals = old_g->convert_to_reals;
624 GLOBALS->disable_mouseover = old_g->disable_mouseover;
625 GLOBALS->clipboard_mouseover = old_g->clipboard_mouseover;
626 GLOBALS->keep_xz_colors = old_g->keep_xz_colors;
627 GLOBALS->disable_tooltips = old_g->disable_tooltips;
628 GLOBALS->do_initial_zoom_fit = old_g->do_initial_zoom_fit;
629 GLOBALS->do_resize_signals = old_g->do_resize_signals;
630 GLOBALS->alt_wheel_mode = old_g->alt_wheel_mode;
631 GLOBALS->initial_signal_window_width = old_g->initial_signal_window_width;
632 GLOBALS->scale_to_time_dimension = old_g->scale_to_time_dimension;
633 GLOBALS->enable_fast_exit = old_g->enable_fast_exit;
634 GLOBALS->enable_ghost_marker = old_g->enable_ghost_marker;
635 GLOBALS->enable_horiz_grid = old_g->enable_horiz_grid;
636 GLOBALS->fill_waveform = old_g->fill_waveform;
637 GLOBALS->make_vcd_save_file = old_g->make_vcd_save_file;
638 GLOBALS->enable_vert_grid = old_g->enable_vert_grid;
639 GLOBALS->force_toolbars = old_g->force_toolbars;
640 GLOBALS->hide_sst = old_g->hide_sst;
641 GLOBALS->sst_expanded = old_g->sst_expanded;
642 GLOBALS->hier_grouping = old_g->hier_grouping;
643 GLOBALS->hier_max_level = old_g->hier_max_level;
644 GLOBALS->hier_max_level_shadow = old_g->hier_max_level_shadow;
645 GLOBALS->paned_pack_semantics = old_g->paned_pack_semantics;
646 GLOBALS->left_justify_sigs = old_g->left_justify_sigs;
647 GLOBALS->lxt_clock_compress_to_z = old_g->lxt_clock_compress_to_z;
648 GLOBALS->ps_maxveclen = old_g->ps_maxveclen;
649 GLOBALS->show_base = old_g->show_base;
650 GLOBALS->display_grid = old_g->display_grid;
651 GLOBALS->highlight_wavewindow = old_g->highlight_wavewindow;
652 GLOBALS->fill_waveform = old_g->fill_waveform;
653 GLOBALS->use_standard_trace_select = old_g->use_standard_trace_select;
654 GLOBALS->use_big_fonts = old_g->use_big_fonts;
655 GLOBALS->use_full_precision = old_g->use_full_precision;
656 GLOBALS->use_frequency_delta = old_g->use_frequency_delta;
657 GLOBALS->use_maxtime_display = old_g->use_maxtime_display;
658 GLOBALS->use_nonprop_fonts = old_g->use_nonprop_fonts;
659 GLOBALS->use_roundcaps = old_g->use_roundcaps;
660 GLOBALS->use_scrollbar_only = old_g->use_scrollbar_only;
661 GLOBALS->vcd_explicit_zero_subscripts = old_g->vcd_explicit_zero_subscripts;
662 GLOBALS->vcd_preserve_glitches = old_g->vcd_preserve_glitches;
663 GLOBALS->vcd_preserve_glitches_real = old_g->vcd_preserve_glitches_real;
664 GLOBALS->vcd_warning_filesize = old_g->vcd_warning_filesize;
665 GLOBALS->vector_padding = old_g->vector_padding;
666 GLOBALS->vlist_compression_depth = old_g->vlist_compression_depth;
667 GLOBALS->wave_scrolling = old_g->wave_scrolling;
668 GLOBALS->do_zoom_center = old_g->do_zoom_center;
669 GLOBALS->zoom_pow10_snap = old_g->zoom_pow10_snap;
670 GLOBALS->zoom_dyn = old_g->zoom_dyn;
671 GLOBALS->zoom_dyne = old_g->zoom_dyne;
672 GLOBALS->alt_hier_delimeter = old_g->alt_hier_delimeter;
673 GLOBALS->cursor_snap = old_g->cursor_snap;
674 GLOBALS->hier_delimeter = old_g->hier_delimeter;
675 GLOBALS->hier_was_explicitly_set = old_g->hier_was_explicitly_set;
676 GLOBALS->page_divisor = old_g->page_divisor;
677 GLOBALS->ps_maxveclen = old_g->ps_maxveclen;
678 GLOBALS->vector_padding = old_g->vector_padding;
679 GLOBALS->vlist_compression_depth = old_g->vlist_compression_depth;
680 GLOBALS->zoombase = old_g->zoombase;
681 GLOBALS->splash_disable = old_g->splash_disable;
682 GLOBALS->use_pango_fonts = old_g->use_pango_fonts;
683 GLOBALS->hier_ignore_escapes = old_g->hier_ignore_escapes;
684
685 GLOBALS->ruler_origin = old_g->ruler_origin;
686 GLOBALS->ruler_step = old_g->ruler_step;
687 GLOBALS->disable_ae2_alias = old_g->disable_ae2_alias;
688
689 GLOBALS->vlist_spill_to_disk = old_g->vlist_spill_to_disk;
690 GLOBALS->vlist_prepack = old_g->vlist_prepack;
691 GLOBALS->do_dynamic_treefilter = old_g->do_dynamic_treefilter;
692 GLOBALS->use_standard_clicking = old_g->use_standard_clicking;
693 GLOBALS->dragzoom_threshold = old_g->dragzoom_threshold;
694 GLOBALS->use_toolbutton_interface = old_g->use_toolbutton_interface;
695
696 GLOBALS->use_scrollwheel_as_y = old_g->use_scrollwheel_as_y;
697 GLOBALS->enable_slider_zoom = old_g->enable_slider_zoom;
698
699 GLOBALS->missing_file_toolbar = old_g->missing_file_toolbar;
700
701 GLOBALS->analog_redraw_skip_count = old_g->analog_redraw_skip_count;
702 GLOBALS->context_tabposition = old_g->context_tabposition;
703 GLOBALS->disable_empty_gui = old_g->disable_empty_gui;
704 GLOBALS->make_vcd_save_file = old_g->make_vcd_save_file;
705 GLOBALS->strace_repeat_count = old_g->strace_repeat_count;
706
707 GLOBALS->extload_max_tree = old_g->extload_max_tree;
708 GLOBALS->do_hier_compress = old_g->do_hier_compress;
709 GLOBALS->disable_auto_comphier = old_g->disable_auto_comphier;
710 GLOBALS->sst_dbl_action_type = old_g->sst_dbl_action_type;
711 GLOBALS->save_on_exit = old_g->save_on_exit;
712
713 strcpy2_into_new_context(GLOBALS, &GLOBALS->sst_exclude_filename, &old_g->sst_exclude_filename);
714
715 strcpy2_into_new_context(GLOBALS, &GLOBALS->editor_name, &old_g->editor_name);
716 strcpy2_into_new_context(GLOBALS, &GLOBALS->fontname_logfile, &old_g->fontname_logfile);
717 strcpy2_into_new_context(GLOBALS, &GLOBALS->fontname_signals, &old_g->fontname_signals);
718 strcpy2_into_new_context(GLOBALS, &GLOBALS->fontname_waves, &old_g->fontname_waves);
719 strcpy2_into_new_context(GLOBALS, &GLOBALS->argvlist, &old_g->argvlist);
720
721 mainwindow_already_built = 1;
722 }
723
724 GLOBALS->whoami=malloc_2(strlen(argv[0])+1); /* cache name in case we fork later */
725 strcpy(GLOBALS->whoami, argv[0]);
726
727 if(!mainwindow_already_built)
728 {
729 #ifdef __MINGW32__
730 gtk_disable_setlocale();
731 #endif
732 if(!gtk_init_check(&argc, &argv))
733 {
734 #if defined(__APPLE__)
735 #ifndef MAC_INTEGRATION
736 if(!getenv("DISPLAY"))
737 {
738 fprintf(stderr, "DISPLAY environment variable is not set. Have you ensured\n");
739 fprintf(stderr, "that x11 has been initialized through open-x11, launching\n");
740 fprintf(stderr, "gtkwave in an xterm or x11 window, etc?\n\n");
741 fprintf(stderr, "Attempting to initialize using DISPLAY=:0.0 value...\n\n");
742 setenv("DISPLAY", ":0.0", 0);
743 if(gtk_init_check(&argc, &argv))
744 {
745 goto do_primary_inits;
746 }
747 }
748 #endif
749 #endif
750 fprintf(stderr, "Could not initialize GTK! Is DISPLAY env var/xhost set?\n\n");
751 print_help(argv[0]);
752 }
753
754 #ifdef WAVE_CRASH_ON_GTK_WARNING
755 g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING);
756 #endif
757 }
758
759 #if defined(__APPLE__)
760 #ifndef MAC_INTEGRATION
761 do_primary_inits:
762 #endif
763 #endif
764
765 if(!mainwindow_already_built)
766 {
767 wave_gconf_init(argc, argv);
768 }
769
770 if(!gtkwave_argv0_cached) gtkwave_argv0_cached = argv[0]; /* for new window option */
771
772 init_filetrans_data(); /* for file translation splay trees */
773 init_proctrans_data(); /* for proc translation structs */
774 init_ttrans_data(); /* for transaction proc translation structs */
775
776 if(!mainwindow_already_built)
777 {
778 atexit(remove_all_proc_filters);
779 atexit(remove_all_ttrans_filters);
780 #if defined __MINGW32__
781 atexit(close_all_fst_files);
782 #endif
783 #ifdef WAVE_FSDB_READER_IS_PRESENT
784 atexit(close_all_fsdb_files);
785 #endif
786 }
787
788 if(mainwindow_already_built)
789 {
790 optind = 1;
791 }
792 else
793 while (1)
794 {
795 int option_index = 0;
796
797 static struct option long_options[] =
798 {
799 {"dump", 1, 0, 'f'},
800 {"fastload", 0, 0, 'F'},
801 {"optimize", 0, 0, 'o'},
802 {"nocli", 1, 0, 'n'},
803 {"save", 1, 0, 'a'},
804 {"autosavename", 0, 0, 'A'},
805 {"rcfile", 1, 0, 'r'},
806 {"defaultskip", 0, 0, 'd'},
807 {"logfile", 1, 0, 'l'},
808 {"start", 1, 0, 's'},
809 {"end", 1, 0, 'e'},
810 {"cpus", 1, 0, 'c'},
811 {"stems", 1, 0, 't'},
812 {"nowm", 0, 0, 'N'},
813 {"script", 1, 0, 'S'},
814 {"vcd", 0, 0, 'v'},
815 {"version", 0, 0, 'V'},
816 {"help", 0, 0, 'h'},
817 {"exit", 0, 0, 'x'},
818 {"xid", 1, 0, 'X'},
819 {"nomenus", 0, 0, 'M'},
820 {"dualid", 1, 0, 'D'},
821 {"interactive", 0, 0, 'I'},
822 {"giga", 0, 0, 'g'},
823 {"comphier", 0, 0, 'C'},
824 {"legacy", 0, 0, 'L'},
825 {"tcl_init", 1, 0, 'T'},
826 {"wish", 0, 0, 'W'},
827 {"repscript", 1, 0, 'R'},
828 {"repperiod", 1, 0, 'P'},
829 {"output", 1, 0, 'O' },
830 {"slider-zoom", 0, 0, 'z'},
831 {"rpcid", 1, 0, '1' },
832 {"chdir", 1, 0, '2'},
833 {"restore", 0, 0, '3'},
834 {"rcvar", 1, 0, '4'},
835 {"sstexclude", 1, 0, '5'},
836 {"saveonexit", 0, 0, '7'},
837 {0, 0, 0, 0}
838 };
839
840 c = getopt_long (argc, argv, "zf:Fon:a:Ar:dl:s:e:c:t:NS:vVhxX:MD:IgCLR:P:O:WT:1:2:34:5:7", long_options,
841 &option_index);
842
843 if (c == -1) break; /* no more args */
844
845 switch (c)
846 {
847 case 'V':
848 printf(
849 WAVE_VERSION_INFO"\n\n"
850 "This is free software; see the source for copying conditions. There is NO\n"
851 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
852 );
853 exit(0);
854
855 case 'W':
856 #if defined(HAVE_LIBTCL)
857 #if defined(WIN32) && defined(USE_TCL_STUBS)
858 #else
859 is_wish = 1;
860 #endif
861 #else
862 fprintf(stderr, "GTKWAVE | Tcl support not compiled into this executable, exiting.\n");
863 exit(255);
864 #endif
865 break;
866
867 case 'I':
868 #if !defined _MSC_VER
869 is_interactive = 1;
870 #endif
871 break;
872
873 case 'L':
874 is_legacy = 1;
875 break;
876
877 case 'D':
878 #if !defined _MSC_VER
879 {
880 char *s = optarg;
881 char *plus = strchr(s, '+');
882 if((plus)&&(*(plus+1)))
883 {
884 sscanf(plus+1, "%x", &GLOBALS->dual_attach_id_main_c_1);
885 if(plus != s)
886 {
887 char p = *(plus-1);
888
889 if(p=='0')
890 {
891 GLOBALS->dual_id = 0;
892 break;
893 }
894 else
895 if(p=='1')
896 {
897 GLOBALS->dual_id = 1;
898 break;
899 }
900 }
901 }
902
903 fprintf(stderr, "Malformed dual session ID. Must be of form m+nnnnnnnn where m is 0 or 1,\n"
904 "and n is a hexadecimal shared memory ID for use with shmat()\n");
905 exit(255);
906 }
907 #else
908 {
909 fprintf(stderr, "Dual operation not implemented for Win32, exiting.\n");
910 exit(255);
911 }
912 #endif
913 break;
914
915 case 'A':
916 is_smartsave = 1;
917 break;
918
919 case 'v':
920 is_vcd = 1;
921 if(GLOBALS->loaded_file_name) free_2(GLOBALS->loaded_file_name);
922 GLOBALS->loaded_file_name = malloc_2(4+1);
923 strcpy(GLOBALS->loaded_file_name, "-vcd");
924 break;
925
926 case 'o':
927 opt_vcd = 1;
928 break;
929
930 case 'n':
931 wave_get_filename(optarg);
932 if(GLOBALS->filesel_ok)
933 {
934 if(GLOBALS->loaded_file_name) free_2(GLOBALS->loaded_file_name);
935 GLOBALS->loaded_file_name = GLOBALS->ftext_main_main_c_1;
936 GLOBALS->ftext_main_main_c_1 = NULL;
937 }
938 break;
939
940 case 'h':
941 print_help(argv[0]);
942 break;
943
944 #ifdef WAVE_USE_XID
945 case 'X':
946 sscanf(optarg, "%x", &GLOBALS->socket_xid);
947 splash_disable_rc_override = 1;
948 break;
949 #endif
950
951 case '1':
952 sscanf(optarg, "%d", &wave_rpc_id);
953 if(wave_rpc_id < 0) wave_rpc_id = 0;
954 break;
955
956 case '2':
957 #ifndef _MSC_VER
958 {
959 char *chdir_env = getenv("GTKWAVE_CHDIR");
960
961 if(chdir_cache)
962 {
963 free_2(chdir_cache);
964 }
965
966 chdir_cache = strdup_2(chdir_env ? chdir_env : optarg);
967 if(chdir(chdir_cache) < 0)
968 {
969 fprintf(stderr, "GTKWAVE | Could not chdir '%s', exiting.\n", chdir_cache);
970 perror("Why");
971 exit(255);
972 }
973 }
974 #endif
975 break;
976
977 case '3':
978 #if defined(WAVE_HAVE_GCONF) || defined(WAVE_HAVE_GSETTINGS)
979 {
980 is_vcd = 0;
981 wave_gconf_restore(&GLOBALS->loaded_file_name, &wname, &override_rc, &chdir_cache, &opt_vcd);
982 if(chdir_cache)
983 {
984 if(chdir(chdir_cache) < 0)
985 {
986 fprintf(stderr, "GTKWAVE | Could not chdir '%s', exiting.\n", chdir_cache);
987 perror("Why");
988 exit(255);
989 }
990 }
991 fprintf(stderr, "GTKWAVE | restore cwd '%s'\n", chdir_cache ? chdir_cache : "(none)");
992 fprintf(stderr, "GTKWAVE | restore dumpfile '%s'\n", GLOBALS->loaded_file_name ? GLOBALS->loaded_file_name : "(none)");
993 fprintf(stderr, "GTKWAVE | restore savefile '%s'\n", wname ? wname : "(none)");
994 fprintf(stderr, "GTKWAVE | restore rcfile '%s'\n", override_rc ? override_rc : "(none)");
995 fprintf(stderr, "GTKWAVE | restore optimize '%s'\n", opt_vcd ? "yes" : "no");
996 }
997 #endif
998 break;
999
1000 case 'M':
1001 GLOBALS->disable_menus = 1;
1002 break;
1003
1004 case 'x':
1005 fast_exit = 1;
1006 splash_disable_rc_override = 1;
1007 break;
1008
1009 case 'd':
1010 GLOBALS->possibly_use_rc_defaults = 0;
1011 break;
1012
1013 case 'f':
1014 is_vcd = 0;
1015 if(GLOBALS->loaded_file_name) free_2(GLOBALS->loaded_file_name);
1016 GLOBALS->loaded_file_name = malloc_2(strlen(optarg)+1);
1017 strcpy(GLOBALS->loaded_file_name, optarg);
1018 break;
1019
1020 case 'F':
1021 is_fastload = VCD_FSL_WRITE;
1022 is_giga = 1;
1023 break;
1024
1025 case 'a':
1026 if(wname) free_2(wname);
1027 wname = malloc_2(strlen(optarg)+1);
1028 strcpy(wname, optarg);
1029 break;
1030
1031 case 'r':
1032 if(override_rc) free_2(override_rc);
1033 override_rc = malloc_2(strlen(optarg)+1);
1034 strcpy(override_rc, optarg);
1035 break;
1036
1037 case '4':
1038 {
1039 struct rc_override *rco = calloc_2(1, sizeof(struct rc_override));
1040 rco->str = strdup_2(optarg);
1041
1042 if(rc_override_curr)
1043 {
1044 rc_override_curr->next = rco;
1045 rc_override_curr = rco;
1046 }
1047 else
1048 {
1049 rc_override_head = rc_override_curr = rco;
1050 }
1051 }
1052 break;
1053
1054 case '5':
1055 {
1056 if(GLOBALS->sst_exclude_filename)
1057 {
1058 free_2(GLOBALS->sst_exclude_filename);
1059 }
1060 GLOBALS->sst_exclude_filename = strdup_2(optarg);
1061 }
1062 break;
1063
1064 case '7':
1065 GLOBALS->save_on_exit = TRUE;
1066 break;
1067
1068 case 's':
1069 if(GLOBALS->skip_start) free_2(GLOBALS->skip_start);
1070 GLOBALS->skip_start = malloc_2(strlen(optarg)+1);
1071 strcpy(GLOBALS->skip_start, optarg);
1072 break;
1073
1074 case 'e':
1075 if(GLOBALS->skip_end) free_2(GLOBALS->skip_end);
1076 GLOBALS->skip_end = malloc_2(strlen(optarg)+1);
1077 strcpy(GLOBALS->skip_end, optarg);
1078 break;
1079
1080 case 't':
1081 #if !defined _MSC_VER
1082 if(GLOBALS->stems_name) free_2(GLOBALS->stems_name);
1083 GLOBALS->stems_name = malloc_2(strlen(optarg)+1);
1084 strcpy(GLOBALS->stems_name, optarg);
1085 #else
1086 fprintf(stderr, "GTKWAVE | Warning: '%c' option does not exist in this executable\n", c);
1087 #endif
1088 break;
1089
1090 case 'c':
1091 #if !defined _MSC_VER && !defined __MINGW32__ && !defined __FreeBSD__ && !defined __CYGWIN__
1092 GLOBALS->num_cpus = atoi(optarg);
1093 if(GLOBALS->num_cpus<1) GLOBALS->num_cpus = 1;
1094 if(GLOBALS->num_cpus>8) GLOBALS->num_cpus = 8;
1095 #else
1096 fprintf(stderr, "GTKWAVE | Warning: '%c' option does not exist in this executable\n", c);
1097 #endif
1098 break;
1099
1100 case 'N':
1101 GLOBALS->disable_window_manager = 1;
1102 break;
1103
1104 case 'S':
1105 if(scriptfile) free_2(scriptfile);
1106 scriptfile = malloc_2(strlen(optarg)+1);
1107 strcpy(scriptfile, optarg);
1108 splash_disable_rc_override = 1;
1109 break;
1110
1111 case 'l':
1112 {
1113 struct logfile_chain *l = calloc_2(1, sizeof(struct logfile_chain));
1114 struct logfile_chain *ltraverse;
1115 l->name = malloc_2(strlen(optarg)+1);
1116 strcpy(l->name, optarg);
1117
1118 if(GLOBALS->logfile)
1119 {
1120 ltraverse = GLOBALS->logfile;
1121 while(ltraverse->next) ltraverse = ltraverse->next;
1122 ltraverse->next = l;
1123 }
1124 else
1125 {
1126 GLOBALS->logfile = l;
1127 }
1128 }
1129 break;
1130
1131 case 'g':
1132 is_giga = 1;
1133 break;
1134
1135 case 'C':
1136 GLOBALS->do_hier_compress = 1;
1137 break;
1138
1139 case 'R':
1140 if(GLOBALS->repscript_name) free_2(GLOBALS->repscript_name);
1141 GLOBALS->repscript_name = malloc_2(strlen(optarg)+1);
1142 strcpy(GLOBALS->repscript_name, optarg);
1143 break;
1144
1145 case 'P':
1146 {
1147 int pd = atoi(optarg);
1148 if(pd > 0)
1149 {
1150 GLOBALS->repscript_period = pd;
1151 }
1152 }
1153 break;
1154
1155 case 'T':
1156 #if defined(WIN32) && defined(USE_TCL_STUBS)
1157 fprintf(stderr, "GTKWAVE | Warning: '%c' option does not exist in this executable\n", c);
1158 #else
1159 {
1160 char* pos;
1161 is_wish = 1;
1162 if(GLOBALS->tcl_init_cmd)
1163 {
1164 int length = strlen(GLOBALS->tcl_init_cmd)+9+strlen(optarg);
1165 char* buffer = malloc_2(strlen(GLOBALS->tcl_init_cmd)+1);
1166 strcpy(buffer, GLOBALS->tcl_init_cmd);
1167 free_2(GLOBALS->tcl_init_cmd);
1168 GLOBALS->tcl_init_cmd = malloc_2(length+1);
1169 strcpy(GLOBALS->tcl_init_cmd, buffer);
1170 pos = GLOBALS->tcl_init_cmd + strlen(GLOBALS->tcl_init_cmd);
1171 free_2(buffer);
1172 }
1173 else
1174 {
1175 int length = 9+strlen(optarg);
1176 GLOBALS->tcl_init_cmd = malloc_2(length+1);
1177 pos = GLOBALS->tcl_init_cmd;
1178 }
1179 strcpy(pos, "; source ");
1180 pos = GLOBALS->tcl_init_cmd + strlen(GLOBALS->tcl_init_cmd);
1181 strcpy(pos, optarg);
1182 }
1183 #endif
1184 break;
1185
1186 case 'O':
1187 if(output_name) free_2(output_name);
1188 output_name = malloc_2(strlen(optarg)+1);
1189 strcpy(output_name, optarg);
1190 break;
1191
1192 case 'z':
1193 GLOBALS->enable_slider_zoom = 1;
1194 break;
1195
1196 case '?':
1197 opt_errors_encountered=1;
1198 break;
1199
1200 default:
1201 /* unreachable */
1202 break;
1203 }
1204 } /* ...while(1) */
1205
1206 if(opt_errors_encountered)
1207 {
1208 print_help(argv[0]);
1209 }
1210
1211 if (optind < argc)
1212 {
1213 while (optind < argc)
1214 {
1215 if(argv[optind][0] == '-')
1216 {
1217 if(!strcmp(argv[optind], "--"))
1218 {
1219 break;
1220 }
1221 }
1222
1223 if(!GLOBALS->loaded_file_name)
1224 {
1225 is_vcd = 0;
1226 GLOBALS->loaded_file_name = malloc_2(strlen(argv[optind])+1);
1227 strcpy(GLOBALS->loaded_file_name, argv[optind++]);
1228 }
1229 else if(!wname)
1230 {
1231 wname = malloc_2(strlen(argv[optind])+1);
1232 strcpy(wname, argv[optind++]);
1233 }
1234 else if(!override_rc)
1235 {
1236 override_rc = malloc_2(strlen(argv[optind])+1);
1237 strcpy(override_rc, argv[optind++]);
1238 break; /* skip any extra args */
1239 }
1240 }
1241 }
1242
1243 if(is_wish && is_vcd)
1244 {
1245 fprintf(stderr,
1246 "GTKWAVE | Cannot use --vcd and --wish options together as both use stdin,\n"
1247 "GTKWAVE | exiting!\n");
1248 exit(255);
1249 }
1250
1251
1252 #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH)
1253 #if !defined(FSDB_IS_PRESENT) || !defined(FSDB_NSYS_IS_PRESENT)
1254 if(GLOBALS->loaded_file_name && suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX))
1255 {
1256 opt_vcd = 1;
1257 }
1258 #endif
1259 #endif
1260 #if defined(EXT2LOAD_SUFFIX) && defined(EXT2CONV_PATH)
1261 if(GLOBALS->loaded_file_name && suffix_check(GLOBALS->loaded_file_name, "."EXT2LOAD_SUFFIX))
1262 {
1263 opt_vcd = 1;
1264 }
1265 #endif
1266 #if defined(EXT3LOAD_SUFFIX) && defined(EXT3CONV_PATH)
1267 if(GLOBALS->loaded_file_name && suffix_check(GLOBALS->loaded_file_name, "."EXT3LOAD_SUFFIX))
1268 {
1269 opt_vcd = 1;
1270 }
1271 #endif
1272
1273 /* attempt to load a dump+save file if only a savefile is specified at the command line */
1274 if((GLOBALS->loaded_file_name) && (!wname) &&
1275 (suffix_check(GLOBALS->loaded_file_name, ".gtkw") || suffix_check(GLOBALS->loaded_file_name, ".sav")))
1276 {
1277 char *extracted_name = extract_dumpname_from_save_file(GLOBALS->loaded_file_name, &GLOBALS->dumpfile_is_modified, &opt_vcd);
1278 if(extracted_name)
1279 {
1280 if(mainwindow_already_built)
1281 {
1282 deal_with_rpc_open_2(GLOBALS->loaded_file_name, NULL, TRUE);
1283 GLOBALS->loaded_file_name = extracted_name;
1284 /* wname is still NULL */
1285 }
1286 else
1287 {
1288 wname = GLOBALS->loaded_file_name;
1289 GLOBALS->loaded_file_name = extracted_name;
1290 }
1291 }
1292 else
1293 {
1294 char *dfn = NULL;
1295 char *sfn = NULL;
1296 off_t dumpsiz = -1;
1297 time_t dumptim = -1;
1298
1299 read_save_helper(GLOBALS->loaded_file_name, &dfn, &sfn, &dumpsiz, &dumptim, &opt_vcd);
1300
1301 fprintf(stderr, "GTKWAVE | Could not initialize '%s' found in '%s', exiting.\n", dfn ? dfn : "(null)", GLOBALS->loaded_file_name);
1302 if(dfn) free_2(dfn);
1303 if(sfn) free_2(sfn);
1304 exit(255);
1305 }
1306 }
1307 else /* same as above but with --save specified */
1308 if((!GLOBALS->loaded_file_name) && wname)
1309 {
1310 GLOBALS->loaded_file_name = extract_dumpname_from_save_file(wname, &GLOBALS->dumpfile_is_modified, &opt_vcd);
1311 /* still can be NULL if file not found... */
1312 if(!GLOBALS->loaded_file_name)
1313 {
1314 char *dfn = NULL;
1315 char *sfn = NULL;
1316 off_t dumpsiz = -1;
1317 time_t dumptim = -1;
1318
1319 read_save_helper(wname, &dfn, &sfn, &dumpsiz, &dumptim, &opt_vcd);
1320
1321 fprintf(stderr, "GTKWAVE | Could not initialize '%s' found in '%s', exiting.\n", dfn ? dfn : "(null)", wname);
1322 if(dfn) free_2(dfn);
1323 if(sfn) free_2(sfn);
1324 exit(255);
1325 }
1326 }
1327
1328
1329 if(!old_g) /* copy all variables earlier when old_g is set */
1330 {
1331 read_rc_file(override_rc);
1332 }
1333
1334 GLOBALS->splash_disable |= splash_disable_rc_override;
1335
1336 if(!GLOBALS->loaded_file_name)
1337 {
1338 /* if rc can gates off gui, default is not to disable */
1339 if(GLOBALS->disable_empty_gui)
1340 {
1341 print_help(argv[0]);
1342 }
1343 }
1344
1345 if(is_giga)
1346 {
1347 GLOBALS->vlist_spill_to_disk = 1;
1348 GLOBALS->vlist_prepack = 1;
1349 }
1350
1351 if(output_name)
1352 {
1353 #if !defined _MSC_VER && !defined __MINGW32__
1354 int iarg;
1355 time_t walltime;
1356 int fd_replace = open(output_name, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
1357 if(fd_replace<0)
1358 {
1359 fprintf(stderr, "Could not open redirect file, exiting.\n");
1360 perror("Why");
1361 exit(255);
1362 }
1363
1364 dup2(fd_replace, 1);
1365 dup2(fd_replace, 2);
1366
1367 time(&walltime);
1368 printf(WAVE_VERSION_INFO"\nDate: %s\n\n",asctime(localtime(&walltime)));
1369
1370 for(iarg=0;iarg<argc;iarg++)
1371 {
1372 if(iarg) printf("\t");
1373 printf("%s\n", argv[iarg]);
1374 }
1375
1376 printf("\n\n");
1377 fflush(stdout);
1378
1379 #endif
1380 free_2(output_name);
1381 output_name = NULL;
1382 }
1383
1384 fprintf(stderr, "\n%s\n\n",WAVE_VERSION_INFO);
1385
1386
1387 if(!old_g) /* copy all variables earlier when old_g is set */
1388 {
1389 while(rc_override_head)
1390 {
1391 int rco_succ;
1392 char *rco_copy_str = strdup_2(rc_override_head->str);
1393 rco_succ = insert_rc_variable(rc_override_head->str);
1394 fprintf(stderr, "RCVAR | '%s' %s\n", rco_copy_str, rco_succ ? "FOUND" : "NOT FOUND");
1395 free_2(rco_copy_str);
1396 rc_override_curr = rc_override_head->next;
1397 free_2(rc_override_head->str);
1398 free_2(rc_override_head);
1399 rc_override_head = rc_override_curr;
1400 }
1401 }
1402
1403 if(!is_wish)
1404 {
1405 if(tcl_interpreter_needs_making)
1406 {
1407 GLOBALS->argvlist = zMergeTclList(argc, (const char**)argv);
1408 make_tcl_interpreter(argv);
1409 }
1410 }
1411
1412 if((!wname)&&(GLOBALS->make_vcd_save_file))
1413 {
1414 vcd_save_handle_cached = GLOBALS->vcd_save_handle=fopen(vcd_autosave_name,"wb");
1415 errno=0; /* just in case */
1416 is_smartsave = (GLOBALS->vcd_save_handle != NULL); /* use smartsave if for some reason can't open auto savefile */
1417 }
1418
1419 if(!GLOBALS->loaded_file_name)
1420 {
1421 GLOBALS->loaded_file_name = strdup_2("[no file loaded]");
1422 is_missing_file = 1;
1423 GLOBALS->min_time=LLDescriptor(0);
1424 GLOBALS->max_time=LLDescriptor(0);
1425 if(!is_wish)
1426 {
1427 fprintf(stderr, "GTKWAVE | Use the -h, --help command line flags to display help.\n");
1428 }
1429 }
1430
1431 /* load either the vcd or aet file depending on suffix then mode setting */
1432 if(is_vcd)
1433 {
1434 GLOBALS->winname=malloc_2(strlen(winstd)+4+1);
1435 strcpy(GLOBALS->winname,winstd);
1436 }
1437 else
1438 {
1439 if(!is_interactive)
1440 {
1441 GLOBALS->winname=malloc_2(strlen(GLOBALS->loaded_file_name)+strlen(winprefix)+1);
1442 strcpy(GLOBALS->winname,winprefix);
1443 }
1444 else
1445 {
1446 char *iact = "GTKWave - Interactive Shared Memory ID ";
1447 GLOBALS->winname=malloc_2(strlen(GLOBALS->loaded_file_name)+strlen(iact)+1);
1448 strcpy(GLOBALS->winname,iact);
1449 }
1450 }
1451
1452 strcat(GLOBALS->winname,GLOBALS->loaded_file_name);
1453 sst_exclusion_loader();
1454
1455 loader_check_head:
1456
1457 if(!is_missing_file)
1458 {
1459 magic_word_filetype = determine_gtkwave_filetype(GLOBALS->loaded_file_name);
1460 }
1461
1462 if(is_missing_file)
1463 {
1464 GLOBALS->loaded_file_type = MISSING_FILE;
1465 }
1466 else
1467 #if defined(EXTLOAD_SUFFIX)
1468 if(
1469 (suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX ) && !opt_vcd) ||
1470 (suffix_check(GLOBALS->loaded_file_name, ".vf" ) && !opt_vcd) || /* virtual file */
1471 (suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX".gz" ) && !opt_vcd) || /* loader automatically does gzip -cd */
1472 (suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX".bz2") && !opt_vcd) /* loader automatically does bzip2 -cd */
1473 )
1474 {
1475 TimeType extload_max;
1476
1477 GLOBALS->loaded_file_type = EXTLOAD_FILE;
1478 extload_max = extload_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end);
1479 if((!GLOBALS->extload) || (GLOBALS->extload_already_errored) || (!extload_max))
1480 {
1481 fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting");
1482 vcd_exit(255);
1483 }
1484 }
1485 else
1486 #endif
1487 if((magic_word_filetype == G_FT_LXT) || (magic_word_filetype == G_FT_LXT2) || suffix_check(GLOBALS->loaded_file_name, ".lxt") || suffix_check(GLOBALS->loaded_file_name, ".lx2") || suffix_check(GLOBALS->loaded_file_name, ".lxt2"))
1488 {
1489 FILE *f = fopen(GLOBALS->loaded_file_name, "rb");
1490 int typ = 0;
1491
1492 if(f)
1493 {
1494 char buf[2];
1495 unsigned int matchword;
1496
1497 if(fread(buf, 2, 1, f))
1498 {
1499 matchword = (((unsigned int)buf[0])<<8) | ((unsigned int)buf[1]);
1500 if(matchword == LT_HDRID) typ = 1;
1501 }
1502
1503 fclose(f);
1504 }
1505
1506 if(typ)
1507 {
1508 GLOBALS->loaded_file_type = LXT_FILE;
1509 lxt_main(GLOBALS->loaded_file_name);
1510 }
1511 else
1512 {
1513 #if !defined _MSC_VER
1514 GLOBALS->stems_type = WAVE_ANNO_LXT2;
1515 GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1);
1516 strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name);
1517 #endif
1518 GLOBALS->loaded_file_type = LX2_FILE;
1519 lx2_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end);
1520 if(!GLOBALS->lx2_lx2_c_1)
1521 {
1522 fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting");
1523 vcd_exit(255);
1524 }
1525 }
1526 }
1527 else
1528 if((magic_word_filetype == G_FT_FST) || suffix_check(GLOBALS->loaded_file_name, ".fst"))
1529 {
1530 #if !defined _MSC_VER
1531 GLOBALS->stems_type = WAVE_ANNO_FST;
1532 GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1);
1533 strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name);
1534 #endif
1535 GLOBALS->loaded_file_type = FST_FILE;
1536 fst_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end);
1537 if(!GLOBALS->fst_fst_c_1)
1538 {
1539 fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting");
1540 vcd_exit(255);
1541 }
1542 }
1543 else
1544 if((magic_word_filetype == G_FT_VZT) || suffix_check(GLOBALS->loaded_file_name, ".vzt"))
1545 {
1546 #if !defined _MSC_VER
1547 GLOBALS->stems_type = WAVE_ANNO_VZT;
1548 GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1);
1549 strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name);
1550 #endif
1551 GLOBALS->loaded_file_type = VZT_FILE;
1552 vzt_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end);
1553 if(!GLOBALS->vzt_vzt_c_1)
1554 {
1555 fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting");
1556 vcd_exit(255);
1557 }
1558 }
1559 else if(suffix_check(GLOBALS->loaded_file_name, ".aet") || suffix_check(GLOBALS->loaded_file_name, ".ae2"))
1560 {
1561 #if !defined _MSC_VER
1562 GLOBALS->stems_type = WAVE_ANNO_AE2;
1563 GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1);
1564 strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name);
1565 #endif
1566 GLOBALS->loaded_file_type = AE2_FILE;
1567 ae2_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end);
1568 #ifdef AET2_IS_PRESENT
1569 if(!GLOBALS->ae2)
1570 {
1571 fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting");
1572 vcd_exit(255);
1573 }
1574 #else
1575 /* fails in stubbed out ae2_main() */
1576 #endif
1577 }
1578 else if (suffix_check(GLOBALS->loaded_file_name, ".ghw") || suffix_check(GLOBALS->loaded_file_name, ".ghw.gz") ||
1579 suffix_check(GLOBALS->loaded_file_name, ".ghw.bz2"))
1580 {
1581 GLOBALS->loaded_file_type = GHW_FILE;
1582 if(!ghw_main(GLOBALS->loaded_file_name))
1583 {
1584 /* error message printed in ghw_main() */
1585 vcd_exit(255);
1586 }
1587 }
1588 else if (strlen(GLOBALS->loaded_file_name)>4) /* case for .aet? type filenames */
1589 {
1590 char sufbuf[5];
1591 memcpy(sufbuf, GLOBALS->loaded_file_name+strlen(GLOBALS->loaded_file_name)-5, 4);
1592 sufbuf[4] = 0;
1593 if(!strcasecmp(sufbuf, ".aet")) /* strncasecmp() in windows? */
1594 {
1595 #if !defined _MSC_VER
1596 GLOBALS->stems_type = WAVE_ANNO_AE2;
1597 GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1);
1598 strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name);
1599 #endif
1600 GLOBALS->loaded_file_type = AE2_FILE;
1601 #ifdef AET2_IS_PRESENT
1602 ae2_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end);
1603 if(!GLOBALS->ae2)
1604 {
1605 fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting");
1606 vcd_exit(255);
1607 }
1608 #else
1609 /* fails in stubbed out ae2_main() */
1610 #endif
1611 }
1612 else
1613 {
1614 goto load_vcd;
1615 }
1616 }
1617 else /* nothing else left so default to "something" */
1618 {
1619 load_vcd:
1620 #if !defined _MSC_VER && !defined __MINGW32__
1621 if(opt_vcd) {
1622 GLOBALS->unoptimized_vcd_file_name = calloc_2(1,strlen(GLOBALS->loaded_file_name) + 1);
1623 strcpy(GLOBALS->unoptimized_vcd_file_name, GLOBALS->loaded_file_name);
1624 optimize_vcd_file();
1625 /* is_vcd = 0; */ /* scan-build */
1626 GLOBALS->optimize_vcd = 1;
1627 goto loader_check_head;
1628 }
1629
1630 #endif
1631
1632 #if !defined _MSC_VER
1633 if(is_interactive)
1634 {
1635 GLOBALS->loaded_file_type = DUMPLESS_FILE;
1636 vcd_partial_main(GLOBALS->loaded_file_name);
1637 }
1638 else
1639 #endif
1640 {
1641 if(is_legacy)
1642 {
1643 GLOBALS->loaded_file_type = (strcmp(GLOBALS->loaded_file_name, "-vcd")) ? VCD_FILE : DUMPLESS_FILE;
1644 vcd_main(GLOBALS->loaded_file_name);
1645 }
1646 else
1647 {
1648 if(strcmp(GLOBALS->loaded_file_name, "-vcd"))
1649 {
1650 GLOBALS->loaded_file_type = VCD_RECODER_FILE;
1651 GLOBALS->use_fastload = is_fastload;
1652 }
1653 else
1654 {
1655 GLOBALS->loaded_file_type = DUMPLESS_FILE;
1656 GLOBALS->use_fastload = VCD_FSL_NONE;
1657 }
1658 vcd_recoder_main(GLOBALS->loaded_file_name);
1659 }
1660 }
1661 }
1662
1663
1664 if(((GLOBALS->loaded_file_type != FST_FILE) && (GLOBALS->loaded_file_type != AE2_FILE)
1665 #if defined(EXTLOAD_SUFFIX)
1666 && (GLOBALS->loaded_file_type != EXTLOAD_FILE)
1667 #endif
1668 ) || (!GLOBALS->fast_tree_sort))
1669 {
1670 GLOBALS->do_hier_compress = 0; /* for now, add more file formats in the future */
1671 }
1672
1673 /* deallocate the symbol hash table */
1674 sym_hash_destroy(GLOBALS);
1675
1676 /* reset/initialize various markers and time values */
1677 for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++) GLOBALS->named_markers[i]=-1; /* reset all named markers */
1678
1679 GLOBALS->tims.last=GLOBALS->max_time;
1680 GLOBALS->tims.end=GLOBALS->tims.last; /* until the configure_event of wavearea */
1681 GLOBALS->tims.first=GLOBALS->tims.start=GLOBALS->tims.laststart=GLOBALS->min_time;
1682 GLOBALS->tims.zoom=GLOBALS->tims.prevzoom=0; /* 1 pixel/ns default */
1683 GLOBALS->tims.marker=GLOBALS->tims.lmbcache=-1; /* uninitialized at first */
1684 GLOBALS->tims.baseline=-1; /* middle button toggle marker */
1685
1686 if((wname)||(vcd_save_handle_cached)||(is_smartsave))
1687 {
1688 int wave_is_compressed;
1689 char *str = NULL;
1690
1691 GLOBALS->is_gtkw_save_file = (!wname) || suffix_check(wname, ".gtkw");
1692
1693 if(vcd_save_handle_cached)
1694 {
1695 wname=vcd_autosave_name;
1696 GLOBALS->do_initial_zoom_fit=1;
1697 }
1698 else
1699 if((!wname) /* && (is_smartsave) */)
1700 {
1701 char *pnt = wave_alloca(strlen(GLOBALS->loaded_file_name) + 1);
1702 char *pnt2;
1703 strcpy(pnt, GLOBALS->loaded_file_name);
1704
1705 if((strlen(pnt)>2)&&(!strcasecmp(pnt+strlen(pnt)-3,".gz")))
1706 {
1707 pnt[strlen(pnt)-3] = 0x00;
1708 }
1709 else if ((strlen(pnt)>3)&&(!strcasecmp(pnt+strlen(pnt)-4,".zip")))
1710 {
1711 pnt[strlen(pnt)-4] = 0x00;
1712 }
1713
1714 pnt2 = pnt + strlen(pnt);
1715 if(pnt != pnt2)
1716 {
1717 do
1718 {
1719 if(*pnt2 == '.')
1720 {
1721 *pnt2 = 0x00;
1722 break;
1723 }
1724 } while(pnt2-- != pnt);
1725 }
1726
1727 wname = malloc_2(strlen(pnt) + 6);
1728 strcpy(wname, pnt);
1729 strcat(wname, ".gtkw");
1730 }
1731
1732 if(((strlen(wname)>2)&&(!strcasecmp(wname+strlen(wname)-3,".gz")))||
1733 ((strlen(wname)>3)&&(!strcasecmp(wname+strlen(wname)-4,".zip"))))
1734 {
1735 int dlen;
1736 dlen=strlen(WAVE_DECOMPRESSOR);
1737 str=wave_alloca(strlen(wname)+dlen+1);
1738 strcpy(str,WAVE_DECOMPRESSOR);
1739 strcpy(str+dlen,wname);
1740 wave=popen(str,"r");
1741 wave_is_compressed=~0;
1742 }
1743 else
1744 {
1745 wave=fopen(wname,"rb");
1746 wave_is_compressed=0;
1747
1748 GLOBALS->filesel_writesave = malloc_2(strlen(wname)+1); /* don't handle compressed files */
1749 strcpy(GLOBALS->filesel_writesave, wname);
1750 }
1751
1752 if(!wave)
1753 {
1754 fprintf(stderr, "** WARNING: Error opening save file '%s', skipping.\n",wname);
1755 }
1756 else
1757 {
1758 char *iline;
1759 int s_ctx_iter;
1760
1761 WAVE_STRACE_ITERATOR(s_ctx_iter)
1762 {
1763 GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter];
1764 GLOBALS->strace_ctx->shadow_encountered_parsewavline = 0;
1765 }
1766
1767 if(GLOBALS->is_lx2)
1768 {
1769 while((iline=fgetmalloc(wave)))
1770 {
1771 parsewavline_lx2(iline, NULL, 0);
1772 free_2(iline);
1773 }
1774
1775 switch(GLOBALS->is_lx2)
1776 {
1777 case LXT2_IS_LXT2: lx2_import_masked(); break;
1778 case LXT2_IS_AET2: ae2_import_masked(); break;
1779 case LXT2_IS_VZT: vzt_import_masked(); break;
1780 case LXT2_IS_VLIST: vcd_import_masked(); break;
1781 case LXT2_IS_FST: fst_import_masked(); break;
1782 case LXT2_IS_FSDB: fsdb_import_masked(); break;
1783 }
1784
1785 if(wave_is_compressed)
1786 {
1787 pclose(wave);
1788 wave=popen(str,"r");
1789 }
1790 else
1791 {
1792 fclose(wave);
1793 wave=fopen(wname,"rb");
1794 }
1795
1796 if(!wave)
1797 {
1798 fprintf(stderr, "** WARNING: Error opening save file '%s', skipping.\n",wname);
1799 EnsureGroupsMatch();
1800 goto savefile_bail;
1801 }
1802 }
1803
1804 read_save_helper_relative_init(wname);
1805 GLOBALS->default_flags=TR_RJUSTIFY;
1806 GLOBALS->default_fpshift = 0;
1807 GLOBALS->shift_timebase_default_for_add=LLDescriptor(0);
1808 GLOBALS->strace_current_window = 0; /* in case there are shadow traces */
1809 GLOBALS->which_t_color = 0;
1810 while((iline=fgetmalloc(wave)))
1811 {
1812 parsewavline(iline, NULL, 0);
1813 GLOBALS->strace_ctx->shadow_encountered_parsewavline |= GLOBALS->strace_ctx->shadow_active;
1814 free_2(iline);
1815 }
1816 GLOBALS->which_t_color = 0;
1817 GLOBALS->default_flags=TR_RJUSTIFY;
1818 GLOBALS->default_fpshift = 0;
1819 GLOBALS->shift_timebase_default_for_add=LLDescriptor(0);
1820
1821 if(wave_is_compressed) pclose(wave); else fclose(wave);
1822
1823 EnsureGroupsMatch();
1824
1825 WAVE_STRACE_ITERATOR(s_ctx_iter)
1826 {
1827 GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter];
1828
1829 if(GLOBALS->strace_ctx->shadow_encountered_parsewavline)
1830 {
1831 GLOBALS->strace_ctx->shadow_encountered_parsewavline = 0;
1832
1833 if(GLOBALS->strace_ctx->shadow_straces)
1834 {
1835 GLOBALS->strace_ctx->shadow_active = 1;
1836
1837 swap_strace_contexts();
1838 strace_maketimetrace(1);
1839 swap_strace_contexts();
1840
1841 GLOBALS->strace_ctx->shadow_active = 0;
1842 }
1843 }
1844 }
1845 }
1846 }
1847
1848 savefile_bail:
1849 GLOBALS->current_translate_file = 0;
1850
1851 if(fast_exit)
1852 {
1853 printf("Exiting early because of --exit request.\n");
1854 exit(0);
1855 }
1856
1857 if ((GLOBALS->loaded_file_type != MISSING_FILE) && (!GLOBALS->zoom_was_explicitly_set) &&
1858 ((GLOBALS->tims.last-GLOBALS->tims.first)<=400)) GLOBALS->do_initial_zoom_fit=1; /* force zoom on small traces */
1859
1860 calczoom(GLOBALS->tims.zoom);
1861
1862 if(!mainwindow_already_built)
1863 {
1864 #ifdef WAVE_USE_XID
1865 if(!GLOBALS->socket_xid)
1866 #endif
1867 {
1868 GLOBALS->mainwindow = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
1869 wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0);
1870
1871 if((GLOBALS->initial_window_width>0)&&(GLOBALS->initial_window_height>0))
1872 {
1873 gtk_window_set_default_size(GTK_WINDOW (GLOBALS->mainwindow), GLOBALS->initial_window_width, GLOBALS->initial_window_height);
1874 }
1875 else
1876 {
1877 gtk_window_set_default_size(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->initial_window_x, GLOBALS->initial_window_y);
1878 }
1879
1880 gtk_signal_connect(GTK_OBJECT(GLOBALS->mainwindow), "delete_event", /* formerly was "destroy" */GTK_SIGNAL_FUNC(file_quit_cmd_callback), "WM destroy");
1881
1882 gtk_widget_show(GLOBALS->mainwindow);
1883 }
1884 #ifdef WAVE_USE_XID
1885 else
1886 {
1887 GLOBALS->mainwindow = gtk_plug_new(GLOBALS->socket_xid);
1888 gtk_widget_show(GLOBALS->mainwindow);
1889
1890 gtk_signal_connect(GTK_OBJECT(GLOBALS->mainwindow), "destroy", /* formerly was "destroy" */GTK_SIGNAL_FUNC(plug_destroy),"Plug destroy");
1891 }
1892 #endif
1893 }
1894
1895 #ifdef MAC_INTEGRATION
1896 dock_pb =
1897 #endif
1898 make_pixmaps(GLOBALS->mainwindow);
1899
1900 #ifdef WAVE_USE_GTK2
1901 if(GLOBALS->use_toolbutton_interface)
1902 {
1903 GtkWidget *tb;
1904 GtkWidget *stock;
1905 GtkStyle *style;
1906 int tb_pos;
1907
1908 if(!mainwindow_already_built)
1909 {
1910 main_vbox = gtk_vbox_new(FALSE, 5);
1911 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
1912 gtk_container_add(GTK_CONTAINER(GLOBALS->mainwindow), main_vbox);
1913 gtk_widget_show(main_vbox);
1914
1915 if(!GLOBALS->disable_menus)
1916 {
1917 #ifdef WAVE_USE_XID
1918 if(GLOBALS->socket_xid) kill_main_menu_accelerators();
1919 #endif
1920
1921 #ifdef WAVE_USE_MLIST_T
1922 menubar = alt_menu_top(GLOBALS->mainwindow);
1923 #else
1924 get_main_menu(GLOBALS->mainwindow, &menubar);
1925 #endif
1926 gtk_widget_show(menubar);
1927
1928 #ifdef MAC_INTEGRATION
1929 {
1930 GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1931 gtk_widget_hide(menubar);
1932 gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(menubar));
1933 gtkosx_application_set_use_quartz_accelerators(theApp, TRUE);
1934 gtkosx_application_ready(theApp);
1935 gtkosx_application_set_dock_icon_pixbuf(theApp, dock_pb);
1936 if(GLOBALS->loaded_file_type == MISSING_FILE)
1937 {
1938 gtkosx_application_attention_request(theApp, INFO_REQUEST);
1939 }
1940
1941 g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(deal_with_finder_open), NULL);
1942 g_signal_connect(theApp, "NSApplicationBlockTermination", G_CALLBACK(deal_with_termination), NULL);
1943 }
1944 #endif
1945
1946 if(GLOBALS->force_toolbars)
1947 {
1948 toolhandle=gtk_handle_box_new();
1949 gtk_widget_show(toolhandle);
1950 gtk_container_add(GTK_CONTAINER(toolhandle), menubar);
1951 gtk_box_pack_start(GTK_BOX(main_vbox), toolhandle, FALSE, TRUE, 0);
1952 }
1953 else
1954 {
1955 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
1956 }
1957 }
1958
1959 whole_table = gtk_table_new (256, 16, FALSE);
1960
1961 tb = gtk_toolbar_new();
1962 top_table = tb; /* export this as our top widget rather than a table */
1963
1964 gtk_toolbar_set_style(GTK_TOOLBAR(tb), GTK_TOOLBAR_ICONS);
1965 tb_pos = 0;
1966
1967 if(GLOBALS->force_toolbars)
1968 {
1969 toolhandle=gtk_handle_box_new();
1970 gtk_widget_show(toolhandle);
1971 gtk_container_add(GTK_CONTAINER(toolhandle), top_table);
1972 }
1973
1974 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
1975 GTK_STOCK_CUT,
1976 "Cut Traces",
1977 NULL,
1978 GTK_SIGNAL_FUNC(menu_cut_traces),
1979 NULL,
1980 tb_pos++);
1981 style = gtk_widget_get_style(stock);
1982 style->xthickness = style->ythickness = 0;
1983 gtk_widget_set_style (stock, style);
1984 gtk_widget_show(stock);
1985
1986 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
1987 GTK_STOCK_COPY,
1988 "Copy Traces",
1989 NULL,
1990 GTK_SIGNAL_FUNC(menu_copy_traces),
1991 NULL,
1992 tb_pos++);
1993 style = gtk_widget_get_style(stock);
1994 style->xthickness = style->ythickness = 0;
1995 gtk_widget_set_style (stock, style);
1996 gtk_widget_show(stock);
1997
1998 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
1999 GTK_STOCK_PASTE,
2000 "Paste Traces",
2001 NULL,
2002 GTK_SIGNAL_FUNC(menu_paste_traces),
2003 NULL,
2004 tb_pos++);
2005 style = gtk_widget_get_style(stock);
2006 style->xthickness = style->ythickness = 0;
2007 gtk_widget_set_style (stock, style);
2008 gtk_widget_show(stock);
2009
2010 gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++);
2011
2012 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2013 GTK_STOCK_ZOOM_FIT,
2014 "Zoom Fit",
2015 NULL,
2016 GTK_SIGNAL_FUNC(service_zoom_fit),
2017 NULL,
2018 tb_pos++);
2019 style = gtk_widget_get_style(stock);
2020 style->xthickness = style->ythickness = 0;
2021 gtk_widget_set_style (stock, style);
2022 gtk_widget_show(stock);
2023
2024 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2025 GTK_STOCK_ZOOM_IN,
2026 "Zoom In",
2027 NULL,
2028 GTK_SIGNAL_FUNC(service_zoom_in),
2029 NULL,
2030 tb_pos++);
2031 style = gtk_widget_get_style(stock);
2032 style->xthickness = style->ythickness = 0;
2033 gtk_widget_set_style (stock, style);
2034 gtk_widget_show(stock);
2035
2036 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2037 GTK_STOCK_ZOOM_OUT,
2038 "Zoom Out",
2039 NULL,
2040 GTK_SIGNAL_FUNC(service_zoom_out),
2041 NULL,
2042 tb_pos++);
2043 style = gtk_widget_get_style(stock);
2044 style->xthickness = style->ythickness = 0;
2045 gtk_widget_set_style (stock, style);
2046 gtk_widget_show(stock);
2047
2048 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2049 GTK_STOCK_UNDO,
2050 "Zoom Undo",
2051 NULL,
2052 GTK_SIGNAL_FUNC(service_zoom_undo),
2053 NULL,
2054 tb_pos++);
2055 style = gtk_widget_get_style(stock);
2056 style->xthickness = style->ythickness = 0;
2057 gtk_widget_set_style (stock, style);
2058 gtk_widget_show(stock);
2059
2060 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2061 GTK_STOCK_GOTO_FIRST,
2062 "Zoom to Start",
2063 NULL,
2064 GTK_SIGNAL_FUNC(service_zoom_left),
2065 NULL,
2066 tb_pos++);
2067 style = gtk_widget_get_style(stock);
2068 style->xthickness = style->ythickness = 0;
2069 gtk_widget_set_style (stock, style);
2070 gtk_widget_show(stock);
2071
2072 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2073 GTK_STOCK_GOTO_LAST,
2074 "Zoom to End",
2075 NULL,
2076 GTK_SIGNAL_FUNC(service_zoom_right),
2077 NULL,
2078 tb_pos++);
2079 style = gtk_widget_get_style(stock);
2080 style->xthickness = style->ythickness = 0;
2081 gtk_widget_set_style (stock, style);
2082 gtk_widget_show(stock);
2083
2084 gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++);
2085
2086 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2087 GTK_STOCK_GO_BACK,
2088 "Find Previous Edge",
2089 NULL,
2090 GTK_SIGNAL_FUNC(service_left_edge),
2091 NULL,
2092 tb_pos++);
2093 style = gtk_widget_get_style(stock);
2094 style->xthickness = style->ythickness = 0;
2095 gtk_widget_set_style (stock, style);
2096 gtk_widget_show(stock);
2097
2098 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2099 GTK_STOCK_GO_FORWARD,
2100 "Find Next Edge",
2101 NULL,
2102 GTK_SIGNAL_FUNC(service_right_edge),
2103 NULL,
2104 tb_pos++);
2105 style = gtk_widget_get_style(stock);
2106 style->xthickness = style->ythickness = 0;
2107 gtk_widget_set_style (stock, style);
2108 gtk_widget_show(stock);
2109
2110 gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++);
2111
2112 entry = create_entry_box();
2113 gtk_widget_show(entry);
2114 gtk_toolbar_insert_widget(GTK_TOOLBAR(tb),
2115 entry,
2116 NULL,
2117 NULL,
2118 tb_pos++);
2119
2120 gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++);
2121
2122 if((GLOBALS->loaded_file_type != DUMPLESS_FILE)&&(!GLOBALS->disable_menus))
2123 {
2124 stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb),
2125 GTK_STOCK_REFRESH,
2126 "Reload",
2127 NULL,
2128 GTK_SIGNAL_FUNC(menu_reload_waveform_marshal),
2129 NULL,
2130 tb_pos++);
2131 style = gtk_widget_get_style(stock);
2132 style->xthickness = style->ythickness = 0;
2133 gtk_widget_set_style (stock, style);
2134 gtk_widget_show(stock);
2135
2136 gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++);
2137 }
2138
2139 timebox = create_time_box();
2140 gtk_widget_show (timebox);
2141 gtk_toolbar_insert_widget(GTK_TOOLBAR(tb),
2142 timebox,
2143 NULL,
2144 NULL,
2145 tb_pos /* ++ */); /* scan-build */
2146
2147 GLOBALS->missing_file_toolbar = tb;
2148 if(GLOBALS->loaded_file_type == MISSING_FILE)
2149 {
2150 gtk_widget_set_sensitive(GLOBALS->missing_file_toolbar, FALSE);
2151 }
2152 } /* of ...if(mainwindow_already_built) */
2153 }
2154 else
2155 #endif
2156 {
2157 if(!mainwindow_already_built)
2158 {
2159 main_vbox = gtk_vbox_new(FALSE, 5);
2160 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
2161 gtk_container_add(GTK_CONTAINER(GLOBALS->mainwindow), main_vbox);
2162 gtk_widget_show(main_vbox);
2163
2164 if(!GLOBALS->disable_menus)
2165 {
2166 #ifdef WAVE_USE_MLIST_T
2167 menubar = alt_menu_top(GLOBALS->mainwindow);
2168 #else
2169 get_main_menu(GLOBALS->mainwindow, &menubar);
2170 #endif
2171 gtk_widget_show(menubar);
2172
2173 #ifdef MAC_INTEGRATION
2174 {
2175 GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
2176 gtk_widget_hide(menubar);
2177 gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(menubar));
2178 gtkosx_application_set_use_quartz_accelerators(theApp, TRUE);
2179 gtkosx_application_ready(theApp);
2180 gtkosx_application_set_dock_icon_pixbuf(theApp, dock_pb);
2181 if(GLOBALS->loaded_file_type == MISSING_FILE)
2182 {
2183 gtkosx_application_attention_request(theApp, INFO_REQUEST);
2184 }
2185
2186 g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(deal_with_finder_open), NULL);
2187 g_signal_connect(theApp, "NSApplicationBlockTermination", G_CALLBACK(deal_with_termination), NULL);
2188 }
2189 #endif
2190
2191 if(GLOBALS->force_toolbars)
2192 {
2193 toolhandle=gtk_handle_box_new();
2194 gtk_widget_show(toolhandle);
2195 gtk_container_add(GTK_CONTAINER(toolhandle), menubar);
2196 gtk_box_pack_start(GTK_BOX(main_vbox), toolhandle, FALSE, TRUE, 0);
2197 }
2198 else
2199 {
2200 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2201 }
2202 }
2203
2204 top_table = gtk_table_new (1, 284, FALSE);
2205
2206 if(GLOBALS->force_toolbars)
2207 {
2208 toolhandle=gtk_handle_box_new();
2209 gtk_widget_show(toolhandle);
2210 gtk_container_add(GTK_CONTAINER(toolhandle), top_table);
2211 }
2212
2213 whole_table = gtk_table_new (256, 16, FALSE);
2214
2215 text1 = create_text ();
2216 gtk_table_attach (GTK_TABLE (top_table), text1, 0, 141, 0, 1,
2217 GTK_FILL,
2218 GTK_FILL | GTK_SHRINK, 0, 0);
2219 gtk_widget_set_usize(GTK_WIDGET(text1), 200, -1);
2220 gtk_widget_show (text1);
2221
2222 dummy1=gtk_label_new("");
2223 gtk_table_attach (GTK_TABLE (top_table), dummy1, 141, 171, 0, 1,
2224 GTK_FILL,
2225 GTK_SHRINK, 0, 0);
2226 gtk_widget_show (dummy1);
2227
2228 zoombuttons = create_zoom_buttons ();
2229 gtk_table_attach (GTK_TABLE (top_table), zoombuttons, 171, 173, 0, 1,
2230 GTK_FILL,
2231 GTK_SHRINK, 0, 0);
2232 gtk_widget_show (zoombuttons);
2233
2234 if(!GLOBALS->use_scrollbar_only)
2235 {
2236 pagebuttons = create_page_buttons ();
2237 gtk_table_attach (GTK_TABLE (top_table), pagebuttons, 173, 174, 0, 1,
2238 GTK_FILL,
2239 GTK_SHRINK, 0, 0);
2240 gtk_widget_show (pagebuttons);
2241 fetchbuttons = create_fetch_buttons ();
2242 gtk_table_attach (GTK_TABLE (top_table), fetchbuttons, 174, 175, 0, 1,
2243 GTK_FILL,
2244 GTK_SHRINK, 0, 0);
2245 gtk_widget_show (fetchbuttons);
2246 discardbuttons = create_discard_buttons ();
2247 gtk_table_attach (GTK_TABLE (top_table), discardbuttons, 175, 176, 0, 1,
2248 GTK_FILL,
2249 GTK_SHRINK, 0, 0);
2250 gtk_widget_show (discardbuttons);
2251
2252 shiftbuttons = create_shift_buttons ();
2253 gtk_table_attach (GTK_TABLE (top_table), shiftbuttons, 176, 177, 0, 1,
2254 GTK_FILL,
2255 GTK_SHRINK, 0, 0);
2256 gtk_widget_show (shiftbuttons);
2257 }
2258
2259 edgebuttons = create_edge_buttons ();
2260 gtk_table_attach (GTK_TABLE (top_table), edgebuttons, 177, 178, 0, 1,
2261 GTK_FILL,
2262 GTK_SHRINK, 0, 0);
2263 gtk_widget_show (edgebuttons);
2264
2265
2266 dummy2=gtk_label_new("");
2267 gtk_table_attach (GTK_TABLE (top_table), dummy2, 178, 215, 0, 1,
2268 GTK_FILL,
2269 GTK_SHRINK, 0, 0);
2270 gtk_widget_show (dummy2);
2271
2272 entry = create_entry_box();
2273 gtk_table_attach (GTK_TABLE (top_table), entry, 215, 216, 0, 1,
2274 GTK_SHRINK,
2275 GTK_SHRINK, 0, 0);
2276 gtk_widget_show(entry);
2277
2278 timebox = create_time_box();
2279 gtk_table_attach (GTK_TABLE (top_table), timebox, 216, 284, 0, 1,
2280 GTK_FILL | GTK_EXPAND,
2281 GTK_FILL | GTK_EXPAND | GTK_SHRINK, 20, 0);
2282 gtk_widget_show (timebox);
2283
2284 if((GLOBALS->loaded_file_type != DUMPLESS_FILE)&&(!GLOBALS->disable_menus))
2285 {
2286 GtkWidget *r_pixmap = gtk_pixmap_new(GLOBALS->redo_pixmap, GLOBALS->redo_mask);
2287 GtkWidget *main_vbox1;
2288 GtkWidget *table, *table2;
2289 GtkWidget *b1, *frame;
2290 GtkTooltips *tooltips;
2291
2292 gtk_widget_show(r_pixmap);
2293
2294 tooltips=gtk_tooltips_new_2();
2295 gtk_tooltips_set_delay_2(tooltips,1500);
2296
2297 table = gtk_table_new (1, 1, FALSE);
2298
2299 main_vbox1 = gtk_vbox_new (FALSE, 1);
2300 gtk_container_border_width (GTK_CONTAINER (main_vbox1), 1);
2301 gtk_container_add (GTK_CONTAINER (table), main_vbox1);
2302
2303 frame = gtk_frame_new ("Reload ");
2304 gtk_box_pack_start (GTK_BOX (main_vbox1), frame, TRUE, TRUE, 0);
2305
2306 gtk_widget_show (frame);
2307 gtk_widget_show (main_vbox1);
2308
2309 table2 = gtk_table_new (2, 1, FALSE);
2310
2311 b1 = gtk_button_new();
2312 gtk_container_add(GTK_CONTAINER(b1), r_pixmap);
2313 gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1,
2314 GTK_FILL | GTK_EXPAND,
2315 GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1);
2316
2317 gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(menu_reload_waveform_marshal), GTK_OBJECT (table2));
2318 gtk_tooltips_set_tip_2(tooltips, b1, "Reload waveform", NULL);
2319 gtk_widget_show(b1);
2320 gtk_container_add (GTK_CONTAINER (frame), table2);
2321 gtk_widget_show(table2);
2322
2323 gtk_table_attach (GTK_TABLE (top_table), table, 284, 285, 0, 1,
2324 0,
2325 0, 2, 0);
2326
2327 gtk_widget_show (table);
2328 }
2329 } /* of ...if(mainwindow_already_built) */
2330 }
2331
2332
2333 GLOBALS->wavewindow = create_wavewindow();
2334 load_all_fonts(); /* must be done before create_signalwindow() */
2335 gtk_widget_show(GLOBALS->wavewindow);
2336 GLOBALS->signalwindow = create_signalwindow();
2337
2338 if(GLOBALS->do_resize_signals)
2339 {
2340 int os;
2341
2342 if(GLOBALS->initial_signal_window_width > GLOBALS->max_signal_name_pixel_width)
2343 {
2344 os=GLOBALS->initial_signal_window_width;
2345 }
2346 else
2347 {
2348 os=GLOBALS->max_signal_name_pixel_width;
2349 }
2350
2351 os=(os<48)?48:os;
2352 gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow),
2353 os+30, -1);
2354 }
2355 else
2356 {
2357 if(GLOBALS->initial_signal_window_width)
2358 {
2359 int os;
2360
2361 os=GLOBALS->initial_signal_window_width;
2362 os=(os<48)?48:os;
2363 gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1);
2364 }
2365 }
2366
2367 gtk_widget_show(GLOBALS->signalwindow);
2368
2369 #if GTK_CHECK_VERSION(2,4,0)
2370 if((!GLOBALS->hide_sst)&&(GLOBALS->loaded_file_type != MISSING_FILE))
2371 {
2372 GLOBALS->toppanedwindow = gtk_hpaned_new();
2373 GLOBALS->sstpane = treeboxframe("SST", GTK_SIGNAL_FUNC(mkmenu_treesearch_cleanup));
2374 GLOBALS->expanderwindow = gtk_expander_new_with_mnemonic("_SST");
2375 gtk_expander_set_expanded(GTK_EXPANDER(GLOBALS->expanderwindow), (GLOBALS->sst_expanded==TRUE));
2376 if(GLOBALS->toppanedwindow_size_cache)
2377 {
2378 gtk_paned_set_position(GTK_PANED(GLOBALS->toppanedwindow), GLOBALS->toppanedwindow_size_cache);
2379 GLOBALS->toppanedwindow_size_cache = 0;
2380 }
2381 gtk_container_add(GTK_CONTAINER(GLOBALS->expanderwindow), GLOBALS->sstpane);
2382 gtk_widget_show(GLOBALS->expanderwindow);
2383 }
2384 #endif
2385
2386 GLOBALS->panedwindow = panedwindow = gtk_hpaned_new();
2387 if(GLOBALS->panedwindow_size_cache)
2388 {
2389 gtk_paned_set_position(GTK_PANED(GLOBALS->panedwindow), GLOBALS->panedwindow_size_cache);
2390 GLOBALS->panedwindow_size_cache = 0;
2391 }
2392
2393 #ifdef HAVE_PANED_PACK
2394 if(GLOBALS->paned_pack_semantics)
2395 {
2396 gtk_paned_pack1(GTK_PANED(panedwindow), GLOBALS->signalwindow, 0, 0);
2397 gtk_paned_pack2(GTK_PANED(panedwindow), GLOBALS->wavewindow, ~0, 0);
2398 }
2399 else
2400 #endif
2401 {
2402 gtk_paned_add1(GTK_PANED(panedwindow), GLOBALS->signalwindow);
2403 gtk_paned_add2(GTK_PANED(panedwindow), GLOBALS->wavewindow);
2404 }
2405
2406 gtk_widget_show(panedwindow);
2407
2408 if(GLOBALS->dnd_sigview)
2409 {
2410 dnd_setup(GLOBALS->dnd_sigview, GLOBALS->signalarea, 1);
2411 }
2412 else
2413 {
2414 dnd_setup(NULL, GLOBALS->signalarea, 1);
2415 }
2416 /* dnd_setup(GLOBALS->signalarea, GLOBALS->signalarea); */
2417 dnd_setup(GLOBALS->signalarea, GLOBALS->wavearea, 1);
2418
2419 #if GTK_CHECK_VERSION(2,4,0)
2420 if((!GLOBALS->hide_sst)&&(GLOBALS->loaded_file_type != MISSING_FILE))
2421 {
2422 gtk_paned_pack1(GTK_PANED(GLOBALS->toppanedwindow), GLOBALS->expanderwindow, 0, 0);
2423 gtk_paned_pack2(GTK_PANED(GLOBALS->toppanedwindow), panedwindow, ~0, 0);
2424 gtk_widget_show(GLOBALS->toppanedwindow);
2425 }
2426 #endif
2427
2428 #if WAVE_USE_GTK2
2429 if(GLOBALS->treeopen_chain_head)
2430 {
2431 struct string_chain_t *t = GLOBALS->treeopen_chain_head;
2432 struct string_chain_t *t2;
2433 while(t)
2434 {
2435 if(GLOBALS->ctree_main)
2436 {
2437 force_open_tree_node(t->str, 0, NULL);
2438 }
2439
2440 t2 = t->next;
2441 if(t->str) free_2(t->str);
2442 free_2(t);
2443 t = t2;
2444 }
2445
2446 GLOBALS->treeopen_chain_head = GLOBALS->treeopen_chain_curr = NULL;
2447 }
2448 #endif
2449
2450 if(!mainwindow_already_built)
2451 {
2452 gtk_widget_show(top_table);
2453 gtk_table_attach (GTK_TABLE (whole_table), GLOBALS->force_toolbars?toolhandle:top_table, 0, 16, 0, 1,
2454 GTK_FILL | GTK_EXPAND,
2455 GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
2456
2457 if(!GLOBALS->do_resize_signals)
2458 {
2459 int dri;
2460 for(dri=0;dri<2;dri++)
2461 {
2462 GLOBALS->signalwindow_width_dirty=1;
2463 MaxSignalLength();
2464 signalarea_configure_event(GLOBALS->signalarea, NULL);
2465 wavearea_configure_event(GLOBALS->wavearea, NULL);
2466 }
2467 }
2468 }
2469
2470
2471 if(!GLOBALS->notebook)
2472 {
2473 GLOBALS->num_notebook_pages = 1;
2474 GLOBALS->this_context_page = 0;
2475 GLOBALS->contexts = calloc(1, sizeof(struct Global **)); /* calloc is deliberate! */ /* scan-build */
2476 *GLOBALS->contexts = calloc(1, sizeof(struct Global *)); /* calloc is deliberate! */ /* scan-build */
2477 (*GLOBALS->contexts)[0] = GLOBALS;
2478
2479 GLOBALS->dead_context = calloc(1, sizeof(struct Global **)); /* calloc is deliberate! */ /* scan-build */
2480 *GLOBALS->dead_context = calloc(1, sizeof(struct Global *)); /* calloc is deliberate! */ /* scan-build */
2481 *(GLOBALS->dead_context)[0] = NULL;
2482
2483 GLOBALS->notebook = gtk_notebook_new();
2484 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->context_tabposition ? GTK_POS_LEFT : GTK_POS_TOP);
2485
2486 gtk_widget_show(GLOBALS->notebook);
2487 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(GLOBALS->notebook), 0); /* hide for first time until next tabs */
2488 gtk_notebook_set_show_border(GTK_NOTEBOOK(GLOBALS->notebook), 0); /* hide for first time until next tabs */
2489 gtk_signal_connect(GTK_OBJECT(GLOBALS->notebook), "switch-page", GTK_SIGNAL_FUNC(switch_page), NULL);
2490 }
2491 else
2492 {
2493 unsigned int ix;
2494
2495 GLOBALS->this_context_page = GLOBALS->num_notebook_pages;
2496 GLOBALS->num_notebook_pages++;
2497 GLOBALS->num_notebook_pages_cumulative++; /* this never decreases, acts as an incrementing flipper id for side tabs */
2498 *GLOBALS->contexts = realloc(*GLOBALS->contexts, GLOBALS->num_notebook_pages * sizeof(struct Global *)); /* realloc is deliberate! */ /* scan-build */
2499 (*GLOBALS->contexts)[GLOBALS->this_context_page] = GLOBALS;
2500
2501 for(ix=0;ix<GLOBALS->num_notebook_pages;ix++)
2502 {
2503 (*GLOBALS->contexts)[ix]->num_notebook_pages = GLOBALS->num_notebook_pages;
2504 (*GLOBALS->contexts)[ix]->num_notebook_pages_cumulative = GLOBALS->num_notebook_pages_cumulative;
2505 (*GLOBALS->contexts)[ix]->dead_context = (*GLOBALS->contexts)[0]->dead_context; /* mirroring this is OK as page 0 always has value! */
2506 }
2507
2508 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(GLOBALS->notebook), ~0); /* then appear */
2509 gtk_notebook_set_show_border(GTK_NOTEBOOK(GLOBALS->notebook), ~0); /* then appear */
2510 gtk_notebook_set_scrollable(GTK_NOTEBOOK(GLOBALS->notebook), ~0);
2511 }
2512
2513 if(!GLOBALS->context_tabposition)
2514 {
2515 gtk_notebook_append_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->toppanedwindow ? GLOBALS->toppanedwindow : panedwindow,
2516 gtk_label_new(GLOBALS->loaded_file_name));
2517 }
2518 else
2519 {
2520 char buf[40];
2521
2522 sprintf(buf, "%d", GLOBALS->num_notebook_pages_cumulative);
2523
2524 gtk_notebook_append_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->toppanedwindow ? GLOBALS->toppanedwindow : panedwindow,
2525 gtk_label_new(buf));
2526 }
2527
2528 if(mainwindow_already_built)
2529 {
2530 gtk_notebook_set_current_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->this_context_page);
2531 return(0);
2532 }
2533
2534 gtk_table_attach (GTK_TABLE (whole_table), GLOBALS->notebook, 0, 16, 1, 256,
2535 GTK_FILL | GTK_EXPAND,
2536 GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0);
2537 gtk_widget_show(whole_table);
2538 gtk_container_add (GTK_CONTAINER (main_vbox), whole_table);
2539
2540 if(GLOBALS->tims.marker != -1)
2541 {
2542 if(GLOBALS->tims.marker<GLOBALS->tims.first) GLOBALS->tims.marker=GLOBALS->tims.first;
2543 }
2544 update_markertime(GLOBALS->tims.marker);
2545
2546 set_window_xypos(GLOBALS->initial_window_xpos, GLOBALS->initial_window_ypos);
2547 GLOBALS->xy_ignore_main_c_1 = 1;
2548
2549 if(GLOBALS->logfile)
2550 {
2551 struct logfile_chain *lprev;
2552 char buf[50];
2553 int which = 1;
2554 while(GLOBALS->logfile)
2555 {
2556 sprintf(buf, "Logfile viewer [%d]", which++);
2557 logbox(buf, 480, GLOBALS->logfile->name);
2558 lprev = GLOBALS->logfile;
2559 GLOBALS->logfile = GLOBALS->logfile->next;
2560 free_2(lprev->name);
2561 free_2(lprev);
2562 }
2563 }
2564
2565 activate_stems_reader(GLOBALS->stems_name);
2566
2567 gtk_events_pending_gtk_main_iteration();
2568
2569 if(1) /* here in order to calculate window manager delta if present... window is completely rendered by here */
2570 {
2571 int dummy_x, dummy_y;
2572 get_window_xypos(&dummy_x, &dummy_y);
2573 }
2574
2575 init_busy();
2576
2577 if(scriptfile
2578 #if defined(HAVE_LIBTCL)
2579 && GLOBALS->interp
2580 #endif
2581 )
2582 {
2583 execute_script(scriptfile, 1); /* deallocate the name in the script because context might swap out from under us! */
2584 scriptfile=NULL;
2585 }
2586
2587 #if defined(WAVE_HAVE_GCONF) || defined(WAVE_HAVE_GSETTINGS)
2588 if(GLOBALS->loaded_file_type != MISSING_FILE)
2589 {
2590 if(!chdir_cache) { wave_gconf_client_set_string("/current/pwd", getenv("PWD")); }
2591 wave_gconf_client_set_string("/current/dumpfile", GLOBALS->optimize_vcd ? GLOBALS->unoptimized_vcd_file_name : GLOBALS->loaded_file_name);
2592 wave_gconf_client_set_string("/current/optimized_vcd", GLOBALS->optimize_vcd ? "1" : "0");
2593 wave_gconf_client_set_string("/current/savefile", GLOBALS->filesel_writesave);
2594 }
2595 #endif
2596
2597 #if !defined _MSC_VER
2598 if(GLOBALS->dual_attach_id_main_c_1)
2599 {
2600 fprintf(stderr, "GTKWAVE | Attaching %08X as dual head session %d\n", GLOBALS->dual_attach_id_main_c_1, GLOBALS->dual_id);
2601
2602 #ifdef __MINGW32__
2603 {
2604 HANDLE hMapFile;
2605 char mapName[257];
2606
2607 sprintf(mapName, "twinwave%d", GLOBALS->dual_attach_id_main_c_1);
2608 hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapName);
2609 if(hMapFile == NULL)
2610 {
2611 fprintf(stderr, "Could not attach shared memory map name '%s', exiting.\n", mapName);
2612 exit(255);
2613 }
2614 GLOBALS->dual_ctx = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 2 * sizeof(struct gtkwave_dual_ipc_t));
2615 if(GLOBALS->dual_ctx == NULL)
2616 {
2617 fprintf(stderr, "Could not map view of file '%s', exiting.\n", mapName);
2618 exit(255);
2619 }
2620 }
2621 #else
2622 GLOBALS->dual_ctx = shmat(GLOBALS->dual_attach_id_main_c_1, NULL, 0);
2623 #endif
2624 if(GLOBALS->dual_ctx)
2625 {
2626 if(memcmp(GLOBALS->dual_ctx[GLOBALS->dual_id].matchword, DUAL_MATCHWORD, 4))
2627 {
2628 fprintf(stderr, "Not a valid shared memory ID for dual head operation, exiting.\n");
2629 exit(255);
2630 }
2631
2632 GLOBALS->dual_ctx[GLOBALS->dual_id].viewer_is_initialized = 1;
2633 for(;;)
2634 {
2635 GtkAdjustment *hadj;
2636 TimeType pageinc, gt;
2637 #ifndef __MINGW32__
2638 struct timeval tv;
2639 #endif
2640 if(GLOBALS->dual_ctx[1-GLOBALS->dual_id].use_new_times)
2641 {
2642 GLOBALS->dual_race_lock = 1;
2643
2644 gt = GLOBALS->dual_ctx[GLOBALS->dual_id].left_margin_time = GLOBALS->dual_ctx[1-GLOBALS->dual_id].left_margin_time;
2645
2646 GLOBALS->dual_ctx[GLOBALS->dual_id].marker = GLOBALS->dual_ctx[1-GLOBALS->dual_id].marker;
2647 GLOBALS->dual_ctx[GLOBALS->dual_id].baseline = GLOBALS->dual_ctx[1-GLOBALS->dual_id].baseline;
2648 GLOBALS->dual_ctx[GLOBALS->dual_id].zoom = GLOBALS->dual_ctx[1-GLOBALS->dual_id].zoom;
2649 GLOBALS->dual_ctx[1-GLOBALS->dual_id].use_new_times = 0;
2650 GLOBALS->dual_ctx[GLOBALS->dual_id].use_new_times = 0;
2651
2652 if(GLOBALS->dual_ctx[GLOBALS->dual_id].baseline != GLOBALS->tims.baseline)
2653 {
2654 if((GLOBALS->tims.marker != -1) && (GLOBALS->dual_ctx[GLOBALS->dual_id].marker == -1))
2655 {
2656 Trptr t;
2657
2658 for(t=GLOBALS->traces.first;t;t=t->t_next)
2659 {
2660 if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; }
2661 }
2662
2663 for(t=GLOBALS->traces.buffer;t;t=t->t_next)
2664 {
2665 if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; }
2666 }
2667 }
2668
2669 GLOBALS->tims.marker = GLOBALS->dual_ctx[GLOBALS->dual_id].marker;
2670 GLOBALS->tims.baseline = GLOBALS->dual_ctx[GLOBALS->dual_id].baseline;
2671 update_basetime(GLOBALS->tims.baseline);
2672 update_markertime(GLOBALS->tims.marker);
2673 GLOBALS->signalwindow_width_dirty = 1;
2674 button_press_release_common();
2675 }
2676 else
2677 if(GLOBALS->dual_ctx[GLOBALS->dual_id].marker != GLOBALS->tims.marker)
2678 {
2679 if((GLOBALS->tims.marker != -1) && (GLOBALS->dual_ctx[GLOBALS->dual_id].marker == -1))
2680 {
2681 Trptr t;
2682
2683 for(t=GLOBALS->traces.first;t;t=t->t_next)
2684 {
2685 if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; }
2686 }
2687
2688 for(t=GLOBALS->traces.buffer;t;t=t->t_next)
2689 {
2690 if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; }
2691 }
2692 }
2693
2694 GLOBALS->tims.marker = GLOBALS->dual_ctx[GLOBALS->dual_id].marker;
2695 update_markertime(GLOBALS->tims.marker);
2696 GLOBALS->signalwindow_width_dirty = 1;
2697 button_press_release_common();
2698 }
2699
2700 GLOBALS->tims.prevzoom=GLOBALS->tims.zoom;
2701 GLOBALS->tims.zoom=GLOBALS->dual_ctx[GLOBALS->dual_id].zoom;
2702
2703 if(gt<GLOBALS->tims.first) gt=GLOBALS->tims.first;
2704 else if(gt>GLOBALS->tims.last) gt=GLOBALS->tims.last;
2705
2706 hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider);
2707 hadj->value=gt;
2708
2709 pageinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
2710 if(gt<(GLOBALS->tims.last-pageinc+1))
2711 GLOBALS->tims.timecache=gt;
2712 else
2713 {
2714 GLOBALS->tims.timecache=GLOBALS->tims.last-pageinc+1;
2715 if(GLOBALS->tims.timecache<GLOBALS->tims.first) GLOBALS->tims.timecache=GLOBALS->tims.first;
2716 }
2717
2718 time_update();
2719 }
2720
2721 if(is_interactive)
2722 {
2723 kick_partial_vcd();
2724 }
2725 else
2726 {
2727 while (gtk_events_pending()) gtk_main_iteration();
2728 }
2729
2730 GLOBALS->dual_race_lock = 0;
2731
2732 #ifdef __MINGW32__
2733 Sleep(1000 / 25);
2734 #else
2735 tv.tv_sec = 0;
2736 tv.tv_usec = 1000000 / 25;
2737 select(0, NULL, NULL, NULL, &tv);
2738 #endif
2739 }
2740 }
2741 else
2742 {
2743 fprintf(stderr, "Could not attach to %08X, exiting.\n", GLOBALS->dual_attach_id_main_c_1);
2744 exit(255);
2745 }
2746 }
2747 else
2748 #endif
2749 if(is_interactive)
2750 {
2751 for(;;) { kick_partial_vcd(); }
2752 }
2753 else
2754 {
2755 #if defined(HAVE_LIBTCL)
2756 if(is_wish)
2757 {
2758 char* argv_mod[1];
2759
2760 set_globals_interp(argv[0], 1);
2761 addPidToExecutableName(1, argv, argv_mod);
2762 Tk_MainEx(1, argv_mod, gtkwaveInterpreterInit, GLOBALS->interp);
2763
2764 /* note: for(kk=0;kk<argc;kk++) { free_2(argv_mod[kk]); } can't really be done here, doesn't matter anyway as context free will get it */
2765 }
2766 else
2767 {
2768 gtk_main();
2769 }
2770 #else
2771 gtk_main();
2772 #endif
2773 }
2774
2775 #ifdef MAC_INTEGRATION
2776 exit(0); /* gtk_target_list_find crashes in OSX/Quartz is return instead of exit */
2777 #else
2778 return(0);
2779 #endif
2780 }
2781
2782 void
get_window_size(int * x,int * y)2783 get_window_size (int *x, int *y)
2784 {
2785 #ifdef WAVE_USE_GTK2
2786 gtk_window_get_size (GTK_WINDOW (GLOBALS->mainwindow), x, y);
2787 #else
2788 *x = GLOBALS->initial_window_x;
2789 *y = GLOBALS->initial_window_y;
2790 #endif
2791 }
2792
2793 void
set_window_size(int x,int y)2794 set_window_size (int x, int y)
2795 {
2796 if(GLOBALS->block_xy_update)
2797 {
2798 return;
2799 }
2800
2801 if (GLOBALS->mainwindow == NULL)
2802 {
2803 GLOBALS->initial_window_width = x;
2804 GLOBALS->initial_window_height = y;
2805 }
2806 else
2807 {
2808 #ifdef WAVE_USE_XID
2809 if(!GLOBALS->socket_xid)
2810 #endif
2811 {
2812 #ifdef MAC_INTEGRATION
2813 gtk_window_resize(GTK_WINDOW (GLOBALS->mainwindow), x, y);
2814 #else
2815 gtk_window_set_default_size(GTK_WINDOW (GLOBALS->mainwindow), x, y);
2816 #endif
2817 }
2818 }
2819 }
2820
2821
2822 void
get_window_xypos(int * root_x,int * root_y)2823 get_window_xypos(int *root_x, int *root_y)
2824 {
2825 if(!GLOBALS->mainwindow) return;
2826
2827 #ifdef WAVE_USE_GTK2
2828 gtk_window_get_position(GTK_WINDOW(GLOBALS->mainwindow), root_x, root_y);
2829
2830 if(!GLOBALS->initial_window_get_valid)
2831 {
2832 if((GLOBALS->mainwindow->window))
2833 {
2834 GLOBALS->initial_window_get_valid = 1;
2835 GLOBALS->initial_window_xpos_get = *root_x;
2836 GLOBALS->initial_window_ypos_get = *root_y;
2837
2838 GLOBALS->xpos_delta = GLOBALS->initial_window_xpos_set - GLOBALS->initial_window_xpos_get;
2839 GLOBALS->ypos_delta = GLOBALS->initial_window_ypos_set - GLOBALS->initial_window_ypos_get;
2840 }
2841 }
2842 #else
2843 *root_x = *root_y = -1;
2844 #endif
2845 }
2846
2847 void
set_window_xypos(int root_x,int root_y)2848 set_window_xypos(int root_x, int root_y)
2849 {
2850 #ifdef MAC_INTEGRATION
2851 if(GLOBALS->num_notebook_pages > 1) return;
2852 #else
2853 if(GLOBALS->xy_ignore_main_c_1) return;
2854 #endif
2855
2856 #if !defined __MINGW32__ && !defined _MSC_VER
2857 GLOBALS->initial_window_xpos = root_x;
2858 GLOBALS->initial_window_ypos = root_y;
2859
2860 if(!GLOBALS->mainwindow) return;
2861 if((GLOBALS->initial_window_xpos>=0)||(GLOBALS->initial_window_ypos>=0))
2862 {
2863 if (GLOBALS->initial_window_xpos<0) { GLOBALS->initial_window_xpos = 0; }
2864 if (GLOBALS->initial_window_ypos<0) { GLOBALS->initial_window_ypos = 0; }
2865 #ifdef WAVE_USE_GTK2
2866 gtk_window_move(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->initial_window_xpos, GLOBALS->initial_window_ypos);
2867 #else
2868 gtk_window_reposition(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->initial_window_xpos, GLOBALS->initial_window_ypos);
2869 #endif
2870
2871 if(!GLOBALS->initial_window_set_valid)
2872 {
2873 GLOBALS->initial_window_set_valid = 1;
2874 GLOBALS->initial_window_xpos_set = GLOBALS->initial_window_xpos;
2875 GLOBALS->initial_window_ypos_set = GLOBALS->initial_window_ypos;
2876 }
2877 }
2878 #endif
2879 }
2880
2881
2882 /*
2883 * bring up stems browser
2884 */
2885 #if !defined _MSC_VER
stems_are_active(void)2886 int stems_are_active(void)
2887 {
2888 #ifdef __MINGW32__
2889 if(GLOBALS->anno_ctx && GLOBALS->anno_ctx->browser_process)
2890 {
2891 /* nothing */
2892 return(1);
2893 }
2894 #else
2895 if(GLOBALS->anno_ctx && GLOBALS->anno_ctx->browser_process)
2896 {
2897 int mystat =0;
2898 pid_t pid = waitpid(GLOBALS->anno_ctx->browser_process, &mystat, WNOHANG);
2899 if(!pid)
2900 {
2901 status_text("Stems reader already active.\n");
2902 return(1);
2903 }
2904 else
2905 {
2906 shmdt((void *)GLOBALS->anno_ctx);
2907 GLOBALS->anno_ctx = NULL;
2908 }
2909 }
2910 #endif
2911 return(0);
2912 }
2913 #endif
2914
2915
activate_stems_reader(char * stems_name)2916 void activate_stems_reader(char *stems_name)
2917 {
2918 #if !defined _MSC_VER
2919
2920 #ifdef __CYGWIN__
2921 /* ajb : ok static as this is a one-time warning message... */
2922 static int cyg_called = 0;
2923 #endif
2924
2925 if(!stems_name) return;
2926
2927 #ifdef __CYGWIN__
2928 if(GLOBALS->stems_type != WAVE_ANNO_NONE)
2929 {
2930 if(!cyg_called)
2931 {
2932 char *cygserver_env = getenv("CYGWIN");
2933 gboolean found = cygserver_env && (strstr(cygserver_env, "server") != NULL);
2934
2935 if(!found)
2936 {
2937 fprintf(stderr, "GTKWAVE | =================================================================\n");
2938 fprintf(stderr, "GTKWAVE | If the viewer crashes with a Bad system call error,\n");
2939 fprintf(stderr, "GTKWAVE | make sure that Cygserver is enabled.\n");
2940 fprintf(stderr, "GTKWAVE | The Cygserver services are used by Cygwin applications only\n");
2941 fprintf(stderr, "GTKWAVE | if you set the environment variable CYGWIN to contain the\n");
2942 fprintf(stderr, "GTKWAVE | string \"server\". You must do this before starting this program.\n");
2943 fprintf(stderr, "GTKWAVE |\n");
2944 fprintf(stderr, "GTKWAVE | If this still does not work, you may have to enable the cygserver\n");
2945 fprintf(stderr, "GTKWAVE | by entering \"cygserver-config\" and answering \"yes\" followed by\n");
2946 fprintf(stderr, "GTKWAVE | \"net start cygserver\".\n");
2947 fprintf(stderr, "GTKWAVE | =================================================================\n");
2948 }
2949 cyg_called = 1;
2950 }
2951 }
2952 #endif
2953
2954 if(GLOBALS->stems_type != WAVE_ANNO_NONE)
2955 {
2956 #ifdef __MINGW32__
2957 int shmid = getpid();
2958 char mapName[257];
2959 HANDLE hMapFile;
2960 STARTUPINFO si;
2961 PROCESS_INFORMATION pi;
2962 BOOL rc;
2963
2964 memset(&si, 0, sizeof(STARTUPINFO));
2965 memset(&pi, 0, sizeof(PROCESS_INFORMATION));
2966 si.cb = sizeof(si);
2967
2968 sprintf(mapName, "rtlbrowse%d", shmid);
2969 hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(struct gtkwave_annotate_ipc_t), mapName);
2970 if(hMapFile != NULL)
2971 {
2972 GLOBALS->anno_ctx = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(struct gtkwave_annotate_ipc_t));
2973 if(GLOBALS->anno_ctx)
2974 {
2975 char mylist[257];
2976
2977 sprintf(mylist, "rtlbrowse.exe %08x", shmid);
2978
2979 memset(GLOBALS->anno_ctx, 0, sizeof(struct gtkwave_annotate_ipc_t));
2980
2981 memcpy(GLOBALS->anno_ctx->matchword, WAVE_MATCHWORD, 4);
2982 GLOBALS->anno_ctx->aet_type = GLOBALS->stems_type;
2983 strcpy(GLOBALS->anno_ctx->aet_name, GLOBALS->aet_name);
2984 strcpy(GLOBALS->anno_ctx->stems_name, stems_name);
2985
2986 update_markertime(GLOBALS->tims.marker);
2987
2988 rc = CreateProcess(
2989 "rtlbrowse.exe",
2990 mylist,
2991 NULL,
2992 NULL,
2993 FALSE,
2994 0,
2995 NULL,
2996 NULL,
2997 &si,
2998 &pi);
2999
3000 if(!rc)
3001 {
3002 UnmapViewOfFile(GLOBALS->anno_ctx);
3003 CloseHandle(hMapFile);
3004 GLOBALS->anno_ctx = NULL;
3005 GLOBALS->stems_type = WAVE_ANNO_NONE;
3006 }
3007 else
3008 {
3009 GLOBALS->anno_ctx->browser_process = pi.hProcess;
3010 }
3011 }
3012 else
3013 {
3014 CloseHandle(hMapFile);
3015 GLOBALS->stems_type = WAVE_ANNO_NONE;
3016 }
3017 }
3018 #else
3019 int shmid = shmget(0, sizeof(struct gtkwave_annotate_ipc_t), IPC_CREAT | 0600 );
3020 if(shmid >=0)
3021 {
3022 struct shmid_ds ds;
3023
3024 GLOBALS->anno_ctx = shmat(shmid, NULL, 0);
3025 if(GLOBALS->anno_ctx)
3026 {
3027 pid_t pid;
3028
3029 memset(GLOBALS->anno_ctx, 0, sizeof(struct gtkwave_annotate_ipc_t));
3030
3031 memcpy(GLOBALS->anno_ctx->matchword, WAVE_MATCHWORD, 4);
3032 GLOBALS->anno_ctx->aet_type = GLOBALS->stems_type;
3033 strcpy(GLOBALS->anno_ctx->aet_name, GLOBALS->aet_name);
3034 strcpy(GLOBALS->anno_ctx->stems_name, stems_name);
3035
3036 GLOBALS->anno_ctx->gtkwave_process = getpid();
3037 update_markertime(GLOBALS->tims.marker);
3038
3039 #ifdef __linux__
3040 shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */
3041 #endif
3042
3043 pid=fork();
3044
3045 if(((int)pid) < 0)
3046 {
3047 /* can't do anything about this */
3048 }
3049 else
3050 {
3051 if(pid) /* parent==original server_pid */
3052 {
3053 #ifndef __CYGWIN__
3054 static int kill_installed = 0;
3055
3056 if(!kill_installed)
3057 {
3058 kill_installed = 1;
3059 atexit(kill_stems_browser);
3060 }
3061 #endif
3062 GLOBALS->anno_ctx->browser_process = pid;
3063 #ifndef __linux__
3064 sleep(2);
3065 shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */
3066 #endif
3067 }
3068 else
3069 {
3070 char buf[64];
3071 #ifdef MAC_INTEGRATION
3072 const gchar *p = gtkosx_application_get_executable_path();
3073 #endif
3074 sprintf(buf, "%08x", shmid);
3075
3076 #ifdef MAC_INTEGRATION
3077 if(p && strstr(p, "Contents/"))
3078 {
3079 const char *xec = "../Resources/bin/rtlbrowse";
3080 char *res = strdup_2(p);
3081 char *slsh = strrchr(res, '/');
3082 if(slsh)
3083 {
3084 *(slsh+1) = 0;
3085 res = realloc_2(res, strlen(res) + strlen(xec) + 1);
3086 strcat(res, xec);
3087 execlp(res, "rtlbrowse", buf, NULL);
3088 fprintf(stderr, "GTKWAVE | Could not find '%s' in .app!\n", res);
3089 free_2(res);
3090 }
3091 }
3092 #endif
3093 execlp("rtlbrowse", "rtlbrowse", buf, NULL);
3094 fprintf(stderr, "GTKWAVE | Could not find rtlbrowse executable, exiting!\n");
3095 exit(255); /* control never gets here if successful */
3096 }
3097 }
3098 }
3099 else
3100 {
3101 shmctl(shmid, IPC_RMID, &ds); /* actually destroy */
3102 GLOBALS->stems_type = WAVE_ANNO_NONE;
3103 }
3104 }
3105 #endif
3106 }
3107 else
3108 {
3109 fprintf(stderr, "GTKWAVE | Unsupported dumpfile type for rtlbrowse.\n");
3110 }
3111 #endif
3112 }
3113
3114
3115 #if !defined _MSC_VER && !defined __MINGW32__
optimize_vcd_file(void)3116 void optimize_vcd_file(void) {
3117 if(!strcmp("-vcd", GLOBALS->unoptimized_vcd_file_name)) {
3118 #ifdef __CYGWIN__
3119 char *buf = strdup_2("vcd2fst -- - vcd.fst");
3120 system(buf);
3121 free_2(buf);
3122 GLOBALS->loaded_file_name = strdup_2("vcd.fst");
3123 GLOBALS->is_optimized_stdin_vcd = 1;
3124 #else
3125 pid_t pid;
3126 char *buf = malloc_2(strlen("vcd") + 4 + 1);
3127 sprintf(buf, "%s.fst", "vcd");
3128 pid = fork();
3129 if(((int)pid) < 0) {
3130 /* can't do anything about this */
3131 }
3132 else {
3133 if(pid) {
3134 int mystat;
3135 int rc = waitpid(pid, &mystat, 0);
3136 if(rc > 0) {
3137 free_2(GLOBALS->loaded_file_name);
3138 GLOBALS->loaded_file_name = buf;
3139 GLOBALS->is_optimized_stdin_vcd = 1;
3140 }
3141 }
3142 else {
3143 execlp("vcd2fst", "vcd2fst", "--", "-", buf, NULL);
3144 exit(255);
3145 }
3146 }
3147 #endif
3148 }
3149 else {
3150 #ifdef __CYGWIN__
3151 char *buf = malloc_2(9 + (strlen(GLOBALS->unoptimized_vcd_file_name) + 1) + (strlen(GLOBALS->unoptimized_vcd_file_name) + 4 + 1));
3152 sprintf(buf, "vcd2fst %s %s.fst", GLOBALS->unoptimized_vcd_file_name, GLOBALS->unoptimized_vcd_file_name);
3153 system(buf);
3154 free_2(buf);
3155 buf = malloc_2(strlen(GLOBALS->unoptimized_vcd_file_name) + 4 + 1);
3156 sprintf(buf, "%s.fst", GLOBALS->unoptimized_vcd_file_name);
3157 GLOBALS->loaded_file_name = buf;
3158 #else
3159 pid_t pid;
3160 char *buf = malloc_2(strlen(GLOBALS->unoptimized_vcd_file_name) + 4 + 1);
3161 sprintf(buf, "%s.fst", GLOBALS->unoptimized_vcd_file_name);
3162 pid = fork();
3163 if(((int)pid) < 0) {
3164 /* can't do anything about this */
3165 }
3166 else {
3167 if(pid) {
3168 int mystat;
3169 int rc = waitpid(pid, &mystat, 0);
3170 if(rc > 0) {
3171 free_2(GLOBALS->loaded_file_name);
3172 GLOBALS->loaded_file_name = buf;
3173 }
3174 }
3175 else {
3176 #ifdef MAC_INTEGRATION
3177 const gchar *p = gtkosx_application_get_executable_path();
3178 if(p && strstr(p, "Contents/"))
3179 {
3180 const char *xec = "../Resources/bin/vcd2fst";
3181 char *res = strdup_2(p);
3182 char *slsh = strrchr(res, '/');
3183 if(slsh)
3184 {
3185 *(slsh+1) = 0;
3186 res = realloc_2(res, strlen(res) + strlen(xec) + 1);
3187 strcat(res, xec);
3188 execlp(res, "vcd2fst", GLOBALS->unoptimized_vcd_file_name, buf, NULL);
3189 fprintf(stderr, "GTKWAVE | Could not find '%s' in .app!\n", res);
3190 free_2(res);
3191 }
3192 }
3193 #endif
3194 execlp("vcd2fst", "vcd2fst", GLOBALS->unoptimized_vcd_file_name, buf, NULL);
3195 fprintf(stderr, "GTKWAVE | Could not find vcd2fst executable, exiting!\n");
3196 exit(255);
3197 }
3198 }
3199 #endif
3200 }
3201 }
3202 #endif
3203