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 /*
11  * note: any functions which add/remove traces must first look at
12  * the global "straces".  if it's active, complain to the status
13  * window and don't do the op. same for "dnd_state".
14  */
15 
16 #include "globals.h"
17 #include <config.h>
18 #include <string.h>
19 #include "gtk12compat.h"
20 #include "main.h"
21 #include "menu.h"
22 #include "vcd.h"
23 #include "vcd_saver.h"
24 #include "translate.h"
25 #include "ptranslate.h"
26 #include "ttranslate.h"
27 #include "lx2.h"
28 #include "hierpack.h"
29 #include "tcl_helper.h"
30 #include <cocoa_misc.h>
31 #include <assert.h>
32 
33 #if !defined __MINGW32__ && !defined _MSC_VER
34 #include <unistd.h>
35 #include <sys/mman.h>
36 #else
37 #include <windows.h>
38 #include <io.h>
39 #endif
40 
41 #ifdef _MSC_VER
42 #define strcasecmp _stricmp
43 #endif
44 
45 #undef WAVE_USE_MENU_BLACKOUTS
46 
47 static gtkwave_mlist_t menu_items[WV_MENU_NUMITEMS];
48 #ifdef WAVE_USE_MLIST_T
49 static GtkWidget **menu_wlist=NULL;
50 #endif
51 
52 extern char *gtkwave_argv0_cached; /* for new window */
53 
54 /* marshals for handling menu items vs button pressed items */
55 
service_left_edge_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)56 static void service_left_edge_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
57 {
58 (void)callback_action;
59 
60 service_left_edge(widget, null_data);
61 }
62 
service_right_edge_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)63 static void service_right_edge_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
64 {
65 (void)callback_action;
66 
67 service_right_edge(widget, null_data);
68 }
69 
service_zoom_in_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)70 static void service_zoom_in_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
71 {
72 (void)callback_action;
73 
74 service_zoom_in(widget, null_data);
75 }
76 
service_zoom_out_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)77 static void service_zoom_out_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
78 {
79 (void)callback_action;
80 
81 service_zoom_out(widget, null_data);
82 }
83 
service_zoom_full_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)84 static void service_zoom_full_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
85 {
86 (void)callback_action;
87 
88 service_zoom_full(widget, null_data);
89 }
90 
service_zoom_fit_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)91 static void service_zoom_fit_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
92 {
93 (void)callback_action;
94 
95 service_zoom_fit(widget, null_data);
96 }
97 
service_zoom_left_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)98 static void service_zoom_left_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
99 {
100 (void)callback_action;
101 
102 service_zoom_left(widget, null_data);
103 }
104 
service_zoom_right_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)105 static void service_zoom_right_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
106 {
107 (void)callback_action;
108 
109 service_zoom_right(widget, null_data);
110 }
111 
service_zoom_undo_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)112 static void service_zoom_undo_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
113 {
114 (void)callback_action;
115 
116 service_zoom_undo(widget, null_data);
117 }
118 
fetch_right_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)119 static void fetch_right_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
120 {
121 (void)callback_action;
122 
123 fetch_right(widget, null_data);
124 }
125 
fetch_left_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)126 static void fetch_left_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
127 {
128 (void)callback_action;
129 
130 fetch_left(widget, null_data);
131 }
132 
discard_right_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)133 static void discard_right_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
134 {
135 (void)callback_action;
136 
137 discard_right(widget, null_data);
138 }
139 
discard_left_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)140 static void discard_left_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
141 {
142 (void)callback_action;
143 
144 discard_left(widget, null_data);
145 }
146 
service_right_shift_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)147 static void service_right_shift_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
148 {
149 (void)callback_action;
150 
151 service_right_shift(widget, null_data);
152 }
153 
service_left_shift_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)154 static void service_left_shift_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
155 {
156 (void)callback_action;
157 
158 service_left_shift(widget, null_data);
159 }
160 
service_right_page_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)161 static void service_right_page_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
162 {
163 (void)callback_action;
164 
165 service_right_page(widget, null_data);
166 }
167 
service_left_page_marshal(gpointer null_data,guint callback_action,GtkWidget * widget)168 static void service_left_page_marshal(gpointer null_data, guint callback_action, GtkWidget *widget)
169 {
170 (void)callback_action;
171 
172 service_left_page(widget, null_data);
173 }
174 
175 /* ruler */
176 
menu_def_ruler(gpointer null_data,guint callback_action,GtkWidget * widget)177 static void menu_def_ruler(gpointer null_data, guint callback_action, GtkWidget *widget)
178 {
179 (void)null_data;
180 (void)callback_action;
181 (void)widget;
182 
183 if(GLOBALS->helpbox_is_active)
184         {
185         help_text_bold("\n\nDefine Time Ruler Marks");
186         help_text(
187                 " changes the ruler markings such that the Baseline marker"
188 		" defines the origin and the Primary marker distance from"
189 		" the Baseline marker defines the period. If either the"
190 		" Baseline marker or Primary marker are not present, the"
191 		" default ruler markers are used. If the Baseline marker"
192 		" and Primary marker have the same value, the default ruler"
193 		" markers are used."
194         );
195 
196 	return;
197 	}
198 
199 if((GLOBALS->tims.baseline>=0) && (GLOBALS->tims.marker>=0))
200 	{
201 	GLOBALS->ruler_origin = GLOBALS->tims.baseline;
202 	GLOBALS->ruler_step = GLOBALS->tims.baseline - GLOBALS->tims.marker;
203 	if(GLOBALS->ruler_step < 0) GLOBALS->ruler_step = -GLOBALS->ruler_step;
204 	}
205 	else
206 	{
207 	GLOBALS->ruler_origin = GLOBALS->ruler_step = LLDescriptor(0);
208 	}
209 
210 GLOBALS->signalwindow_width_dirty=1;
211 MaxSignalLength();
212 signalarea_configure_event(GLOBALS->signalarea, NULL);
213 wavearea_configure_event(GLOBALS->wavearea, NULL);
214 }
215 
216 
217 /* marker locking */
218 
lock_marker_left(gpointer null_data,guint callback_action,GtkWidget * widget)219 static void lock_marker_left(gpointer null_data, guint callback_action, GtkWidget *widget)
220 {
221 (void)null_data;
222 (void)callback_action;
223 (void)widget;
224 
225 int ent_idx = GLOBALS->named_marker_lock_idx;
226 int i;
227 int success = 0;
228 
229 if(GLOBALS->helpbox_is_active)
230         {
231         help_text_bold("\n\nLock to Lesser Named Marker");
232         help_text(
233                 " locks the primary marker to a named marker."
234 		" If no named marker is currently selected, the last defined one is used,"
235 		" otherwise the marker selected will be one lower in the alphabet, scrolling"
236 		" through to the end of the alphabet on wrap."
237 		" If no named marker exists, one is dropped down for 'A' and the primary"
238 		" marker is locked to it."
239         );
240 
241 	return;
242 	}
243 
244 if(ent_idx < 0) ent_idx = WAVE_NUM_NAMED_MARKERS;
245 ent_idx--;
246 if(ent_idx < 0) ent_idx = WAVE_NUM_NAMED_MARKERS-1;
247 
248 for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
249 	{
250 	if(GLOBALS->named_markers[ent_idx] >= 0)
251 		{
252 		success = 1;
253 		break;
254 		}
255 
256 	ent_idx--;
257 	if(ent_idx < 0) ent_idx = WAVE_NUM_NAMED_MARKERS-1;
258 	}
259 
260 if(!success)
261 	{
262 	ent_idx = 0;
263 	GLOBALS->named_markers[ent_idx] = GLOBALS->tims.marker;
264 	}
265 
266 GLOBALS->named_marker_lock_idx = ent_idx;
267 GLOBALS->tims.marker = GLOBALS->named_markers[ent_idx];
268 
269 update_markertime(GLOBALS->tims.marker);
270 GLOBALS->signalwindow_width_dirty=1;
271 MaxSignalLength();
272 signalarea_configure_event(GLOBALS->signalarea, NULL);
273 wavearea_configure_event(GLOBALS->wavearea, NULL);
274 }
275 
lock_marker_right(gpointer null_data,guint callback_action,GtkWidget * widget)276 static void lock_marker_right(gpointer null_data, guint callback_action, GtkWidget *widget)
277 {
278 (void)null_data;
279 (void)callback_action;
280 (void)widget;
281 
282 int ent_idx = GLOBALS->named_marker_lock_idx;
283 int i;
284 int success = 0;
285 
286 if(ent_idx < 0) ent_idx = -1; /* not really necessary */
287 ent_idx++;
288 if(ent_idx > (WAVE_NUM_NAMED_MARKERS-1)) ent_idx = 0;
289 
290 if(GLOBALS->helpbox_is_active)
291         {
292         help_text_bold("\n\nLock to Greater Named Marker");
293         help_text(
294                 " locks the primary marker to a named marker."
295 		" If no named marker is currently selected, the first defined one is used,"
296 		" otherwise the marker selected will be one higher in the alphabet, scrolling"
297 		" through to the beginning of the alphabet on wrap."
298 		" If no named marker exists, one is dropped down for 'A' and the primary"
299 		" marker is locked to it."
300         );
301 
302 	return;
303 	}
304 
305 for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
306 	{
307 	if(GLOBALS->named_markers[ent_idx] >= 0)
308 		{
309 		success = 1;
310 		break;
311 		}
312 
313 	ent_idx++;
314 	if(ent_idx > (WAVE_NUM_NAMED_MARKERS-1)) ent_idx = 0;
315 	}
316 
317 if(!success)
318 	{
319 	ent_idx = 0;
320 	GLOBALS->named_markers[ent_idx] = GLOBALS->tims.marker;
321 	}
322 
323 GLOBALS->named_marker_lock_idx = ent_idx;
324 GLOBALS->tims.marker = GLOBALS->named_markers[ent_idx];
325 
326 update_markertime(GLOBALS->tims.marker);
327 
328 GLOBALS->signalwindow_width_dirty=1;
329 MaxSignalLength();
330 signalarea_configure_event(GLOBALS->signalarea, NULL);
331 wavearea_configure_event(GLOBALS->wavearea, NULL);
332 }
333 
334 
unlock_marker(gpointer null_data,guint callback_action,GtkWidget * widget)335 static void unlock_marker(gpointer null_data, guint callback_action, GtkWidget *widget)
336 {
337 (void)null_data;
338 (void)callback_action;
339 (void)widget;
340 
341 if(GLOBALS->helpbox_is_active)
342         {
343         help_text_bold("\n\nUnlock from Named Marker");
344         help_text(
345                 " unlocks the primary marker from the currently selected named marker."
346         );
347 
348 	return;
349 	}
350 
351 GLOBALS->named_marker_lock_idx = -1;
352 
353 GLOBALS->signalwindow_width_dirty=1;
354 MaxSignalLength();
355 signalarea_configure_event(GLOBALS->signalarea, NULL);
356 wavearea_configure_event(GLOBALS->wavearea, NULL);
357 }
358 
359 
360 /* toggles for time dimension conversion */
361 
362 #ifdef WAVE_USE_MLIST_T
menu_scale_to_td_x(GtkWidget * widget,gpointer data)363 void menu_scale_to_td_x(GtkWidget *widget, gpointer data)
364 {
365 (void)widget;
366 (void)data;
367 #else
368 void menu_scale_to_td_x(gpointer null_data, guint callback_action, GtkWidget *widget)
369 {
370 (void)null_data;
371 (void)callback_action;
372 (void)widget;
373 #endif
374 
375 if(GLOBALS->helpbox_is_active)
376         {
377         help_text_bold("\n\nScale To Time Dimension: None");
378         help_text(
379 		" turns off time dimension conversion."
380         );
381         }
382 	else
383 	{
384 #ifdef WAVE_USE_MLIST_T
385 	if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
386 #endif
387 		{
388 		GLOBALS->scale_to_time_dimension = 0;
389 		set_scale_to_time_dimension_toggles();
390 		signalarea_configure_event(GLOBALS->signalarea, NULL);
391 		wavearea_configure_event(GLOBALS->wavearea, NULL);
392 		}
393 	}
394 }
395 
396 #ifdef WAVE_USE_MLIST_T
397 void menu_scale_to_td_s(GtkWidget *widget, gpointer data)
398 {
399 (void)widget;
400 (void)data;
401 #else
402 void menu_scale_to_td_s(gpointer null_data, guint callback_action, GtkWidget *widget)
403 {
404 (void)null_data;
405 (void)callback_action;
406 (void)widget;
407 #endif
408 
409 if(GLOBALS->helpbox_is_active)
410         {
411         help_text_bold("\n\nScale To Time Dimension: sec");
412         help_text(
413 		" changes the time dimension conversion value to seconds."
414         );
415         }
416 	else
417 	{
418 #ifdef WAVE_USE_MLIST_T
419 	if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
420 #endif
421 		{
422 		GLOBALS->scale_to_time_dimension = 's';
423 		set_scale_to_time_dimension_toggles();
424 		signalarea_configure_event(GLOBALS->signalarea, NULL);
425 		wavearea_configure_event(GLOBALS->wavearea, NULL);
426 		}
427 	}
428 }
429 
430 #ifdef WAVE_USE_MLIST_T
431 void menu_scale_to_td_m(GtkWidget *widget, gpointer data)
432 {
433 (void)widget;
434 (void)data;
435 #else
436 void menu_scale_to_td_m(gpointer null_data, guint callback_action, GtkWidget *widget)
437 {
438 (void)null_data;
439 (void)callback_action;
440 (void)widget;
441 #endif
442 
443 if(GLOBALS->helpbox_is_active)
444         {
445         help_text_bold("\n\nScale To Time Dimension: ms");
446         help_text(
447 		" changes the time dimension conversion value to milliseconds."
448         );
449         }
450 	else
451 	{
452 #ifdef WAVE_USE_MLIST_T
453 	if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
454 #endif
455 		{
456 		GLOBALS->scale_to_time_dimension = 'm';
457 		set_scale_to_time_dimension_toggles();
458 		signalarea_configure_event(GLOBALS->signalarea, NULL);
459 		wavearea_configure_event(GLOBALS->wavearea, NULL);
460 		}
461 	}
462 }
463 
464 #ifdef WAVE_USE_MLIST_T
465 void menu_scale_to_td_u(GtkWidget *widget, gpointer data)
466 {
467 (void)widget;
468 (void)data;
469 #else
470 void menu_scale_to_td_u(gpointer null_data, guint callback_action, GtkWidget *widget)
471 {
472 (void)null_data;
473 (void)callback_action;
474 (void)widget;
475 #endif
476 
477 if(GLOBALS->helpbox_is_active)
478         {
479         help_text_bold("\n\nScale To Time Dimension: us");
480         help_text(
481 		" changes the time dimension conversion value to microseconds."
482         );
483         }
484 	else
485 	{
486 #ifdef WAVE_USE_MLIST_T
487 	if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
488 #endif
489 		{
490 		GLOBALS->scale_to_time_dimension = 'u';
491 		set_scale_to_time_dimension_toggles();
492 		signalarea_configure_event(GLOBALS->signalarea, NULL);
493 		wavearea_configure_event(GLOBALS->wavearea, NULL);
494 		}
495 	}
496 }
497 
498 #ifdef WAVE_USE_MLIST_T
499 void menu_scale_to_td_n(GtkWidget *widget, gpointer data)
500 {
501 (void)widget;
502 (void)data;
503 #else
504 void menu_scale_to_td_n(gpointer null_data, guint callback_action, GtkWidget *widget)
505 {
506 (void)null_data;
507 (void)callback_action;
508 (void)widget;
509 #endif
510 
511 if(GLOBALS->helpbox_is_active)
512         {
513         help_text_bold("\n\nScale To Time Dimension: ns");
514         help_text(
515 		" changes the time dimension conversion value to nanoseconds."
516         );
517         }
518 	else
519 	{
520 #ifdef WAVE_USE_MLIST_T
521 	if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
522 #endif
523 		{
524 		GLOBALS->scale_to_time_dimension = 'n';
525 		set_scale_to_time_dimension_toggles();
526 		signalarea_configure_event(GLOBALS->signalarea, NULL);
527 		wavearea_configure_event(GLOBALS->wavearea, NULL);
528 		}
529 	}
530 }
531 
532 #ifdef WAVE_USE_MLIST_T
533 void menu_scale_to_td_p(GtkWidget *widget, gpointer data)
534 {
535 (void)widget;
536 (void)data;
537 #else
538 void menu_scale_to_td_p(gpointer null_data, guint callback_action, GtkWidget *widget)
539 {
540 (void)null_data;
541 (void)callback_action;
542 (void)widget;
543 #endif
544 
545 if(GLOBALS->helpbox_is_active)
546         {
547         help_text_bold("\n\nScale To Time Dimension: ps");
548         help_text(
549 		" changes the time dimension conversion value to picoseconds."
550         );
551         }
552 	else
553 	{
554 #ifdef WAVE_USE_MLIST_T
555 	if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
556 #endif
557 		{
558 		GLOBALS->scale_to_time_dimension = 'p';
559 		set_scale_to_time_dimension_toggles();
560 		signalarea_configure_event(GLOBALS->signalarea, NULL);
561 		wavearea_configure_event(GLOBALS->wavearea, NULL);
562 		}
563 	}
564 }
565 
566 #ifdef WAVE_USE_MLIST_T
567 void menu_scale_to_td_f(GtkWidget *widget, gpointer data)
568 {
569 (void)widget;
570 (void)data;
571 #else
572 void menu_scale_to_td_f(gpointer null_data, guint callback_action, GtkWidget *widget)
573 {
574 (void)null_data;
575 (void)callback_action;
576 (void)widget;
577 #endif
578 
579 if(GLOBALS->helpbox_is_active)
580         {
581         help_text_bold("\n\nScale To Time Dimension: fs");
582         help_text(
583 		" changes the time dimension conversion value to femtoseconds."
584         );
585         }
586 	else
587 	{
588 #ifdef WAVE_USE_MLIST_T
589 	if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
590 #endif
591 		{
592 		GLOBALS->scale_to_time_dimension = 'f';
593 		set_scale_to_time_dimension_toggles();
594 		signalarea_configure_event(GLOBALS->signalarea, NULL);
595 		wavearea_configure_event(GLOBALS->wavearea, NULL);
596 		}
597 	}
598 }
599 
600 
601 /********** transaction procsel filter install ********/
602 
603 void menu_dataformat_xlate_ttrans_1(gpointer null_data, guint callback_action, GtkWidget *widget)
604 {
605 (void)null_data;
606 (void)callback_action;
607 (void)widget;
608 
609 if(GLOBALS->helpbox_is_active)
610         {
611         help_text_bold("\n\nTransaction Filter Process");
612         help_text(
613                 " will enable transaction filtering on marked traces using a filter process.  A requester will appear to get the filter filename."
614         );
615         return;
616         }
617 
618 ttrans_searchbox("Select Transaction Filter Process");
619 }
620 
621 void menu_dataformat_xlate_ttrans_0(gpointer null_data, guint callback_action, GtkWidget *widget)
622 {
623 (void)null_data;
624 (void)callback_action;
625 (void)widget;
626 
627 if(GLOBALS->helpbox_is_active)
628         {
629         help_text_bold("\n\nTransaction Filter Process Disable");
630         help_text(
631                 " will remove transaction filtering."
632         );
633         return;
634         }
635 
636 install_ttrans_filter(0); /* disable, 0 is always NULL */
637 }
638 
639 /********** procsel filter install ********/
640 
641 void menu_dataformat_xlate_proc_1(gpointer null_data, guint callback_action, GtkWidget *widget)
642 {
643 (void)null_data;
644 (void)callback_action;
645 (void)widget;
646 
647 if(GLOBALS->helpbox_is_active)
648         {
649         help_text_bold("\n\nTranslate Filter Process");
650         help_text(
651                 " will enable translation on marked traces using a filter process.  A requester will appear to get the filter filename."
652         );
653         return;
654         }
655 
656 ptrans_searchbox("Select Signal Filter Process");
657 }
658 
659 void menu_dataformat_xlate_proc_0(gpointer null_data, guint callback_action, GtkWidget *widget)
660 {
661 (void)null_data;
662 (void)callback_action;
663 (void)widget;
664 
665 if(GLOBALS->helpbox_is_active)
666         {
667         help_text_bold("\n\nTranslate Filter Process Disable");
668         help_text(
669                 " will remove translation filtering used to reconstruct"
670                 " enums for marked traces."
671         );
672         return;
673         }
674 
675 install_proc_filter(0); /* disable, 0 is always NULL */
676 }
677 
678 /********** filesel filter install ********/
679 
680 void menu_dataformat_xlate_file_1(gpointer null_data, guint callback_action, GtkWidget *widget)
681 {
682 (void)null_data;
683 (void)callback_action;
684 (void)widget;
685 
686 if(GLOBALS->helpbox_is_active)
687         {
688         help_text_bold("\n\nTranslate Filter File");
689         help_text(
690                 " will enable translation on marked traces using a filter file.  A requester will appear to get the filter filename."
691         );
692         return;
693         }
694 
695 trans_searchbox("Select Signal Filter");
696 }
697 
698 
699 void menu_dataformat_xlate_file_0(gpointer null_data, guint callback_action, GtkWidget *widget)
700 {
701 (void)null_data;
702 (void)callback_action;
703 (void)widget;
704 
705 if(GLOBALS->helpbox_is_active)
706         {
707         help_text_bold("\n\nTranslate Filter File Disable");
708         help_text(
709                 " will remove translation filtering used to reconstruct"
710                 " enums for marked traces."
711         );
712         return;
713         }
714 
715 install_file_filter(0); /* disable, 0 is always NULL */
716 }
717 
718 
719 /******************************************************************/
720 
721 void menu_write_lxt_file_cleanup(GtkWidget *widget, gpointer data)
722 {
723 (void)widget;
724 (void)data;
725 
726 int rc;
727 
728 if(!GLOBALS->filesel_ok)
729         {
730         return;
731         }
732 
733 if(GLOBALS->lock_menu_c_1 == 1) return; /* avoid recursion */
734 GLOBALS->lock_menu_c_1 = 1;
735 
736 status_text("Saving LXT...\n");
737 gtkwave_main_iteration(); /* make requester disappear requester */
738 
739 rc = save_nodes_to_export(*GLOBALS->fileselbox_text, WAVE_EXPORT_LXT);
740 
741 GLOBALS->lock_menu_c_1 = 0;
742 
743 switch(rc)
744 	{
745 	case VCDSAV_EMPTY:	status_text("No traces onscreen to save!\n");
746 				break;
747 
748 	case VCDSAV_FILE_ERROR:	status_text("Problem writing LXT: ");
749 				status_text(strerror(errno));
750 				break;
751 
752 	case VCDSAV_OK:		status_text("LXT written successfully.\n");
753 	default:		break;
754 	}
755 }
756 
757 void
758 menu_write_lxt_file(gpointer null_data, guint callback_action, GtkWidget *widget)
759 {
760 (void)null_data;
761 (void)callback_action;
762 (void)widget;
763 
764 if(GLOBALS->helpbox_is_active)
765 	{
766 	help_text_bold("\n\nWrite LXT File As");
767 	help_text(
768 		" will open a file requester that will ask for the name"
769 		" of an LXT dumpfile.  The contents of the dumpfile"
770 		" generated will be the vcd representation of the traces onscreen"
771  		" that can be seen by manipulating the signal and wavewindow scrollbars."
772 		" The data saved corresponds to the trace information needed"
773 		" to allow viewing when used in tandem with the corresponding GTKWave save file."
774 	);
775 	return;
776 	}
777 
778 if(GLOBALS->traces.first)
779 	{
780 	if((GLOBALS->is_ghw)&&(0))
781 		{
782 		status_text("LXT export not supported for GHW.\n");
783 		}
784 		else
785 		{
786 		fileselbox("Write LXT File As",&GLOBALS->filesel_lxt_writesave,GTK_SIGNAL_FUNC(menu_write_lxt_file_cleanup), GTK_SIGNAL_FUNC(NULL),"*.lxt", 1);
787 		}
788 	}
789 	else
790 	{
791 	status_text("No traces onscreen to save!\n");
792 	}
793 }
794 
795 
796 /******************************************************************/
797 
798 void menu_write_vcd_file_cleanup(GtkWidget *widget, gpointer data)
799 {
800 (void)widget;
801 (void)data;
802 
803 int rc;
804 
805 if(!GLOBALS->filesel_ok)
806         {
807         return;
808         }
809 
810 if(GLOBALS->lock_menu_c_2 == 1) return; /* avoid recursion */
811 GLOBALS->lock_menu_c_2 = 1;
812 
813 status_text("Saving VCD...\n");
814 gtkwave_main_iteration(); /* make requester disappear requester */
815 
816 rc = save_nodes_to_export(*GLOBALS->fileselbox_text, WAVE_EXPORT_VCD);
817 
818 GLOBALS->lock_menu_c_2 = 0;
819 
820 switch(rc)
821 	{
822 	case VCDSAV_EMPTY:	status_text("No traces onscreen to save!\n");
823 				break;
824 
825 	case VCDSAV_FILE_ERROR:	status_text("Problem writing VCD: ");
826 				status_text(strerror(errno));
827 				break;
828 
829 	case VCDSAV_OK:		status_text("VCD written successfully.\n");
830 	default:		break;
831 	}
832 }
833 
834 void
835 menu_write_vcd_file(gpointer null_data, guint callback_action, GtkWidget *widget)
836 {
837 (void)null_data;
838 (void)callback_action;
839 (void)widget;
840 
841 if(GLOBALS->helpbox_is_active)
842 	{
843 	help_text_bold("\n\nWrite VCD File As");
844 	help_text(
845 		" will open a file requester that will ask for the name"
846 		" of a VCD dumpfile.  The contents of the dumpfile"
847 		" generated will be the vcd representation of the traces onscreen"
848  		" that can be seen by manipulating the signal and wavewindow scrollbars."
849 		" The data saved corresponds to the trace information needed"
850 		" to allow viewing when used in tandem with the corresponding GTKWave save file."
851 	);
852 	return;
853 	}
854 
855 if(GLOBALS->traces.first)
856 	{
857 	fileselbox("Write VCD File As",&GLOBALS->filesel_vcd_writesave,GTK_SIGNAL_FUNC(menu_write_vcd_file_cleanup), GTK_SIGNAL_FUNC(NULL),"*.vcd", 1);
858 	}
859 	else
860 	{
861 	status_text("No traces onscreen to save!\n");
862 	}
863 }
864 
865 /******************************************************************/
866 
867 void menu_write_tim_file_cleanup(GtkWidget *widget, gpointer data)
868 {
869 (void)widget;
870 (void)data;
871 
872 int rc;
873 
874 if(!GLOBALS->filesel_ok)
875         {
876         return;
877         }
878 
879 if(GLOBALS->lock_menu_c_2 == 1) return; /* avoid recursion */
880 GLOBALS->lock_menu_c_2 = 1;
881 
882 status_text("Saving TIM...\n");
883 gtkwave_main_iteration(); /* make requester disappear requester */
884 
885 rc = save_nodes_to_export(*GLOBALS->fileselbox_text, WAVE_EXPORT_TIM);
886 
887 GLOBALS->lock_menu_c_2 = 0;
888 
889 switch(rc)
890 	{
891 	case VCDSAV_EMPTY:	status_text("No traces onscreen to save!\n");
892 				break;
893 
894 	case VCDSAV_FILE_ERROR:	status_text("Problem writing TIM: ");
895 				status_text(strerror(errno));
896 				break;
897 
898 	case VCDSAV_OK:		status_text("TIM written successfully.\n");
899 	default:		break;
900 	}
901 }
902 
903 void
904 menu_write_tim_file(gpointer null_data, guint callback_action, GtkWidget *widget)
905 {
906 (void)null_data;
907 (void)callback_action;
908 (void)widget;
909 
910 if(GLOBALS->helpbox_is_active)
911 	{
912 	help_text_bold("\n\nWrite TIM File As");
913 	help_text(
914 		" will open a file requester that will ask for the name"
915 		" of a TimingAnalyzer .tim file.  The contents of the file"
916 		" generated will be the representation of the traces onscreen."
917 		" If the baseline and primary marker are set, the time range"
918 		" written to the file will be between the two markers, otherwise"
919 		" it will be the entire time range."
920 	);
921 	return;
922 	}
923 
924 if(GLOBALS->traces.first)
925 	{
926 	fileselbox("Write TIM File As",&GLOBALS->filesel_tim_writesave,GTK_SIGNAL_FUNC(menu_write_tim_file_cleanup), GTK_SIGNAL_FUNC(NULL),"*.tim", 1);
927 	}
928 	else
929 	{
930 	status_text("No traces onscreen to save!\n");
931 	}
932 }
933 
934 
935 /******************************************************************/
936 
937 void menu_unwarp_traces_all(gpointer null_data, guint callback_action, GtkWidget *widget)
938 {
939 (void)null_data;
940 (void)callback_action;
941 (void)widget;
942 
943 Trptr t;
944 int found=0;
945 
946 if(GLOBALS->helpbox_is_active)
947         {
948         help_text_bold("\n\nUnwarp All");
949         help_text(
950                 " unconditionally removes all offsets on all traces."
951         );
952         return;
953         }
954 
955 t=GLOBALS->traces.first;
956 while(t)
957 	{
958 	if(t->shift)
959 		{
960 		t->shift=LLDescriptor(0);
961 		found++;
962 		}
963 	t=t->t_next;
964 	}
965 
966 if(found)
967 	{
968 	GLOBALS->signalwindow_width_dirty=1;
969 	MaxSignalLength();
970 	signalarea_configure_event(GLOBALS->signalarea, NULL);
971 	wavearea_configure_event(GLOBALS->wavearea, NULL);
972 	}
973 }
974 
975 void menu_unwarp_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
976 {
977 (void)null_data;
978 (void)callback_action;
979 (void)widget;
980 
981 Trptr t;
982 int found=0;
983 
984 if(GLOBALS->helpbox_is_active)
985         {
986         help_text_bold("\n\nUnwarp Marked");
987         help_text(
988                 " removes all offsets on all highlighted traces."
989         );
990         return;
991         }
992 
993 t=GLOBALS->traces.first;
994 while(t)
995 	{
996 	if(t->flags&TR_HIGHLIGHT)
997 		{
998 		t->shift=LLDescriptor(0);
999 		t->flags&=(~TR_HIGHLIGHT);
1000 		found++;
1001 		}
1002 	t=t->t_next;
1003 	}
1004 
1005 if(found)
1006 	{
1007 	GLOBALS->signalwindow_width_dirty=1;
1008 	MaxSignalLength();
1009 	signalarea_configure_event(GLOBALS->signalarea, NULL);
1010 	wavearea_configure_event(GLOBALS->wavearea, NULL);
1011 	}
1012 }
1013 
1014 void warp_cleanup(GtkWidget *widget, gpointer data)
1015 {
1016 (void)widget;
1017 (void)data;
1018 
1019 if(GLOBALS->entrybox_text)
1020 	{
1021 	TimeType gt, delta;
1022 	Trptr t;
1023 
1024 	gt=unformat_time(GLOBALS->entrybox_text, GLOBALS->time_dimension);
1025 	free_2(GLOBALS->entrybox_text);
1026 	GLOBALS->entrybox_text=NULL;
1027 
1028 	if(gt<0)
1029 		{
1030 		delta=GLOBALS->tims.first-GLOBALS->tims.last;
1031 		if(gt<delta) gt=delta;
1032 		}
1033 	else
1034 	if(gt>0)
1035 		{
1036 		delta=GLOBALS->tims.last-GLOBALS->tims.first;
1037 		if(gt>delta) gt=delta;
1038 		}
1039 
1040 	t=GLOBALS->traces.first;
1041 	while(t)
1042 	  {
1043 	    if(t->flags&TR_HIGHLIGHT)
1044 	      {
1045 		if(HasWave(t)) /* though note if a user specifies comment warping in a .sav file we will honor it.. */
1046 		  {
1047 		    t->shift=gt;
1048 		  }
1049 		else
1050 		  {
1051 		    t->shift=LLDescriptor(0);
1052 				}
1053 			t->flags&=(~TR_HIGHLIGHT);
1054 			}
1055 		t=t->t_next;
1056 		}
1057 	}
1058 
1059 	GLOBALS->signalwindow_width_dirty=1;
1060 	MaxSignalLength();
1061 	signalarea_configure_event(GLOBALS->signalarea, NULL);
1062 	wavearea_configure_event(GLOBALS->wavearea, NULL);
1063 }
1064 
1065 void menu_warp_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
1066 {
1067 (void)null_data;
1068 (void)callback_action;
1069 (void)widget;
1070 
1071 char gt[32];
1072 Trptr t;
1073 int found=0;
1074 
1075 if(GLOBALS->helpbox_is_active)
1076         {
1077         help_text_bold("\n\nWarp Marked");
1078         help_text(
1079                 " offsets all highlighted traces by the amount of"
1080                 " time entered in the requester.  (Positive values"
1081 		" will shift traces to the right.)"
1082 		" Attempting to shift greater than the absolute value of total simulation"
1083 		" time will cap the shift magnitude at the length of simulation."
1084 		" Note that you can also warp traces dynamically by holding"
1085 		" down CTRL and dragging a group of highlighted traces to"
1086 		" the left or right with the left mouse button pressed.  When you release"
1087 		" the mouse button, if CTRL is pressed, the drag warp commits, else"
1088 		" it reverts to its pre-drag condition."
1089         );
1090         return;
1091         }
1092 
1093 
1094 t=GLOBALS->traces.first;
1095 while(t)
1096 	{
1097 	if(t->flags&TR_HIGHLIGHT)
1098 		{
1099 		found++;
1100 		break;
1101 		}
1102 	t=t->t_next;
1103 	}
1104 
1105 if(found)
1106 	{
1107 	reformat_time(gt, LLDescriptor(0), GLOBALS->time_dimension);
1108 	entrybox("Warp Traces",200,gt,NULL,20,GTK_SIGNAL_FUNC(warp_cleanup));
1109 	}
1110 }
1111 
1112 
1113 
1114 
1115 void menu_altwheel(gpointer null_data, guint callback_action, GtkWidget *widget)
1116 {
1117 (void)null_data;
1118 (void)callback_action;
1119 (void)widget;
1120 
1121   if(GLOBALS->helpbox_is_active)
1122   {
1123     help_text_bold("\n\nAlternate Wheel Mode");
1124     help_text(
1125 		" makes the mouse wheel act how TomB expects it to."
1126 		" Wheel alone will pan part of a page (so you can still"
1127 		" see where you were).  Ctrl+Wheel will zoom around the"
1128 		" cursor (not where the marker is), and Alt+Wheel will"
1129 		" edge left or right on the selected signal.");
1130   }
1131 	else
1132 	{
1133 #ifndef WAVE_USE_MLIST_T
1134 	if(!GLOBALS->alt_wheel_mode)
1135 		{
1136 		status_text("Alternate Wheel Mode On.\n");
1137 		GLOBALS->alt_wheel_mode=1;
1138 		}
1139 		else
1140 		{
1141 		status_text("Alternate Wheel Mode Off.\n");
1142 		GLOBALS->alt_wheel_mode=0;
1143 		}
1144 #else
1145         GLOBALS->alt_wheel_mode = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HSWM]));
1146         if(GLOBALS->alt_wheel_mode)
1147         {
1148           status_text("Alternate Wheel Mode On.\n");
1149         }
1150         else
1151         {
1152           status_text("Alternate Wheel Mode Off.\n");
1153         }
1154 #endif
1155 	}
1156 #ifndef WAVE_USE_MLIST_T
1157 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HSWM].path))->active=(GLOBALS->alt_wheel_mode)?TRUE:FALSE;
1158 #endif
1159 }
1160 
1161 
1162 
1163 
1164 void wave_scrolling_on(gpointer null_data, guint callback_action, GtkWidget *widget)
1165 {
1166 (void)null_data;
1167 (void)callback_action;
1168 (void)widget;
1169 
1170 if(GLOBALS->helpbox_is_active)
1171         {
1172         help_text_bold("\n\nWave Scrolling");
1173         help_text(
1174 		" allows movement of the primary marker beyond screen boundaries"
1175 		" which causes the wave window to scroll when enabled."
1176 		" When disabled, it"
1177 		" disallows movement of the primary marker beyond screen boundaries."
1178         );
1179         }
1180 	else
1181 	{
1182 #ifndef WAVE_USE_MLIST_T
1183 	if(!GLOBALS->wave_scrolling)
1184 		{
1185 		status_text("Wave Scrolling On.\n");
1186 		GLOBALS->wave_scrolling=1;
1187 		}
1188 		else
1189 		{
1190 		status_text("Wave Scrolling Off.\n");
1191 		GLOBALS->wave_scrolling=0;
1192 		}
1193 #else
1194         GLOBALS->wave_scrolling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_MWSON]));
1195         if(GLOBALS->wave_scrolling)
1196                 {
1197                 status_text("Wave Scrolling On.\n");
1198                 }
1199                 else
1200                 {
1201                 status_text("Wave Scrolling Off.\n");
1202                 }
1203 #endif
1204 	}
1205 #ifndef WAVE_USE_MLIST_T
1206 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_MWSON].path))->active=(GLOBALS->wave_scrolling)?TRUE:FALSE;
1207 #endif
1208 }
1209 
1210 
1211 
1212 
1213 /**/
1214 
1215 void menu_keep_xz_colors(gpointer null_data, guint callback_action, GtkWidget *widget)
1216 {
1217 (void)null_data;
1218 (void)callback_action;
1219 (void)widget;
1220 
1221 if(GLOBALS->helpbox_is_active)
1222         {
1223         help_text_bold("\n\nKeep xz Colors");
1224         help_text(
1225 		" when enabled"
1226 		" keeps the old non 0/1 signal value colors when a user specifies a color override"
1227 		" by using Edit/Color Format."
1228         );
1229         }
1230 	else
1231 	{
1232 #ifndef WAVE_USE_MLIST_T
1233 	if(!GLOBALS->keep_xz_colors)
1234 		{
1235 		GLOBALS->keep_xz_colors=1;
1236 		}
1237 		else
1238 		{
1239 		GLOBALS->keep_xz_colors=0;
1240 		}
1241 #else
1242 	GLOBALS->keep_xz_colors = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_KEEPXZ]));
1243 #endif
1244 	}
1245 
1246 #ifndef WAVE_USE_MLIST_T
1247 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_KEEPXZ].path))->active=(GLOBALS->keep_xz_colors)?TRUE:FALSE;
1248 #endif
1249 
1250 GLOBALS->signalwindow_width_dirty=1;
1251 MaxSignalLength();
1252 signalarea_configure_event(GLOBALS->signalarea, NULL);
1253 wavearea_configure_event(GLOBALS->wavearea, NULL);
1254 }
1255 
1256 /**/
1257 
1258 void menu_autocoalesce(gpointer null_data, guint callback_action, GtkWidget *widget)
1259 {
1260 (void)null_data;
1261 (void)callback_action;
1262 (void)widget;
1263 
1264 if(GLOBALS->helpbox_is_active)
1265         {
1266         help_text_bold("\n\nAutocoalesce");
1267         help_text(
1268 		" when enabled"
1269 		" allows the wave viewer to reconstruct split vectors."
1270 		" Split vectors will be indicated by a \"[]\""
1271 		" prefix in the search requesters."
1272         );
1273         }
1274 	else
1275 	{
1276 #ifndef WAVE_USE_MLIST_T
1277 	if(!GLOBALS->autocoalesce)
1278 		{
1279 		status_text("Autocoalesce On.\n");
1280 		GLOBALS->autocoalesce=1;
1281 		}
1282 		else
1283 		{
1284 		status_text("Autocoalesce Off.\n");
1285 		GLOBALS->autocoalesce=0;
1286 		}
1287 #else
1288         GLOBALS->autocoalesce = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOL]));
1289         if(GLOBALS->autocoalesce)
1290                 {
1291                 status_text("Autocoalesce On.\n");
1292                 }
1293                 else
1294                 {
1295                 status_text("Autocoalesce Off.\n");
1296                 }
1297 #endif
1298 	}
1299 
1300 #ifndef WAVE_USE_MLIST_T
1301 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOL].path))->active=(GLOBALS->autocoalesce)?TRUE:FALSE;
1302 #endif
1303 }
1304 
1305 void menu_autocoalesce_reversal(gpointer null_data, guint callback_action, GtkWidget *widget)
1306 {
1307 (void)null_data;
1308 (void)callback_action;
1309 (void)widget;
1310 
1311 if(GLOBALS->helpbox_is_active)
1312         {
1313         help_text_bold("\n\nAutocoalesce Reversal");
1314         help_text(
1315 		" causes split vectors to be reconstructed in reverse order (only if autocoalesce is also active).  This is necessary with some simulators."
1316 		" Split vectors will be indicated by a \"[]\""
1317 		" prefix in the search requesters."
1318         );
1319         }
1320 	else
1321 	{
1322 #ifndef WAVE_USE_MLIST_T
1323 	if(!GLOBALS->autocoalesce_reversal)
1324 		{
1325 		status_text("Autocoalesce Rvs On.\n");
1326 		GLOBALS->autocoalesce_reversal=1;
1327 		}
1328 		else
1329 		{
1330 		status_text("Autocoalesce Rvs Off.\n");
1331 		GLOBALS->autocoalesce_reversal=0;
1332 		}
1333 #else
1334        	GLOBALS->autocoalesce_reversal = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOLR]));
1335         if(GLOBALS->autocoalesce_reversal)
1336                 {
1337                 status_text("Autocoalesce Rvs On.\n");
1338                 }
1339                 else
1340                 {
1341                 status_text("Autocoalesce Rvs Off.\n");
1342                 }
1343 #endif
1344 	}
1345 
1346 #ifndef WAVE_USE_MLIST_T
1347 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOLR].path))->active=(GLOBALS->autocoalesce_reversal)?TRUE:FALSE;
1348 #endif
1349 }
1350 
1351 void menu_autoname_bundles_on(gpointer null_data, guint callback_action, GtkWidget *widget)
1352 {
1353 (void)null_data;
1354 (void)callback_action;
1355 (void)widget;
1356 
1357 if(GLOBALS->helpbox_is_active)
1358         {
1359         help_text_bold("\n\nAutoname Bundles");
1360         help_text(
1361 		" when enabled"
1362 		" modifies the bundle up/down operations in the hierarchy"
1363 		" and tree searches such that a NULL bundle name is"
1364 		" implicitly created which informs GTKWave to create bundle"
1365 		" and signal names based on the position in the hierarchy."
1366 		" When disabled, it"
1367 		" modifies the bundle up/down operations in the hierarchy"
1368 		" and tree searches such that a NULL bundle name is"
1369 		" not implicitly created.  This informs GTKWave to create bundle"
1370 		" and signal names based on the position in the hierarchy"
1371 		" only if the user enters a zero-length bundle name.  This"
1372 		" behavior is the default."
1373         );
1374         }
1375 	else
1376 	{
1377 #ifndef WAVE_USE_MLIST_T
1378 	if(!GLOBALS->autoname_bundles)
1379 		{
1380 		status_text("Autoname On.\n");
1381 		GLOBALS->autoname_bundles=1;
1382 		}
1383 		else
1384 		{
1385 		status_text("Autoname Off.\n");
1386 		GLOBALS->autoname_bundles=0;
1387 		}
1388 #else
1389         GLOBALS->autoname_bundles = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ABON]));
1390         if(GLOBALS->autoname_bundles)
1391                 {
1392                 status_text("Autoname On.\n");
1393                 }
1394                 else
1395                 {
1396                 status_text("Autoname Off.\n");
1397                 }
1398 #endif
1399 	}
1400 
1401 #ifndef WAVE_USE_MLIST_T
1402 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ABON].path))->active=(GLOBALS->autoname_bundles)?TRUE:FALSE;
1403 #endif
1404 }
1405 
1406 
1407 void menu_hgrouping(gpointer null_data, guint callback_action, GtkWidget *widget)
1408 {
1409 (void)null_data;
1410 (void)callback_action;
1411 (void)widget;
1412 
1413 if(GLOBALS->helpbox_is_active)
1414         {
1415         help_text_bold("\n\nSearch Hierarchy Grouping");
1416         help_text(
1417 		" when enabled ensures that new members added to the ``Tree Search'' and"
1418 		" ``Hierarchy Search'' widgets are added alphanumerically: first hierarchy names as a group followed by signal names as a group."
1419 		" This is the default and is recommended.  When disabled, hierarchy names and signal names are interleaved together in"
1420 		" strict alphanumerical ordering."
1421 		" Note that due to the caching mechanism in ``Tree Search'', dynamically changing this flag when the widget is active"
1422 		" may not produce immediately obvious results.  Closing the widget then opening it up again will ensure that it follows the"
1423 		" behavior of this flag."
1424         );
1425         }
1426 	else
1427 	{
1428 #ifndef WAVE_USE_MLIST_T
1429 	if(!GLOBALS->hier_grouping)
1430 		{
1431 		status_text("Hier Grouping On.\n");
1432 		GLOBALS->hier_grouping=1;
1433 		}
1434 		else
1435 		{
1436 		status_text("Hier Grouping Off.\n");
1437 		GLOBALS->hier_grouping=0;
1438 		}
1439 #else
1440         GLOBALS->hier_grouping = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HTGP]));
1441         if(GLOBALS->hier_grouping)
1442                 {
1443                 status_text("Hier Grouping On.\n");
1444                 }
1445                 else
1446                 {
1447                 status_text("Hier Grouping Off.\n");
1448                 }
1449 #endif
1450 	}
1451 
1452 #ifndef WAVE_USE_MLIST_T
1453 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HTGP].path))->active=(GLOBALS->hier_grouping)?TRUE:FALSE;
1454 #endif
1455 }
1456 
1457 
1458 void set_hier_cleanup(GtkWidget *widget, gpointer data, int level)
1459 {
1460 (void)widget;
1461 (void)data;
1462 
1463   char update_string[128];
1464   Trptr t;
1465   int i;
1466 
1467   GLOBALS->hier_max_level=level;
1468   if(GLOBALS->hier_max_level<0) GLOBALS->hier_max_level=0;
1469 
1470   for(i=0;i<2;i++)
1471     {
1472       if(i==0) t=GLOBALS->traces.first; else t=GLOBALS->traces.buffer;
1473 
1474       while(t)
1475 	{
1476 	  if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
1477 	    {
1478 	      if (HasAlias(t))
1479 		{
1480 		  t->name = t->name_full;
1481 		  if(GLOBALS->hier_max_level)
1482 		    t->name = hier_extract(t->name, GLOBALS->hier_max_level);
1483 		}
1484 	      else if(t->vector==TRUE)
1485 		{
1486 		  t->name = t->n.vec->bvname;
1487 		  if(GLOBALS->hier_max_level)
1488 		    t->name = hier_extract(t->name, GLOBALS->hier_max_level);
1489 		}
1490 	      else
1491 		{
1492 		  if(!GLOBALS->hier_max_level)
1493 		      {
1494 			int flagged = HIER_DEPACK_ALLOC;
1495 
1496 			if(t->name&&t->is_depacked) { free_2(t->name); }
1497 			t->name = hier_decompress_flagged(t->n.nd->nname, &flagged);
1498 			t->is_depacked = (flagged != 0);
1499 		      }
1500 		    else
1501 		      {
1502 			int flagged = HIER_DEPACK_ALLOC;
1503 			char *tbuff;
1504 
1505 			if(t->name&&t->is_depacked) { free_2(t->name); }
1506 			tbuff = hier_decompress_flagged(t->n.nd->nname, &flagged);
1507 			t->is_depacked = (flagged != 0);
1508 
1509 			if(!flagged)
1510 			  {
1511 			    t->name = hier_extract(t->n.nd->nname, GLOBALS->hier_max_level);
1512 			  }
1513 			else
1514 			  {
1515 			    t->name = strdup_2(hier_extract(tbuff, GLOBALS->hier_max_level));
1516 			    free_2(tbuff);
1517 			  }
1518 		      }
1519 		}
1520 	    }
1521 	  t=t->t_next;
1522 	}
1523     }
1524 
1525   GLOBALS->signalwindow_width_dirty=1;
1526   MaxSignalLength();
1527   signalarea_configure_event(GLOBALS->signalarea, NULL);
1528   wavearea_configure_event(GLOBALS->wavearea, NULL);
1529   sprintf(update_string, "Trace Hier Max Depth is now: %d\n", GLOBALS->hier_max_level);
1530   status_text(update_string);
1531 
1532 }
1533 
1534 void max_hier_cleanup(GtkWidget *widget, gpointer data)
1535 {
1536 if(GLOBALS->entrybox_text)
1537   {
1538     int i;
1539 
1540     i = atoi_64(GLOBALS->entrybox_text);
1541     set_hier_cleanup(widget, data, i);
1542     GLOBALS->hier_max_level_shadow = GLOBALS->hier_max_level; /* used for the toggle function */
1543 
1544     free_2(GLOBALS->entrybox_text);
1545     GLOBALS->entrybox_text=NULL;
1546   }
1547 }
1548 
1549 
1550 void menu_set_max_hier(gpointer null_data, guint callback_action, GtkWidget *widget)
1551 {
1552 (void)null_data;
1553 (void)callback_action;
1554 (void)widget;
1555 
1556 char za[32];
1557 
1558 if(GLOBALS->helpbox_is_active)
1559         {
1560         help_text_bold("\n\nSet Max Hier");
1561         help_text(
1562 		" sets the maximum hierarchy depth (counting from the right"
1563 		" with bit numbers or ranges ignored) that is displayable"
1564 		" for trace names.  Zero indicates that no truncation will"
1565 		" be performed (default).  Note that any aliased signals"
1566 		" (prefix of a \"+\") will not have truncated names."
1567         );
1568         return;
1569         }
1570 
1571 
1572 sprintf(za,"%d",GLOBALS->hier_max_level);
1573 
1574 entrybox("Max Hier Depth",200,za,NULL,20,GTK_SIGNAL_FUNC(max_hier_cleanup));
1575 }
1576 
1577 void menu_toggle_hier(gpointer null_data, guint callback_action, GtkWidget *widget)
1578 {
1579 (void)callback_action;
1580 
1581 if(GLOBALS->helpbox_is_active)
1582         {
1583         help_text_bold("\n\nToggle Trace Hier");
1584         help_text(
1585 		" toggles the maximum hierarchy depth from zero to whatever was previously set."
1586         );
1587         return;
1588         }
1589 
1590  if (GLOBALS->hier_max_level)
1591    set_hier_cleanup(widget, null_data, 0);
1592  else
1593    set_hier_cleanup(widget, null_data, GLOBALS->hier_max_level_shadow); /* instead of just '1' */
1594 }
1595 
1596 
1597 /**/
1598 void menu_use_roundcaps(gpointer null_data, guint callback_action, GtkWidget *widget)
1599 {
1600 (void)null_data;
1601 (void)callback_action;
1602 (void)widget;
1603 
1604 if(GLOBALS->helpbox_is_active)
1605         {
1606         help_text_bold("\n\nDraw Roundcapped Vectors");
1607         help_text(
1608 		" draws vector transitions that have sloping edges when enabled."
1609 		" Draws vector transitions that have sharp edges when disabled;"
1610 		" this is the default."
1611         );
1612         }
1613 	else
1614 	{
1615 #ifndef WAVE_USE_MLIST_T
1616 	if(!GLOBALS->use_roundcaps)
1617 		{
1618 		status_text("Using roundcaps.\n");
1619 		GLOBALS->use_roundcaps=1;
1620 		}
1621 		else
1622 		{
1623 		status_text("Using flatcaps.\n");
1624 		GLOBALS->use_roundcaps=0;
1625 		}
1626 	MaxSignalLength();
1627 	signalarea_configure_event(GLOBALS->signalarea, NULL);
1628 	wavearea_configure_event(GLOBALS->wavearea, NULL);
1629 #else
1630       GLOBALS->use_roundcaps = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDRV]));
1631         if(GLOBALS->use_roundcaps)
1632                 {
1633                 status_text("Using roundcaps.\n");
1634                 }
1635                 else
1636                 {
1637                 status_text("Using flatcaps.\n");
1638                 }
1639         if(GLOBALS->signalarea && GLOBALS->wavearea)
1640                 {
1641                 MaxSignalLength();
1642                 signalarea_configure_event(GLOBALS->signalarea, NULL);
1643                 wavearea_configure_event(GLOBALS->wavearea, NULL);
1644                 }
1645 #endif
1646 	}
1647 
1648 #ifndef WAVE_USE_MLIST_T
1649 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDRV].path))->active=(GLOBALS->use_roundcaps)?TRUE:FALSE;
1650 #endif
1651 }
1652 
1653 /**/
1654 void menu_lxt_clk_compress(gpointer null_data, guint callback_action, GtkWidget *widget)
1655 {
1656 (void)null_data;
1657 (void)callback_action;
1658 (void)widget;
1659 
1660 if(GLOBALS->helpbox_is_active)
1661         {
1662         help_text_bold("\n\nLXT Clock Compress to Z");
1663         help_text(
1664 		" reduces memory usage when active as clocks compressed in LXT format are"
1665 		" kept at Z in order to save memory.  Traces imported with this are permanently"
1666 		" kept at Z."
1667         );
1668         }
1669 	else
1670 	{
1671 #ifndef WAVE_USE_MLIST_T
1672 	if(GLOBALS->lxt_clock_compress_to_z)
1673 		{
1674 		GLOBALS->lxt_clock_compress_to_z=0;
1675 		status_text("LXT CC2Z Off.\n");
1676 		}
1677 		else
1678 		{
1679 		GLOBALS->lxt_clock_compress_to_z=1;
1680 		status_text("LXT CC2Z On.\n");
1681 		}
1682 #else
1683         GLOBALS->lxt_clock_compress_to_z = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LXTCC2Z]));
1684         if(!GLOBALS->lxt_clock_compress_to_z)
1685                 {
1686                 status_text("LXT CC2Z Off.\n");
1687                 }
1688                 else
1689                 {
1690                 status_text("LXT CC2Z On.\n");
1691                 }
1692 #endif
1693 	}
1694 
1695 #ifndef WAVE_USE_MLIST_T
1696 if(GLOBALS->loaded_file_type == LXT_FILE)
1697 	{
1698 	GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LXTCC2Z].path))->active=(GLOBALS->lxt_clock_compress_to_z)?TRUE:FALSE;
1699 	}
1700 #endif
1701 }
1702 /**/
1703 void menu_use_full_precision(gpointer null_data, guint callback_action, GtkWidget *widget)
1704 {
1705 (void)null_data;
1706 (void)callback_action;
1707 (void)widget;
1708 
1709 if(GLOBALS->helpbox_is_active)
1710         {
1711         help_text_bold("\n\nFull Precision");
1712         help_text(
1713 		" does not round time values when the number of ticks per pixel onscreen is greater than"
1714 		" 10 when active.  The default is that this feature is disabled."
1715         );
1716         }
1717 	else
1718 	{
1719 #ifndef WAVE_USE_MLIST_T
1720 	if(GLOBALS->use_full_precision)
1721 		{
1722 		GLOBALS->use_full_precision=0;
1723 		status_text("Full Prec Off.\n");
1724 		}
1725 		else
1726 		{
1727 		GLOBALS->use_full_precision=1;
1728 		status_text("Full Prec On.\n");
1729 		}
1730 #else
1731         GLOBALS->use_full_precision = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VFTP]));
1732         if(!GLOBALS->use_full_precision)
1733                 {
1734                 status_text("Full Prec Off.\n");
1735                 }
1736                 else
1737                 {
1738                 status_text("Full Prec On.\n");
1739                 }
1740 #endif
1741 
1742 	calczoom(GLOBALS->tims.zoom);
1743 	fix_wavehadj();
1744 
1745 	gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */
1746 	gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */
1747 	update_maxmarker_labels();
1748 	}
1749 
1750 #ifndef WAVE_USE_MLIST_T
1751 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VFTP].path))->active=(GLOBALS->use_full_precision)?TRUE:FALSE;
1752 #endif
1753 }
1754 /**/
1755 void menu_remove_marked(gpointer null_data, guint callback_action, GtkWidget *widget)
1756 {
1757 (void)null_data;
1758 (void)callback_action;
1759 (void)widget;
1760 
1761 if(GLOBALS->helpbox_is_active)
1762         {
1763         help_text_bold("\n\nRemove Pattern Marks");
1764         help_text(
1765 		" removes any vertical traces on the display caused by the Mark"
1766 		" feature in pattern search and reverts to the normal format."
1767         );
1768         }
1769 	else
1770 	{
1771 	int i;
1772 
1773 	WAVE_STRACE_ITERATOR(i)
1774 		{
1775 		GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = i];
1776 
1777 		if(GLOBALS->strace_ctx->shadow_straces)
1778 			{
1779 			delete_strace_context();
1780 			}
1781 
1782 		strace_maketimetrace(0);
1783 		}
1784 
1785 	MaxSignalLength();
1786 	signalarea_configure_event(GLOBALS->signalarea, NULL);
1787 	wavearea_configure_event(GLOBALS->wavearea, NULL);
1788 	}
1789 }
1790 /**/
1791 void menu_use_color(gpointer null_data, guint callback_action, GtkWidget *widget)
1792 {
1793 (void)null_data;
1794 (void)callback_action;
1795 (void)widget;
1796 
1797 if(GLOBALS->helpbox_is_active)
1798         {
1799         help_text_bold("\n\nUse Color");
1800         help_text(
1801 		" draws signal names and trace data in color.  This is normal operation."
1802         );
1803         }
1804 	else
1805 	{
1806 	force_normal_gcs();
1807 
1808 	MaxSignalLength();
1809 	signalarea_configure_event(GLOBALS->signalarea, NULL);
1810 	wavearea_configure_event(GLOBALS->wavearea, NULL);
1811 	}
1812 }
1813 /**/
1814 void menu_use_bw(gpointer null_data, guint callback_action, GtkWidget *widget)
1815 {
1816 (void)null_data;
1817 (void)callback_action;
1818 (void)widget;
1819 
1820 if(GLOBALS->helpbox_is_active)
1821         {
1822         help_text_bold("\n\nUse Black and White");
1823         help_text(
1824 		" draws signal names and trace data in black and white.  This is intended for use in"
1825 		" black and white screen dumps."
1826         );
1827         }
1828 	else
1829 	{
1830 	force_screengrab_gcs();
1831 
1832 	MaxSignalLength();
1833 	signalarea_configure_event(GLOBALS->signalarea, NULL);
1834 	wavearea_configure_event(GLOBALS->wavearea, NULL);
1835 	}
1836 }
1837 /**/
1838 void menu_zoom10_snap(gpointer null_data, guint callback_action, GtkWidget *widget)
1839 {
1840 (void)null_data;
1841 (void)callback_action;
1842 (void)widget;
1843 
1844 if(GLOBALS->helpbox_is_active)
1845         {
1846         help_text_bold("\n\nZoom Pow10 Snap");
1847         help_text(
1848 		" snaps time values to a power of ten boundary when active.  Fractional zooms are"
1849 		" internally stored, but what is actually displayed will be rounded up/down to the"
1850 		" nearest power of 10.  This only works when the ticks per frame is greater than 100"
1851 		" units."
1852         );
1853         }
1854 	else
1855 	{
1856 #ifndef WAVE_USE_MLIST_T
1857 	if(GLOBALS->zoom_pow10_snap)
1858 		{
1859 		GLOBALS->zoom_pow10_snap=0;
1860 		status_text("Pow10 Snap Off.\n");
1861 		}
1862 		else
1863 		{
1864 		GLOBALS->zoom_pow10_snap=1;
1865 		status_text("Pow10 Snap On.\n");
1866 		}
1867 #else
1868        GLOBALS->zoom_pow10_snap = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZPS]));
1869         if(!GLOBALS->zoom_pow10_snap)
1870                 {
1871                 status_text("Pow10 Snap Off.\n");
1872                 }
1873                 else
1874                 {
1875                 status_text("Pow10 Snap On.\n");
1876                 }
1877 #endif
1878 
1879 	if(GLOBALS->wave_hslider)
1880 		{
1881 		calczoom(GLOBALS->tims.zoom);
1882 		fix_wavehadj();
1883 
1884 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */
1885 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */
1886 		}
1887 	}
1888 
1889 #ifndef WAVE_USE_MLIST_T
1890 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZPS].path))->active=(GLOBALS->zoom_pow10_snap)?TRUE:FALSE;
1891 #endif
1892 }
1893 
1894 /**/
1895 void menu_zoom_dynf(gpointer null_data, guint callback_action, GtkWidget *widget)
1896 {
1897 (void)null_data;
1898 (void)callback_action;
1899 (void)widget;
1900 
1901 if(GLOBALS->helpbox_is_active)
1902         {
1903         help_text_bold("\n\nPartial VCD Dynamic Zoom Full");
1904         help_text(
1905 		" causes the screen to be in full zoom mode while a VCD file is loading"
1906 		" incrementally."
1907         );
1908         }
1909 	else
1910 	{
1911 #ifndef WAVE_USE_MLIST_T
1912 	if(GLOBALS->zoom_dyn)
1913 		{
1914 		GLOBALS->zoom_dyn=0;
1915 		status_text("Dynamic Zoom Full Off.\n");
1916 		}
1917 		else
1918 		{
1919 		GLOBALS->zoom_dyn=1;
1920 		status_text("Dynamic Zoom Full On.\n");
1921 		}
1922 #else
1923         GLOBALS->zoom_dyn = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYN]));
1924         if(!GLOBALS->zoom_dyn)
1925                 {
1926                 status_text("Dynamic Zoom Full Off.\n");
1927                 }
1928                 else
1929                 {
1930                 status_text("Dynamic Zoom Full On.\n");
1931                 }
1932 #endif
1933 	}
1934 
1935 #ifndef WAVE_USE_MLIST_T
1936 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYN].path))->active=(GLOBALS->zoom_dyn)?TRUE:FALSE;
1937 #endif
1938 }
1939 
1940 /**/
1941 void menu_zoom_dyne(gpointer null_data, guint callback_action, GtkWidget *widget)
1942 {
1943 (void)null_data;
1944 (void)callback_action;
1945 (void)widget;
1946 
1947 if(GLOBALS->helpbox_is_active)
1948         {
1949         help_text_bold("\n\nPartial VCD Dynamic Zoom To End");
1950         help_text(
1951 		" causes the screen to zoom to the end while a VCD file is loading"
1952 		" incrementally."
1953         );
1954         }
1955 	else
1956 	{
1957 #ifndef WAVE_USE_MLIST_T
1958 	if(GLOBALS->zoom_dyne)
1959 		{
1960 		GLOBALS->zoom_dyne=0;
1961 		status_text("Dynamic Zoom To End Off.\n");
1962 		}
1963 		else
1964 		{
1965 		GLOBALS->zoom_dyne=1;
1966 		status_text("Dynamic Zoom To End On.\n");
1967 		}
1968 #else
1969         GLOBALS->zoom_dyne = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYNE]));
1970         if(!GLOBALS->zoom_dyne)
1971                 {
1972                 status_text("Dynamic Zoom To End Off.\n");
1973                 }
1974                 else
1975                 {
1976                 status_text("Dynamic Zoom To End On.\n");
1977                 }
1978 #endif
1979 	}
1980 
1981 #ifndef WAVE_USE_MLIST_T
1982 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYNE].path))->active=(GLOBALS->zoom_dyne)?TRUE:FALSE;
1983 #endif
1984 }
1985 
1986 /**/
1987 void menu_left_justify(gpointer null_data, guint callback_action, GtkWidget *widget)
1988 {
1989 (void)null_data;
1990 (void)callback_action;
1991 (void)widget;
1992 
1993 if(GLOBALS->helpbox_is_active)
1994         {
1995         help_text_bold("\n\nLeft Justify Signals");
1996         help_text(
1997 		" draws signal names flushed to the left border of the signal window."
1998         );
1999         }
2000 	else
2001 	{
2002 	status_text("Left Justification.\n");
2003 	GLOBALS->left_justify_sigs=~0;
2004 	MaxSignalLength();
2005 	signalarea_configure_event(GLOBALS->signalarea, NULL);
2006 	}
2007 }
2008 
2009 /**/
2010 void menu_right_justify(gpointer null_data, guint callback_action, GtkWidget *widget)
2011 {
2012 (void)null_data;
2013 (void)callback_action;
2014 (void)widget;
2015 
2016 if(GLOBALS->helpbox_is_active)
2017         {
2018         help_text_bold("\n\nRight Justify Signals");
2019         help_text(
2020 		" draws signal names flushed to the right (\"equals\") side of the signal window."
2021         );
2022         }
2023 	else
2024 	{
2025 	status_text("Right Justification.\n");
2026 	GLOBALS->left_justify_sigs=0;
2027 	MaxSignalLength();
2028 	signalarea_configure_event(GLOBALS->signalarea, NULL);
2029 	}
2030 }
2031 
2032 /**/
2033 void menu_enable_constant_marker_update(gpointer null_data, guint callback_action, GtkWidget *widget)
2034 {
2035 (void)null_data;
2036 (void)callback_action;
2037 (void)widget;
2038 
2039 if(GLOBALS->helpbox_is_active)
2040         {
2041         help_text_bold("\n\nConstant Marker Update");
2042         help_text(
2043 		" when enabled,"
2044 		" allows GTKWave to dynamically show the changing values of the"
2045 		" traces under the primary marker while it is being dragged"
2046 		" across the screen.  This works best with dynamic resizing disabled."
2047 		" When disabled, it"
2048 		" restricts GTKWave to only update the trace values when the"
2049 		" left mouse button is initially pressed then again when it is released."
2050 		" This is the default behavior."
2051         );
2052         }
2053 	else
2054 	{
2055 #ifndef WAVE_USE_MLIST_T
2056 	if(!GLOBALS->constant_marker_update)
2057 		{
2058 		status_text("Constant marker update enabled.\n");
2059 		GLOBALS->constant_marker_update=~0;
2060 		}
2061 		else
2062 		{
2063 		status_text("Constant marker update disabled.\n");
2064 		GLOBALS->constant_marker_update=0;
2065 		}
2066 #else
2067         GLOBALS->constant_marker_update = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCMU]));
2068         if(GLOBALS->constant_marker_update)
2069                 {
2070                 status_text("Constant marker update enabled.\n");
2071                 }
2072                 else
2073                 {
2074                 status_text("Constant marker update disabled.\n");
2075                 }
2076 #endif
2077 	}
2078 
2079 #ifndef WAVE_USE_MLIST_T
2080 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCMU].path))->active=(GLOBALS->constant_marker_update)?TRUE:FALSE;
2081 #endif
2082 }
2083 /**/
2084 void menu_enable_standard_trace_select(gpointer null_data, guint callback_action, GtkWidget *widget)
2085 {
2086 (void)null_data;
2087 (void)callback_action;
2088 (void)widget;
2089 
2090 if(GLOBALS->helpbox_is_active)
2091         {
2092         help_text_bold("\n\nStandard Trace Select");
2093         help_text(
2094 		" when enabled,"
2095 		" keeps the currently selected traces from deselecting on mouse button press."
2096 		" This allows drag and drop to function more smoothly.  As this behavior is not"
2097 		" how GTK normally functions, it is by default disabled."
2098         );
2099         }
2100 	else
2101 	{
2102 #ifndef WAVE_USE_MLIST_T
2103 	if(!GLOBALS->use_standard_trace_select)
2104 		{
2105 		status_text("Standard Trace Select enabled.\n");
2106 		GLOBALS->use_standard_trace_select=~0;
2107 		}
2108 		else
2109 		{
2110 		status_text("Standard Trace Select disabled.\n");
2111 		GLOBALS->use_standard_trace_select=0;
2112 		}
2113 #else
2114         GLOBALS->use_standard_trace_select = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ESTS]));
2115         if(GLOBALS->use_standard_trace_select)
2116                 {
2117                 status_text("Standard Trace Select enabled.\n");
2118                 }
2119                 else
2120                 {
2121                 status_text("Standard Trace Select disabled.\n");
2122                 }
2123 #endif
2124 	}
2125 
2126 #ifndef WAVE_USE_MLIST_T
2127 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ESTS].path))->active=(GLOBALS->use_standard_trace_select)?TRUE:FALSE;
2128 #endif
2129 }
2130 /**/
2131 void menu_enable_dynamic_resize(gpointer null_data, guint callback_action, GtkWidget *widget)
2132 {
2133 (void)null_data;
2134 (void)callback_action;
2135 (void)widget;
2136 int i;
2137 
2138 if(GLOBALS->helpbox_is_active)
2139         {
2140         help_text_bold("\n\nDynamic Resize");
2141         help_text(
2142 		" allows GTKWave to dynamically resize the signal"
2143 		" window for you when toggled active.  This can be helpful during numerous"
2144 		" signal additions and/or deletions.  This is the default"
2145 		" behavior."
2146         );
2147         }
2148 	else
2149 	{
2150 #ifndef WAVE_USE_MLIST_T
2151 	if(!GLOBALS->do_resize_signals)
2152 		{
2153 		status_text("Resizing enabled.\n");
2154 		GLOBALS->do_resize_signals=~0;
2155 		}
2156 		else
2157 		{
2158 		status_text("Resizing disabled.\n");
2159 		GLOBALS->do_resize_signals=0;
2160 		}
2161 
2162 	for(i=0;i<2;i++)
2163 		{
2164 		GLOBALS->signalwindow_width_dirty=1;
2165 		MaxSignalLength();
2166 		signalarea_configure_event(GLOBALS->signalarea, NULL);
2167 		wavearea_configure_event(GLOBALS->wavearea, NULL);
2168 		}
2169 #else
2170         GLOBALS->do_resize_signals = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDR]));
2171         if(GLOBALS->do_resize_signals)
2172                 {
2173                 status_text("Resizing enabled.\n");
2174                 }
2175                 else
2176                 {
2177                 status_text("Resizing disabled.\n");
2178                 }
2179 
2180         if(GLOBALS->signalarea && GLOBALS->wavearea)
2181                 {
2182 		for(i=0;i<2;i++)
2183 			{
2184 	                GLOBALS->signalwindow_width_dirty=1;
2185 	                MaxSignalLength();
2186 	                signalarea_configure_event(GLOBALS->signalarea, NULL);
2187 	                wavearea_configure_event(GLOBALS->wavearea, NULL);
2188 			}
2189                 }
2190 #endif
2191 	}
2192 
2193 #ifndef WAVE_USE_MLIST_T
2194 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDR].path))->active=(GLOBALS->do_resize_signals)?TRUE:FALSE;
2195 #endif
2196 }
2197 /**/
2198 void menu_toggle_delta_or_frequency(gpointer null_data, guint callback_action, GtkWidget *widget)
2199 {
2200 (void)null_data;
2201 (void)callback_action;
2202 (void)widget;
2203 
2204 if(GLOBALS->helpbox_is_active)
2205         {
2206         help_text_bold("\n\nToggle Delta-Frequency");
2207         help_text(
2208 		" allows you to switch between the delta time and"
2209 		" frequency display in the upper right corner"
2210 		" of the main window when measuring distances between markers.  Default behavior is that the"
2211 		" delta time is displayed."
2212         );
2213         }
2214 	else
2215 	{
2216 	GLOBALS->use_frequency_delta=(GLOBALS->use_frequency_delta)?0:1;
2217 	update_maxmarker_labels();
2218 	}
2219 }
2220 /**/
2221 void menu_toggle_max_or_marker(gpointer null_data, guint callback_action, GtkWidget *widget)
2222 {
2223 (void)null_data;
2224 (void)callback_action;
2225 (void)widget;
2226 
2227 if(GLOBALS->helpbox_is_active)
2228         {
2229         help_text_bold("\n\nToggle Max-Marker");
2230         help_text(
2231 		" allows you to switch between the maximum time and"
2232 		" marker time for display in the upper right corner"
2233 		" of the main window.  Default behavior is that the"
2234 		" maximum time is displayed."
2235         );
2236         }
2237 	else
2238 	{
2239 	GLOBALS->use_maxtime_display=(GLOBALS->use_maxtime_display)?0:1;
2240 	update_maxmarker_labels();
2241 	}
2242 }
2243 /**/
2244 #ifdef MAC_INTEGRATION
2245 void menu_help_manual(gpointer null_data, guint callback_action, GtkWidget *widget)
2246 {
2247 (void)null_data;
2248 (void)callback_action;
2249 (void)widget;
2250 
2251 if(GLOBALS->helpbox_is_active)
2252         {
2253         help_text_bold("\n\nWave User's Guide");
2254         help_text(
2255 		" opens the PDF file of the GTKWave User's Guide for viewing."
2256         );
2257         return;
2258         }
2259 	else
2260 	{
2261         const gchar *bundle_id = gtkosx_application_get_bundle_id();
2262         if(bundle_id)
2263                 {
2264                 const gchar *rpath = gtkosx_application_get_resource_path();
2265                 const char *suf = "/doc/gtkwave.pdf";
2266 		char *pdfpath = NULL;
2267 		FILE *handle;
2268 
2269                 if(rpath)
2270                         {
2271                         pdfpath = (char *)alloca(strlen(rpath) + strlen(suf) + 1);
2272                         strcpy(pdfpath, rpath);
2273                         strcat(pdfpath, suf);
2274                         }
2275 
2276                 if(!pdfpath || !(handle=fopen(pdfpath,"rb")))
2277 			{
2278 			}
2279 			else
2280 			{
2281 			fclose(handle);
2282 			gtk_open_external_file(pdfpath);
2283 			return;
2284 			}
2285 		}
2286 
2287 	simplereqbox("Wave User's Guide",400,"Could not open PDF!","OK", NULL, NULL, 1);
2288 	}
2289 }
2290 #endif
2291 /**/
2292 void menu_help(gpointer null_data, guint callback_action, GtkWidget *widget)
2293 {
2294 (void)null_data;
2295 (void)callback_action;
2296 (void)widget;
2297 
2298 if(GLOBALS->helpbox_is_active)
2299         {
2300         help_text_bold("\n\nWave Help");
2301         help_text(
2302 		" is already active.  It's this window."
2303         );
2304         return;
2305         }
2306 
2307 helpbox("Wave Help",480,"Select any main window menu item");
2308 }
2309 /**/
2310 void menu_version(gpointer null_data, guint callback_action, GtkWidget *widget)
2311 {
2312 (void)null_data;
2313 (void)callback_action;
2314 (void)widget;
2315 
2316 if(GLOBALS->helpbox_is_active)
2317         {
2318         help_text_bold("\n\nWave Version");
2319         help_text(
2320                 " merely brings up a requester which indicates the current"
2321 		" version of this program."
2322         );
2323         return;
2324         }
2325 
2326 simplereqbox("Wave Version",480,WAVE_VERSION_INFO,"OK", NULL, NULL, 0);
2327 }
2328 /**/
2329 void menu_quit_callback(GtkWidget *widget, gpointer data)
2330 {
2331 (void)widget;
2332 
2333 char sstr[32];
2334 
2335 if(data)
2336 	{
2337 #ifdef __CYGWIN__
2338 	kill_stems_browser();
2339 #endif
2340 	g_print("Exiting.\n");
2341 	sprintf(sstr, "%d", GLOBALS->this_context_page);
2342 	gtkwavetcl_setvar(WAVE_TCLCB_QUIT_PROGRAM, sstr, WAVE_TCLCB_QUIT_PROGRAM_FLAGS);
2343 
2344 	gtk_exit(0);
2345 	}
2346 }
2347 void menu_quit(gpointer null_data, guint callback_action, GtkWidget *widget)
2348 {
2349 (void)null_data;
2350 (void)callback_action;
2351 (void)widget;
2352 
2353 if(GLOBALS->helpbox_is_active)
2354 	{
2355 	help_text_bold("\n\nQuit");
2356 	help_text(
2357 		" closes GTKWave and exits immediately."
2358 	);
2359 	return;
2360 	}
2361 
2362 if(GLOBALS->save_on_exit) { menu_write_save_file(NULL, 0, NULL); }
2363 
2364 if(!GLOBALS->enable_fast_exit)
2365 	{
2366 	simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", GTK_SIGNAL_FUNC(menu_quit_callback), 1);
2367 	}
2368 	else
2369 	{
2370 	menu_quit_callback(NULL, &GLOBALS->enable_fast_exit); /* nonzero dummy arg */
2371 	}
2372 }
2373 
2374 /**/
2375 
2376 void menu_quit_close_callback(GtkWidget *widget, gpointer dummy_data)
2377 {
2378 (void)widget;
2379 (void)dummy_data;
2380 
2381 unsigned int i, j=0;
2382 unsigned int this_page = GLOBALS->this_context_page;
2383 unsigned np = GLOBALS->num_notebook_pages;
2384 unsigned int new_page = (this_page != np-1) ? this_page : (this_page-1);
2385 GtkWidget *n = GLOBALS->notebook;
2386 struct Global *old_g = NULL, *saved_g;
2387 char sstr[32];
2388 gboolean is_mf = (GLOBALS->loaded_file_type == MISSING_FILE);
2389 
2390 sprintf(sstr, "%d", this_page);
2391 gtkwavetcl_setvar(WAVE_TCLCB_CLOSE_TAB_NUMBER, sstr, WAVE_TCLCB_CLOSE_TAB_NUMBER_FLAGS);
2392 
2393 kill_stems_browser_single(GLOBALS);
2394 dead_context_sweep();
2395 
2396 for(i=0;i<np;i++)
2397 	{
2398 	if(i!=this_page)
2399 		{
2400 		(*GLOBALS->contexts)[j] = (*GLOBALS->contexts)[i];
2401 		(*GLOBALS->contexts)[j]->this_context_page = j;
2402 		(*GLOBALS->contexts)[j]->num_notebook_pages--;
2403 
2404 		j++;
2405 		}
2406 		else
2407 		{
2408 		old_g = (*GLOBALS->contexts)[j];
2409 		}
2410 	}
2411 (*GLOBALS->contexts)[j] = old_g;
2412 
2413 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(n), (np>2));
2414 gtk_notebook_set_show_border(GTK_NOTEBOOK(n), (np>2));
2415 
2416 gtk_notebook_remove_page(GTK_NOTEBOOK(n), this_page);
2417 gtk_notebook_set_current_page(GTK_NOTEBOOK(n), new_page);
2418 
2419 set_GLOBALS((*GLOBALS->contexts)[new_page]);
2420 saved_g = GLOBALS;
2421 
2422 gtkwave_main_iteration();
2423 
2424 set_GLOBALS(old_g);
2425 if(!is_mf)
2426 	{
2427 	free_and_destroy_page_context();
2428 	}
2429 set_GLOBALS(saved_g);
2430 
2431 /* need to do this if 2 pages -> 1 */
2432 reformat_time(sstr, GLOBALS->tims.first, GLOBALS->time_dimension);
2433 gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),sstr);
2434 reformat_time(sstr, GLOBALS->tims.last, GLOBALS->time_dimension);
2435 gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),sstr);
2436 update_maxmarker_labels();
2437 update_basetime(GLOBALS->tims.baseline);
2438 
2439 gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname);
2440 
2441 MaxSignalLength();
2442 signalarea_configure_event(GLOBALS->signalarea, NULL);
2443 wavearea_configure_event(GLOBALS->wavearea, NULL);
2444 }
2445 
2446 void menu_quit_close(gpointer null_data, guint callback_action, GtkWidget *widget)
2447 {
2448 (void)null_data;
2449 (void)callback_action;
2450 (void)widget;
2451 
2452 if(GLOBALS->helpbox_is_active)
2453         {
2454         help_text_bold("\n\nClose");
2455         help_text(
2456 		" immediately closes the current tab if multiple tabs exist or"
2457                 " exits GTKWave after an additional confirmation"
2458                 " requester is given the OK to quit."
2459         );
2460         return;
2461         }
2462 
2463 if((GLOBALS->num_notebook_pages < 2) && (!GLOBALS->enable_fast_exit))
2464 	{
2465 	simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", GTK_SIGNAL_FUNC(menu_quit_callback), 1);
2466 	}
2467 	else
2468 	{
2469 	if(GLOBALS->num_notebook_pages < 2)
2470 		{
2471 		menu_quit_callback(NULL, &GLOBALS->num_notebook_pages); /* nonzero dummy arg */
2472 		}
2473 		else
2474 		{
2475 		menu_quit_close_callback(NULL, NULL); /* dummy arg, not needed to be nonzero */
2476 		}
2477 	}
2478 }
2479 
2480 /**/
2481 void must_sel(void)
2482 {
2483   status_text("Select one or more traces.\n");
2484 }
2485 static void must_sel_nb(void)
2486 {
2487   status_text("Select one or more nonblank traces.\n");
2488 }
2489 static void must_sel_bg(void)
2490 {
2491   status_text("Select a bundle or group.\n");
2492 }
2493 /**/
2494 
2495 static void
2496 menu_open_group(GtkWidget *widget, gpointer data)
2497 {
2498 (void)widget;
2499 (void)data;
2500 
2501   Trptr t;
2502   unsigned dirty = 0;
2503 
2504   /* currently only called by toggle menu option, so no help menu text */
2505 
2506  if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
2507 
2508  t=GLOBALS->traces.first;
2509  while(t)
2510    {
2511      if((t->flags&TR_HIGHLIGHT)&&(IsGroupBegin(t) || IsGroupEnd(t)))
2512        {
2513 	 dirty=1;
2514 	 break;
2515        }
2516      t=t->t_next;
2517    }
2518 
2519  if(dirty)
2520    {
2521      OpenTrace(t);
2522      GLOBALS->signalwindow_width_dirty=1;
2523      MaxSignalLength();
2524      signalarea_configure_event(GLOBALS->signalarea, NULL);
2525      wavearea_configure_event(GLOBALS->wavearea, NULL);
2526    }
2527  else
2528    {
2529      must_sel_bg();
2530    }
2531 }
2532 
2533 
2534 static void
2535 menu_close_group(GtkWidget *widget, gpointer data)
2536 {
2537 (void)widget;
2538 (void)data;
2539 
2540   Trptr t;
2541   unsigned dirty = 0;
2542 
2543   /* currently only called by toggle menu option, so no help menu text */
2544 
2545  if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
2546 
2547  t=GLOBALS->traces.first;
2548  while(t)
2549    {
2550      if((t->flags&TR_HIGHLIGHT)&&(IsGroupBegin(t) || IsGroupEnd(t)))
2551        {
2552 	 dirty=1;
2553 	 break;
2554        }
2555      t=t->t_next;
2556    }
2557 
2558  if(dirty)
2559    {
2560 
2561      CloseTrace(t);
2562      GLOBALS->signalwindow_width_dirty=1;
2563      MaxSignalLength();
2564      signalarea_configure_event(GLOBALS->signalarea, NULL);
2565      wavearea_configure_event(GLOBALS->wavearea, NULL);
2566    }
2567  else
2568    {
2569      must_sel_bg();
2570    }
2571 }
2572 
2573 
2574 
2575 
2576 unsigned create_group (char* name, Trptr t_composite)
2577 {
2578   Trptr t, t_prev, t_begin, t_end;
2579   unsigned dirty = 0;
2580 
2581  if(!name) name = "Group"; /* generate anonymous name */
2582 
2583  t=GLOBALS->traces.first;
2584  while(t)
2585    {
2586      if(t->flags&TR_HIGHLIGHT)
2587        {
2588 	 dirty=1;
2589 	 break;
2590        }
2591      t=t->t_next;
2592    }
2593 
2594  if(dirty)
2595    {
2596 
2597      t_prev = t->t_prev;
2598 
2599      CutBuffer();
2600 
2601      if (t_composite)
2602        {
2603 	 t_begin = t_composite;
2604 	 t_begin->flags |=TR_GRP_BEGIN;
2605        }
2606      else
2607        {
2608 	 if( (t_begin = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL )
2609 	   {
2610 	     fprintf( stderr, "Out of memory, can't add trace.\n");
2611 	     return(0);
2612 	   }
2613 
2614 	 t_begin->flags = (TR_BLANK|TR_GRP_BEGIN);
2615 	 t_begin->name = (char *)malloc_2(1+strlen(name));
2616 	 strcpy(t_begin->name, name);
2617        }
2618 
2619      GLOBALS->traces.buffer->t_prev = t_begin;
2620      t_begin->t_next = GLOBALS->traces.buffer;
2621      GLOBALS->traces.buffer = t_begin;
2622      GLOBALS->traces.buffercount++;
2623 
2624      if( (t_end = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL )
2625        {
2626 	 fprintf( stderr, "Out of memory, can't add trace.\n");
2627 	 return(0);
2628        }
2629 
2630      t_end->flags = (TR_BLANK|TR_GRP_END);
2631 
2632      if (t_composite)
2633        {
2634 	 /* make the group end trace invisible */
2635 	 t_end->flags |= TR_COLLAPSED;
2636 	 t_end->name = (char *)malloc_2(1+strlen("group_end"));
2637 	 strcpy(t_end->name, "group_end");
2638        }
2639      else
2640        {
2641 	 t_end->name = (char *)malloc_2(1+strlen(name));
2642 	 strcpy(t_end->name, name);
2643        }
2644 
2645      GLOBALS->traces.bufferlast->t_next = t_end;
2646      t_end->t_prev = GLOBALS->traces.bufferlast;
2647      GLOBALS->traces.bufferlast = t_end;
2648      GLOBALS->traces.buffercount++;
2649 
2650      t_begin->t_match = t_end;
2651      t_end->t_match   = t_begin;
2652 
2653      if (t_prev)
2654        {
2655 	 t_prev->flags |= TR_HIGHLIGHT;
2656 	 PasteBuffer();
2657        }
2658      else
2659        {
2660 	 PrependBuffer();
2661        }
2662    }
2663  return dirty;
2664 }
2665 
2666 
2667 static void
2668 create_group_cleanup(GtkWidget *widget, gpointer data)
2669 {
2670 (void)widget;
2671 (void)data;
2672 
2673   unsigned dirty = 0;
2674 
2675   dirty = create_group(GLOBALS->entrybox_text, NULL);
2676 
2677   if (!dirty)
2678     	{
2679       	must_sel_bg();
2680     	}
2681     	else
2682 	{
2683       	GLOBALS->signalwindow_width_dirty=1;
2684       	MaxSignalLength();
2685       	signalarea_configure_event(GLOBALS->signalarea, NULL);
2686       	wavearea_configure_event(GLOBALS->wavearea, NULL);
2687 	}
2688 }
2689 
2690 
2691 
2692 void
2693 menu_create_group(gpointer null_data, guint callback_action, GtkWidget *widget)
2694 {
2695 (void)null_data;
2696 (void)callback_action;
2697 (void)widget;
2698 
2699   Trptr t;
2700   unsigned dirty = 0;
2701 
2702   if(GLOBALS->helpbox_is_active)
2703     {
2704       help_text_bold("\n\nCreate Group");
2705       help_text(
2706 		" creates a group of traces which may be opened or closed."
2707 		" It is permitted for groups to be nested."
2708 		);
2709       return;
2710     }
2711 
2712   t=GLOBALS->traces.first;
2713   while(t)
2714     {
2715       if(t->flags&TR_HIGHLIGHT)
2716        {
2717 	 dirty=1;
2718 	 break;
2719        }
2720       t=t->t_next;
2721     }
2722 
2723   if(dirty)
2724     {
2725       /* don't mess with sigs when dnd active */
2726       if(GLOBALS->dnd_state) { dnd_error(); return; }
2727       entrybox("Create Group",300,"","Enter group name:",128,GTK_SIGNAL_FUNC(create_group_cleanup));
2728     }
2729   else
2730     {
2731       must_sel_bg();
2732     }
2733 }
2734 
2735 
2736 static unsigned expand_trace(Trptr t_top)
2737 {
2738 
2739   Trptr t, tmp;
2740   int tmpi;
2741   unsigned dirty = 0;
2742   int color;
2743 
2744   t = t_top;
2745 
2746   if(HasWave(t) && !IsGroupBegin(t) && !IsGroupEnd(t))
2747     {
2748       FreeCutBuffer();
2749       GLOBALS->traces.buffer=GLOBALS->traces.first;
2750       GLOBALS->traces.bufferlast=GLOBALS->traces.last;
2751       GLOBALS->traces.buffercount=GLOBALS->traces.total;
2752 
2753       GLOBALS->traces.first=GLOBALS->traces.last=NULL; GLOBALS->traces.total=0;
2754 
2755       color = t->t_color;
2756 
2757       if(t->vector)
2758 	{
2759 	  bptr bits;
2760 	  int i;
2761 	  Trptr tfix;
2762 	  TimeType otime = t->shift;
2763 
2764 	  bits=t->n.vec->bits;
2765 	  if(!(t->flags&TR_REVERSE))
2766 	    {
2767 	      for(i=0;i<bits->nnbits;i++)
2768 		{
2769 		  if(bits->nodes[i]->expansion) bits->nodes[i]->expansion->refcnt++;
2770 		  GLOBALS->which_t_color = color;
2771 		  AddNodeTraceReturn(bits->nodes[i],NULL, &tfix);
2772 		  if(bits->attribs)
2773 		    {
2774 		      tfix->shift = otime + bits->attribs[i].shift;
2775 		    }
2776 		}
2777 	    }
2778 	  else
2779 	    {
2780 	      for(i=(bits->nnbits-1);i>-1;i--)
2781 		{
2782 		  if(bits->nodes[i]->expansion) bits->nodes[i]->expansion->refcnt++;
2783 		  GLOBALS->which_t_color = color;
2784 		  AddNodeTraceReturn(bits->nodes[i],NULL, &tfix);
2785 		  if(bits->attribs)
2786 		    {
2787 		      tfix->shift = otime + bits->attribs[i].shift;
2788 		    }
2789 		}
2790 	    }
2791 	}
2792       else
2793 	{
2794 	  eptr e=ExpandNode(t->n.nd);
2795 	  int i;
2796 	  if(!e)
2797 	    {
2798 	      /* 		      if(t->n.nd->expansion) t->n.nd->expansion->refcnt++; */
2799 	      /* 		      AddNode(t->n.nd,NULL); */
2800 	    }
2801 	  else
2802 	    {
2803 	      int dhc_sav = GLOBALS->do_hier_compress;
2804 	      GLOBALS->do_hier_compress = 0;
2805 	      for(i=0;i<e->width;i++)
2806 		{
2807 		  GLOBALS->which_t_color = color;
2808 		  AddNode(e->narray[i], NULL);
2809 		}
2810 	      GLOBALS->do_hier_compress = dhc_sav;
2811 	      free_2(e->narray);
2812 	      free_2(e);
2813 	    }
2814 	}
2815 
2816       tmp=GLOBALS->traces.buffer; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.first=tmp;
2817       tmp=GLOBALS->traces.bufferlast; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.last=tmp;
2818       tmpi=GLOBALS->traces.buffercount; GLOBALS->traces.buffercount=GLOBALS->traces.total;
2819       GLOBALS->traces.total=tmpi;
2820 
2821       if (GLOBALS->traces.buffercount > 0)
2822 	{
2823 
2824 	  /* buffer now contains the created signals */
2825 	  ClearTraces();
2826 
2827 	  if (t_top->t_prev)
2828 	    {
2829 	      t_top->t_prev->flags |= TR_HIGHLIGHT;
2830 	      RemoveTrace(t_top, 0);
2831 	      PasteBuffer();
2832 	      t_top->t_prev->flags &= ~TR_HIGHLIGHT;
2833 	    }
2834 	  else
2835 	    {
2836 	      RemoveTrace(t_top, 0);
2837 	      PrependBuffer();
2838 	    }
2839 
2840 	  dirty = create_group("unused_2", t_top);
2841 
2842 	}
2843     }
2844 
2845   GLOBALS->which_t_color = 0;
2846   return dirty;
2847 }
2848 
2849 void
2850 menu_expand(gpointer null_data, guint callback_action, GtkWidget *widget)
2851 {
2852 (void)null_data;
2853 (void)callback_action;
2854 (void)widget;
2855 
2856   Trptr t, t_next;
2857   int dirty=0;
2858   int j;
2859   GtkAdjustment *wadj;
2860 
2861   if(GLOBALS->helpbox_is_active)
2862     {
2863       help_text_bold("\n\nExpand");
2864       help_text(
2865 		" decomposes the highlighted signals into their individual bits."
2866 		" The resulting bits are converted to traces and inserted after the"
2867 		" last highlighted trace.  The original unexpanded traces will"
2868 		" be placed in the cut buffer."
2869 		" It will function seemingly randomly"
2870 		" when used upon real valued single-bit traces."
2871 		" When used upon multi-bit vectors that contain"
2872 		" real valued traces, those traces will expand to their normal \"correct\" values,"
2873 		" not individual bits."
2874 		);
2875       return;
2876     }
2877 
2878 
2879   if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
2880 
2881   DEBUG(printf("Expand Traces\n"));
2882 
2883   t=GLOBALS->traces.first;
2884   while(t)
2885     {
2886       if(IsSelected(t) && HasWave(t))
2887 	{
2888 	  t->flags |= TR_COLLAPSED;
2889 	  dirty=1;
2890 	}
2891       t=t->t_next;
2892     }
2893 
2894   if(dirty)
2895     {
2896       ClearTraces();
2897       t=GLOBALS->traces.first;
2898       while(t)
2899 	{
2900 	  t_next = t->t_next;
2901 	  if(HasWave(t) && (t->flags&TR_COLLAPSED))
2902 	    {
2903 	      if (!IsGroupBegin(t) && !IsGroupEnd(t))
2904 		{
2905 		  expand_trace(t);
2906 		}
2907 	      else
2908 		{
2909 		  OpenTrace(t);
2910 		}
2911 	    }
2912 	  t=t_next;
2913 	}
2914       t=GLOBALS->traces.first;
2915       if(t) { t->t_grp = NULL; } /* scan-build */
2916       while(t)
2917 	{
2918 	  if(HasWave(t) && (t->flags&TR_COLLAPSED))
2919 	    {
2920 	      t->flags &= ~TR_COLLAPSED;
2921       	      t->flags |= TR_HIGHLIGHT;
2922 	    }
2923 
2924 	  updateTraceGroup(t);
2925 	  t=t->t_next;
2926 	}
2927 
2928       t=GLOBALS->traces.first;
2929       while(t)
2930 	{
2931 	  if (IsSelected(t)) { break; }
2932 	  t=t->t_next;
2933 	}
2934 
2935       j = GetTraceNumber(t);
2936       wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
2937       if (j < wadj->value)
2938 	{
2939 	  SetTraceScrollbarRowValue(j, 0);
2940 	}
2941 
2942       GLOBALS->signalwindow_width_dirty=1;
2943       MaxSignalLength();
2944       signalarea_configure_event(GLOBALS->signalarea, NULL);
2945       wavearea_configure_event(GLOBALS->wavearea, NULL);
2946     }
2947   else
2948     {
2949       must_sel_nb();
2950     }
2951 }
2952 
2953 void
2954 menu_toggle_group(gpointer null_data, guint callback_action, GtkWidget *widget)
2955 {
2956 (void)null_data;
2957 (void)callback_action;
2958 (void)widget;
2959 
2960   Trptr t;
2961   unsigned dirty_group  = 0;
2962   unsigned dirty_signal = 0;
2963 
2964   if(GLOBALS->helpbox_is_active)
2965         {
2966         help_text_bold("\n\nToggle Group");
2967         help_text(
2968 		" toggles a group opened or closed."
2969         );
2970         return;
2971         }
2972 
2973 
2974  if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
2975 
2976  t=GLOBALS->traces.first;
2977  while(t)
2978    {
2979      if((t->flags&TR_HIGHLIGHT)&&(IsGroupBegin(t) || IsGroupEnd(t)))
2980        {
2981 	 dirty_group=1;
2982 	 break;
2983        }
2984 
2985      if((t->flags&TR_HIGHLIGHT)&&HasWave(t))
2986        {
2987 	 dirty_signal=1;
2988 	 break;
2989        }
2990      t=t->t_next;
2991    }
2992 
2993  if(dirty_group)
2994    {
2995      if(IsClosed(t))
2996        {
2997 	 menu_open_group(widget, null_data);
2998 	 gtkwavetcl_setvar(WAVE_TCLCB_OPEN_TRACE_GROUP, t->name, WAVE_TCLCB_OPEN_TRACE_GROUP_FLAGS);
2999        }
3000      else
3001        {
3002 	 menu_close_group(widget, null_data);
3003 	 gtkwavetcl_setvar(WAVE_TCLCB_CLOSE_TRACE_GROUP, t->name, WAVE_TCLCB_CLOSE_TRACE_GROUP_FLAGS);
3004        }
3005      return;
3006    }
3007  if(dirty_signal)
3008    {
3009      ClearTraces();
3010      t->flags |= TR_HIGHLIGHT;
3011      menu_expand(null_data, 0, widget);
3012      gtkwavetcl_setvar(WAVE_TCLCB_OPEN_TRACE_GROUP, t->name, WAVE_TCLCB_OPEN_TRACE_GROUP_FLAGS);
3013      return;
3014    }
3015 
3016  must_sel_bg();
3017 }
3018 
3019 static void rename_cleanup(GtkWidget *widget, gpointer data)
3020 {
3021 (void)widget;
3022 (void)data;
3023 
3024   Trptr t = GLOBALS->trace_to_alias_menu_c_1;
3025 
3026   if(GLOBALS->entrybox_text)
3027     {
3028       char *efix;
3029       /* code to turn '{' and '}' into '[' and ']' */
3030       if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
3031 	{
3032 	  efix=GLOBALS->entrybox_text;
3033 	  while(*efix)
3034 	    {
3035 	      if(*efix=='{')
3036 		{
3037 		  *efix='[';
3038 		}
3039 	      if(*efix=='}')
3040 		{
3041 		  *efix=']';
3042 		}
3043 	      efix++;
3044 	    }
3045 	}
3046 
3047       if(t->vector)
3048 	{
3049 	  if(t->name_full)
3050 	    {
3051 	      free_2(t->name_full);
3052 	      t->name_full = NULL;
3053 	    }
3054 	  if (t->n.vec->bvname)
3055 	    {
3056 	      free_2(t->n.vec->bvname);
3057 	    }
3058 
3059 	  t->n.vec->bvname = (char *)malloc_2(1+strlen(GLOBALS->entrybox_text));
3060 	  strcpy(t->n.vec->bvname, GLOBALS->entrybox_text);
3061 	  t->name = t->n.vec->bvname;
3062 	  if(GLOBALS->hier_max_level)
3063 	    t->name = hier_extract(t->name, GLOBALS->hier_max_level);
3064 
3065 	  t->flags&= ~TR_HIGHLIGHT;
3066 
3067 	}
3068 
3069       GLOBALS->signalwindow_width_dirty=1;
3070       MaxSignalLength();
3071       signalarea_configure_event(GLOBALS->signalarea, NULL);
3072       wavearea_configure_event(GLOBALS->wavearea, NULL);
3073     }
3074 }
3075 
3076 
3077 static void menu_rename(GtkWidget *widget, gpointer data)
3078 {
3079 (void)widget;
3080 (void)data;
3081 
3082   Trptr t;
3083   /* currently only called by various combine menu options, so no help menu text */
3084 
3085   GLOBALS->trace_to_alias_menu_c_1=NULL;
3086 
3087   /* don't mess with sigs when dnd active */
3088   if(GLOBALS->dnd_state) { dnd_error(); return; }
3089 
3090   t = GLOBALS->traces.first;
3091   while(t)
3092     {
3093       if(IsSelected(t)&&(t->vector==TRUE))
3094 	{
3095 	  GLOBALS->trace_to_alias_menu_c_1 = t;
3096 	  break;
3097 	}
3098       t=t->t_next;
3099     }
3100 
3101   if(GLOBALS->trace_to_alias_menu_c_1)
3102     {
3103       int was_packed = HIER_DEPACK_ALLOC;
3104       char* current = GetFullName(GLOBALS->trace_to_alias_menu_c_1, &was_packed);
3105       ClearTraces();
3106       GLOBALS->trace_to_alias_menu_c_1->flags |= TR_HIGHLIGHT;
3107       entrybox("Trace Name",300,current,NULL,128,GTK_SIGNAL_FUNC(rename_cleanup));
3108       if(was_packed) { free_2(current); }
3109     }
3110   else
3111     {
3112       must_sel();
3113     }
3114 }
3115 
3116 
3117 bvptr combine_traces(int direction, Trptr single_trace_only)
3118 {
3119   Trptr t, tmp;
3120   Trptr tfirst = NULL;
3121   int tmpi,dirty=0, attrib_reqd=0;
3122   nptr bitblast_parent;
3123   int bitblast_delta=0;
3124 
3125   DEBUG(printf("Combine Traces\n"));
3126 
3127   t=single_trace_only ? single_trace_only : GLOBALS->traces.first;
3128   while(t)
3129     {
3130       if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))))
3131 	{
3132 	  if(t->vector)
3133 	    {
3134 	      dirty+=t->n.vec->nbits;
3135 	    }
3136 	  else
3137 	    {
3138 	      if(t->n.nd->extvals)
3139 		{
3140 		  int msb, lsb, width;
3141 		  msb = t->n.nd->msi;
3142 		  lsb = t->n.nd->lsi;
3143 		  if(msb>lsb) width = msb-lsb+1; else width = lsb-msb+1;
3144 		  dirty += width;
3145 		}
3146 	      else
3147 		{
3148 		  dirty++;
3149 		}
3150 	    }
3151 	}
3152       if(t == single_trace_only) break;
3153       t=t->t_next;
3154     }
3155 
3156   if(!dirty)
3157     {
3158       if(!single_trace_only) must_sel_nb();
3159       return NULL;
3160     }
3161   if(dirty>BITATTRIBUTES_MAX)
3162     {
3163       char buf[128];
3164 
3165       if(!single_trace_only)
3166 		{
3167 	      	sprintf(buf, "%d bits selected, please use <= %d.\n", dirty, BITATTRIBUTES_MAX);
3168 	      	status_text(buf);
3169 		}
3170       return NULL;
3171     }
3172   else
3173     {
3174       int i,nodepnt=0;
3175       struct Node *n[BITATTRIBUTES_MAX];
3176       struct BitAttributes ba[BITATTRIBUTES_MAX];
3177       struct Bits *b=NULL;
3178       bvptr v=NULL;
3179 
3180       memset(n, 0, sizeof(n)); /* scan-build */
3181 
3182       if(!single_trace_only)
3183 	{
3184       	FreeCutBuffer();
3185       	GLOBALS->traces.buffer=GLOBALS->traces.first;
3186       	GLOBALS->traces.bufferlast=GLOBALS->traces.last;
3187       	GLOBALS->traces.buffercount=GLOBALS->traces.total;
3188 
3189       	GLOBALS->traces.first=GLOBALS->traces.last=NULL; GLOBALS->traces.total=0;
3190 
3191       	t=GLOBALS->traces.buffer;
3192 	}
3193 	else
3194 	{
3195 	t = single_trace_only;
3196 	}
3197 
3198       tfirst = t;
3199       while(t)
3200 	{
3201 	  if(t->flags&TR_HIGHLIGHT)
3202 	    {
3203 	      if(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))
3204 		{
3205 		  /* nothing */
3206 		}
3207 	      else
3208 		{
3209 		  if(t->vector)
3210 		    {
3211 		      int ix;
3212 		      bptr bits = t->n.vec->bits;
3213 		      baptr oldba = bits ? bits->attribs : NULL;
3214 
3215 		      bits=t->n.vec->bits;
3216 
3217 		      if(!(t->flags&TR_REVERSE))
3218 			{
3219 			  for(ix=0;ix<bits->nnbits;ix++)
3220 			    {
3221 			      if(bits->nodes[ix]->expansion) bits->nodes[ix]->expansion->refcnt++;
3222 			      ba[nodepnt].shift = t->shift + (oldba ? oldba[ix].shift : 0);
3223 			      ba[nodepnt].flags = t->flags ^ (oldba ? oldba[ix].flags&TR_INVERT : 0);
3224 			      n[nodepnt++]=bits->nodes[ix];
3225 			    }
3226 			}
3227 		      else
3228 			{
3229 			  for(ix=(bits->nnbits-1);ix>-1;ix--)
3230 			    {
3231 			      if(bits->nodes[ix]->expansion) bits->nodes[ix]->expansion->refcnt++;
3232 			      ba[nodepnt].shift = t->shift + (oldba ? oldba[ix].shift : 0);
3233 			      ba[nodepnt].flags = t->flags ^ (oldba ? oldba[ix].flags&TR_INVERT : 0);
3234 			      n[nodepnt++]=bits->nodes[ix];
3235 			    }
3236 			}
3237 		    }
3238 		  else
3239 		    {
3240 		      eptr e=ExpandNode(t->n.nd);
3241 		      int ix;
3242 		      if(!e)
3243 			{
3244 			  if(t->n.nd->expansion) t->n.nd->expansion->refcnt++;
3245 			  ba[nodepnt].shift = t->shift;
3246 			  ba[nodepnt].flags = t->flags;
3247 			  n[nodepnt++]=t->n.nd;
3248 			}
3249 		      else
3250 			{
3251 			  for(ix=0;ix<e->width;ix++)
3252 			    {
3253 			      ba[nodepnt].shift = t->shift;
3254 			      ba[nodepnt].flags = t->flags;
3255 			      n[nodepnt++]=e->narray[ix];
3256 			      e->narray[ix]->expansion->refcnt++;
3257 			    }
3258 			  free_2(e->narray);
3259 			  free_2(e);
3260 			}
3261 		    }
3262 		}
3263 	    }
3264 	  if(nodepnt==dirty) break;
3265 	  if(t == single_trace_only) break;
3266 	  t=t->t_next;
3267 	}
3268 
3269       b=(struct Bits *)calloc_2(1,sizeof(struct Bits)+(nodepnt)*sizeof(struct Node *));
3270 
3271       b->attribs = malloc_2(nodepnt * sizeof(struct BitAttributes));
3272       for(i=0;i<nodepnt;i++)	/* for up combine we need to reverse the attribs list! */
3273 	{
3274 	  if(direction)
3275 	    {
3276 	      memcpy(b->attribs+i, ba+i, sizeof(struct BitAttributes));
3277 	    }
3278 	  else
3279 	    {
3280 	      memcpy(b->attribs+i, ba+(nodepnt-1-i), sizeof(struct BitAttributes));
3281 	    }
3282 
3283 	  if((ba[i].shift)||(ba[i].flags&TR_INVERT))	/* timeshift/invert are only relevant flags */
3284 	    {
3285 	      attrib_reqd = 1;
3286 	    }
3287 	}
3288 
3289       if(!attrib_reqd)
3290 	{
3291 	  free_2(b->attribs);
3292 	  b->attribs = NULL;
3293 	}
3294 
3295       if(nodepnt && n[0] && n[0]->expansion) /* scan-build */
3296 	{
3297 	  bitblast_parent = n[0]->expansion->parent;
3298 	}
3299       else
3300 	{
3301 	  bitblast_parent = NULL;
3302 	}
3303 
3304       if(direction)
3305 	{
3306 	  for(i=0;i<nodepnt;i++)
3307 	    {
3308 	      b->nodes[i]=n[i];
3309 	      if(n[i] && n[i]->expansion) /* scan-build */
3310 		{
3311 		  if(bitblast_parent != n[i]->expansion->parent)
3312 		    {
3313 		      bitblast_parent=NULL;
3314 		    }
3315 		  else
3316 		    {
3317 		      if(i==1)
3318 			{
3319 		          if(n[0] && n[0]->expansion) /* scan-build */
3320 				{
3321 				bitblast_delta = n[1]->expansion->actual - n[0]->expansion->actual;
3322 				if(bitblast_delta<-1) bitblast_delta=0;
3323 				else if(bitblast_delta>1) bitblast_delta=0;
3324 				}
3325 				else
3326 				{
3327 				bitblast_delta = 0;
3328 				}
3329 			}
3330 		      else if((bitblast_delta)&&(i>1))
3331 			{
3332 			  if((n[i]->expansion->actual - n[i-1]->expansion->actual) != bitblast_delta) bitblast_delta=0;
3333 			}
3334 		    }
3335 		}
3336 	      else
3337 		{
3338 		  bitblast_parent = NULL;
3339 		}
3340 	    }
3341 	}
3342       else
3343 	{
3344 	  int rev;
3345 	  rev=nodepnt-1;
3346 	  for(i=0;i<nodepnt;i++)
3347 	    {
3348 	      b->nodes[i]=n[rev--];
3349 	      if(n[i] && n[i]->expansion) /* scan-build */
3350 		{
3351 		  if(bitblast_parent != n[i]->expansion->parent)
3352 		    {
3353 		      bitblast_parent=NULL;
3354 		    }
3355 		  else
3356 		    {
3357 		      if(i==1)
3358 			{
3359 		          if(n[0] && n[0]->expansion) /* scan-build */
3360 				{
3361 			  	bitblast_delta = n[1]->expansion->actual - n[0]->expansion->actual;
3362 			  	if(bitblast_delta<-1) bitblast_delta=0;
3363 			  	else if(bitblast_delta>1) bitblast_delta=0;
3364 				}
3365 				else
3366 				{
3367 				bitblast_delta=0;
3368 				}
3369 			}
3370 		      else if((bitblast_delta)&&(i>1))
3371 			{
3372 			  if((n[i]->expansion->actual - n[i-1]->expansion->actual) != bitblast_delta) bitblast_delta=0;
3373 			}
3374 		    }
3375 		}
3376 	      else
3377 		{
3378 		  bitblast_parent = NULL;
3379 		}
3380 	    }
3381 	}
3382 
3383       b->nnbits=nodepnt;
3384 
3385       if(!bitblast_parent)
3386 	{
3387 	  char *aname;
3388 	  int match_iter = 1;
3389 
3390 	  if(direction)
3391 	    {
3392 	      aname = (nodepnt && n[0]) ? attempt_vecmatch(n[0]->nname, n[nodepnt-1]->nname) : NULL;  /* scan-build */
3393 	    }
3394 	  else
3395 	    {
3396 	      aname = (nodepnt && n[0]) ? attempt_vecmatch(n[nodepnt-1]->nname, n[0]->nname) : NULL; /* scan-build */
3397 	    }
3398 
3399 	  if(aname)
3400 	    {
3401 	      int ix;
3402 
3403 	      for(ix=0;ix<nodepnt-1;ix++)
3404 		{
3405 		  char *mat = attempt_vecmatch(n[0]->nname, n[ix]->nname);
3406 		  if(!mat) { match_iter = 0; break; } else { free_2(mat); }
3407 		}
3408 	    }
3409 
3410 	  if(!match_iter)
3411 	    {
3412 	      free_2(aname);
3413 	      aname = NULL;
3414 	    }
3415 
3416 	  if((!aname) && !single_trace_only) /* ajb 020716: recent add to handle combine down on 2D vectors */
3417 		{
3418 		char *t_topname = NULL;
3419 		char *t_botname = NULL;
3420 		t = tfirst;
3421       		while(t)
3422 			{
3423 	  		if(t->flags&TR_HIGHLIGHT)
3424 	    			{
3425 	      			if(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))
3426 					{
3427 		  			/* nothing */
3428 					}
3429 	      			else
3430 					{
3431 		  			if(t->vector)
3432 		    				{
3433 						char *vname = t->n.vec ? t->n.vec->bvname : NULL;
3434 						if(vname)
3435 							{
3436 							if(!t_topname)
3437 								{
3438 								t_topname = vname;
3439 								}
3440 								else
3441 								{
3442 								t_botname = vname;
3443 								}
3444 							}
3445 						}
3446 						else
3447 						{
3448 						if(!t_topname)
3449 							{
3450 							t_topname = t->n.nd->nname;
3451 							}
3452 							else
3453 							{
3454 							t_botname = t->n.nd->nname;
3455 							}
3456 
3457 						if(t_topname && t_botname)
3458 							{
3459 							char *mat = attempt_vecmatch(t_topname, t_botname);
3460 							if(!mat) { t_topname = t_botname = NULL; break; } else { free_2(mat); }
3461 							}
3462 						}
3463 					}
3464 
3465 				}
3466 
3467 		      	t=t->t_next;
3468 			}
3469 
3470 		if(t_topname && t_botname)
3471 			{
3472 			aname = direction ? attempt_vecmatch(t_topname, t_botname) : attempt_vecmatch(t_botname, t_topname); /* return this match */
3473 			}
3474 		}
3475 
3476 
3477 	  if(!b->attribs)
3478 	    {
3479 	      if(aname)
3480 		{
3481 		  b->name = aname;
3482 		}
3483 	      else
3484 		{
3485 		  strcpy(b->name=(char *)malloc_2(strlen("<Vector>")+1),"<Vector>");
3486 		}
3487 	    }
3488 	  else
3489 	    {
3490 	      if(aname)
3491 		{
3492 		  b->name = aname;
3493 		}
3494 	      else
3495 		{
3496 		  strcpy(b->name=(char *)malloc_2(strlen("<ComplexVector>")+1),"<ComplexVector>");
3497 		}
3498 	    }
3499 	}
3500       else
3501 	{
3502 	  int ix, offset;
3503 	  char *nam;
3504 	  char *namex;
3505 	  int was_packed = HIER_DEPACK_ALLOC;
3506 
3507 	  int row = 0, bit = 0;
3508 	  int row2 = 0, bit2 = 0;
3509 	  int is_2d = 0;
3510 	  int iy, offsety;
3511 	  char *namey;
3512 	  char sep2d = ':';
3513 
3514 	  namex = hier_decompress_flagged(n[0]->nname, &was_packed);
3515 
3516 	  offset = strlen(namex);
3517 	  for(ix=offset-1;ix>=0;ix--)
3518 	    {
3519 	      if(namex[ix]=='[') break;
3520 	    }
3521 	  if(ix>-1) offset=ix;
3522 
3523           if(ix>3) /* is_2d is for handling 2-d stored in 1-d vector */
3524                 {
3525                 if(namex[ix-1]==']')
3526                         {
3527                         int j = ix-2;
3528                         for(;j>=0;j--)
3529                                 {
3530                                 if(namex[j]=='[') break;
3531                                 }
3532 
3533                         if(j>-1)
3534                                 {
3535                                 int items = sscanf(namex+j, "[%d][%d]", &row, &bit);
3536                                 if(items == 2)
3537                                         {
3538                                         /* printf(">> %d %d (items = %d)\n", row, bit, items); */
3539 
3540                                         offset = j;
3541 					is_2d = 1;
3542                                         }
3543                                 }
3544                         }
3545                 }
3546 
3547 	  nam=(char *)wave_alloca(offset+50); /* to handle [a:b][c:d] case */
3548 	  memcpy(nam, namex, offset);
3549 	  if(was_packed) { free_2(namex); }
3550 
3551 	  if(is_2d)
3552 		{
3553 		is_2d = 0;
3554 		namey = hier_decompress_flagged(n[nodepnt-1]->nname, &was_packed);
3555 
3556 	  	offsety = strlen(namey);
3557 	  	for(iy=offsety-1;iy>=0;iy--)
3558 	    		{
3559 	      		if(namey[iy]=='[') break;
3560 	    		}
3561 	  	/* if(iy>-1) offsety=iy; not needed as in above as gets overwritten below by offsety = j */
3562 	        if(iy>3)
3563                 	{
3564                 	if(namey[iy-1]==']')
3565                 	        {
3566                 	        int j = iy-2;
3567                 	        for(;j>=0;j--)
3568                 	                {
3569                 	                if(namey[j]=='[') break;
3570                 	                }
3571 
3572 	                        if(j>-1)
3573 	                                {
3574 	                                int items = sscanf(namey+j, "[%d][%d]", &row2, &bit2);
3575 	                                if(items == 2)
3576 	                                        {
3577 						int rowabs, bitabs, width2d;
3578 	                                        /* printf(">> %d %d (items = %d)\n", row2, bit2, items); */
3579 
3580 	                                        offsety = j;
3581 						is_2d = (offset == offsety) && !memcmp(nam, namey, offsety);
3582 
3583 						rowabs = (row2 > row) ? (row2 - row + 1) : (row - row2 + 1);
3584 						bitabs = (bit2 > bit) ? (bit2 - bit + 1) : (bit - bit2 + 1);
3585 						width2d = rowabs * bitabs;
3586 						sep2d = (width2d == nodepnt) ? ':' : '|';
3587 	                                        }
3588 	                                }
3589 	                        }
3590 	                }
3591 
3592 		if(was_packed) { free_2(namey); }
3593 		}
3594 
3595 
3596 	  if(direction)
3597 	    {
3598 	      if(!is_2d)
3599 		{
3600 	      	sprintf(nam+offset, "[%d%s%d]", n[0]->expansion->actual, (bitblast_delta!=0) ? ":" : "|", n[nodepnt-1]->expansion->actual);
3601 		}
3602 		else
3603 		{
3604 		if(row == row2)
3605 			{
3606 			if(bit == bit2)
3607 				{
3608 			      	sprintf(nam+offset, "[%d][%d]", row, bit);
3609 				}
3610 				else
3611 				{
3612 			      	sprintf(nam+offset, "[%d][%d%c%d]", row, bit, sep2d, bit2);
3613 				}
3614 			}
3615 			else
3616 			{
3617 			if(bit == bit2)
3618 				{
3619 			      	sprintf(nam+offset, "[%d%c%d][%d]", row, sep2d, row2, bit);
3620 				}
3621 				else
3622 				{
3623 			      	sprintf(nam+offset, "[%d%c%d][%d%c%d]", row, sep2d, row2, bit, sep2d, bit2);
3624 				}
3625 			}
3626 		}
3627 	    }
3628 	  else
3629 	    {
3630 	      if(!is_2d)
3631 		{
3632 	      	sprintf(nam+offset, "[%d%s%d]", n[nodepnt-1]->expansion->actual,  (bitblast_delta!=0) ? ":" : "|", n[0]->expansion->actual);
3633 		}
3634 		else
3635 		{
3636 		if(row == row2)
3637 			{
3638 			if(bit == bit2)
3639 				{
3640 			      	sprintf(nam+offset, "[%d][%d]", row, bit);
3641 				}
3642 				else
3643 				{
3644 			      	sprintf(nam+offset, "[%d][%d%c%d]", row, bit2, sep2d, bit);
3645 				}
3646 			}
3647 			else
3648 			{
3649 			if(bit == bit2)
3650 				{
3651 			      	sprintf(nam+offset, "[%d%c%d][%d]", row2, sep2d, row, bit);
3652 				}
3653 				else
3654 				{
3655 			      	sprintf(nam+offset, "[%d%c%d][%d%c%d]", row2, sep2d, row, bit2, sep2d, bit);
3656 				}
3657 			}
3658 		}
3659 	    }
3660 
3661 	  strcpy(b->name=(char *)malloc_2(offset + strlen(nam+offset)+1), nam);
3662 	  DEBUG(printf("Name is: '%s'\n", nam));
3663 	}
3664 
3665       if((v=bits2vector(b)))
3666 	{
3667  	  v->bits=b;      /* only needed for savefile function */
3668 	}
3669       else
3670 	{
3671 	  free_2(b->name);
3672 	  if(b->attribs) free_2(b->attribs);
3673 	  free_2(b);
3674 	  return NULL;
3675 	}
3676 
3677       if(!single_trace_only)
3678 	{
3679       	tmp=GLOBALS->traces.buffer; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.first=tmp;
3680       	tmp=GLOBALS->traces.bufferlast; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.last=tmp;
3681       	tmpi=GLOBALS->traces.buffercount; GLOBALS->traces.buffercount=GLOBALS->traces.total;
3682       	GLOBALS->traces.total=tmpi;
3683       	PasteBuffer();
3684 	}
3685 
3686       return v;
3687     }
3688 }
3689 
3690 void
3691 menu_combine_down(gpointer null_data, guint callback_action, GtkWidget *widget)
3692 {
3693 (void)null_data;
3694 (void)callback_action;
3695 (void)widget;
3696 
3697   bvptr v;
3698 
3699   if(GLOBALS->helpbox_is_active)
3700     {
3701       help_text_bold("\n\nCombine Down");
3702       help_text(
3703                 " coalesces the highlighted signals into a single vector named"
3704 		" \"<Vector>\" in a top to bottom fashion"
3705                 " placed after the last highlighted trace.  The original traces will"
3706                 " be placed in the cut buffer."
3707 		" It will function seemingly randomly"
3708 		" when used upon real valued single-bit traces."
3709 		);
3710       return;
3711     }
3712 
3713   if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
3714   v = combine_traces(1, NULL); /* down */
3715 
3716   if (v)
3717     {
3718       Trptr t;
3719 
3720       AddVector(v, NULL);
3721       free_2(v->bits->name);
3722       v->bits->name=NULL;
3723 
3724       t = GLOBALS->traces.last;
3725 
3726       RemoveTrace(t, 0);
3727 
3728       /* t is now the composite signal trace */
3729 
3730       create_group("unused_0", t);
3731 
3732       GLOBALS->signalwindow_width_dirty=1;
3733       MaxSignalLength();
3734       signalarea_configure_event(GLOBALS->signalarea, NULL);
3735       wavearea_configure_event(GLOBALS->wavearea, NULL);
3736 
3737       menu_rename(widget, null_data);
3738     }
3739   else
3740     {
3741     }
3742 }
3743 
3744 void
3745 menu_combine_up(gpointer null_data, guint callback_action, GtkWidget *widget)
3746 {
3747 (void)null_data;
3748 (void)callback_action;
3749 (void)widget;
3750 
3751   bvptr v;
3752 
3753   if(GLOBALS->helpbox_is_active)
3754     {
3755       help_text_bold("\n\nCombine Up");
3756       help_text(
3757                 " coalesces the highlighted signals into a single vector named"
3758                 " \"<Vector>\" in a bottom to top fashion"
3759                 " placed after the last highlighted trace.  The original traces will"
3760                 " be placed in the cut buffer."
3761 		" It will function seemingly randomly"
3762 		" when used upon real valued single-bit traces."
3763 		);
3764       return;
3765     }
3766 
3767   if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
3768   v = combine_traces(0, NULL); /* up */
3769 
3770   if (v)
3771     {
3772       Trptr t;
3773 
3774       AddVector(v, NULL);
3775       free_2(v->bits->name);
3776       v->bits->name=NULL;
3777 
3778       t = GLOBALS->traces.last;
3779 
3780       RemoveTrace(t, 0);
3781 
3782       /* t is now the composite signal trace */
3783 
3784       create_group("unused_1", t);
3785 
3786       GLOBALS->signalwindow_width_dirty=1;
3787       MaxSignalLength();
3788       signalarea_configure_event(GLOBALS->signalarea, NULL);
3789       wavearea_configure_event(GLOBALS->wavearea, NULL);
3790 
3791       menu_rename(widget, null_data);
3792     }
3793   else
3794     {
3795     }
3796 }
3797 
3798 /**/
3799 
3800 void menu_tracesearchbox_callback(GtkWidget *widget, gpointer data)
3801 {
3802 (void)widget;
3803 (void)data;
3804 }
3805 
3806 void menu_tracesearchbox(gpointer null_data, guint callback_action, GtkWidget *widget)
3807 {
3808 (void)null_data;
3809 (void)callback_action;
3810 (void)widget;
3811 
3812 Trptr t;
3813 
3814 if(GLOBALS->helpbox_is_active)
3815         {
3816         help_text_bold("\n\nPattern Search");
3817         help_text(
3818 		" only works when at least one trace is highlighted. "
3819 		" A requester will appear that lists all the selected"
3820 		" traces (maximum of 500) and allows various criteria"
3821 		" to be specified for each trace.  Searches can go forward"
3822 		" or backward from the primary (unnamed) marker.  If the"
3823 		" primary marker has not been set, the search starts at the"
3824 		" beginning of the displayed data (\"From\") for a forwards"
3825 		" search and starts at the end of the displayed data (\"To\")"
3826 		" for a backwards search."
3827 		" \"Mark\" and \"Clear\" are used to modify the normal time"
3828 		" vertical markings such that they can be used to indicate"
3829 		" all the times that a specific pattern search condition is"
3830 		" true (e.g., every upclock of a specific signal).  The"
3831 		" \"Mark Count\" field indicates how many times the specific"
3832 		" pattern search condition was encountered."
3833 		" The \"Marking Begins at\" and \"Marking Stops at\" fields are"
3834 		" used to limit the time over which marking is applied"
3835 		" (but they have no effect on searching)."
3836         );
3837         return;
3838         }
3839 
3840  for(t=GLOBALS->traces.first;t;t=t->t_next)
3841 	{
3842 	if ((t->flags&TR_HIGHLIGHT)&&HasWave(t))
3843 	  {
3844 	    /* at least one good trace, so do it */
3845 	    /* data contains WV_MENU_SPS or WV_MENU_SPS2 or ... but the base is WV_MENU_SPS*/
3846 	    char buf[128];
3847 	    intptr_t which = ((long)callback_action) - WV_MENU_SPS;
3848 
3849 	    if((which < 0) || (which >= WAVE_NUM_STRACE_WINDOWS))
3850 			{ /* should never happen unless menus are defined wrong */
3851 			sprintf(buf, "Pattern search ID %d out of range of 1-%d available, ignoring.", (int)(which+1), WAVE_NUM_STRACE_WINDOWS);
3852 			status_text(buf);
3853 			}
3854 			else
3855 			{
3856 			sprintf(buf, "Waveform Display Search (%d)", (int)(which+1));
3857 			tracesearchbox(buf, GTK_SIGNAL_FUNC(menu_tracesearchbox_callback), (gpointer)which);
3858 			}
3859 	    return;
3860 	  }
3861 	}
3862  must_sel();
3863 }
3864 
3865 /**/
3866 void
3867 menu_new_viewer_cleanup(GtkWidget *widget, gpointer data)
3868 {
3869 (void)widget;
3870 (void)data;
3871 
3872 pid_t pid;
3873 
3874 if(GLOBALS->filesel_ok)
3875 	{
3876 	/* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */
3877     	if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); }
3878 
3879 #if !defined __MINGW32__ && !defined _MSC_VER
3880 	/*
3881 	 * for some reason, X won't let us double-fork in order to cleanup zombies.. *shrug*
3882          */
3883 	pid=fork();
3884 	if(((int)pid) < 0) { return; /* not much we can do about this.. */ }
3885 
3886 	if(pid)         /* parent==original server_pid */
3887 	        {
3888 		return;
3889        		}
3890 
3891 #ifdef MAC_INTEGRATION
3892 	/* from : @pfx = split(' ', "open -n -W -a gtkwave --args --chdir dummy"); */
3893 	if(GLOBALS->optimize_vcd)
3894 		{
3895 		execlp("open", "open", "-n", "-W", "-a", "gtkwave", "--args", "--optimize", "--dump", *GLOBALS->fileselbox_text, NULL);
3896 		}
3897 		else
3898 		{
3899 		execlp("open", "open", "-n", "-W", "-a", "gtkwave", "--args", "--dump", *GLOBALS->fileselbox_text, NULL);
3900 		}
3901 #else
3902 	if(GLOBALS->optimize_vcd)
3903 		{
3904 		execlp(GLOBALS->whoami, GLOBALS->whoami, "-o", *GLOBALS->fileselbox_text, NULL);
3905 		}
3906 		else
3907 		{
3908 		execlp(GLOBALS->whoami, GLOBALS->whoami, *GLOBALS->fileselbox_text, NULL);
3909 		}
3910 #endif
3911 	exit(0);	/* control never gets here if successful */
3912 
3913 #else
3914 
3915 	BOOL bSuccess = FALSE;
3916 	PROCESS_INFORMATION piProcInfo;
3917 	TCHAR *szCmdline;
3918 	STARTUPINFO si;
3919 
3920 	memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
3921 	memset(&si, 0, sizeof(STARTUPINFO));
3922 
3923         szCmdline = malloc_2(strlen(GLOBALS->whoami) + 1 + strlen(*GLOBALS->fileselbox_text) + 1);
3924         sprintf(szCmdline, "%s %s", GLOBALS->whoami, *GLOBALS->fileselbox_text);
3925 
3926 	bSuccess = CreateProcess(NULL,
3927 	      szCmdline,     /* command line */
3928 	      NULL,          /* process security attributes */
3929 	      NULL,          /* primary thread security attributes */
3930 	      TRUE,          /* handles are inherited */
3931 	      0,             /* creation flags */
3932 	      NULL,          /* use parent's environment */
3933 	      NULL,          /* use parent's current directory */
3934 	      &si,           /* STARTUPINFO pointer */
3935 	      &piProcInfo);  /* receives PROCESS_INFORMATION */
3936 
3937 	free_2(szCmdline);
3938 
3939 	if(!bSuccess)
3940 	        {
3941 	        /* failed */
3942 	        }
3943 #endif
3944 	}
3945 }
3946 
3947 void
3948 menu_new_viewer(gpointer null_data, guint callback_action, GtkWidget *widget)
3949 {
3950 (void)null_data;
3951 (void)callback_action;
3952 (void)widget;
3953 
3954 static int mnv = 0;
3955 
3956 if(!mnv && !GLOBALS->busy_busy_c_1)
3957 	{
3958 	mnv = 1;
3959 	if(GLOBALS->helpbox_is_active)
3960 		{
3961 		help_text_bold("\n\nOpen New Window");
3962 		help_text(
3963 			" will open a file requester that will ask for the name"
3964 			" of a VCD or AET file to view.  This will fork off a"
3965 			" new viewer process."
3966 		);
3967 		}
3968 		else
3969 		{
3970 		if(in_main_iteration()) { mnv = 0; return; }
3971 
3972 		fileselbox("Select a trace to view...",&GLOBALS->filesel_newviewer_menu_c_1,GTK_SIGNAL_FUNC(menu_new_viewer_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0);
3973 		}
3974 	mnv = 0;
3975 	}
3976 }
3977 
3978 /**/
3979 
3980 int
3981 menu_new_viewer_tab_cleanup_2(char *fname, int optimize_vcd)
3982 {
3983 	int rc = 0;
3984 	char *argv[2];
3985 	struct Global *g_old = GLOBALS;
3986 	struct Global *g_now;
3987 
3988 	argv[0] = gtkwave_argv0_cached ? gtkwave_argv0_cached : "gtkwave";
3989 	argv[1] = fname;
3990 
3991 	/* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */
3992     	if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); }
3993 
3994 	GLOBALS->vcd_jmp_buf = calloc(1, sizeof(jmp_buf));
3995 
3996 	splash_button_press_event(NULL, NULL); /* kill any possible splash screens (e.g., if automated) */
3997 	set_window_busy(NULL);
3998 	gtkwave_main_iteration();
3999 
4000 	if(!setjmp(*(GLOBALS->vcd_jmp_buf)))
4001 		{
4002 		main_2(optimize_vcd, 2, argv);
4003 
4004 		g_now = GLOBALS;
4005 		set_GLOBALS(g_old);
4006 
4007 		clone_icon_pointers_across_contexts(g_now, GLOBALS);
4008 
4009 		free(GLOBALS->vcd_jmp_buf); GLOBALS->vcd_jmp_buf = NULL;
4010 		set_window_idle(NULL);
4011 		set_GLOBALS(g_now);
4012 		g_now->vcd_jmp_buf = NULL;
4013 
4014 		/* copy old file req strings into new context */
4015 		strcpy2_into_new_context(GLOBALS, &GLOBALS->fcurr_ttranslate_c_1, &g_old->fcurr_ttranslate_c_1);
4016 		strcpy2_into_new_context(GLOBALS, &GLOBALS->fcurr_ptranslate_c_1, &g_old->fcurr_ptranslate_c_1);
4017 		strcpy2_into_new_context(GLOBALS, &GLOBALS->fcurr_translate_c_2, &g_old->fcurr_translate_c_2);
4018 
4019 #if 0
4020 		/* disabled for now...these probably would be disruptive */
4021 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_lxt_writesave, &g_old->filesel_lxt_writesave);
4022 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_vcd_writesave, &g_old->filesel_vcd_writesave);
4023 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_tim_writesave, &g_old->filesel_tim_writesave);
4024 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_writesave, &g_old->filesel_writesave);
4025 		strcpy2_into_new_context(GLOBALS, &GLOBALS->stems_name, &g_old->stems_name);
4026 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_logfile_menu_c_1, &g_old->filesel_logfile_menu_c_1);
4027 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_scriptfile_menu, &g_old->filesel_scriptfile_menu);
4028 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_print_pdf_renderopt_c_1, &g_old->filesel_print_pdf_renderopt_c_1);
4029 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_print_ps_renderopt_c_1, &g_old->filesel_print_ps_renderopt_c_1);
4030 		strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_print_mif_renderopt_c_1, &g_old->filesel_print_mif_renderopt_c_1);
4031 #endif
4032 
4033 		/* not sure what's really needed here */
4034 		/* for now, add back in repscript_name */
4035 		GLOBALS->repscript_period = g_old->repscript_period;
4036 		strcpy2_into_new_context(GLOBALS, &GLOBALS->repscript_name, &g_old->repscript_name);
4037 
4038 		GLOBALS->strace_repeat_count = g_old->strace_repeat_count;
4039 
4040 		if(g_old->loaded_file_type == MISSING_FILE) /* remove original "blank" page */
4041 			{
4042                         if(g_old->missing_file_toolbar) gtk_widget_set_sensitive(g_old->missing_file_toolbar, TRUE);
4043 			menu_set_sensitive();
4044 			gtk_notebook_set_current_page(GTK_NOTEBOOK(g_old->notebook), g_old->this_context_page);
4045 			set_GLOBALS(g_old);
4046 			menu_quit_close_callback(NULL, NULL);
4047 			}
4048 
4049 	        wave_gconf_client_set_string("/current/pwd", getenv("PWD"));
4050 
4051 	        wave_gconf_client_set_string("/current/dumpfile", GLOBALS->optimize_vcd ? GLOBALS->unoptimized_vcd_file_name : GLOBALS->loaded_file_name);
4052 	        wave_gconf_client_set_string("/current/optimized_vcd", GLOBALS->optimize_vcd ? "1" : "0");
4053 
4054 	        wave_gconf_client_set_string("/current/savefile", GLOBALS->filesel_writesave);
4055 
4056 		rc = 1;
4057 		}
4058                 else
4059                 {
4060                 if(GLOBALS->vcd_handle_vcd_c_1) { fclose(GLOBALS->vcd_handle_vcd_c_1); GLOBALS->vcd_handle_vcd_c_1 = NULL; }
4061                 if(GLOBALS->vcd_handle_vcd_recoder_c_2) { fclose(GLOBALS->vcd_handle_vcd_recoder_c_2); GLOBALS->vcd_handle_vcd_recoder_c_2 =NULL; }
4062                 if(GLOBALS->mm_lxt_mmap_addr)
4063                 	{
4064                         munmap(GLOBALS->mm_lxt_mmap_addr, GLOBALS->mm_lxt_mmap_len);
4065                         GLOBALS->mm_lxt_mmap_addr = NULL;
4066                         }
4067                 free_outstanding(); /* free anything allocated in loader ctx */
4068 		free(GLOBALS);
4069 		GLOBALS = NULL; /* valgrind fix */
4070 
4071 		set_GLOBALS(g_old);
4072                 free(GLOBALS->vcd_jmp_buf); GLOBALS->vcd_jmp_buf = NULL;
4073 		set_window_idle(NULL);
4074 
4075 		/* load failed */
4076 		wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0);
4077 		printf("GTKWAVE | File load failure, new tab not created.\n");
4078 		rc = 0;
4079                 }
4080 
4081 return(rc);
4082 }
4083 
4084 
4085 void
4086 menu_new_viewer_tab_cleanup(GtkWidget *widget, gpointer data)
4087 {
4088 (void)widget;
4089 (void)data;
4090 
4091 if(GLOBALS->filesel_ok)
4092         {
4093 	menu_new_viewer_tab_cleanup_2(*GLOBALS->fileselbox_text, GLOBALS->optimize_vcd);
4094 	}
4095 }
4096 
4097 
4098 void
4099 menu_new_viewer_tab(gpointer null_data, guint callback_action, GtkWidget *widget)
4100 {
4101 (void)null_data;
4102 (void)callback_action;
4103 (void)widget;
4104 
4105 if(GLOBALS->helpbox_is_active)
4106 	{
4107 	help_text_bold("\n\nOpen New Tab");
4108 	help_text(
4109 		" will open a file requester that will ask for the name"
4110 		" of a VCD or AET file to view.  This will create a tabbed page."
4111 	);
4112 	return;
4113 	}
4114 
4115 if(in_main_iteration()) return;
4116 
4117 #ifdef WAVE_USE_GTK2
4118 if((!GLOBALS->socket_xid)&&(!GLOBALS->partial_vcd))
4119 #else
4120 if(!GLOBALS->partial_vcd)
4121 #endif
4122 	{
4123 	fileselbox("Select a trace to view...",&GLOBALS->filesel_newviewer_menu_c_1,GTK_SIGNAL_FUNC(menu_new_viewer_tab_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0);
4124 	}
4125 }
4126 
4127 /**/
4128 
4129 void
4130 menu_reload_waveform(gpointer null_data, guint callback_action, GtkWidget *widget)
4131 {
4132 (void)null_data;
4133 (void)callback_action;
4134 (void)widget;
4135 
4136  if(GLOBALS->helpbox_is_active)
4137 	{
4138 	help_text_bold("\n\nReload Current Waveform");
4139 	help_text(
4140 		" will reload the currently displayed waveform"
4141 		" from a potentially updated file."
4142 	);
4143 	return;
4144 	}
4145 
4146  if(in_main_iteration()) return;
4147 
4148  if(GLOBALS->gt_splash_c_1 || GLOBALS->splash_is_loading)
4149 	{
4150 	return; /* don't attempt reload if splash screen is still active...that's pointless anyway */
4151 	}
4152 
4153  /* XXX if there's no file (for some reason), this function shouldn't occur
4154     we should probably gray it out. */
4155  if(GLOBALS->loaded_file_type == DUMPLESS_FILE) {
4156    printf("GTKWAVE | DUMPLESS_FILE type cannot be reloaded\n");
4157    return;
4158  }
4159 
4160  reload_into_new_context();
4161 }
4162 
4163 
4164 void
4165 menu_reload_waveform_marshal(GtkWidget *widget, gpointer data)
4166 {
4167 menu_reload_waveform(data, 0, widget);
4168 }
4169 
4170 
4171 /**/
4172 
4173 void
4174 menu_print(gpointer null_data, guint callback_action, GtkWidget *widget)
4175 {
4176 (void)null_data;
4177 (void)callback_action;
4178 (void)widget;
4179 
4180 if(GLOBALS->helpbox_is_active)
4181 	{
4182 	help_text_bold("\n\nPrint To File");
4183 	help_text(
4184 		" will open up a requester that will allow you to select"
4185 		" print options (PS or MIF; Letter, A4, or Legal; Full or Minimal)."
4186 		" After selecting the options you want,"
4187 		" a file requester will ask for the name of the"
4188 		" output file to generate"
4189 		" that reflects the current main window display's contents."
4190 	);
4191 	return;
4192 	}
4193 
4194 renderbox("Print Formatting Options");
4195 }
4196 
4197 /**/
4198 void menu_markerbox_callback(GtkWidget *widget, gpointer data)
4199 {
4200 (void)widget;
4201 (void)data;
4202 }
4203 
4204 void menu_markerbox(gpointer null_data, guint callback_action, GtkWidget *widget)
4205 {
4206 (void)null_data;
4207 (void)callback_action;
4208 (void)widget;
4209 
4210 if(GLOBALS->helpbox_is_active)
4211         {
4212         help_text_bold("\n\nShow-Change Marker Data");
4213         help_text(
4214                 " displays and allows the modification of the times for"
4215 		" all named markers by filling in the leftmost entry boxes.  In addition, optional marker text"
4216 		" rather than a generic single letter name may be specified by filling in the rightmost entry boxes."
4217 		" Note that the time for each marker must be unique."
4218         );
4219         return;
4220         }
4221 
4222 markerbox("Markers", GTK_SIGNAL_FUNC(menu_markerbox_callback));
4223 }
4224 
4225 
4226 void copy_pri_b_marker(gpointer null_data, guint callback_action, GtkWidget *widget)
4227 {
4228 (void)null_data;
4229 (void)callback_action;
4230 (void)widget;
4231 
4232 if(GLOBALS->helpbox_is_active)
4233         {
4234         help_text_bold("\n\nCopy Primary -> B Marker");
4235         help_text(
4236                 " copies the primary marker position to the B marker (handy for measuring deltas)."
4237         );
4238         return;
4239         }
4240 
4241   DEBUG(printf("copy_pri_b_marker()\n"));
4242 
4243   if(GLOBALS->tims.marker!=-1)
4244   {
4245     GLOBALS->tims.baseline = GLOBALS->tims.marker;
4246     update_basetime(GLOBALS->tims.baseline);
4247     GLOBALS->signalwindow_width_dirty=1;
4248     MaxSignalLength();
4249     signalarea_configure_event(GLOBALS->signalarea, NULL);
4250     wavearea_configure_event(GLOBALS->wavearea, NULL);
4251   }
4252 }
4253 
4254 
4255 
4256 /**/
4257 void delete_unnamed_marker(gpointer null_data, guint callback_action, GtkWidget *widget)
4258 {
4259 (void)null_data;
4260 (void)callback_action;
4261 (void)widget;
4262 
4263 if(GLOBALS->helpbox_is_active)
4264         {
4265         help_text_bold("\n\nDelete Primary Marker");
4266         help_text(
4267                 " removes the primary marker from the display if present."
4268         );
4269         return;
4270         }
4271 
4272 DEBUG(printf("delete_unnamed marker()\n"));
4273 
4274 if(GLOBALS->tims.marker!=-1)
4275 	{
4276 	Trptr t;
4277 
4278 	for(t=GLOBALS->traces.first;t;t=t->t_next)
4279 		{
4280 		if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; }
4281 		}
4282 
4283 	for(t=GLOBALS->traces.buffer;t;t=t->t_next)
4284 		{
4285 		if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; }
4286 		}
4287 
4288 	update_markertime(GLOBALS->tims.marker=-1);
4289 	GLOBALS->signalwindow_width_dirty=1;
4290 	MaxSignalLength();
4291 	signalarea_configure_event(GLOBALS->signalarea, NULL);
4292 	wavearea_configure_event(GLOBALS->wavearea, NULL);
4293 	}
4294 }
4295 
4296 /**/
4297 void collect_all_named_markers(gpointer null_data, guint callback_action, GtkWidget *widget)
4298 {
4299 (void)null_data;
4300 (void)callback_action;
4301 (void)widget;
4302 
4303 int i;
4304 int dirty=0;
4305 
4306 if(GLOBALS->helpbox_is_active)
4307         {
4308         help_text_bold("\n\nCollect All Named Markers");
4309         help_text(
4310 		" simply collects any and all named markers which have"
4311 		" been dropped."
4312         );
4313         return;
4314         }
4315 
4316 DEBUG(printf("collect_all_unnamed_markers()\n"));
4317 
4318 for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
4319 	{
4320 	if(GLOBALS->named_markers[i]!=-1)
4321 		{
4322 		GLOBALS->named_markers[i]=-1;
4323 		dirty=1;
4324 		}
4325 
4326 	if(GLOBALS->marker_names[i])
4327 		{
4328 		free_2(GLOBALS->marker_names[i]);
4329 		GLOBALS->marker_names[i] = NULL;
4330 		}
4331 	}
4332 
4333 if(dirty)
4334 	{
4335 	signalarea_configure_event(GLOBALS->signalarea, NULL);
4336 	wavearea_configure_event(GLOBALS->wavearea, NULL);
4337 	}
4338 }
4339 /**/
4340 void collect_named_marker(gpointer null_data, guint callback_action, GtkWidget *widget)
4341 {
4342 (void)null_data;
4343 (void)callback_action;
4344 (void)widget;
4345 
4346 int i;
4347 
4348 if(GLOBALS->helpbox_is_active)
4349         {
4350         help_text_bold("\n\nCollect Named Marker");
4351         help_text(
4352                 " collects a named marker where the current primary (unnamed)"
4353                 " marker is placed if there is a named marker at its position."
4354         );
4355         return;
4356         }
4357 
4358 DEBUG(printf("collect_named_marker()\n"));
4359 
4360 if(GLOBALS->tims.marker!=-1)
4361 	{
4362 	for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
4363 		{
4364 		if(GLOBALS->named_markers[i]==GLOBALS->tims.marker)
4365 			{
4366 			GLOBALS->named_markers[i]=-1;
4367 			signalarea_configure_event(GLOBALS->signalarea, NULL);
4368 			wavearea_configure_event(GLOBALS->wavearea, NULL);
4369 
4370 			if(GLOBALS->marker_names[i])
4371 				{
4372 				free_2(GLOBALS->marker_names[i]);
4373 				GLOBALS->marker_names[i] = NULL;
4374 				}
4375 
4376 			/* return; */
4377 			}
4378 		}
4379 	}
4380 }
4381 /**/
4382 void drop_named_marker(gpointer null_data, guint callback_action, GtkWidget *widget)
4383 {
4384 (void)null_data;
4385 (void)callback_action;
4386 (void)widget;
4387 
4388 int i;
4389 
4390 if(GLOBALS->helpbox_is_active)
4391         {
4392 	char nm_s[32];
4393 
4394 	sprintf(nm_s, "%d", WAVE_NUM_NAMED_MARKERS);
4395 
4396         help_text_bold("\n\nDrop Named Marker");
4397         help_text(
4398 		" drops a named marker where the current primary (unnamed)"
4399 		" marker is placed.  A maximum of "
4400 	);
4401 
4402         help_text(
4403 		nm_s
4404 	);
4405 
4406         help_text(
4407 		" named markers are allowed"
4408 		" and the times for all must be different."
4409         );
4410         return;
4411         }
4412 
4413 
4414 DEBUG(printf("drop_named_marker()\n"));
4415 
4416 if(GLOBALS->tims.marker!=-1)
4417 	{
4418 /* only one per slot requirement removed...
4419 #if 0
4420 	for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
4421 		{
4422 		if(GLOBALS->named_markers[i]==GLOBALS->tims.marker) return;
4423 		}
4424 #endif
4425 ...only one per slot requirement removed */
4426 
4427 	for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
4428 		{
4429 		if(GLOBALS->named_markers[i]==-1)
4430 			{
4431 			GLOBALS->named_markers[i]=GLOBALS->tims.marker;
4432 			signalarea_configure_event(GLOBALS->signalarea, NULL);
4433 			wavearea_configure_event(GLOBALS->wavearea, NULL);
4434 			return;
4435 			}
4436 		}
4437 	}
4438 }
4439 /**/
4440 void menu_treesearch_cleanup(GtkWidget *widget, gpointer data)
4441 {
4442 (void)widget;
4443 (void)data;
4444 
4445 MaxSignalLength();
4446 signalarea_configure_event(GLOBALS->signalarea, NULL);
4447 wavearea_configure_event(GLOBALS->wavearea, NULL);
4448 DEBUG(printf("menu_treesearch_cleanup()\n"));
4449 }
4450 
4451 void menu_treesearch(gpointer null_data, guint callback_action, GtkWidget *widget)
4452 {
4453 (void)null_data;
4454 (void)callback_action;
4455 (void)widget;
4456 
4457 if(GLOBALS->helpbox_is_active)
4458         {
4459         help_text_bold("\n\nSignal Search Tree");
4460         help_text(
4461                 " provides an easy means of adding traces to the display."
4462                 " Various functions are provided in the Signal Search Tree requester"
4463                 " which allow searching a treelike hierarchy and bundling"
4464                 " (coalescing individual bits into a single vector)."
4465         );
4466         return;
4467         }
4468 
4469 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
4470 
4471 treebox("Signal Search Tree",GTK_SIGNAL_FUNC(menu_treesearch_cleanup), NULL);
4472 }
4473 /**/
4474 void
4475 menu_showchangeall_cleanup(GtkWidget *widget, gpointer data)
4476 {
4477 (void)widget;
4478 (void)data;
4479 
4480 Trptr t;
4481 TraceFlagsType flags;
4482 
4483 t=GLOBALS->showchangeall_menu_c_1;
4484 if(t)
4485 	{
4486 	flags = t->flags & (TR_NUMMASK | TR_HIGHLIGHT | TR_ATTRIBS);
4487 	while(t)
4488 		{
4489 		if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name))
4490 			{
4491 			t->flags = (t->flags & ~(TR_NUMMASK | TR_HIGHLIGHT | TR_ATTRIBS)) | flags;
4492 			t->minmax_valid = 0; /* force analog traces to regenerate if necessary */
4493 			}
4494 		t=t->t_next;
4495 		}
4496 	}
4497 
4498 GLOBALS->signalwindow_width_dirty=1;
4499 MaxSignalLength();
4500 signalarea_configure_event(GLOBALS->signalarea, NULL);
4501 wavearea_configure_event(GLOBALS->wavearea, NULL);
4502 DEBUG(printf("menu_showchangeall_cleanup()\n"));
4503 }
4504 
4505 void
4506 menu_showchangeall(gpointer null_data, guint callback_action, GtkWidget *widget)
4507 {
4508 (void)null_data;
4509 (void)callback_action;
4510 (void)widget;
4511 
4512 Trptr t;
4513 
4514 if(GLOBALS->helpbox_is_active)
4515         {
4516         help_text_bold("\n\nShow-Change All Highlighted");
4517         help_text(
4518                 " provides an easy means of changing trace attributes en masse."
4519                 " Various functions are provided in a Show-Change requester."
4520         );
4521         return;
4522         }
4523 
4524 DEBUG(printf("menu_showchangeall()\n"));
4525 
4526 GLOBALS->showchangeall_menu_c_1=NULL;
4527 t=GLOBALS->traces.first;
4528 while(t)
4529 	{
4530 	if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name))
4531 		{
4532 		showchange("Show-Change All", GLOBALS->showchangeall_menu_c_1=t, GTK_SIGNAL_FUNC(menu_showchangeall_cleanup));
4533 		return;
4534 		}
4535 	t=t->t_next;
4536 	}
4537 
4538 must_sel();
4539 }
4540 
4541 /**/
4542 void
4543 menu_showchange_cleanup(GtkWidget *widget, gpointer data)
4544 {
4545 (void)widget;
4546 (void)data;
4547 
4548 GLOBALS->signalwindow_width_dirty=1;
4549 MaxSignalLength();
4550 signalarea_configure_event(GLOBALS->signalarea, NULL);
4551 wavearea_configure_event(GLOBALS->wavearea, NULL);
4552 DEBUG(printf("menu_showchange_cleanup()\n"));
4553 }
4554 
4555 void
4556 menu_showchange(gpointer null_data, guint callback_action, GtkWidget *widget)
4557 {
4558 (void)null_data;
4559 (void)callback_action;
4560 (void)widget;
4561 
4562 Trptr t;
4563 
4564 if(GLOBALS->helpbox_is_active)
4565         {
4566         help_text_bold("\n\nShow-Change First Highlighted");
4567         help_text(
4568                 " provides a means of changing trace attributes for the"
4569 		" first highlighted trace. "
4570                 " Various functions are provided in a Show-Change requester. "
4571   		" When a function is applied, the trace will be unhighlighted."
4572         );
4573         return;
4574         }
4575 
4576 DEBUG(printf("menu_showchange()\n"));
4577 
4578 t=GLOBALS->traces.first;
4579 while(t)
4580 	{
4581 	if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name))
4582 		{
4583 		showchange("Show-Change", t, GTK_SIGNAL_FUNC(menu_showchange_cleanup));
4584 		return;
4585 		}
4586 	t=t->t_next;
4587 	}
4588 
4589 must_sel();
4590 }
4591 /**/
4592 void menu_remove_aliases(gpointer null_data, guint callback_action, GtkWidget *widget)
4593 {
4594 (void)null_data;
4595 (void)callback_action;
4596 (void)widget;
4597 
4598   Trptr t;
4599   int dirty=0, none_selected = 1;
4600 
4601   if(GLOBALS->helpbox_is_active)
4602     {
4603       help_text_bold("\n\nRemove Highlighted Aliases");
4604       help_text(
4605                 " only works when at least one trace has been highlighted. "
4606                 " Any aliased traces will have their names restored to their"
4607 		" original names.  As vectors get their names from aliases,"
4608 		" vector aliases will not be removed."
4609 		);
4610       return;
4611     }
4612 
4613   if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
4614 
4615   t=GLOBALS->traces.first;
4616   while(t)
4617     {
4618       if(HasAlias(t) && IsSelected(t))
4619 	{
4620           char *name_full;
4621           int was_packed = HIER_DEPACK_ALLOC;
4622 
4623 	  free_2(t->name_full);
4624 	  t->name_full = NULL;
4625 
4626 	  if(t->vector)
4627 		{
4628 		name_full = t->n.vec->bvname;
4629 		}
4630 		else
4631 		{
4632 		name_full = hier_decompress_flagged(t->n.nd->nname, &was_packed);
4633 		}
4634 
4635 	  t->name = name_full;
4636 	  if (GLOBALS->hier_max_level)
4637 		{
4638 		if(!was_packed)
4639 			{
4640 		    	t->name = hier_extract(t->name, GLOBALS->hier_max_level);
4641 			}
4642 			else
4643 			{
4644 		    	t->name = strdup_2(hier_extract(name_full, GLOBALS->hier_max_level));
4645 			free_2(name_full);
4646 			}
4647 		}
4648 
4649 	  if(was_packed) t->is_depacked = 1;
4650 
4651 	  dirty = 1;
4652 	}
4653       if (IsSelected(t)) none_selected = 0;
4654       t=t->t_next;
4655     }
4656 
4657   if(dirty)
4658     {
4659       GLOBALS->signalwindow_width_dirty=1;
4660       MaxSignalLength();
4661       signalarea_configure_event(GLOBALS->signalarea, NULL);
4662       wavearea_configure_event(GLOBALS->wavearea, NULL);
4663       DEBUG(printf("menu_remove_aliases()\n"));
4664     }
4665   if (none_selected)
4666     {
4667       must_sel();
4668     }
4669 }
4670 
4671 
4672 static void alias_cleanup(GtkWidget *widget, gpointer data)
4673 {
4674 (void)widget;
4675 (void)data;
4676 
4677   Trptr t = GLOBALS->trace_to_alias_menu_c_1;
4678 
4679   if(GLOBALS->entrybox_text)
4680     {
4681       char *efix;
4682       /* code to turn '{' and '}' into '[' and ']' */
4683       if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
4684 	{
4685 	  efix=GLOBALS->entrybox_text;
4686 	  while(*efix)
4687 	    {
4688 	      if(*efix=='{')
4689 		{
4690 		  *efix='[';
4691 		}
4692 	      if(*efix=='}')
4693 		{
4694 		  *efix=']';
4695 		}
4696 	      efix++;
4697 	    }
4698 	}
4699 
4700       if (CanAlias(t))
4701 	{
4702 	  if(HasAlias(t)) free_2(t->name_full);
4703 	  t->name_full = (char *)malloc_2(1+strlen(GLOBALS->entrybox_text));
4704 	  strcpy(t->name_full, GLOBALS->entrybox_text);
4705 	  t->name = t->name_full;
4706 	  if(GLOBALS->hier_max_level)
4707 	    t->name = hier_extract(t->name, GLOBALS->hier_max_level);
4708 
4709 	  t->flags&= ~TR_HIGHLIGHT;
4710 	}
4711 
4712       GLOBALS->signalwindow_width_dirty=1;
4713       MaxSignalLength();
4714       signalarea_configure_event(GLOBALS->signalarea, NULL);
4715       wavearea_configure_event(GLOBALS->wavearea, NULL);
4716     }
4717 }
4718 
4719 void menu_alias(gpointer null_data, guint callback_action, GtkWidget *widget)
4720 {
4721 (void)null_data;
4722 (void)callback_action;
4723 (void)widget;
4724 
4725   Trptr t;
4726 
4727   if(GLOBALS->helpbox_is_active)
4728     {
4729       help_text_bold("\n\nAlias Highlighted Trace");
4730       help_text(
4731                 " only works when at least one trace has been highlighted. "
4732                 " With this function, you will be prompted for an alias"
4733                 " name for the first highlighted trace.  After successfully"
4734 		" aliasing a trace, the aliased trace will be unhighlighted."
4735 		" Single bits will be marked with a leading \"+\" and vectors"
4736 		" will have no such designation.  The purpose of this is to"
4737 		" provide a fast method of determining which trace names are"
4738 		" real and which ones are aliases."
4739 		);
4740       return;
4741     }
4742 
4743   GLOBALS->trace_to_alias_menu_c_1=NULL;
4744 
4745   /* don't mess with sigs when dnd active */
4746   if(GLOBALS->dnd_state) { dnd_error(); return; }
4747 
4748   t = GLOBALS->traces.first;
4749   while(t)
4750     {
4751       if(IsSelected(t)&&CanAlias(t))
4752 	{
4753 	  GLOBALS->trace_to_alias_menu_c_1=t;
4754 	  break;
4755 	}
4756       t=t->t_next;
4757     }
4758 
4759   if(GLOBALS->trace_to_alias_menu_c_1)
4760     {
4761       int was_packed = HIER_DEPACK_ALLOC;
4762       char* current = GetFullName(GLOBALS->trace_to_alias_menu_c_1, &was_packed);
4763       ClearTraces();
4764       GLOBALS->trace_to_alias_menu_c_1->flags |= TR_HIGHLIGHT;
4765       entrybox("Alias Highlighted Trace",300,current,NULL,128,GTK_SIGNAL_FUNC(alias_cleanup));
4766       if(was_packed) { free_2(current); }
4767     }
4768   else
4769     {
4770       must_sel();
4771     }
4772 }
4773 
4774 
4775 
4776 
4777 /**/
4778 void menu_hiersearch_cleanup(GtkWidget *widget, gpointer data)
4779 {
4780 (void)widget;
4781 (void)data;
4782 
4783 MaxSignalLength();
4784 signalarea_configure_event(GLOBALS->signalarea, NULL);
4785 wavearea_configure_event(GLOBALS->wavearea, NULL);
4786 DEBUG(printf("menu_hiersearch_cleanup()\n"));
4787 }
4788 
4789 void menu_hiersearch(gpointer null_data, guint callback_action, GtkWidget *widget)
4790 {
4791 (void)null_data;
4792 (void)callback_action;
4793 (void)widget;
4794 
4795 if(GLOBALS->helpbox_is_active)
4796         {
4797         help_text_bold("\n\nHierarchy Search");
4798         help_text(
4799 		" provides an easy means of adding traces to the display in a text based"
4800 		" treelike fashion."
4801         );
4802         return;
4803         }
4804 
4805 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
4806 
4807 hier_searchbox("Hierarchy Search",GTK_SIGNAL_FUNC(menu_hiersearch_cleanup));
4808 }
4809 /**/
4810 void menu_signalsearch_cleanup(GtkWidget *widget, gpointer data)
4811 {
4812 (void)widget;
4813 (void)data;
4814 
4815 MaxSignalLength();
4816 signalarea_configure_event(GLOBALS->signalarea, NULL);
4817 wavearea_configure_event(GLOBALS->wavearea, NULL);
4818 DEBUG(printf("menu_signalsearch_cleanup()\n"));
4819 }
4820 
4821 void menu_signalsearch(gpointer null_data, guint callback_action, GtkWidget *widget)
4822 {
4823 (void)null_data;
4824 (void)callback_action;
4825 (void)widget;
4826 
4827 if(GLOBALS->helpbox_is_active)
4828         {
4829         help_text_bold("\n\nSignal Search Regexp");
4830         help_text(
4831 		" provides an easy means of adding traces to the display. "
4832 		" Various functions are provided in the Signal Search requester"
4833 		" which allow searching using POSIX regular expressions and bundling"
4834 		" (coalescing individual bits into a single vector). "
4835         );
4836         return;
4837         }
4838 
4839 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
4840 
4841 searchbox("Signal Search",GTK_SIGNAL_FUNC(menu_signalsearch_cleanup));
4842 }
4843 /**/
4844 static void
4845 regexp_highlight_generic(int mode)
4846 {
4847 if(GLOBALS->entrybox_text)
4848 	{
4849 	Trptr t;
4850 	Ulong modebits;
4851 	char dirty=0;
4852 
4853 	modebits=(mode)?TR_HIGHLIGHT:0;
4854 
4855 	strcpy(GLOBALS->regexp_string_menu_c_1, GLOBALS->entrybox_text);
4856 	wave_regex_compile(GLOBALS->regexp_string_menu_c_1, WAVE_REGEX_SEARCH);
4857 	free_2(GLOBALS->entrybox_text);
4858 	t=GLOBALS->traces.first;
4859 	while(t)
4860 		{
4861 		char *pnt;
4862 
4863 		pnt=(t->name)?t->name:""; /* handle (really) blank lines */
4864 
4865 		if(*pnt=='+')		  /* skip alias prefix if present */
4866 			{
4867 			pnt++;
4868 			if(*pnt==' ')
4869 				{
4870 				pnt++;
4871 				}
4872 			}
4873 
4874 		if(wave_regex_match(pnt, WAVE_REGEX_SEARCH))
4875 			{
4876 			t->flags=((t->flags&(~TR_HIGHLIGHT))|modebits);
4877 			dirty=1;
4878 			}
4879 
4880 		t=t->t_next;
4881 		}
4882 
4883 	if(dirty)
4884 		{
4885 		signalarea_configure_event(GLOBALS->signalarea, NULL);
4886 		wavearea_configure_event(GLOBALS->wavearea, NULL);
4887 		}
4888 	}
4889 }
4890 
4891 static void
4892 regexp_unhighlight_cleanup(GtkWidget *widget, gpointer data)
4893 {
4894 (void)widget;
4895 (void)data;
4896 
4897 regexp_highlight_generic(0);
4898 }
4899 
4900 void
4901 menu_regexp_unhighlight(gpointer null_data, guint callback_action, GtkWidget *widget)
4902 {
4903 (void)null_data;
4904 (void)callback_action;
4905 (void)widget;
4906 
4907 if(GLOBALS->helpbox_is_active)
4908         {
4909         help_text_bold("\n\nUnHighlight Regexp");
4910         help_text(
4911                 " brings up a text requester that will ask for a"
4912                 " regular expression that may contain text with POSIX regular expressions."
4913                 " All traces meeting this criterion / these criteria will be"
4914                 " unhighlighted if they are currently highlighted."
4915         );
4916         return;
4917         }
4918 
4919 entrybox("Regexp UnHighlight",300,GLOBALS->regexp_string_menu_c_1,NULL,128,GTK_SIGNAL_FUNC(regexp_unhighlight_cleanup));
4920 }
4921 /**/
4922 static void
4923 regexp_highlight_cleanup(GtkWidget *widget, gpointer data)
4924 {
4925 (void)widget;
4926 (void)data;
4927 
4928 regexp_highlight_generic(1);
4929 }
4930 
4931 void
4932 menu_regexp_highlight(gpointer null_data, guint callback_action, GtkWidget *widget)
4933 {
4934 (void)null_data;
4935 (void)callback_action;
4936 (void)widget;
4937 
4938 if(GLOBALS->helpbox_is_active)
4939         {
4940         help_text_bold("\n\nHighlight Regexp");
4941         help_text(
4942                 " brings up a text requester that will ask for a"
4943                 " regular expression that may contain text with POSIX regular expressions."
4944 		" All traces meeting this criterion / these criteria will be"
4945 		" highlighted."
4946         );
4947         return;
4948         }
4949 
4950 entrybox("Regexp Highlight",300,GLOBALS->regexp_string_menu_c_1,NULL,128,GTK_SIGNAL_FUNC(regexp_highlight_cleanup));
4951 }
4952 
4953 /**/
4954 
4955 #if GTK_CHECK_VERSION(2,14,0)
4956 
4957 void
4958 menu_write_screengrab_cleanup(GtkWidget *widget, gpointer data)
4959 {
4960 (void)widget;
4961 (void)data;
4962 
4963 GdkWindow *gw;
4964 gint w, h;
4965 GdkColormap *cm;
4966 GdkPixbuf *dest = NULL;
4967 GdkPixbuf *dest2;
4968 GError *err = NULL;
4969 gboolean succ = FALSE;
4970 
4971 if(!GLOBALS->filesel_ok)
4972 	{
4973 	return;
4974 	}
4975 
4976 gw = gtk_widget_get_window(GTK_WIDGET(GLOBALS->mainwindow));
4977 if(gw)
4978 	{
4979 	gdk_drawable_get_size(gw, &w, &h);
4980 	cm = gdk_drawable_get_colormap(gw);
4981 	if(cm)
4982 		{
4983 		dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, w, h);
4984 		if(dest)
4985 			{
4986 			dest2 = gdk_pixbuf_get_from_drawable(dest, gw, cm, 0, 0, 0, 0, w, h);
4987 			if(dest2)
4988 				{
4989 				succ = gdk_pixbuf_save (dest2, *GLOBALS->fileselbox_text, "png", &err, NULL);
4990 				}
4991 			}
4992 		}
4993 	}
4994 
4995 if(dest)
4996 	{
4997 	g_object_unref(dest);
4998 	}
4999 
5000 if(!succ)
5001 	{
5002         fprintf(stderr, "Error opening imagegrab file '%s' for writing.\n",*GLOBALS->fileselbox_text);
5003 	perror("Why");
5004 	errno=0;
5005 	}
5006 	else
5007 	{
5008 	wave_gconf_client_set_string("/current/imagegrab", GLOBALS->filesel_imagegrab);
5009 	}
5010 }
5011 
5012 void
5013 menu_write_screengrab_as(gpointer null_data, guint callback_action, GtkWidget *widget)
5014 {
5015 (void)null_data;
5016 (void)callback_action;
5017 (void)widget;
5018 
5019 if(GLOBALS->helpbox_is_active)
5020 	{
5021 	help_text_bold("\n\nGrab To File");
5022 	help_text(
5023 		" will open a file requester that will ask for the name"
5024 		" to be used for a PNG format image grab of the main GTKWave window."
5025 		" Note that if the main window is covered by other windows or"
5026 		" is partially offscreen, the grabbed image might not appear properly."
5027 	);
5028 	return;
5029 	}
5030 
5031 errno = 0;
5032 fileselbox("Grab To File",&GLOBALS->filesel_imagegrab,GTK_SIGNAL_FUNC(menu_write_screengrab_cleanup), GTK_SIGNAL_FUNC(NULL), "*.png", 1);
5033 }
5034 
5035 #endif
5036 
5037 /**/
5038 
5039 void
5040 menu_write_save_cleanup(GtkWidget *widget, gpointer data)
5041 {
5042 (void)widget;
5043 (void)data;
5044 
5045 FILE *wave;
5046 int len;
5047 
5048 if(!GLOBALS->filesel_ok)
5049 	{
5050 	return;
5051 	}
5052 
5053 len = strlen(*GLOBALS->fileselbox_text);
5054 if((!len) || ((*GLOBALS->fileselbox_text)[len-1] == '/')
5055 #if !defined __MINGW32__ && !defined _MSC_VER
5056           || ((*GLOBALS->fileselbox_text)[len-1] == '\\')
5057 #endif
5058 )
5059 	{
5060 	GLOBALS->save_success_menu_c_1 = 2;
5061 	return;
5062 	}
5063 
5064 if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb")))
5065         {
5066         fprintf(stderr, "Error opening save file '%s' for writing.\n",*GLOBALS->fileselbox_text);
5067 	perror("Why");
5068 	errno=0;
5069         }
5070 	else
5071 	{
5072           write_save_helper(*GLOBALS->fileselbox_text, wave);
5073 	  wave_gconf_client_set_string("/current/savefile", GLOBALS->filesel_writesave);
5074 	  GLOBALS->save_success_menu_c_1 = 1;
5075 	  fclose(wave);
5076 	}
5077 
5078 }
5079 
5080 void
5081 menu_write_save_file_as(gpointer null_data, guint callback_action, GtkWidget *widget)
5082 {
5083 (void)null_data;
5084 (void)callback_action;
5085 (void)widget;
5086 
5087 if(GLOBALS->helpbox_is_active)
5088 	{
5089 	help_text_bold("\n\nWrite Save File As");
5090 	help_text(
5091 		" will open a file requester that will ask for the name"
5092 		" of a GTKWave save file.  The contents of the save file"
5093 		" generated will be the traces as well as their"
5094  		" format (binary, decimal, hex, reverse, etc.) which"
5095 		" are currently a part of the display.  Marker positional"
5096 		" data and the zoom factor are also a part of the save file."
5097 	);
5098 	return;
5099 	}
5100 
5101 fileselbox("Write Save File",&GLOBALS->filesel_writesave,GTK_SIGNAL_FUNC(menu_write_save_cleanup), GTK_SIGNAL_FUNC(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 1);
5102 }
5103 
5104 void
5105 menu_write_save_file(gpointer null_data, guint callback_action, GtkWidget *widget)
5106 {
5107 (void)null_data;
5108 (void)callback_action;
5109 (void)widget;
5110 int len = 0;
5111 
5112 if(GLOBALS->helpbox_is_active)
5113 	{
5114 	help_text_bold("\n\nWrite Save File");
5115 	help_text(
5116 		" will invoke Write Save File As if no save file name has been specified previously."
5117 		" Otherwise it will write the save file data without prompting."
5118 	);
5119 	return;
5120 	}
5121 
5122 if(GLOBALS->filesel_writesave)
5123 	{
5124 	len = strlen(GLOBALS->filesel_writesave);
5125 	}
5126 
5127 if	((!len) || (GLOBALS->filesel_writesave[len-1] == '/')
5128 #if !defined __MINGW32__ && !defined _MSC_VER
5129 	|| (GLOBALS->filesel_writesave[len-1] == '\\')
5130 #endif
5131 	)
5132 	{
5133 	fileselbox("Write Save File",&GLOBALS->filesel_writesave,GTK_SIGNAL_FUNC(menu_write_save_cleanup), GTK_SIGNAL_FUNC(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 1);
5134 	}
5135 	else
5136 	{
5137 	GLOBALS->filesel_ok = 1;
5138 	GLOBALS->save_success_menu_c_1 = 0;
5139 	GLOBALS->fileselbox_text = &GLOBALS->filesel_writesave;
5140 	menu_write_save_cleanup(NULL, NULL);
5141 	if(GLOBALS->save_success_menu_c_1 != 2) /* cancelled */
5142 		{
5143 		if(GLOBALS->save_success_menu_c_1)
5144 			{
5145 			status_text("Wrote save file OK.\n");
5146 			}
5147 			else
5148 			{
5149 			status_text("Problem writing save file.\n");
5150 			}
5151 		}
5152 	}
5153 }
5154 /**/
5155 
5156 void
5157 menu_read_save_cleanup(GtkWidget *widget, gpointer data)
5158 {
5159 (void)widget;
5160 (void)data;
5161 
5162 if(GLOBALS->filesel_ok)
5163 	{
5164 	char *wname;
5165 
5166 	DEBUG(printf("Read Save Fini: %s\n", *GLOBALS->fileselbox_text));
5167 
5168         wname=*GLOBALS->fileselbox_text;
5169         wave_gconf_client_set_string("/current/savefile", wname);
5170         read_save_helper(wname, NULL, NULL, NULL, NULL, NULL);
5171   }
5172 }
5173 
5174 
5175 void
5176 menu_read_save_file(gpointer null_data, guint callback_action, GtkWidget *widget)
5177 {
5178 (void)null_data;
5179 (void)callback_action;
5180 (void)widget;
5181 
5182 if(GLOBALS->helpbox_is_active)
5183 	{
5184 	help_text_bold("\n\nRead Save File");
5185 	help_text(
5186 		" will open a file requester that will ask for the name"
5187 		" of a GTKWave save file.  The contents of the save file"
5188 		" will determine which traces and vectors as well as their"
5189  		" format (binary, decimal, hex, reverse, etc.) are to be"
5190 		" appended to the display.  Note that the marker positional"
5191 		" data and zoom factor present in the save file will"
5192 		" replace any current settings."
5193 	);
5194 	return;
5195 	}
5196 
5197 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
5198 
5199 fileselbox("Read Save File",&GLOBALS->filesel_writesave,GTK_SIGNAL_FUNC(menu_read_save_cleanup), GTK_SIGNAL_FUNC(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 0);
5200 }
5201 
5202 #if !defined _MSC_VER
5203 /**/
5204 void
5205 menu_read_stems_cleanup(GtkWidget *widget, gpointer data)
5206 {
5207 (void)widget;
5208 (void)data;
5209 
5210 char *fname;
5211 
5212 if(GLOBALS->filesel_ok)
5213 	{
5214 	DEBUG(printf("Read Stems Fini: %s\n", *GLOBALS->fileselbox_text));
5215 
5216         fname=*GLOBALS->fileselbox_text;
5217 	if((fname)&&strlen(fname))
5218 		{
5219 	        activate_stems_reader(fname);
5220 		}
5221 	}
5222 }
5223 /**/
5224 void
5225 menu_read_stems_file(gpointer null_data, guint callback_action, GtkWidget *widget)
5226 {
5227 (void)null_data;
5228 (void)callback_action;
5229 (void)widget;
5230 
5231 if(GLOBALS->helpbox_is_active)
5232 	{
5233 	help_text_bold("\n\nRead Verilog Stemsfile");
5234 	help_text(
5235 		" will open a file requester that will ask for the name"
5236 		" of a Verilog stemsfile.  This will then launch an RTL browser and allow source code annotation based on"
5237 		" the primary marker position."
5238 		" Stems files are generated by xml2stems.  Please see its manpage"
5239 		" for syntax and more information on stems file generation."
5240 	);
5241 	return;
5242 	}
5243 
5244 if(!stems_are_active())
5245 	{
5246 	if(GLOBALS->stems_type != WAVE_ANNO_NONE)
5247 		{
5248 		fileselbox("Read Verilog Stemsfile",&GLOBALS->stems_name, GTK_SIGNAL_FUNC(menu_read_stems_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0);
5249 		}
5250 		else
5251 		{
5252 		status_text("Unsupported dumpfile type for rtlbrowse.\n");
5253 		}
5254 	}
5255 }
5256 #endif
5257 
5258 /**/
5259 void
5260 menu_read_log_cleanup(GtkWidget *widget, gpointer data)
5261 {
5262 (void)widget;
5263 (void)data;
5264 
5265 char *fname ;
5266 
5267 if(GLOBALS->filesel_ok)
5268 	{
5269 	DEBUG(printf("Read Log Fini: %s\n", *GLOBALS->fileselbox_text));
5270 
5271         fname=*GLOBALS->fileselbox_text;
5272 	if((fname)&&strlen(fname))
5273 		{
5274 	        logbox("Logfile viewer", 480, fname);
5275 		}
5276 	}
5277 }
5278 /**/
5279 void
5280 menu_read_log_file(gpointer null_data, guint callback_action, GtkWidget *widget)
5281 {
5282 (void)null_data;
5283 (void)callback_action;
5284 (void)widget;
5285 
5286 if(GLOBALS->helpbox_is_active)
5287 	{
5288 	help_text_bold("\n\nRead Logfile");
5289 	help_text(
5290 		" will open a file requester that will ask for the name"
5291 		" of a plaintext simulation log.  By clicking on the numbers in the logfile,"
5292 		" the marker will jump to the appropriate time value in the wave window."
5293 	);
5294 	return;
5295 	}
5296 
5297 fileselbox("Read Logfile",&GLOBALS->filesel_logfile_menu_c_1,GTK_SIGNAL_FUNC(menu_read_log_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0);
5298 }
5299 
5300 /**/
5301 void
5302 menu_read_script_cleanup(GtkWidget *widget, gpointer data)
5303 {
5304 (void)widget;
5305 (void)data;
5306 
5307 char *fname;
5308 
5309 if(GLOBALS->filesel_ok)
5310 	{
5311 	DEBUG(printf("Read Script Fini: %s\n", *GLOBALS->fileselbox_text));
5312 
5313         fname=*GLOBALS->fileselbox_text;
5314 	if((fname)&&strlen(fname))
5315 		{
5316 		execute_script(fname, 0);
5317 		}
5318 	}
5319 }
5320 /**/
5321 void
5322 menu_read_script_file(gpointer null_data, guint callback_action, GtkWidget *widget)
5323 {
5324 (void)null_data;
5325 (void)callback_action;
5326 (void)widget;
5327 
5328 if(GLOBALS->helpbox_is_active)
5329 	{
5330 	help_text_bold("\n\nRead Script File");
5331 	help_text(
5332 		" will open a file requester that will ask for the name"
5333 		" of a TCL script to run.  This menu option itself is not callable"
5334 		" by TCL scripts."
5335 	);
5336 	return;
5337 	}
5338 
5339 fileselbox("Read Script File",&GLOBALS->filesel_scriptfile_menu,GTK_SIGNAL_FUNC(menu_read_script_cleanup), GTK_SIGNAL_FUNC(NULL), "*.tcl", 0);
5340 }
5341 
5342 /**/
5343 void
5344 menu_insert_blank_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
5345 {
5346 (void)null_data;
5347 (void)callback_action;
5348 (void)widget;
5349 
5350 if(GLOBALS->helpbox_is_active)
5351         {
5352         help_text_bold("\n\nInsert Blank");
5353         help_text(
5354                 " inserts a blank trace after the last highlighted trace."
5355                 " If no traces are highlighted, the blank is inserted after"
5356 		" the last trace."
5357         );
5358         return;
5359         }
5360 
5361 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
5362 
5363 DEBUG(printf("Insert Blank Trace\n"));
5364 
5365 InsertBlankTrace(NULL, 0);
5366 signalarea_configure_event(GLOBALS->signalarea, NULL);
5367 wavearea_configure_event(GLOBALS->wavearea, NULL);
5368 }
5369 
5370 void
5371 menu_insert_analog_height_extension(gpointer null_data, guint callback_action, GtkWidget *widget)
5372 {
5373 (void)null_data;
5374 (void)callback_action;
5375 (void)widget;
5376 
5377 if(GLOBALS->helpbox_is_active)
5378         {
5379         help_text_bold("\n\nInsert Analog Height Extension");
5380         help_text(
5381                 " inserts a blank analog extension trace after the last highlighted trace."
5382                 " If no traces are highlighted, the blank is inserted after"
5383 		" the last trace.  This type of trace is used to increase the height of analog traces."
5384         );
5385         return;
5386         }
5387 
5388 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
5389 
5390 DEBUG(printf("Insert Analog Blank Trace\n"));
5391 
5392 InsertBlankTrace(NULL, TR_ANALOG_BLANK_STRETCH);
5393 signalarea_configure_event(GLOBALS->signalarea, NULL);
5394 wavearea_configure_event(GLOBALS->wavearea, NULL);
5395 }
5396 /**/
5397 static void
5398 comment_trace_cleanup(GtkWidget *widget, gpointer data)
5399 {
5400 (void)widget;
5401 (void)data;
5402 
5403 InsertBlankTrace(GLOBALS->entrybox_text, 0);
5404 if(GLOBALS->entrybox_text) { free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; }
5405 GLOBALS->signalwindow_width_dirty=1;
5406 MaxSignalLength();
5407 signalarea_configure_event(GLOBALS->signalarea, NULL);
5408 wavearea_configure_event(GLOBALS->wavearea, NULL);
5409 }
5410 
5411 void
5412 menu_insert_comment_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
5413 {
5414 (void)null_data;
5415 (void)callback_action;
5416 (void)widget;
5417 
5418 if(GLOBALS->helpbox_is_active)
5419         {
5420         help_text_bold("\n\nInsert Comment");
5421         help_text(
5422                 " inserts a comment trace after the last highlighted trace."
5423                 " If no traces are highlighted, the comment is inserted after"
5424 		" the last trace."
5425         );
5426         return;
5427         }
5428 
5429 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
5430 
5431 DEBUG(printf("Insert Comment Trace\n"));
5432 
5433 entrybox("Insert Comment Trace",300,"",NULL,128,GTK_SIGNAL_FUNC(comment_trace_cleanup));
5434 }
5435 /**/
5436 static void strace_repcnt_cleanup(GtkWidget *widget, gpointer data)
5437 {
5438 (void)widget;
5439 (void)data;
5440 
5441 if(GLOBALS->entrybox_text)
5442 	{
5443 	GLOBALS->strace_repeat_count = atoi_64(GLOBALS->entrybox_text);
5444 
5445 	free_2(GLOBALS->entrybox_text);
5446 	GLOBALS->entrybox_text=NULL;
5447 	}
5448 }
5449 
5450 void menu_strace_repcnt(gpointer null_data, guint callback_action, GtkWidget *widget)
5451 {
5452 (void)null_data;
5453 (void)callback_action;
5454 (void)widget;
5455 
5456 char gt[32];
5457 
5458 if(GLOBALS->helpbox_is_active)
5459         {
5460         help_text_bold("\n\nSet Pattern Search Repeat Count");
5461         help_text(
5462                 " sets the number of times that both edge and pattern searches iterate forward or backward when marker forward/backward is selected."
5463 		" Default value is one.  This can be used, for example, to skip forward 10 clock edges at a time rather than a single edge."
5464         );
5465         return;
5466         }
5467 
5468 sprintf(gt, "%d", GLOBALS->strace_repeat_count);
5469 entrybox("Repeat Count",300,gt,NULL,20,GTK_SIGNAL_FUNC(strace_repcnt_cleanup));
5470 }
5471 /**/
5472 void movetotime_cleanup(GtkWidget *widget, gpointer data)
5473 {
5474 (void)widget;
5475 (void)data;
5476 
5477 if(GLOBALS->entrybox_text)
5478 	{
5479 	TimeType gt = GLOBALS->tims.first;
5480 	char update_string[128];
5481 	char timval[40];
5482 	GtkAdjustment *hadj;
5483 	TimeType pageinc;
5484 
5485         if((GLOBALS->entrybox_text[0] >= 'A' && GLOBALS->entrybox_text[0] <= 'Z')||(GLOBALS->entrybox_text[0] >= 'a' && GLOBALS->entrybox_text[0] <= 'z'))
5486                 {
5487 		char *su = GLOBALS->entrybox_text;
5488 		int uch;
5489 		while(*su)
5490 			{
5491 			uch = toupper((int)(unsigned char)*su);
5492 			*su = uch;
5493 			su++;
5494 			}
5495 
5496 		uch = bijective_marker_id_string_hash(GLOBALS->entrybox_text);
5497 
5498 		if((uch >= 0)&&(uch < WAVE_NUM_NAMED_MARKERS))
5499 			{
5500 	                gt=GLOBALS->named_markers[uch];
5501 			}
5502                 }
5503                 else
5504                 {
5505                 gt=unformat_time(GLOBALS->entrybox_text, GLOBALS->time_dimension);
5506 		gt -= GLOBALS->global_time_offset;
5507                 }
5508 	free_2(GLOBALS->entrybox_text);
5509 	GLOBALS->entrybox_text=NULL;
5510 
5511 	if(gt<GLOBALS->tims.first) gt=GLOBALS->tims.first;
5512 	else if(gt>GLOBALS->tims.last) gt=GLOBALS->tims.last;
5513 
5514 	hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider);
5515 	hadj->value=gt;
5516 
5517 	pageinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
5518 	if(gt<(GLOBALS->tims.last-pageinc+1))
5519 		GLOBALS->tims.timecache=gt;
5520 	        else
5521 	        {
5522 	        GLOBALS->tims.timecache=GLOBALS->tims.last-pageinc+1;
5523         	if(GLOBALS->tims.timecache<GLOBALS->tims.first) GLOBALS->tims.timecache=GLOBALS->tims.first;
5524         	}
5525 
5526 	reformat_time(timval,GLOBALS->tims.timecache + GLOBALS->global_time_offset,GLOBALS->time_dimension);
5527 	sprintf(update_string, "Moved to time: %s\n", timval);
5528 	status_text(update_string);
5529 
5530 	time_update();
5531 	}
5532 }
5533 
5534 void menu_movetotime(gpointer null_data, guint callback_action, GtkWidget *widget)
5535 {
5536 (void)null_data;
5537 (void)callback_action;
5538 (void)widget;
5539 
5540 char gt[32];
5541 
5542 if(GLOBALS->helpbox_is_active)
5543         {
5544         help_text_bold("\n\nMove To Time");
5545         help_text(
5546                 " scrolls the waveform display such that the left border"
5547                 " is the time entered in the requester."
5548                 " Use one of the letters A-Z to move to a named marker."
5549         );
5550         return;
5551         }
5552 
5553 reformat_time(gt, GLOBALS->tims.start + GLOBALS->global_time_offset, GLOBALS->time_dimension);
5554 
5555 entrybox("Move To Time",200,gt,NULL,20,GTK_SIGNAL_FUNC(movetotime_cleanup));
5556 }
5557 /**/
5558 static void fetchsize_cleanup(GtkWidget *widget, gpointer data)
5559 {
5560 (void)widget;
5561 (void)data;
5562 
5563 if(GLOBALS->entrybox_text)
5564 	{
5565 	TimeType fw;
5566 	char update_string[128];
5567 	fw=unformat_time(GLOBALS->entrybox_text, GLOBALS->time_dimension);
5568 	if(fw<1)
5569 		{
5570 		fw=GLOBALS->fetchwindow; /* in case they try to pull 0 or <0 */
5571 		}
5572 		else
5573 		{
5574 		GLOBALS->fetchwindow=fw;
5575 		}
5576 	free_2(GLOBALS->entrybox_text);
5577 	GLOBALS->entrybox_text=NULL;
5578 	sprintf(update_string, "Fetch Size is now: "TTFormat"\n", fw);
5579 	status_text(update_string);
5580 	}
5581 }
5582 
5583 void menu_fetchsize(gpointer null_data, guint callback_action, GtkWidget *widget)
5584 {
5585 (void)null_data;
5586 (void)callback_action;
5587 (void)widget;
5588 
5589 char fw[32];
5590 
5591 if(GLOBALS->helpbox_is_active)
5592         {
5593         help_text_bold("\n\nFetch Size");
5594         help_text(
5595                 " brings up a requester which allows input of the"
5596                 " number of ticks used for fetch/discard operations."
5597 		"  Default is 100."
5598         );
5599         return;
5600         }
5601 
5602 reformat_time(fw, GLOBALS->fetchwindow, GLOBALS->time_dimension);
5603 
5604 entrybox("New Fetch Size",200,fw,NULL,20,GTK_SIGNAL_FUNC(fetchsize_cleanup));
5605 }
5606 /**/
5607 void zoomsize_cleanup(GtkWidget *widget, gpointer data)
5608 {
5609 (void)widget;
5610 (void)data;
5611 
5612 if(GLOBALS->entrybox_text)
5613 	{
5614 	float f;
5615 	char update_string[128];
5616 
5617 	sscanf(GLOBALS->entrybox_text, "%f", &f);
5618 	if(f>0.0)
5619 		{
5620 		f=0.0; /* in case they try to go out of range */
5621 		}
5622 	else
5623 	if(f<-62.0)
5624 		{
5625 		f=-62.0; /* in case they try to go out of range */
5626 		}
5627 
5628 	GLOBALS->tims.prevzoom=GLOBALS->tims.zoom;
5629 	GLOBALS->tims.zoom=(gdouble)f;
5630 	calczoom(GLOBALS->tims.zoom);
5631 	fix_wavehadj();
5632 
5633 	gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed");
5634 	gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed");
5635 
5636 	free_2(GLOBALS->entrybox_text);
5637 	GLOBALS->entrybox_text=NULL;
5638 	sprintf(update_string, "Zoom Amount is now: %g\n", f);
5639 	status_text(update_string);
5640 	}
5641 }
5642 
5643 void menu_zoomsize(gpointer null_data, guint callback_action, GtkWidget *widget)
5644 {
5645 (void)null_data;
5646 (void)callback_action;
5647 (void)widget;
5648 
5649 char za[32];
5650 
5651 if(GLOBALS->helpbox_is_active)
5652         {
5653         help_text_bold("\n\nZoom Amount");
5654         help_text(
5655                 " allows entry of zero or a negative value for the display"
5656 		" zoom.  Zero is no magnification."
5657         );
5658         return;
5659         }
5660 
5661 
5662 sprintf(za,"%g",(float)(GLOBALS->tims.zoom));
5663 
5664 entrybox("New Zoom Amount",200,za,NULL,20,GTK_SIGNAL_FUNC(zoomsize_cleanup));
5665 }
5666 /**/
5667 static void zoombase_cleanup(GtkWidget *widget, gpointer data)
5668 {
5669 (void)widget;
5670 (void)data;
5671 
5672 if(GLOBALS->entrybox_text)
5673 	{
5674 	float za;
5675 	char update_string[128];
5676 	sscanf(GLOBALS->entrybox_text, "%f", &za);
5677 	if(za>10.0)
5678 		{
5679 		za=10.0;
5680 		}
5681 	else
5682 	if(za<1.5)
5683 		{
5684 		za=1.5;
5685 		}
5686 
5687 	GLOBALS->zoombase=(gdouble)za;
5688 	calczoom(GLOBALS->tims.zoom);
5689 	fix_wavehadj();
5690 
5691 	gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed");
5692 	gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed");
5693 
5694 	free_2(GLOBALS->entrybox_text);
5695 	GLOBALS->entrybox_text=NULL;
5696 	sprintf(update_string, "Zoom Base is now: %g\n", za);
5697 	status_text(update_string);
5698 	}
5699 }
5700 
5701 void menu_zoombase(gpointer null_data, guint callback_action, GtkWidget *widget)
5702 {
5703 (void)null_data;
5704 (void)callback_action;
5705 (void)widget;
5706 
5707 char za[32];
5708 
5709 if(GLOBALS->helpbox_is_active)
5710         {
5711         help_text_bold("\n\nZoom Base");
5712         help_text(
5713                 " allows entry of a zoom base for the zoom (magnification per integer step)"
5714 		" Allowable values are 1.5 to 10.0.  Default is 2.0."
5715         );
5716         return;
5717         }
5718 
5719 
5720 sprintf(za,"%g",GLOBALS->zoombase);
5721 
5722 entrybox("New Zoom Base Amount",200,za,NULL,20,GTK_SIGNAL_FUNC(zoombase_cleanup));
5723 }
5724 /**/
5725 static void colorformat(int color)
5726 {
5727   Trptr t;
5728   int fix=0;
5729   int color_prev = WAVE_COLOR_NORMAL;
5730   int is_first = 0;
5731 
5732   if((t=GLOBALS->traces.first))
5733     {
5734       while(t)
5735         {
5736           if(IsSelected(t)&&!IsShadowed(t))
5737             {
5738 	      if(color != WAVE_COLOR_CYCLE)
5739 		{
5740               	t->t_color = color;
5741 		}
5742 		else
5743 		{
5744 		if(!is_first)
5745 			{
5746 			is_first = 1;
5747 			if(t->t_color == WAVE_COLOR_NORMAL) { color_prev = WAVE_COLOR_RED; } else { color_prev = t->t_color; }
5748 			}
5749 			else
5750 			{
5751 			color_prev++;
5752 			}
5753 
5754 		if(color_prev > WAVE_COLOR_VIOLET) color_prev = WAVE_COLOR_RED;
5755               	t->t_color = color_prev;
5756 		}
5757               fix=1;
5758             }
5759           t=t->t_next;
5760         }
5761       if(fix)
5762         {
5763           GLOBALS->signalwindow_width_dirty=1;
5764           MaxSignalLength();
5765           signalarea_configure_event(GLOBALS->signalarea, NULL);
5766           wavearea_configure_event(GLOBALS->wavearea, NULL);
5767         }
5768     }
5769 }
5770 
5771 void
5772 menu_colorformat_0(gpointer null_data, guint callback_action, GtkWidget *widget)
5773 {
5774 (void)null_data;
5775 (void)callback_action;
5776 (void)widget;
5777 
5778 if(GLOBALS->helpbox_is_active)
5779         {
5780         help_text_bold("\n\nColor Format Normal");
5781         help_text(
5782                 " uses normal waveform colorings for all selected traces."
5783         );
5784         return;
5785         }
5786 
5787 colorformat(WAVE_COLOR_NORMAL);
5788 }
5789 
5790 void
5791 menu_colorformat_1(gpointer null_data, guint callback_action, GtkWidget *widget)
5792 {
5793 (void)null_data;
5794 (void)callback_action;
5795 (void)widget;
5796 
5797 if(GLOBALS->helpbox_is_active)
5798         {
5799         help_text_bold("\n\nColor Format Red");
5800         help_text(
5801                 " uses red waveform colorings for all selected traces."
5802         );
5803         return;
5804         }
5805 
5806 colorformat(WAVE_COLOR_RED);
5807 }
5808 
5809 void
5810 menu_colorformat_2(gpointer null_data, guint callback_action, GtkWidget *widget)
5811 {
5812 (void)null_data;
5813 (void)callback_action;
5814 (void)widget;
5815 
5816 if(GLOBALS->helpbox_is_active)
5817         {
5818         help_text_bold("\n\nColor Format Orange");
5819         help_text(
5820                 " uses orange waveform colorings for all selected traces."
5821         );
5822         return;
5823         }
5824 
5825 colorformat(WAVE_COLOR_ORANGE);
5826 }
5827 
5828 void
5829 menu_colorformat_3(gpointer null_data, guint callback_action, GtkWidget *widget)
5830 {
5831 (void)null_data;
5832 (void)callback_action;
5833 (void)widget;
5834 
5835 if(GLOBALS->helpbox_is_active)
5836         {
5837         help_text_bold("\n\nColor Format Yellow");
5838         help_text(
5839                 " uses yellow waveform colorings for all selected traces."
5840         );
5841         return;
5842         }
5843 
5844 colorformat(WAVE_COLOR_YELLOW);
5845 }
5846 
5847 void
5848 menu_colorformat_4(gpointer null_data, guint callback_action, GtkWidget *widget)
5849 {
5850 (void)null_data;
5851 (void)callback_action;
5852 (void)widget;
5853 
5854 if(GLOBALS->helpbox_is_active)
5855         {
5856         help_text_bold("\n\nColor Format Green");
5857         help_text(
5858                 " uses green waveform colorings for all selected traces."
5859         );
5860         return;
5861         }
5862 
5863 colorformat(WAVE_COLOR_GREEN);
5864 }
5865 
5866 void
5867 menu_colorformat_5(gpointer null_data, guint callback_action, GtkWidget *widget)
5868 {
5869 (void)null_data;
5870 (void)callback_action;
5871 (void)widget;
5872 
5873 if(GLOBALS->helpbox_is_active)
5874         {
5875         help_text_bold("\n\nColor Format Blue");
5876         help_text(
5877                 " uses blue waveform colorings for all selected traces."
5878         );
5879         return;
5880         }
5881 
5882 colorformat(WAVE_COLOR_BLUE);
5883 }
5884 
5885 void
5886 menu_colorformat_6(gpointer null_data, guint callback_action, GtkWidget *widget)
5887 {
5888 (void)null_data;
5889 (void)callback_action;
5890 (void)widget;
5891 
5892 if(GLOBALS->helpbox_is_active)
5893         {
5894         help_text_bold("\n\nColor Format Indigo");
5895         help_text(
5896                 " uses indigo waveform colorings for all selected traces."
5897         );
5898         return;
5899         }
5900 
5901 colorformat(WAVE_COLOR_INDIGO);
5902 }
5903 
5904 void
5905 menu_colorformat_7(gpointer null_data, guint callback_action, GtkWidget *widget)
5906 {
5907 (void)null_data;
5908 (void)callback_action;
5909 (void)widget;
5910 
5911 if(GLOBALS->helpbox_is_active)
5912         {
5913         help_text_bold("\n\nColor Format Violet");
5914         help_text(
5915                 " uses violet waveform colorings for all selected traces."
5916         );
5917         return;
5918         }
5919 
5920 colorformat(WAVE_COLOR_VIOLET);
5921 }
5922 
5923 void
5924 menu_colorformat_cyc(gpointer null_data, guint callback_action, GtkWidget *widget)
5925 {
5926 (void)null_data;
5927 (void)callback_action;
5928 (void)widget;
5929 
5930 if(GLOBALS->helpbox_is_active)
5931         {
5932         help_text_bold("\n\nColor Format Cycle");
5933         help_text(
5934                 " uses cycling waveform colorings for all selected traces."
5935         );
5936         return;
5937         }
5938 
5939 colorformat(WAVE_COLOR_CYCLE);
5940 }
5941 /**/
5942 
5943 char **grow_array(char ***src, int *siz, char *str)
5944 {
5945 if(!*src)
5946         {
5947         *src = malloc_2(sizeof(char *));
5948         (*src)[0] = str;
5949         *siz = 1;
5950         }
5951         else
5952         {
5953         *src = realloc_2(*src, (*siz + 1) * sizeof(char *));
5954         (*src)[*siz] = str;
5955         *siz = *siz + 1;
5956         }
5957 
5958 return(*src);
5959 }
5960 
5961 
5962 #if WAVE_USE_GTK2
5963 static void open_index_in_forked_editor(uint32_t idx, int typ)
5964 {
5965 if(idx)
5966 	{
5967 	int lineno = 1;
5968 	char *edname = getenv("GTKWAVE_EDITOR");
5969 	char *fname = NULL;
5970 	FILE *ftest = NULL;
5971 
5972 	if(GLOBALS->editor_name)
5973 		{
5974 		edname = GLOBALS->editor_name;		/* rcfile "editor" variable first */
5975 		}
5976 	else
5977 		{
5978 		if(edname)
5979 			{
5980 			/* ok, env var GTKWAVE_EDITOR second */
5981 			}
5982 #ifdef GEDIT_PATH
5983 			else
5984 			{
5985 			/* fallback */
5986 			edname = GEDIT_PATH;
5987 			}
5988 #endif
5989 		}
5990 
5991 #ifdef MAC_INTEGRATION
5992 	if(!edname)
5993 		{
5994 		edname = "open -t"; /* Use OSX TextEdit as editor of last resort */
5995 		}
5996 #endif
5997 
5998 	idx--;
5999 	if(typ == FST_MT_SOURCESTEM)
6000 		{
6001                 lineno = GLOBALS->stem_struct_base[idx].stem_line_number;
6002                 fname = GLOBALS->stem_path_string_table[GLOBALS->stem_struct_base[idx].stem_idx];
6003 		}
6004 		else
6005 		{
6006                 lineno = GLOBALS->istem_struct_base[idx].stem_line_number;
6007                 fname = GLOBALS->stem_path_string_table[GLOBALS->istem_struct_base[idx].stem_idx];
6008 		}
6009 
6010 #ifdef __MINGW32__
6011 	{
6012         fprintf(stderr, "GTKWAVE | Not supported in Windows!\n");
6013 	}
6014 #else
6015 
6016 	if(!(ftest = fopen(fname, "rb")))
6017 		{
6018 		char *rp = get_relative_adjusted_name(GLOBALS->loaded_file_name, fname, GLOBALS->loaded_file_name);
6019 		if(!rp)
6020 			{
6021 			int clen = strlen(fname);
6022 			int wid = clen * 10;
6023 
6024 			if(wid < 400) wid = 400;
6025 
6026 			simplereqbox("Could not open file!", wid, fname, "OK", NULL, NULL, 1);
6027 			return;
6028 			}
6029 
6030 		fname = wave_alloca(strlen(rp) + 1);
6031 		strcpy(fname, rp);
6032 		free_2(rp);
6033 		}
6034 		else
6035 		{
6036 		fclose(ftest); ftest = NULL;
6037 		}
6038 
6039 	{
6040         pid_t pid=fork();
6041 
6042         if(((int)pid) < 0)
6043                 {
6044                 /* can't do anything about this */
6045                 }
6046                 else
6047                 {
6048                 if(pid) /* parent==original server_pid */
6049                         {
6050                         }
6051                         else
6052                         {
6053 			char *str = strdup_2(edname);
6054 	                char nbuf[32];
6055 
6056 			char *saveptr1 = NULL;
6057 			char *str1, *token, *sd_token;
6058 			const char *delim = " \t";
6059 			int num_seen = 0;
6060 			int fn_seen = 0;
6061 
6062 			char **ar = NULL;
6063 			int siz = 0;
6064 
6065        			for(str1 = str;;str1 = NULL)
6066 			        {
6067 			        token = strtok_r(str1, delim, &saveptr1);
6068 			        if(!token) break;
6069 
6070 			        if(strstr(token, "%d"))
6071 			                {
6072 			                sprintf(nbuf, token, lineno);
6073 			                sd_token = strdup_2(nbuf);
6074 					num_seen = 1;
6075 			                }
6076 			        else if(!strcmp(token, "%s"))
6077 			                {
6078 			                sd_token = strdup_2(fname);
6079 					fn_seen = 1;
6080 			                }
6081 		                else
6082 			                {
6083 			                sd_token = strdup_2(token);
6084 			                }
6085 			        grow_array(&ar, &siz, sd_token);
6086 			        }
6087 
6088 			if(ar && edname)
6089 				{
6090 				if(!num_seen)
6091 					{
6092 					if((strstr(ar[0], "vi")) || (strstr(ar[0], "emacs")) || (strstr(ar[0], "gedit")))
6093 						{
6094 						sprintf(nbuf, "+%d", lineno);
6095 						sd_token = strdup_2(nbuf);
6096 					        grow_array(&ar, &siz, sd_token);
6097 						}
6098 					}
6099 
6100 				if(!fn_seen)
6101 					{
6102 					sd_token = strdup_2(fname);
6103 					grow_array(&ar, &siz, sd_token);
6104 					}
6105 
6106 				grow_array(&ar, &siz, NULL);
6107 
6108 	                        execvp(ar[0], ar);
6109 				}
6110 
6111                         fprintf(stderr, "GTKWAVE | Could not find editor executable!\n");
6112                         exit(255); /* control never gets here if successful */
6113                         }
6114                 }
6115 	}
6116 #endif
6117 	}
6118 	else
6119 	{
6120 	simplereqbox("Open Source", 400, "Source stem not present!", "OK", NULL, NULL, 1);
6121 	}
6122 }
6123 #endif
6124 
6125 
6126 static void
6127 menu_open_hierarchy_2(gpointer null_data, guint callback_action, GtkWidget *widget, int typ)
6128 {
6129 (void)null_data;
6130 (void)callback_action;
6131 (void)widget;
6132 
6133 #if WAVE_USE_GTK2
6134 Trptr t;
6135 int fix=0;
6136 struct tree *t_forced = NULL;
6137 #endif
6138 
6139 if(GLOBALS->helpbox_is_active)
6140         {
6141 	if((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM))
6142 		{
6143 		if(typ == FST_MT_SOURCESTEM)
6144 			{
6145 		        help_text_bold("\n\nOpen Source Definition");
6146 			}
6147 			else
6148 			{
6149 		        help_text_bold("\n\nOpen Source Instantiation");
6150 			}
6151 	        help_text(
6152 #if WAVE_USE_GTK2
6153                         " opens and selects the appropriate level of hierarchy in the SST"
6154                         " for the first selected signal and also invokes the editor specified by the"
6155                         " \"editor\" gtkwaverc variable, that specified by the environment variable $GTKWAVE_EDITOR,"
6156 #ifndef MAC_INTEGRATION
6157 
6158                         " or gedit (if found during ./configure)"
6159 #else
6160                         " gedit (if found during ./configure), or lastly open -t"
6161 #endif
6162 			" on the appropriate source unit.  This is currently only supported by FST."
6163 #else
6164 			" is not available with this build.  Please build against GTK 2."
6165 #endif
6166 			);
6167 		}
6168 		else
6169 		{
6170 	        help_text_bold("\n\nOpen Scope");
6171 	        help_text(
6172 #if WAVE_USE_GTK2
6173 			" opens and selects the appropriate level of hierarchy in the SST"
6174 			" for the first selected signal."
6175 #else
6176 			" is not available with this build.  Please build against GTK 2."
6177 #endif
6178 		        );
6179 		}
6180         return;
6181         }
6182 
6183 #if WAVE_USE_GTK2
6184 
6185 if((t=GLOBALS->traces.first))
6186     	{
6187       	while(t)
6188 		{
6189 	  	if(IsSelected(t)&&!IsShadowed(t))
6190 	    		{
6191 			char *tname = NULL;
6192 
6193 			if(!HasWave(t))
6194 				{
6195 				break;
6196 				}
6197 
6198 	      		if (HasAlias(t))
6199 				{
6200 		  		tname = strdup_2(t->name_full);
6201 				}
6202 	      		else if(t->vector==TRUE)
6203 				{
6204 		  		tname = strdup_2(t->n.vec->bvname);
6205 				}
6206 	      		else
6207 				{
6208 				int flagged = HIER_DEPACK_ALLOC;
6209 
6210 				if(!t->n.nd)
6211 					{
6212 					break; /* additional guard on top of !HasWave(t) */
6213 					}
6214 
6215 				tname = hier_decompress_flagged(t->n.nd->nname, &flagged);
6216 				if(!flagged)
6217 					{
6218 					tname = strdup_2(tname);
6219 					}
6220 				}
6221 
6222 			if(tname)
6223 				{
6224 				char *lasthier = strrchr(tname, GLOBALS->hier_delimeter);
6225 				if(lasthier)
6226 					{
6227 					char *tname_copy;
6228 
6229 					lasthier++; /* zero out character after hierarchy */
6230 					*lasthier = 0;
6231 					tname_copy = strdup_2(tname); /* force_open_tree_node() is destructive */
6232 					if(force_open_tree_node(tname_copy, 1, &t_forced) >= 0)
6233 						{
6234 						if(GLOBALS->selected_hierarchy_name)
6235 							{
6236 							free_2(GLOBALS->selected_hierarchy_name);
6237 							GLOBALS->selected_hierarchy_name = strdup_2(tname);
6238 							}
6239 
6240 						select_tree_node(tname);
6241 						}
6242 					free_2(tname_copy);
6243 					}
6244 
6245 				free_2(tname);
6246 				fix=1;
6247 		      		break;
6248 				}
6249 			}
6250 
6251 		t=t->t_next;
6252 		}
6253 
6254 	if(fix)
6255 		{
6256 		GLOBALS->signalwindow_width_dirty=1;
6257 		MaxSignalLength();
6258 		signalarea_configure_event(GLOBALS->signalarea, NULL);
6259 		wavearea_configure_event(GLOBALS->wavearea, NULL);
6260 		}
6261 
6262 	}
6263 
6264 if(((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM)) && t_forced)
6265 	{
6266 	uint32_t idx = (typ == FST_MT_SOURCESTEM) ? t_forced->t_stem : t_forced->t_istem;
6267 
6268 	if(!GLOBALS->stem_path_string_table)
6269 		{
6270                 fprintf(stderr, "GTKWAVE | Could not find stems information in this file!\n");
6271 		}
6272 		else
6273 		{
6274 		if(!idx && (typ == FST_MT_SOURCEISTEM) && GLOBALS->istem_struct_base)
6275 			{
6276 			/* handle top level where istem == stem and istem is deliberately not specified */
6277 			typ = FST_MT_SOURCESTEM;
6278 			idx = t_forced->t_stem;
6279 			}
6280 
6281 		open_index_in_forked_editor(idx, typ);
6282 		}
6283 	}
6284 
6285 #endif
6286 }
6287 
6288 
6289 static void
6290 menu_open_hierarchy_2a(gpointer null_data, guint callback_action, GtkWidget *widget, int typ)
6291 {
6292 (void)null_data;
6293 (void)callback_action;
6294 (void)widget;
6295 
6296 if(GLOBALS->helpbox_is_active)
6297         {
6298 	if((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM))
6299 		{
6300 		if(typ == FST_MT_SOURCESTEM)
6301 			{
6302 		        help_text_bold("\n\nOpen Source Definition");
6303 			}
6304 			else
6305 			{
6306 		        help_text_bold("\n\nOpen Source Instantiation");
6307 			}
6308 	        help_text(
6309 #if WAVE_USE_GTK2
6310 			" invokes $GTKWAVE_EDITOR or gedit (if found) on the appropriate source unit."
6311 #else
6312 			" is not available with this build.  Please build against GTK 2."
6313 #endif
6314 			);
6315 		}
6316 		else
6317 		{
6318 	        help_text_bold("\n\nOpen Scope");
6319 	        help_text(
6320 #if WAVE_USE_GTK2
6321 			" opens and selects the appropriate level of hierarchy in the SST"
6322 			" for the first selected signal."
6323 #else
6324 			" is not available with this build.  Please build against GTK 2."
6325 #endif
6326 		        );
6327 		}
6328         return;
6329         }
6330 
6331 #if WAVE_USE_GTK2
6332 
6333 if((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM))
6334 	{
6335 	struct tree *t_forced = GLOBALS->sst_sig_root_treesearch_gtk2_c_1;
6336 
6337 	if(t_forced)
6338 		{
6339 		uint32_t idx = (typ == FST_MT_SOURCESTEM) ? t_forced->t_stem : t_forced->t_istem;
6340 
6341 		if(!GLOBALS->stem_path_string_table)
6342 			{
6343 	                fprintf(stderr, "GTKWAVE | Could not find stems information in this file!\n");
6344 			}
6345 			else
6346 			{
6347 			if(!idx && (typ == FST_MT_SOURCEISTEM) && GLOBALS->istem_struct_base)
6348 				{
6349 				/* handle top level where istem == stem and istem is deliberately not specified */
6350 				typ = FST_MT_SOURCESTEM;
6351 				idx = t_forced->t_stem;
6352 				}
6353 
6354 			open_index_in_forked_editor(idx, typ);
6355 			}
6356 		}
6357 	}
6358 
6359 #endif
6360 }
6361 
6362 
6363 void menu_open_hierarchy(gpointer null_data, guint callback_action, GtkWidget *widget)
6364 {
6365 menu_open_hierarchy_2(null_data, callback_action, widget, FST_MT_MIN); /* zero for regular open */
6366 }
6367 
6368 
6369 void menu_open_hierarchy_source(gpointer null_data, guint callback_action, GtkWidget *widget)
6370 {
6371 menu_open_hierarchy_2(null_data, callback_action, widget, FST_MT_SOURCESTEM); /* for definition source */
6372 }
6373 
6374 void menu_open_hierarchy_isource(gpointer null_data, guint callback_action, GtkWidget *widget)
6375 {
6376 menu_open_hierarchy_2(null_data, callback_action, widget, FST_MT_SOURCEISTEM); /* for instantiation source */
6377 }
6378 
6379 
6380 void menu_open_sst_hierarchy_source(gpointer null_data, guint callback_action, GtkWidget *widget)
6381 {
6382 menu_open_hierarchy_2a(null_data, callback_action, widget, FST_MT_SOURCESTEM); /* for definition source */
6383 }
6384 
6385 void menu_open_sst_hierarchy_isource(gpointer null_data, guint callback_action, GtkWidget *widget)
6386 {
6387 menu_open_hierarchy_2a(null_data, callback_action, widget, FST_MT_SOURCEISTEM); /* for instantiation source */
6388 }
6389 
6390 /**/
6391 
6392 #if WAVE_USE_GTK2
6393 void menu_recurse_import(gpointer null_data, guint callback_action, GtkWidget *widget)
6394 {
6395 (void) null_data;
6396 
6397 recurse_import(widget, callback_action);
6398 }
6399 #endif
6400 
6401 /**/
6402 
6403 
6404 static void dataformat(TraceFlagsType mask, TraceFlagsType patch)
6405 {
6406   Trptr t;
6407   int fix=0;
6408 
6409   if((t=GLOBALS->traces.first))
6410     {
6411       while(t)
6412 	{
6413 	  if(IsSelected(t)&&!IsShadowed(t))
6414 	    {
6415 	      t->minmax_valid = 0; /* force analog traces to regenerate if necessary */
6416 	      t->flags=((t->flags)&mask)|patch;
6417 	      fix=1;
6418 	    }
6419 	  t=t->t_next;
6420 	}
6421       if(fix)
6422 	{
6423 	  GLOBALS->signalwindow_width_dirty=1;
6424 	  MaxSignalLength();
6425 	  signalarea_configure_event(GLOBALS->signalarea, NULL);
6426 	  wavearea_configure_event(GLOBALS->wavearea, NULL);
6427 	}
6428     }
6429 }
6430 
6431 void
6432 menu_dataformat_ascii(gpointer null_data, guint callback_action, GtkWidget *widget)
6433 {
6434 (void)null_data;
6435 (void)callback_action;
6436 (void)widget;
6437 
6438 if(GLOBALS->helpbox_is_active)
6439         {
6440         help_text_bold("\n\nData Format-ASCII");
6441         help_text(
6442 		" will step through all highlighted traces and ensure that"
6443 		" vectors with this qualifier will be displayed with ASCII"
6444 		" values."
6445         );
6446         return;
6447         }
6448 
6449 dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_ASCII );
6450 }
6451 
6452 void
6453 menu_dataformat_real(gpointer null_data, guint callback_action, GtkWidget *widget)
6454 {
6455 (void)null_data;
6456 (void)callback_action;
6457 (void)widget;
6458 
6459 if(GLOBALS->helpbox_is_active)
6460         {
6461         help_text_bold("\n\nData Format-BitsToReal");
6462         help_text(
6463 		" will step through all highlighted traces and ensure that"
6464 		" vectors with this qualifier will be displayed with Real"
6465 		" values.  Note that this only works for 64 or 32-bit quantities"
6466 		" and that ones of other sizes (e.g., binary16) will display as binary."
6467         );
6468         return;
6469         }
6470 
6471 dataformat( ~(TR_NUMMASK), TR_REAL );
6472 }
6473 
6474 void
6475 menu_dataformat_real2bon(gpointer null_data, guint callback_action, GtkWidget *widget)
6476 {
6477 (void)null_data;
6478 (void)callback_action;
6479 (void)widget;
6480 
6481 if(GLOBALS->helpbox_is_active)
6482         {
6483         help_text_bold("\n\nData Format-RealToBits On");
6484         help_text(
6485 		" will step through all highlighted traces and ensure that"
6486 		" Real vectors with this qualifier will be displayed as Hex"
6487 		" values.  Note that this only works for Real quantities"
6488 		" and other ones will remain to display as binary.  This is a pre-filter"
6489 		" so it is possible to invert, reverse, apply Decimal, etc.  It will not be"
6490 		" possible however to expand those values into their constituent bits."
6491         );
6492         return;
6493         }
6494 
6495 dataformat( ~(TR_REAL2BITS|TR_NUMMASK|TR_ANALOGMASK), TR_REAL2BITS|TR_HEX );
6496 }
6497 
6498 void
6499 menu_dataformat_real2boff(gpointer null_data, guint callback_action, GtkWidget *widget)
6500 {
6501 (void)null_data;
6502 (void)callback_action;
6503 (void)widget;
6504 
6505 if(GLOBALS->helpbox_is_active)
6506         {
6507         help_text_bold("\n\nData Format-RealToBits Off");
6508         help_text(
6509 		" will step through all highlighted traces and ensure that"
6510 		" the Real To Bits qualifier is removed from those traces."
6511         );
6512         return;
6513         }
6514 
6515 dataformat( ~(TR_REAL2BITS|TR_ANALOGMASK), 0 );
6516 }
6517 
6518 void
6519 menu_dataformat_hex(gpointer null_data, guint callback_action, GtkWidget *widget)
6520 {
6521 (void)null_data;
6522 (void)callback_action;
6523 (void)widget;
6524 
6525 if(GLOBALS->helpbox_is_active)
6526         {
6527         help_text_bold("\n\nData Format-Hex");
6528         help_text(
6529 		" will step through all highlighted traces and ensure that"
6530 		" vectors with this qualifier will be displayed with hexadecimal"
6531 		" values."
6532         );
6533         return;
6534         }
6535 
6536 dataformat( ~(TR_NUMMASK), TR_HEX );
6537 }
6538 
6539 void
6540 menu_dataformat_dec(gpointer null_data, guint callback_action, GtkWidget *widget)
6541 {
6542 (void)null_data;
6543 (void)callback_action;
6544 (void)widget;
6545 
6546 if(GLOBALS->helpbox_is_active)
6547         {
6548         help_text_bold("\n\nData Format-Decimal");
6549         help_text(
6550 		" will step through all highlighted traces and ensure that"
6551 		" vectors with this qualifier will be displayed with decimal"
6552 		" values."
6553         );
6554         return;
6555         }
6556 
6557 dataformat( ~(TR_NUMMASK), TR_DEC );
6558 }
6559 
6560 void
6561 menu_dataformat_signed(gpointer null_data, guint callback_action, GtkWidget *widget)
6562 {
6563 (void)null_data;
6564 (void)callback_action;
6565 (void)widget;
6566 
6567 if(GLOBALS->helpbox_is_active)
6568         {
6569         help_text_bold("\n\nData Format-Signed");
6570         help_text(
6571 		" will step through all highlighted traces and ensure that"
6572 		" vectors with this qualifier will be displayed as sign extended decimal"
6573 		" values."
6574         );
6575         return;
6576         }
6577 
6578 dataformat( ~(TR_NUMMASK), TR_SIGNED );
6579 }
6580 
6581 void
6582 menu_dataformat_bin(gpointer null_data, guint callback_action, GtkWidget *widget)
6583 {
6584 (void)null_data;
6585 (void)callback_action;
6586 (void)widget;
6587 
6588 if(GLOBALS->helpbox_is_active)
6589         {
6590         help_text_bold("\n\nData Format-Binary");
6591         help_text(
6592 		" will step through all highlighted traces and ensure that"
6593 		" vectors with this qualifier will be displayed with binary"
6594 		" values."
6595         );
6596         return;
6597         }
6598 
6599 dataformat( ~(TR_NUMMASK), TR_BIN );
6600 }
6601 
6602 void
6603 menu_dataformat_oct(gpointer null_data, guint callback_action, GtkWidget *widget)
6604 {
6605 (void)null_data;
6606 (void)callback_action;
6607 (void)widget;
6608 
6609 if(GLOBALS->helpbox_is_active)
6610         {
6611         help_text_bold("\n\nData Format-Octal");
6612         help_text(
6613 		" will step through all highlighted traces and ensure that"
6614 		" vectors with this qualifier will be displayed with octal"
6615 		" values."
6616         );
6617         return;
6618         }
6619 
6620 dataformat( ~(TR_NUMMASK), TR_OCT );
6621 }
6622 
6623 void
6624 menu_dataformat_rjustify_on(gpointer null_data, guint callback_action, GtkWidget *widget)
6625 {
6626 (void)null_data;
6627 (void)callback_action;
6628 (void)widget;
6629 
6630 if(GLOBALS->helpbox_is_active)
6631         {
6632         help_text_bold("\n\nData Format-Right Justify-On");
6633         help_text(
6634 		" will step through all highlighted traces and ensure that"
6635 		" vectors with this qualifier will be displayed right"
6636 		" justified."
6637         );
6638         return;
6639         }
6640 
6641 dataformat( ~(TR_RJUSTIFY), TR_RJUSTIFY );
6642 }
6643 
6644 void
6645 menu_dataformat_rjustify_off(gpointer null_data, guint callback_action, GtkWidget *widget)
6646 {
6647 (void)null_data;
6648 (void)callback_action;
6649 (void)widget;
6650 
6651 if(GLOBALS->helpbox_is_active)
6652         {
6653         help_text_bold("\n\nData Format-Right Justify-Off");
6654         help_text(
6655                 " will step through all highlighted traces and ensure that"
6656                 " vectors with this qualifier will not be displayed right"
6657                 " justified."
6658         );
6659         return;
6660         }
6661 
6662 dataformat( ~(TR_RJUSTIFY), 0 );
6663 }
6664 
6665 void
6666 menu_dataformat_bingray_on(gpointer null_data, guint callback_action, GtkWidget *widget)
6667 {
6668 (void)null_data;
6669 (void)callback_action;
6670 (void)widget;
6671 
6672 if(GLOBALS->helpbox_is_active)
6673         {
6674         help_text_bold("\n\nData Format-Gray Filters-To Gray");
6675         help_text(
6676                 " will step through all highlighted traces and ensure that"
6677                 " bits and vectors with this qualifier will be displayed after"
6678                 " going through normal to gray conversion. This is a filter"
6679 		" which sits before other Data Format options such as hex, etc."
6680         );
6681         return;
6682         }
6683 
6684 dataformat( ~(TR_GRAYMASK|TR_ANALOGMASK), TR_BINGRAY );
6685 }
6686 
6687 void
6688 menu_dataformat_graybin_on(gpointer null_data, guint callback_action, GtkWidget *widget)
6689 {
6690 (void)null_data;
6691 (void)callback_action;
6692 (void)widget;
6693 
6694 if(GLOBALS->helpbox_is_active)
6695         {
6696         help_text_bold("\n\nData Format-Gray Filters-From Gray");
6697         help_text(
6698                 " will step through all highlighted traces and ensure that"
6699                 " bits and vectors with this qualifier will be displayed after"
6700                 " going through gray to normal conversion. This is a filter"
6701                 " which sits before other Data Format options such as hex, etc."
6702         );
6703         return;
6704         }
6705 
6706 dataformat( ~(TR_GRAYMASK|TR_ANALOGMASK), TR_GRAYBIN );
6707 }
6708 
6709 
6710 void
6711 menu_dataformat_nogray(gpointer null_data, guint callback_action, GtkWidget *widget)
6712 {
6713 (void)null_data;
6714 (void)callback_action;
6715 (void)widget;
6716 
6717 if(GLOBALS->helpbox_is_active)
6718         {
6719         help_text_bold("\n\nData Format-Gray Filters-None");
6720         help_text(
6721                 " will step through all highlighted traces and ensure that"
6722                 " bits and vectors with this qualifier will be displayed with"
6723                 " normal encoding."
6724         );
6725         return;
6726         }
6727 
6728 dataformat( ~(TR_GRAYMASK|TR_ANALOGMASK), 0 );
6729 }
6730 
6731 void
6732 menu_dataformat_popcnt_on(gpointer null_data, guint callback_action, GtkWidget *widget)
6733 {
6734 (void)null_data;
6735 (void)callback_action;
6736 (void)widget;
6737 
6738 if(GLOBALS->helpbox_is_active)
6739         {
6740         help_text_bold("\n\nData Format-Popcnt-On");
6741         help_text(
6742                 " will step through all highlighted traces and ensure that"
6743                 " bits and vectors with this qualifier will be displayed after"
6744                 " going through a population (one's) count conversion.  This is a filter"
6745                 " which sits before other Data Format options such as hex, etc."
6746         );
6747         return;
6748         }
6749 
6750 dataformat( ~(TR_POPCNT), TR_POPCNT );
6751 }
6752 
6753 void
6754 menu_dataformat_popcnt_off(gpointer null_data, guint callback_action, GtkWidget *widget)
6755 {
6756 (void)null_data;
6757 (void)callback_action;
6758 (void)widget;
6759 
6760 if(GLOBALS->helpbox_is_active)
6761         {
6762         help_text_bold("\n\nData Format-Popcnt-Off");
6763         help_text(
6764                 " will step through all highlighted traces and ensure that"
6765                 " bits and vectors with this qualifier will be displayed with"
6766                 " normal encoding."
6767         );
6768         return;
6769         }
6770 
6771 dataformat( ~(TR_POPCNT), 0 );
6772 }
6773 
6774 void
6775 menu_dataformat_ffo_on(gpointer null_data, guint callback_action, GtkWidget *widget)
6776 {
6777 (void)null_data;
6778 (void)callback_action;
6779 (void)widget;
6780 
6781 if(GLOBALS->helpbox_is_active)
6782         {
6783 	help_text_bold("\n\nData Format-Find First Rightmost One Index-On");
6784         help_text(
6785                 " will step through all highlighted traces and ensure that"
6786                 " bits and vectors with this qualifier will be displayed after"
6787                 " going through a right->left FFO index conversion.  This is a filter"
6788                 " which sits before other Data Format options such as hex, etc."
6789         );
6790 	return;
6791         }
6792 
6793 dataformat( ~(TR_FFO), TR_FFO );
6794 }
6795 
6796 void
6797 menu_dataformat_ffo_off(gpointer null_data, guint callback_action, GtkWidget *widget)
6798 {
6799 (void)null_data;
6800 (void)callback_action;
6801 (void)widget;
6802 
6803 if(GLOBALS->helpbox_is_active)
6804         {
6805 	help_text_bold("\n\nData Format-Find First Rightmost One Index-Off");
6806         help_text(
6807                 " will step through all highlighted traces and ensure that"
6808                 " bits and vectors with this qualifier will be displayed with"
6809                 " normal encoding."
6810         );
6811         return;
6812         }
6813 
6814 dataformat( ~(TR_FFO), 0 );
6815 }
6816 
6817 
6818 void
6819 menu_dataformat_time(gpointer null_data, guint callback_action, GtkWidget *widget)
6820 {
6821 (void)null_data;
6822 (void)callback_action;
6823 (void)widget;
6824 
6825 if(GLOBALS->helpbox_is_active)
6826         {
6827         help_text_bold("\n\nData Format-Time");
6828         help_text(
6829                 " will step through all highlighted traces and ensure that"
6830                 " bits and vectors with this qualifier will display as time values."
6831         );
6832         return;
6833         }
6834 
6835 dataformat( ~(TR_NUMMASK), (TR_TIME | TR_DEC) );
6836 }
6837 
6838 void
6839 menu_dataformat_enum(gpointer null_data, guint callback_action, GtkWidget *widget)
6840 {
6841 (void)null_data;
6842 (void)callback_action;
6843 (void)widget;
6844 
6845 if(GLOBALS->helpbox_is_active)
6846         {
6847         help_text_bold("\n\nData Format-Enum");
6848         help_text(
6849                 " will step through all highlighted traces and ensure that"
6850                 " bits and vectors with this qualifier will display as enum values, provided such values were dumped into file."
6851         );
6852         return;
6853         }
6854 
6855 dataformat( ~(TR_NUMMASK), (TR_ENUM | TR_BIN) );
6856 }
6857 
6858 
6859 void
6860 menu_dataformat_fpshift_on(gpointer null_data, guint callback_action, GtkWidget *widget)
6861 {
6862 (void)null_data;
6863 (void)callback_action;
6864 (void)widget;
6865 
6866 if(GLOBALS->helpbox_is_active)
6867         {
6868         help_text_bold("\n\nData Format-Fixed Point Shift-On");
6869         help_text(
6870                 " will step through all highlighted traces and ensure that"
6871                 " bits and vectors with this qualifier will be right shifted"
6872 		" prior to being displayed as Signed Decimal or Decimal values."
6873         );
6874         return;
6875         }
6876 
6877 dataformat( ~(TR_FPDECSHIFT), TR_FPDECSHIFT );
6878 }
6879 
6880 void
6881 menu_dataformat_fpshift_off(gpointer null_data, guint callback_action, GtkWidget *widget)
6882 {
6883 (void)null_data;
6884 (void)callback_action;
6885 (void)widget;
6886 
6887 if(GLOBALS->helpbox_is_active)
6888         {
6889         help_text_bold("\n\nData Format-Fixed Point Shift-Off");
6890         help_text(
6891                 " will step through all highlighted traces and ensure that"
6892                 " bits and vectors with this qualifier will not be right shifted"
6893 		" prior to being displayed as Signed Decimal or Decimal values."
6894         );
6895         return;
6896         }
6897 
6898 dataformat( ~(TR_FPDECSHIFT), 0 );
6899 }
6900 
6901 
6902 static void
6903 menu_dataformat_fpshift_specify_cleanup(GtkWidget *widget, gpointer data)
6904 {
6905 (void)widget;
6906 (void)data;
6907 
6908   Trptr t;
6909   int fix=0;
6910   int shamt = GLOBALS->entrybox_text ? atoi(GLOBALS->entrybox_text) : 0;
6911   TraceFlagsType mask = ~(TR_FPDECSHIFT);
6912   TraceFlagsType patch = TR_FPDECSHIFT;
6913 
6914   if((shamt < 0)||(shamt > 255)) { shamt = 0; patch = 0; }
6915 
6916   if((t=GLOBALS->traces.first))
6917     {
6918       while(t)
6919 	{
6920 	  if(IsSelected(t)&&!IsShadowed(t))
6921 	    {
6922 	      t->minmax_valid = 0; /* force analog traces to regenerate if necessary */
6923 
6924 	      t->t_fpdecshift = shamt;
6925 	      t->flags=((t->flags)&mask)|patch;
6926 	      fix=1;
6927 	    }
6928 	  t=t->t_next;
6929 	}
6930       if(fix)
6931 	{
6932 	  GLOBALS->signalwindow_width_dirty=1;
6933 	  MaxSignalLength();
6934 	  signalarea_configure_event(GLOBALS->signalarea, NULL);
6935 	  wavearea_configure_event(GLOBALS->wavearea, NULL);
6936 	}
6937     }
6938 
6939 if(GLOBALS->entrybox_text) { free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; }
6940 GLOBALS->signalwindow_width_dirty=1;
6941 MaxSignalLength();
6942 signalarea_configure_event(GLOBALS->signalarea, NULL);
6943 wavearea_configure_event(GLOBALS->wavearea, NULL);
6944 }
6945 
6946 
6947 void
6948 menu_dataformat_fpshift_specify(gpointer null_data, guint callback_action, GtkWidget *widget)
6949 {
6950 (void)null_data;
6951 (void)callback_action;
6952 (void)widget;
6953 
6954 if(GLOBALS->helpbox_is_active)
6955         {
6956         help_text_bold("\n\nData Format-Fixed Point Shift-Specify");
6957         help_text(
6958 		" will open up a requester to specify a shift count then"
6959                 " will step through all highlighted traces and ensure that"
6960                 " bits and vectors with this qualifier will be right shifted"
6961 		" prior to being displayed as Signed Decimal or Decimal values."
6962         );
6963         return;
6964         }
6965 
6966 entrybox("Fixed Point Shift Specify",300,"",NULL,128,GTK_SIGNAL_FUNC(menu_dataformat_fpshift_specify_cleanup));
6967 
6968 dataformat( ~(TR_FPDECSHIFT), 0 );
6969 }
6970 
6971 void
6972 menu_dataformat_invert_on(gpointer null_data, guint callback_action, GtkWidget *widget)
6973 {
6974 (void)null_data;
6975 (void)callback_action;
6976 (void)widget;
6977 
6978 if(GLOBALS->helpbox_is_active)
6979         {
6980         help_text_bold("\n\nData Format-Invert-On");
6981         help_text(
6982                 " will step through all highlighted traces and ensure that"
6983                 " bits and vectors with this qualifier will be displayed with"
6984                 " 1's and 0's inverted."
6985         );
6986         return;
6987         }
6988 
6989 dataformat( ~(TR_INVERT), TR_INVERT );
6990 }
6991 
6992 void
6993 menu_dataformat_invert_off(gpointer null_data, guint callback_action, GtkWidget *widget)
6994 {
6995 (void)null_data;
6996 (void)callback_action;
6997 (void)widget;
6998 
6999 if(GLOBALS->helpbox_is_active)
7000         {
7001         help_text_bold("\n\nData Format-Invert-Off");
7002         help_text(
7003                 " will step through all highlighted traces and ensure that"
7004                 " bits and vectors with this qualifier will not be displayed with"
7005                 " 1's and 0's inverted."
7006         );
7007         return;
7008         }
7009 
7010 dataformat( ~(TR_INVERT), 0 );
7011 }
7012 
7013 void
7014 menu_dataformat_reverse_on(gpointer null_data, guint callback_action, GtkWidget *widget)
7015 {
7016 (void)null_data;
7017 (void)callback_action;
7018 (void)widget;
7019 
7020 if(GLOBALS->helpbox_is_active)
7021         {
7022         help_text_bold("\n\nData Format-Reverse Bits-On");
7023         help_text(
7024                 " will step through all highlighted traces and ensure that"
7025                 " vectors with this qualifier will be displayed in"
7026                 " reversed bit order."
7027         );
7028         return;
7029         }
7030 
7031 dataformat( ~(TR_REVERSE), TR_REVERSE );
7032 }
7033 
7034 void
7035 menu_dataformat_reverse_off(gpointer null_data, guint callback_action, GtkWidget *widget)
7036 {
7037 (void)null_data;
7038 (void)callback_action;
7039 (void)widget;
7040 
7041 if(GLOBALS->helpbox_is_active)
7042         {
7043         help_text_bold("\n\nData Format-Reverse Bits-Off");
7044         help_text(
7045                 " will step through all highlighted traces and ensure that"
7046                 " vectors with this qualifier will not be displayed in"
7047                 " reversed bit order."
7048         );
7049         return;
7050         }
7051 
7052 dataformat( ~(TR_REVERSE), 0 );
7053 }
7054 
7055 void
7056 menu_dataformat_exclude_on(gpointer null_data, guint callback_action, GtkWidget *widget)
7057 {
7058 (void)null_data;
7059 (void)callback_action;
7060 (void)widget;
7061 
7062 if(GLOBALS->helpbox_is_active)
7063         {
7064         help_text_bold("\n\nExclude");
7065         help_text(
7066 		" causes the waveform data for all currently highlighted traces"
7067 		" to be blanked out."
7068         );
7069         return;
7070         }
7071 
7072 dataformat( ~(TR_EXCLUDE), TR_EXCLUDE );
7073 }
7074 
7075 void
7076 menu_dataformat_exclude_off(gpointer null_data, guint callback_action, GtkWidget *widget)
7077 {
7078 (void)null_data;
7079 (void)callback_action;
7080 (void)widget;
7081 
7082 if(GLOBALS->helpbox_is_active)
7083         {
7084         help_text_bold("\n\nShow");
7085         help_text(
7086                 " causes the waveform data for all currently highlighted traces"
7087                 " to be displayed as normal if the exclude attribute is currently"
7088 		" set on the highlighted traces."
7089         );
7090         return;
7091         }
7092 
7093 dataformat( ~(TR_EXCLUDE), 0 );
7094 }
7095 /**/
7096 void
7097 menu_dataformat_rangefill_zero(gpointer null_data, guint callback_action, GtkWidget *widget)
7098 {
7099 (void)null_data;
7100 (void)callback_action;
7101 (void)widget;
7102 
7103 if(GLOBALS->helpbox_is_active)
7104         {
7105         help_text_bold("\n\nData Format-Range Fill With 0s");
7106         help_text(
7107                 " will step through all highlighted traces and ensure that"
7108                 " vectors with this qualifier will be displayed as if"
7109                 " the bitrange of the MSB or LSB as appropriate goes to zero."
7110 		" Zero bits will be filled in for the missing bits."
7111         );
7112         return;
7113         }
7114 
7115 dataformat( ~(TR_ZEROFILL|TR_ONEFILL|TR_ANALOGMASK), TR_ZEROFILL );
7116 }
7117 
7118 void
7119 menu_dataformat_rangefill_one(gpointer null_data, guint callback_action, GtkWidget *widget)
7120 {
7121 (void)null_data;
7122 (void)callback_action;
7123 (void)widget;
7124 
7125 if(GLOBALS->helpbox_is_active)
7126         {
7127         help_text_bold("\n\nData Format-Range Fill With 1s");
7128         help_text(
7129                 " will step through all highlighted traces and ensure that"
7130                 " vectors with this qualifier will be displayed as if"
7131                 " the bitrange of the MSB or LSB as appropriate goes to zero."
7132 		" One bits will be filled in for the missing bits; this is mostly intended"
7133 		" to be used when viewing values which are inverted in the logic and need"
7134 		" to be inverted in the viewer."
7135         );
7136         return;
7137         }
7138 
7139 dataformat( ~(TR_ZEROFILL|TR_ONEFILL|TR_ANALOGMASK), TR_ONEFILL );
7140 }
7141 
7142 void
7143 menu_dataformat_rangefill_off(gpointer null_data, guint callback_action, GtkWidget *widget)
7144 {
7145 (void)null_data;
7146 (void)callback_action;
7147 (void)widget;
7148 
7149 if(GLOBALS->helpbox_is_active)
7150         {
7151         help_text_bold("\n\nData Format-Zero Range Fill Off");
7152         help_text(
7153                 " will step through all highlighted traces and ensure that"
7154 		" normal bitrange displays are used."
7155         );
7156         return;
7157         }
7158 
7159 dataformat( ~(TR_ZEROFILL|TR_ONEFILL|TR_ANALOGMASK), 0 );
7160 }
7161 /**/
7162 void
7163 menu_dataformat_analog_off(gpointer null_data, guint callback_action, GtkWidget *widget)
7164 {
7165 (void)null_data;
7166 (void)callback_action;
7167 (void)widget;
7168 
7169 if(GLOBALS->helpbox_is_active)
7170         {
7171         help_text_bold("\n\nAnalog Off");
7172         help_text(
7173                 " causes the waveform data for all currently highlighted traces"
7174                 " to be displayed as normal."
7175         );
7176         return;
7177         }
7178 
7179 dataformat( ~(TR_ANALOGMASK), 0 );
7180 }
7181 
7182 void
7183 menu_dataformat_analog_step(gpointer null_data, guint callback_action, GtkWidget *widget)
7184 {
7185 (void)null_data;
7186 (void)callback_action;
7187 (void)widget;
7188 
7189 if(GLOBALS->helpbox_is_active)
7190         {
7191         help_text_bold("\n\nAnalog Step");
7192         help_text(
7193                 " causes the waveform data for all currently highlighted traces"
7194                 " to be displayed as stepwise analog waveform."
7195         );
7196         return;
7197         }
7198 
7199 dataformat( ~(TR_ANALOGMASK), TR_ANALOG_STEP );
7200 }
7201 
7202 void
7203 menu_dataformat_analog_interpol(gpointer null_data, guint callback_action, GtkWidget *widget)
7204 {
7205 (void)null_data;
7206 (void)callback_action;
7207 (void)widget;
7208 
7209 if(GLOBALS->helpbox_is_active)
7210         {
7211         help_text_bold("\n\nAnalog Interpolate");
7212         help_text(
7213                 " causes the waveform data for all currently highlighted traces"
7214                 " to be displayed as interpolated analog waveform."
7215         );
7216         return;
7217         }
7218 
7219 dataformat( ~(TR_ANALOGMASK), TR_ANALOG_INTERPOLATED );
7220 }
7221 
7222 void
7223 menu_dataformat_analog_interpol_step(gpointer null_data, guint callback_action, GtkWidget *widget)
7224 {
7225 (void)null_data;
7226 (void)callback_action;
7227 (void)widget;
7228 
7229 if(GLOBALS->helpbox_is_active)
7230         {
7231         help_text_bold("\n\nAnalog Interpolate Annotated");
7232         help_text(
7233                 " causes the waveform data for all currently highlighted traces"
7234                 " to be displayed as an interpolated analog waveform annotated"
7235 		" with the non-interpolated data sampling points that the cursor snaps to."
7236         );
7237         return;
7238         }
7239 
7240 dataformat( ~(TR_ANALOGMASK), (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP) );
7241 }
7242 
7243 void
7244 menu_dataformat_analog_resize_screen(gpointer null_data, guint callback_action, GtkWidget *widget)
7245 {
7246 (void)null_data;
7247 (void)callback_action;
7248 (void)widget;
7249 
7250 if(GLOBALS->helpbox_is_active)
7251         {
7252         help_text_bold("\n\nAnalog Resizing Screen Data");
7253         help_text(
7254                 " causes the waveform data for all currently highlighted traces"
7255                 " to be displayed such that the y-value scaling maximizes the on-screen trace"
7256 		" data so if fills the whole trace width at all times."
7257         );
7258         return;
7259         }
7260 
7261 dataformat( ~(TR_ANALOG_FULLSCALE), 0 );
7262 }
7263 
7264 void
7265 menu_dataformat_analog_resize_all(gpointer null_data, guint callback_action, GtkWidget *widget)
7266 {
7267 (void)null_data;
7268 (void)callback_action;
7269 (void)widget;
7270 
7271 if(GLOBALS->helpbox_is_active)
7272         {
7273         help_text_bold("\n\nAnalog Resizing All Data");
7274         help_text(
7275                 " causes the waveform data for all currently highlighted traces"
7276                 " to be displayed such that the y-value scaling maximizes the on-screen trace"
7277 		" data so if fills the whole trace width only when fully zoomed out."
7278 		" (i.e., the scale used goes across all trace data)"
7279         );
7280         return;
7281         }
7282 
7283 dataformat( ~(TR_ANALOG_FULLSCALE), (TR_ANALOG_FULLSCALE) );
7284 }
7285 /**/
7286 void menu_dataformat_highlight_all(gpointer null_data, guint callback_action, GtkWidget *widget)
7287 {
7288 (void)null_data;
7289 (void)callback_action;
7290 (void)widget;
7291 
7292 Trptr t;
7293 
7294 if(GLOBALS->helpbox_is_active)
7295         {
7296         help_text_bold("\n\nHighlight All");
7297         help_text(
7298 		" simply highlights all displayed traces."
7299         );
7300         return;
7301         }
7302 
7303 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7304 
7305 if((t=GLOBALS->traces.first))
7306 	{
7307 	while(t)
7308 		{
7309 		t->flags|=TR_HIGHLIGHT;
7310 		t=t->t_next;
7311 		}
7312 	signalarea_configure_event(GLOBALS->signalarea, NULL);
7313 	wavearea_configure_event(GLOBALS->wavearea, NULL);
7314 	}
7315 }
7316 
7317 void menu_dataformat_unhighlight_all(gpointer null_data, guint callback_action, GtkWidget *widget)
7318 {
7319 (void)null_data;
7320 (void)callback_action;
7321 (void)widget;
7322 
7323 Trptr t;
7324 
7325 if(GLOBALS->helpbox_is_active)
7326         {
7327         help_text_bold("\n\nUnHighlight All");
7328         help_text(
7329                 " simply unhighlights all displayed traces."
7330         );
7331         return;
7332         }
7333 
7334 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7335 
7336 if((t=GLOBALS->traces.first))
7337 	{
7338 	while(t)
7339 		{
7340 		t->flags&=(~TR_HIGHLIGHT);
7341 		t=t->t_next;
7342 		}
7343 	signalarea_configure_event(GLOBALS->signalarea, NULL);
7344 	wavearea_configure_event(GLOBALS->wavearea, NULL);
7345 	}
7346 }
7347 
7348 void menu_lexize(gpointer null_data, guint callback_action, GtkWidget *widget)
7349 {
7350 (void)null_data;
7351 (void)callback_action;
7352 (void)widget;
7353 
7354 if(GLOBALS->helpbox_is_active)
7355         {
7356         help_text_bold("\n\nSigsort All");
7357         help_text(
7358                 " sorts all displayed traces with the numeric parts being taken into account.  Blank traces are sorted to the bottom."
7359         );
7360         return;
7361         }
7362 
7363 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7364 
7365 if(GLOBALS->traces.first)
7366 	{
7367 	if(TracesReorder(TR_SORT_LEX))
7368 		{
7369 		signalarea_configure_event(GLOBALS->signalarea, NULL);
7370 		wavearea_configure_event(GLOBALS->wavearea, NULL);
7371 		}
7372 	}
7373 }
7374 /**/
7375 void menu_alphabetize(gpointer null_data, guint callback_action, GtkWidget *widget)
7376 {
7377 (void)null_data;
7378 (void)callback_action;
7379 (void)widget;
7380 
7381 if(GLOBALS->helpbox_is_active)
7382         {
7383         help_text_bold("\n\nAlphabetize All");
7384         help_text(
7385                 " alphabetizes all displayed traces.  Blank traces are sorted to the bottom."
7386         );
7387         return;
7388         }
7389 
7390 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7391 
7392 if(GLOBALS->traces.first)
7393 	{
7394 	if(TracesReorder(TR_SORT_NORM))
7395 		{
7396 		signalarea_configure_event(GLOBALS->signalarea, NULL);
7397 		wavearea_configure_event(GLOBALS->wavearea, NULL);
7398 		}
7399 	}
7400 }
7401 /**/
7402 void menu_alphabetize2(gpointer null_data, guint callback_action, GtkWidget *widget)
7403 {
7404 (void)null_data;
7405 (void)callback_action;
7406 (void)widget;
7407 
7408 if(GLOBALS->helpbox_is_active)
7409         {
7410         help_text_bold("\n\nAlphabetize All (CaseIns)");
7411         help_text(
7412                 " alphabetizes all displayed traces without regard to case.  Blank traces are sorted to the bottom."
7413         );
7414         return;
7415         }
7416 
7417 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7418 
7419 if(GLOBALS->traces.first)
7420 	{
7421 	if(TracesReorder(TR_SORT_INS))
7422 		{
7423 		signalarea_configure_event(GLOBALS->signalarea, NULL);
7424 		wavearea_configure_event(GLOBALS->wavearea, NULL);
7425 		}
7426 	}
7427 }
7428 /**/
7429 void menu_reverse(gpointer null_data, guint callback_action, GtkWidget *widget)
7430 {
7431 (void)null_data;
7432 (void)callback_action;
7433 (void)widget;
7434 
7435 if(GLOBALS->helpbox_is_active)
7436         {
7437         help_text_bold("\n\nReverse All");
7438         help_text(
7439                 " reverses all displayed traces unconditionally."
7440         );
7441         return;
7442         }
7443 
7444 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7445 
7446 if(GLOBALS->traces.first)
7447 	{
7448 	if(TracesReorder(TR_SORT_RVS))
7449 		{
7450 		signalarea_configure_event(GLOBALS->signalarea, NULL);
7451 		wavearea_configure_event(GLOBALS->wavearea, NULL);
7452 		}
7453 	}
7454 }
7455 /**/
7456 void
7457 menu_cut_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
7458 {
7459 (void)null_data;
7460 (void)callback_action;
7461 (void)widget;
7462 
7463 Trptr cutbuffer = NULL;
7464 
7465 if(GLOBALS->helpbox_is_active)
7466         {
7467         help_text_bold("\n\nCut");
7468         help_text(
7469                 " removes highlighted signals from the display and places them"
7470 		" in an offscreen cut/copy buffer for later Paste operations. "
7471 		" Cut implicitly destroys the previous contents of the cut/copy buffer."
7472         );
7473         return;
7474         }
7475 
7476 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7477 
7478 DEBUG(printf("Cut Traces\n"));
7479 
7480 /* fix up if there are traces above the current row being cut */
7481 if(GLOBALS->wave_vslider)
7482 	{
7483 	GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
7484 	int value = wadj->value;
7485 
7486 	Trptr t = GLOBALS->traces.first;
7487 	int cnt = 0;
7488 	int high = 0;
7489 
7490 	while(t)
7491 	    	{
7492 		if(cnt >= value) break;
7493 
7494 		if(t->flags & TR_HIGHLIGHT)
7495 			{
7496 		      	high++;
7497 			}
7498 
7499 		t = GiveNextTrace(t);
7500 		cnt++;
7501 		}
7502 
7503 	if(value - high > 0) { wadj->value -= high; }
7504 	}
7505 
7506 cutbuffer = CutBuffer();
7507 if(cutbuffer)
7508 	{
7509 	if(GLOBALS->cutcopylist)
7510 		{
7511 		free_2(GLOBALS->cutcopylist);
7512 		}
7513 	GLOBALS->cutcopylist = emit_gtkwave_savefile_formatted_entries_in_tcl_list(cutbuffer, FALSE);
7514 	/* printf("Cutlist: '%s'\n", GLOBALS->cutcopylist); */
7515 
7516 	MaxSignalLength();
7517 	signalarea_configure_event(GLOBALS->signalarea, NULL);
7518 	wavearea_configure_event(GLOBALS->wavearea, NULL);
7519 	}
7520 	else
7521 	{
7522 	must_sel();
7523 	}
7524 }
7525 
7526 void
7527 menu_delete_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
7528 {
7529 (void)null_data;
7530 (void)callback_action;
7531 (void)widget;
7532 
7533 int num_cut;
7534 
7535 if(GLOBALS->helpbox_is_active)
7536         {
7537         help_text_bold("\n\nDelete");
7538         help_text(
7539                 " removes highlighted signals from the display and discards them"
7540 		" without affecting the previous contents of the cut/copy buffer."
7541         );
7542         return;
7543         }
7544 
7545 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7546 
7547 DEBUG(printf("Delete Traces\n"));
7548 
7549 num_cut = DeleteBuffer();
7550 if(num_cut)
7551 	{
7552 	MaxSignalLength();
7553 	signalarea_configure_event(GLOBALS->signalarea, NULL);
7554 	wavearea_configure_event(GLOBALS->wavearea, NULL);
7555 	}
7556 	else
7557 	{
7558 	must_sel();
7559 	}
7560 }
7561 
7562 void
7563 menu_copy_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
7564 {
7565 (void)null_data;
7566 (void)callback_action;
7567 (void)widget;
7568 
7569 Trptr t = GLOBALS->traces.first;
7570 gboolean highlighted = FALSE;
7571 
7572 if(GLOBALS->helpbox_is_active)
7573         {
7574         help_text_bold("\n\nCopy");
7575         help_text(
7576                 " copies highlighted signals from the display and places them"
7577 		" in an offscreen cut/copy buffer for later Paste operations. "
7578 		" Copy implicitly destroys the previous contents of the cut/copy buffer."
7579         );
7580         return;
7581         }
7582 
7583 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7584 
7585 DEBUG(printf("Copy Traces\n"));
7586 
7587 while(t)
7588 	{
7589 	if(t->flags & TR_HIGHLIGHT)
7590 		{
7591 		highlighted = TRUE;
7592 		break;
7593 		}
7594 	t = t->t_next;
7595 	}
7596 
7597 if(!highlighted)
7598 	{
7599 	must_sel();
7600 	}
7601 	else
7602 	{
7603 	if(GLOBALS->cutcopylist)
7604 		{
7605 		free_2(GLOBALS->cutcopylist);
7606 		}
7607 	GLOBALS->cutcopylist = emit_gtkwave_savefile_formatted_entries_in_tcl_list(GLOBALS->traces.first, TRUE);
7608 	/* printf("Copylist: '%s'\n", GLOBALS->cutcopylist); */
7609 
7610 	FreeCutBuffer();
7611 	}
7612 }
7613 
7614 void
7615 menu_paste_traces(gpointer null_data, guint callback_action, GtkWidget *widget)
7616 {
7617 (void)null_data;
7618 (void)callback_action;
7619 (void)widget;
7620 
7621 if(GLOBALS->helpbox_is_active)
7622         {
7623         help_text_bold("\n\nPaste");
7624         help_text(
7625                 " pastes signals from"
7626                 " an offscreen cut/copy buffer and places them in a group after"
7627 		" the last highlighted signal, or at the end of the display"
7628 		" if no signal is highlighted."
7629         );
7630         return;
7631         }
7632 
7633 if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */
7634 
7635 DEBUG(printf("Paste Traces\n"));
7636 
7637 if(PasteBuffer())
7638 	{
7639 	GLOBALS->signalwindow_width_dirty=1;
7640 	MaxSignalLength();
7641 	signalarea_configure_event(GLOBALS->signalarea, NULL);
7642 	wavearea_configure_event(GLOBALS->wavearea, NULL);
7643 	}
7644 	else
7645 	{
7646 	if(GLOBALS->cutcopylist)
7647 		{
7648 		/*int num_traces =*/ process_tcl_list(GLOBALS->cutcopylist, FALSE);
7649 		/* printf("Pastelist: %d '%s'\n", num_traces, GLOBALS->cutcopylist); */
7650 
7651 	        GLOBALS->signalwindow_width_dirty=1;
7652 	        MaxSignalLength();
7653 	        signalarea_configure_event(GLOBALS->signalarea, NULL);
7654 	        wavearea_configure_event(GLOBALS->wavearea, NULL);
7655 		}
7656 	}
7657 
7658 }
7659 /**/
7660 void menu_center_zooms(gpointer null_data, guint callback_action, GtkWidget *widget)
7661 {
7662 (void)null_data;
7663 (void)callback_action;
7664 (void)widget;
7665 
7666 if(GLOBALS->helpbox_is_active)
7667         {
7668         help_text_bold("\n\nCenter Zooms");
7669         help_text(
7670 		" when enabled"
7671 		" configures zoom in/out operations such that all zooms use the center of the"
7672 		" display as the fixed zoom origin if the primary (unnamed) marker is"
7673 		" not present, otherwise, the primary marker is used as the center origin."
7674 		" When disabled, it"
7675 		" configures zoom in/out operations such that all zooms use the"
7676 		" left margin of the display as the fixed zoom origin."
7677         );
7678         }
7679 	else
7680 	{
7681 #ifndef WAVE_USE_MLIST_T
7682 	GLOBALS->do_zoom_center=(GLOBALS->do_zoom_center)?0:1;
7683 #else
7684         GLOBALS->do_zoom_center = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCZ]));
7685 #endif
7686 	DEBUG(printf("Center Zooms\n"));
7687 	}
7688 
7689 #ifndef WAVE_USE_MLIST_T
7690 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCZ].path))->active=(GLOBALS->do_zoom_center)?TRUE:FALSE;
7691 #endif
7692 }
7693 
7694 
7695 void menu_show_base(gpointer null_data, guint callback_action, GtkWidget *widget)
7696 {
7697 (void)null_data;
7698 (void)callback_action;
7699 (void)widget;
7700 
7701 if(GLOBALS->helpbox_is_active)
7702         {
7703         help_text_bold("\n\nShow Base Symbols");
7704         help_text(
7705 		" enables the display of leading base symbols ('$' for hex,"
7706 		" '%' for binary, '#' for octal if they are turned off and"
7707 		" disables the drawing of leading base symbols if"
7708 		" they are turned on."
7709 		" Base symbols are displayed by default."
7710         );
7711         }
7712 	else
7713 	{
7714 #ifndef WAVE_USE_MLIST_T
7715 	GLOBALS->show_base=(GLOBALS->show_base)?0:~0;
7716 #else
7717 	GLOBALS->show_base = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSBS]));
7718 #endif
7719 	GLOBALS->signalwindow_width_dirty=1;
7720 	MaxSignalLength();
7721 	signalarea_configure_event(GLOBALS->signalarea, NULL);
7722 	wavearea_configure_event(GLOBALS->wavearea, NULL);
7723 	DEBUG(printf("Show Base Symbols\n"));
7724 	}
7725 
7726 #ifndef WAVE_USE_MLIST_T
7727 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSBS].path))->active=(GLOBALS->show_base)?TRUE:FALSE;
7728 #endif
7729 }
7730 
7731 /**/
7732 void menu_show_grid(gpointer null_data, guint callback_action, GtkWidget *widget)
7733 {
7734 (void)null_data;
7735 (void)callback_action;
7736 (void)widget;
7737 
7738 if(GLOBALS->helpbox_is_active)
7739         {
7740         help_text_bold("\n\nShow Grid");
7741         help_text(
7742 		" toggles the drawing of gridlines in the waveform display."
7743         );
7744         }
7745 	else
7746 	{
7747 #ifndef WAVE_USE_MLIST_T
7748 	GLOBALS->display_grid=(GLOBALS->display_grid)?0:~0;
7749 #else
7750 	GLOBALS->display_grid = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSG]));
7751 #endif
7752 	if(GLOBALS->wave_hslider)
7753 		{
7754 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed");
7755 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed");
7756 		}
7757 	DEBUG(printf("Show Grid\n"));
7758 	}
7759 
7760 #ifndef WAVE_USE_MLIST_T
7761 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSG].path))->active=(GLOBALS->display_grid)?TRUE:FALSE;
7762 #endif
7763 }
7764 
7765 /**/
7766 void menu_show_wave_highlight(gpointer null_data, guint callback_action, GtkWidget *widget)
7767 {
7768 (void)null_data;
7769 (void)callback_action;
7770 (void)widget;
7771 
7772 if(GLOBALS->helpbox_is_active)
7773         {
7774         help_text_bold("\n\nShow Wave Highlight");
7775         help_text(
7776 		" toggles the drawing of highlighted waveforms (instead of gridlines) in the waveform display."
7777         );
7778         }
7779 	else
7780 	{
7781 #ifndef WAVE_USE_MLIST_T
7782 	GLOBALS->highlight_wavewindow=(GLOBALS->highlight_wavewindow)?0:~0;
7783 #else
7784 	GLOBALS->highlight_wavewindow = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_SHW]));
7785 #endif
7786 	if(GLOBALS->wave_hslider)
7787 		{
7788 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed");
7789 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed");
7790 		}
7791 	DEBUG(printf("Show Wave Highlight\n"));
7792 	}
7793 
7794 #ifndef WAVE_USE_MLIST_T
7795 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_SHW].path))->active=(GLOBALS->highlight_wavewindow)?TRUE:FALSE;
7796 #endif
7797 }
7798 
7799 /**/
7800 void menu_show_filled_high_values(gpointer null_data, guint callback_action, GtkWidget *widget)
7801 {
7802 (void)null_data;
7803 (void)callback_action;
7804 (void)widget;
7805 
7806 if(GLOBALS->helpbox_is_active)
7807         {
7808         help_text_bold("\n\nShow Filled High Values");
7809         help_text(
7810 		" toggles the drawing of filled in 1/H values in the waveform display."
7811         );
7812         }
7813 	else
7814 	{
7815 #ifndef WAVE_USE_MLIST_T
7816 	GLOBALS->fill_waveform=(GLOBALS->fill_waveform)?0:~0;
7817 #else
7818 	GLOBALS->fill_waveform = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_FILL1]));
7819 #endif
7820 	if(GLOBALS->wave_hslider)
7821 		{
7822 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed");
7823 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed");
7824 		}
7825 	DEBUG(printf("Show Filled High Values\n"));
7826 	}
7827 
7828 #ifndef WAVE_USE_MLIST_T
7829 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_FILL1].path))->active=(GLOBALS->fill_waveform)?TRUE:FALSE;
7830 #endif
7831 }
7832 
7833 /**/
7834 void menu_show_mouseover(gpointer null_data, guint callback_action, GtkWidget *widget)
7835 {
7836 (void)null_data;
7837 (void)callback_action;
7838 (void)widget;
7839 
7840 if(GLOBALS->helpbox_is_active)
7841         {
7842         help_text_bold("\n\nShow Mouseover");
7843         help_text(
7844 		" toggles the dynamic tooltip for signal names and values which follow the marker on mouse button presses in the waveform display."
7845 		" This is useful for examining the values of closely packed value changes without having to zoom outward and without having to"
7846 		" refer to the signal name pane to the left.  Note that an encoded string will be displayed next to the signal name that"
7847 		" indicates what data format flags are currently active for that signal.  Flags are as follows:\n"
7848                 " + = Signed Decimal\n"
7849                 " X = Hexadecimal\n"
7850                 " A = ASCII\n"
7851                 " D = Decimal\n"
7852                 " B = Binary\n"
7853                 " O = Octal\n"
7854                 " J = Right Justify\n"
7855                 " ~ = Invert\n"
7856                 " V = Reverse\n"
7857                 " * = Analog Step+Interpolated\n"
7858                 " S = Analog Step\n"
7859                 " I = Analog Interpolated\n"
7860                 " R = Real\n"
7861 		" r = Real to Bits\n"
7862                 " 0 = Range Fill with 0s\n"
7863                 " 1 = Range Fill with 1s\n"
7864 		" G = Binary to Gray\n"
7865 		" g = Gray to Binary\n"
7866 		" F = File Filter\n"
7867 		" P = Process Filter\n"
7868 		" T = Transaction Filter\n"
7869 		" p = Population Count\n"
7870 		" s = Fixed Point Shift (count)\n"
7871         );
7872         }
7873 	else
7874 	{
7875 	GLOBALS->disable_mouseover=(GLOBALS->disable_mouseover)?0:~0;
7876 	DEBUG(printf("Show Mouseover\n"));
7877 	}
7878 
7879 #ifndef WAVE_USE_MLIST_T
7880 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSMO].path))->active=(GLOBALS->disable_mouseover)?FALSE:TRUE;
7881 #else
7882 GLOBALS->disable_mouseover = !gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMO]));
7883 #endif
7884 }
7885 
7886 /**/
7887 #ifdef WAVE_USE_GTK2
7888 void menu_clipboard_mouseover(gpointer null_data, guint callback_action, GtkWidget *widget)
7889 {
7890 (void)null_data;
7891 (void)callback_action;
7892 (void)widget;
7893 
7894 if(GLOBALS->helpbox_is_active)
7895         {
7896         help_text_bold("\n\nMouseover Copies To Clipboard");
7897         help_text(
7898 		" toggles automatic copying to the clipboard of mouseover values.  Requires that Show Mouseover is enabled.\n"
7899         );
7900         }
7901 	else
7902 	{
7903 	GLOBALS->clipboard_mouseover=(GLOBALS->clipboard_mouseover)?0:~0;
7904 	DEBUG(printf("Mouseover Copies To Clipboard\n"));
7905 	}
7906 
7907 #ifndef WAVE_USE_MLIST_T
7908 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSMC].path))->active=(GLOBALS->clipboard_mouseover)?TRUE:FALSE;
7909 #else
7910 GLOBALS->clipboard_mouseover = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMC]));
7911 #endif
7912 }
7913 #endif
7914 /**/
7915 
7916 
7917 /* this is the GtkMenuEntry structure used to create new menus.  The
7918  * first member is the menu definition string.  The second, the
7919  * default accelerator key used to access this menu function with
7920  * the keyboard.  The third is the callback function to call when
7921  * this menu item is selected (by the accelerator key, or with the
7922  * mouse.) The last member is the data to pass to your callback function.
7923  *
7924  * ...This has all been changed to use itemfactory stuff which is more
7925  * powerful.  The only real difference is the final item which tells
7926  * the itemfactory just what the item "is".
7927  */
7928 #ifdef WAVE_USE_MENU_BLACKOUTS
7929 static const char *menu_blackouts[] = { "/Edit", "/Search", "/Time", "/Markers", "/View" };
7930 #endif
7931 
7932 static gtkwave_mlist_t menu_items[] =
7933 {
7934     WAVE_GTKIFE("/File/Open New Window", "<Control>N", menu_new_viewer, WV_MENU_FONV, "<Item>"),
7935     WAVE_GTKIFE("/File/Open New Tab", "<Control>T", menu_new_viewer_tab, WV_MENU_FONVT, "<Item>"),
7936     WAVE_GTKIFE("/File/Reload Waveform", "<Shift><Control>R", menu_reload_waveform, WV_MENU_FRW, "<Item>"),
7937     WAVE_GTKIFE("/File/Export/Write VCD File As", NULL, menu_write_vcd_file, WV_MENU_WRVCD, "<Item>"),
7938     WAVE_GTKIFE("/File/Export/Write LXT File As", NULL, menu_write_lxt_file, WV_MENU_WRLXT, "<Item>"),
7939     WAVE_GTKIFE("/File/Export/Write TIM File As", NULL, menu_write_tim_file, WV_MENU_WRTIM, "<Item>"),
7940     WAVE_GTKIFE("/File/Close", "<Control>W", menu_quit_close, WV_MENU_WCLOSE, "<Item>"),
7941     WAVE_GTKIFE("/File/<separator>", NULL, NULL, WV_MENU_SEP2VCD, "<Separator>"),
7942     WAVE_GTKIFE("/File/Print To File", "<Control>P", menu_print, WV_MENU_FPTF, "<Item>"),
7943 
7944 #if GTK_CHECK_VERSION(2,14,0)
7945     WAVE_GTKIFE("/File/Grab To File", NULL, menu_write_screengrab_as, WV_MENU_SGRAB, "<Item>"),
7946 #endif
7947 
7948     WAVE_GTKIFE("/File/<separator>", NULL, NULL, WV_MENU_SEP1, "<Separator>"),
7949     WAVE_GTKIFE("/File/Read Save File", "<Control>O", menu_read_save_file, WV_MENU_FRSF, "<Item>"),
7950     WAVE_GTKIFE("/File/Write Save File", "<Control>S", menu_write_save_file, WV_MENU_FWSF, "<Item>"),
7951     WAVE_GTKIFE("/File/Write Save File As", "<Shift><Control>S", menu_write_save_file_as, WV_MENU_FWSFAS, "<Item>"),
7952     WAVE_GTKIFE("/File/<separator>", NULL, NULL, WV_MENU_SEP2, "<Separator>"),
7953     WAVE_GTKIFE("/File/Read Sim Logfile", "L", menu_read_log_file, WV_MENU_FRLF, "<Item>"),
7954       /* 10 */
7955     WAVE_GTKIFE("/File/<separator>", NULL, NULL, WV_MENU_SEP2LF, "<Separator>"),
7956 #if !defined _MSC_VER
7957     WAVE_GTKIFE("/File/Read Verilog Stemsfile", NULL, menu_read_stems_file, WV_MENU_FRSTMF, "<Item>"),
7958     WAVE_GTKIFE("/File/<separator>", NULL, NULL, WV_MENU_SEP2STMF, "<Separator>"),
7959 #endif
7960 #if defined(HAVE_LIBTCL)
7961     WAVE_GTKIFE("/File/Read Tcl Script File", NULL, menu_read_script_file, WV_MENU_TCLSCR, "<Item>"),
7962     WAVE_GTKIFE("/File/<separator>", NULL, NULL, WV_MENU_TCLSEP, "<Separator>"),
7963 #endif
7964 
7965     WAVE_GTKIFE("/File/Quit", "<Control>Q", menu_quit, WV_MENU_FQY, "<Item>"),
7966 
7967     WAVE_GTKIFE("/Edit/Set Trace Max Hier", NULL, menu_set_max_hier, WV_MENU_ESTMH, "<Item>"),
7968     WAVE_GTKIFE("/Edit/Toggle Trace Hier", "H", menu_toggle_hier, WV_MENU_ETH, "<Item>"),
7969     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP3, "<Separator>"),
7970     WAVE_GTKIFE("/Edit/Insert Blank", "<Control>B", menu_insert_blank_traces, WV_MENU_EIB, "<Item>"),
7971     WAVE_GTKIFE("/Edit/Insert Comment", NULL, menu_insert_comment_traces, WV_MENU_EIC, "<Item>"),
7972     WAVE_GTKIFE("/Edit/Insert Analog Height Extension", NULL, menu_insert_analog_height_extension, WV_MENU_EIA, "<Item>"),
7973 
7974 #ifdef MAC_INTEGRATION
7975     WAVE_GTKIFE("/Edit/Cut", NULL, menu_cut_traces, WV_MENU_EC, "<Item>"),
7976     WAVE_GTKIFE("/Edit/Copy", NULL, menu_copy_traces, WV_MENU_ECY, "<Item>"),
7977     WAVE_GTKIFE("/Edit/Paste", NULL, menu_paste_traces, WV_MENU_EP, "<Item>"),
7978     WAVE_GTKIFE("/Edit/Delete", NULL, menu_delete_traces, WV_MENU_DEL, "<Item>"),
7979 #else
7980     WAVE_GTKIFE("/Edit/Cut", "<Control>X", menu_cut_traces, WV_MENU_EC, "<Item>"),
7981     WAVE_GTKIFE("/Edit/Copy", "<Control>C", menu_copy_traces, WV_MENU_ECY, "<Item>"),
7982     WAVE_GTKIFE("/Edit/Paste", "<Control>V", menu_paste_traces, WV_MENU_EP, "<Item>"),
7983     WAVE_GTKIFE("/Edit/Delete", "<Control>Delete", menu_delete_traces, WV_MENU_DEL, "<Item>"),
7984 #endif
7985 
7986     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP3A, "<Separator>"),
7987 
7988     WAVE_GTKIFE("/Edit/Alias Highlighted Trace", "<Alt>A", menu_alias, WV_MENU_EAHT, "<Item>"),
7989     WAVE_GTKIFE("/Edit/Remove Highlighted Aliases", "<Shift><Alt>A", menu_remove_aliases, WV_MENU_ERHA, "<Item>"),
7990       /* 20 */
7991     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP4, "<Separator>"),
7992     WAVE_GTKIFE("/Edit/Expand", "F3", menu_expand, WV_MENU_EE, "<Item>"),
7993     WAVE_GTKIFE("/Edit/Combine Down", "F4", menu_combine_down, WV_MENU_ECD, "<Item>"),
7994     WAVE_GTKIFE("/Edit/Combine Up", "F5", menu_combine_up, WV_MENU_ECU, "<Item>"),
7995     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP5, "<Separator>"),
7996     WAVE_GTKIFE("/Edit/Data Format/Hex", "<Alt>X", menu_dataformat_hex, WV_MENU_EDFH, "<Item>"),
7997     WAVE_GTKIFE("/Edit/Data Format/Decimal", "<Alt>D", menu_dataformat_dec, WV_MENU_EDFD, "<Item>"),
7998       /* 30 */
7999     WAVE_GTKIFE("/Edit/Data Format/Signed Decimal", NULL, menu_dataformat_signed, WV_MENU_EDFSD, "<Item>"),
8000     WAVE_GTKIFE("/Edit/Data Format/Binary", "<Alt>B", menu_dataformat_bin, WV_MENU_EDFB, "<Item>"),
8001     WAVE_GTKIFE("/Edit/Data Format/Octal", "<Alt>O", menu_dataformat_oct, WV_MENU_EDFO, "<Item>"),
8002     WAVE_GTKIFE("/Edit/Data Format/ASCII", NULL, menu_dataformat_ascii, WV_MENU_EDFA, "<Item>"),
8003     WAVE_GTKIFE("/Edit/Data Format/Time", NULL, menu_dataformat_time, WV_MENU_TIME, "<Item>"),
8004     WAVE_GTKIFE("/Edit/Data Format/Enum", NULL, menu_dataformat_enum, WV_MENU_ENUM, "<Item>"),
8005     WAVE_GTKIFE("/Edit/Data Format/BitsToReal", NULL, menu_dataformat_real, WV_MENU_EDRL, "<Item>"),
8006     WAVE_GTKIFE("/Edit/Data Format/RealToBits/On", NULL, menu_dataformat_real2bon, WV_MENU_EDR2BON, "<Item>"),
8007     WAVE_GTKIFE("/Edit/Data Format/RealToBits/Off", NULL, menu_dataformat_real2boff, WV_MENU_EDR2BOFF, "<Item>"),
8008     WAVE_GTKIFE("/Edit/Data Format/Right Justify/On", "<Alt>J", menu_dataformat_rjustify_on, WV_MENU_EDFRJON, "<Item>"),
8009     WAVE_GTKIFE("/Edit/Data Format/Right Justify/Off", "<Shift><Alt>J", menu_dataformat_rjustify_off, WV_MENU_EDFRJOFF, "<Item>"),
8010     WAVE_GTKIFE("/Edit/Data Format/Invert/On", "<Alt>I", menu_dataformat_invert_on, WV_MENU_EDFION, "<Item>"),
8011     WAVE_GTKIFE("/Edit/Data Format/Invert/Off", "<Shift><Alt>I", menu_dataformat_invert_off, WV_MENU_EDFIOFF, "<Item>"),
8012     WAVE_GTKIFE("/Edit/Data Format/Reverse Bits/On", "<Alt>V", menu_dataformat_reverse_on, WV_MENU_EDFRON, "<Item>"),
8013       /* 40 */
8014     WAVE_GTKIFE("/Edit/Data Format/Reverse Bits/Off", "<Shift><Alt>V", menu_dataformat_reverse_off, WV_MENU_EDFROFF, "<Item>"),
8015     WAVE_GTKIFE("/Edit/Data Format/Translate Filter File/Disable", NULL, menu_dataformat_xlate_file_0, WV_MENU_XLF_0, "<Item>"),
8016     WAVE_GTKIFE("/Edit/Data Format/Translate Filter File/Enable and Select", NULL, menu_dataformat_xlate_file_1, WV_MENU_XLF_1, "<Item>"),
8017     WAVE_GTKIFE("/Edit/Data Format/Translate Filter Process/Disable", NULL, menu_dataformat_xlate_proc_0, WV_MENU_XLP_0, "<Item>"),
8018     WAVE_GTKIFE("/Edit/Data Format/Translate Filter Process/Enable and Select", NULL, menu_dataformat_xlate_proc_1, WV_MENU_XLP_1, "<Item>"),
8019     WAVE_GTKIFE("/Edit/Data Format/Transaction Filter Process/Disable", NULL, menu_dataformat_xlate_ttrans_0, WV_MENU_TTXLP_0, "<Item>"),
8020     WAVE_GTKIFE("/Edit/Data Format/Transaction Filter Process/Enable and Select", NULL, menu_dataformat_xlate_ttrans_1, WV_MENU_TTXLP_1, "<Item>"),
8021     WAVE_GTKIFE("/Edit/Data Format/Analog/Off", NULL, menu_dataformat_analog_off, WV_MENU_EDFAOFF, "<Item>"),
8022     WAVE_GTKIFE("/Edit/Data Format/Analog/Step", NULL, menu_dataformat_analog_step, WV_MENU_EDFASTEP, "<Item>"),
8023     WAVE_GTKIFE("/Edit/Data Format/Analog/Interpolated", NULL, menu_dataformat_analog_interpol, WV_MENU_EDFAINTERPOL, "<Item>"),
8024     WAVE_GTKIFE("/Edit/Data Format/Analog/Interpolated Annotated", NULL, menu_dataformat_analog_interpol_step, WV_MENU_EDFAINTERPOL2, "<Item>"),
8025     WAVE_GTKIFE("/Edit/Data Format/Analog/Resizing/Screen Data", NULL, menu_dataformat_analog_resize_screen, WV_MENU_EDFARSD, "<Item>"),
8026     WAVE_GTKIFE("/Edit/Data Format/Analog/Resizing/All Data", NULL, menu_dataformat_analog_resize_all, WV_MENU_EDFARAD, "<Item>"),
8027     WAVE_GTKIFE("/Edit/Data Format/Range Fill/With 0s", NULL, menu_dataformat_rangefill_zero, WV_MENU_RFILL0, "<Item>"),
8028     WAVE_GTKIFE("/Edit/Data Format/Range Fill/With 1s", NULL, menu_dataformat_rangefill_one, WV_MENU_RFILL1, "<Item>"),
8029     WAVE_GTKIFE("/Edit/Data Format/Range Fill/Off", NULL, menu_dataformat_rangefill_off, WV_MENU_RFILLOFF, "<Item>"),
8030 
8031     WAVE_GTKIFE("/Edit/Data Format/Gray Filters/To Gray", NULL, menu_dataformat_bingray_on, WV_MENU_B2G, "<Item>"),
8032     WAVE_GTKIFE("/Edit/Data Format/Gray Filters/From Gray", NULL, menu_dataformat_graybin_on, WV_MENU_G2B, "<Item>"),
8033     WAVE_GTKIFE("/Edit/Data Format/Gray Filters/None", NULL, menu_dataformat_nogray,    WV_MENU_GBNONE, "<Item>"),
8034     WAVE_GTKIFE("/Edit/Data Format/Popcnt/On", NULL, menu_dataformat_popcnt_on, WV_MENU_POPON, "<Item>"),
8035     WAVE_GTKIFE("/Edit/Data Format/Popcnt/Off", NULL, menu_dataformat_popcnt_off,    WV_MENU_POPOFF, "<Item>"),
8036     WAVE_GTKIFE("/Edit/Data Format/Find First One/On", NULL, menu_dataformat_ffo_on, WV_MENU_FFOON, "<Item>"),
8037     WAVE_GTKIFE("/Edit/Data Format/Find First One/Off", NULL, menu_dataformat_ffo_off,    WV_MENU_FFOOFF, "<Item>"),
8038     WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/On", NULL, menu_dataformat_fpshift_on, WV_MENU_FPSHIFTON, "<Item>"),
8039     WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/Off", NULL, menu_dataformat_fpshift_off,    WV_MENU_FPSHIFTOFF, "<Item>"),
8040     WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/Specify", NULL, menu_dataformat_fpshift_specify,    WV_MENU_FPSHIFTVAL, "<Item>"),
8041 
8042     WAVE_GTKIFE("/Edit/Color Format/Normal", NULL, menu_colorformat_0,    WV_MENU_CLRFMT0, "<Item>"),
8043     WAVE_GTKIFE("/Edit/Color Format/Red", NULL, menu_colorformat_1,    WV_MENU_CLRFMT1, "<Item>"),
8044     WAVE_GTKIFE("/Edit/Color Format/Orange", NULL, menu_colorformat_2,    WV_MENU_CLRFMT2, "<Item>"),
8045     WAVE_GTKIFE("/Edit/Color Format/Yellow", NULL, menu_colorformat_3,    WV_MENU_CLRFMT3, "<Item>"),
8046     WAVE_GTKIFE("/Edit/Color Format/Green", NULL, menu_colorformat_4,    WV_MENU_CLRFMT4, "<Item>"),
8047     WAVE_GTKIFE("/Edit/Color Format/Blue", NULL, menu_colorformat_5,    WV_MENU_CLRFMT5, "<Item>"),
8048     WAVE_GTKIFE("/Edit/Color Format/Indigo", NULL, menu_colorformat_6,    WV_MENU_CLRFMT6, "<Item>"),
8049     WAVE_GTKIFE("/Edit/Color Format/Violet", NULL, menu_colorformat_7,    WV_MENU_CLRFMT7, "<Item>"),
8050     WAVE_GTKIFE("/Edit/Color Format/Cycle", NULL, menu_colorformat_cyc,    WV_MENU_CLRFMTC, "<Item>"),
8051     WAVE_GTKIFE("/Edit/Color Format/<separator>", NULL, NULL, WV_MENU_SEP5A, "<Separator>"),
8052     WAVE_GTKIFE("/Edit/Color Format/Keep xz Colors", NULL, menu_keep_xz_colors, WV_MENU_KEEPXZ, "<ToggleItem>"),
8053     WAVE_GTKIFE("/Edit/Show-Change All Highlighted", NULL, menu_showchangeall, WV_MENU_ESCAH, "<Item>"),
8054     WAVE_GTKIFE("/Edit/Show-Change First Highlighted", "<Control>F", menu_showchange, WV_MENU_ESCFH, "<Item>"),
8055       /* 50 */
8056     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP6, "<Separator>"),
8057     WAVE_GTKIFE("/Edit/Time Warp/Warp Marked", NULL, menu_warp_traces, WV_MENU_WARP, "<Item>"),
8058     WAVE_GTKIFE("/Edit/Time Warp/Unwarp Marked", NULL, menu_unwarp_traces, WV_MENU_UNWARP, "<Item>"),
8059     WAVE_GTKIFE("/Edit/Time Warp/Unwarp All", NULL, menu_unwarp_traces_all, WV_MENU_UNWARPA, "<Item>"),
8060     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP7A, "<Separator>"),
8061     WAVE_GTKIFE("/Edit/Exclude", "<Shift><Alt>E", menu_dataformat_exclude_on, WV_MENU_EEX, "<Item>"),
8062     WAVE_GTKIFE("/Edit/Show", "<Shift><Alt>S", menu_dataformat_exclude_off, WV_MENU_ESH, "<Item>"),
8063     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP6A, "<Separator>"),
8064     /* WAVE_GTKIFE("/Edit/Expand All Groups", "F12", menu_expand_all, WV_MENU_EXA, "<Item>"), */
8065     /* WAVE_GTKIFE("/Edit/Collapse All Groups", "<Shift>F12", menu_collapse_all, WV_MENU_CPA, "<Item>"), */
8066       /* 60 */
8067     WAVE_GTKIFE("/Edit/Toggle Group Open|Close", "T", menu_toggle_group, WV_MENU_TG, "<Item>"),
8068     WAVE_GTKIFE("/Edit/Create Group", "G", menu_create_group, WV_MENU_AG, "<Item>"),
8069     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP6A1, "<Separator>"),
8070     WAVE_GTKIFE("/Edit/Highlight Regexp", "<Alt>R", menu_regexp_highlight, WV_MENU_EHR, "<Item>"),
8071     WAVE_GTKIFE("/Edit/UnHighlight Regexp", "<Shift><Alt>R", menu_regexp_unhighlight, WV_MENU_EUHR, "<Item>"),
8072 
8073 #ifdef MAC_INTEGRATION
8074     WAVE_GTKIFE("/Edit/Highlight All", NULL, menu_dataformat_highlight_all, WV_MENU_EHA, "<Item>"),
8075     WAVE_GTKIFE("/Edit/UnHighlight All", NULL, menu_dataformat_unhighlight_all, WV_MENU_EUHA, "<Item>"),
8076 #else
8077     WAVE_GTKIFE("/Edit/Highlight All", "<Control>A", menu_dataformat_highlight_all, WV_MENU_EHA, "<Item>"),
8078     WAVE_GTKIFE("/Edit/UnHighlight All", "<Shift><Control>A", menu_dataformat_unhighlight_all, WV_MENU_EUHA, "<Item>"),
8079 #endif
8080 
8081     WAVE_GTKIFE("/Edit/<separator>", NULL, NULL, WV_MENU_SEP6B, "<Separator>"),
8082     WAVE_GTKIFE("/Edit/Sort/Alphabetize All", NULL, menu_alphabetize, WV_MENU_ALPHA, "<Item>"),
8083     WAVE_GTKIFE("/Edit/Sort/Alphabetize All (CaseIns)", NULL, menu_alphabetize2, WV_MENU_ALPHA2, "<Item>"),
8084     WAVE_GTKIFE("/Edit/Sort/Sigsort All", NULL, menu_lexize, WV_MENU_LEX, "<Item>"),
8085     WAVE_GTKIFE("/Edit/Sort/Reverse All", NULL, menu_reverse, WV_MENU_RVS, "<Item>"),
8086       /* 70 */
8087     WAVE_GTKIFE("/Search/Pattern Search 1", NULL, menu_tracesearchbox, WV_MENU_SPS, "<Item>"),
8088 #ifdef WAVE_USE_GTK2
8089     WAVE_GTKIFE("/Search/Pattern Search 2", NULL, menu_tracesearchbox, WV_MENU_SPS2, "<Item>"),
8090 #endif
8091     WAVE_GTKIFE("/Search/<separator>", NULL, NULL, WV_MENU_SEP7B, "<Separator>"),
8092     WAVE_GTKIFE("/Search/Signal Search Regexp", "<Alt>S", menu_signalsearch, WV_MENU_SSR, "<Item>"),
8093     WAVE_GTKIFE("/Search/Signal Search Hierarchy", "<Alt>T", menu_hiersearch, WV_MENU_SSH, "<Item>"),
8094     WAVE_GTKIFE("/Search/Signal Search Tree", "<Shift><Alt>T", menu_treesearch, WV_MENU_SST, "<Item>"),
8095     WAVE_GTKIFE("/Search/<separator>", NULL, NULL, WV_MENU_SEP7, "<Separator>"),
8096 #if !defined __MINGW32__ && !defined _MSC_VER
8097     WAVE_GTKIFE("/Search/Open Source Definition", NULL, menu_open_hierarchy_source, WV_MENU_OPENHS, "<Item>"),
8098     WAVE_GTKIFE("/Search/Open Source Instantiation", NULL, menu_open_hierarchy_isource, WV_MENU_OPENIHS, "<Item>"),
8099 #endif
8100     WAVE_GTKIFE("/Search/Open Scope", NULL, menu_open_hierarchy, WV_MENU_OPENH, "<Item>"),
8101     WAVE_GTKIFE("/Search/<separator>", NULL, NULL, WV_MENU_SEP7D, "<Separator>"),
8102     WAVE_GTKIFE("/Search/Autocoalesce", NULL, menu_autocoalesce, WV_MENU_ACOL, "<ToggleItem>"),
8103     WAVE_GTKIFE("/Search/Autocoalesce Reversal", NULL, menu_autocoalesce_reversal, WV_MENU_ACOLR, "<ToggleItem>"),
8104     WAVE_GTKIFE("/Search/Autoname Bundles", NULL, menu_autoname_bundles_on, WV_MENU_ABON, "<ToggleItem>"),
8105     WAVE_GTKIFE("/Search/Search Hierarchy Grouping", NULL, menu_hgrouping, WV_MENU_HTGP, "<ToggleItem>"),
8106       /* 80 */
8107     WAVE_GTKIFE("/Search/<separator>", NULL, NULL, WV_MENU_SEP7C, "<Separator>"),
8108     WAVE_GTKIFE("/Search/Set Pattern Search Repeat Count", NULL, menu_strace_repcnt, WV_MENU_STRSE, "<Item>"),
8109 
8110     WAVE_GTKIFE("/Time/Move To Time", "F1", menu_movetotime, WV_MENU_TMTT, "<Item>"),
8111     WAVE_GTKIFE("/Time/Zoom/Zoom Amount", "F2", menu_zoomsize, WV_MENU_TZZA, "<Item>"),
8112     WAVE_GTKIFE("/Time/Zoom/Zoom Base", "<Shift>F2", menu_zoombase, WV_MENU_TZZB, "<Item>"),
8113     WAVE_GTKIFE("/Time/Zoom/Zoom In", "<Control>plus", service_zoom_in_marshal, WV_MENU_TZZI, "<Item>"),
8114     WAVE_GTKIFE("/Time/Zoom/Zoom Out", "<Control>minus", service_zoom_out_marshal, WV_MENU_TZZO, "<Item>"),
8115     WAVE_GTKIFE("/Time/Zoom/Zoom Full", "<Control>0", service_zoom_full_marshal, WV_MENU_TZZBFL, "<Item>"),
8116     WAVE_GTKIFE("/Time/Zoom/Zoom Best Fit", "<Shift><Alt>F", service_zoom_fit_marshal, WV_MENU_TZZBF, "<Item>"),
8117     WAVE_GTKIFE("/Time/Zoom/Zoom To Start", "Home", service_zoom_left_marshal, WV_MENU_TZZTS, "<Item>"),
8118     WAVE_GTKIFE("/Time/Zoom/Zoom To End", "End", service_zoom_right_marshal, WV_MENU_TZZTE, "<Item>"),
8119     WAVE_GTKIFE("/Time/Zoom/Undo Zoom", "<Alt>U", service_zoom_undo_marshal, WV_MENU_TZUZ, "<Item>"),
8120       /* 90 */
8121     WAVE_GTKIFE("/Time/Fetch/Fetch Size", "F7", menu_fetchsize, WV_MENU_TFFS, "<Item>"),
8122     WAVE_GTKIFE("/Time/Fetch/Fetch ->", "<Alt>2", fetch_right_marshal, WV_MENU_TFFR, "<Item>"),
8123     WAVE_GTKIFE("/Time/Fetch/Fetch <-", "<Alt>1", fetch_left_marshal, WV_MENU_TFFL, "<Item>"),
8124     WAVE_GTKIFE("/Time/Discard/Discard ->", "<Alt>4", discard_right_marshal, WV_MENU_TDDR, "<Item>"),
8125     WAVE_GTKIFE("/Time/Discard/Discard <-", "<Alt>3", discard_left_marshal, WV_MENU_TDDL, "<Item>"),
8126     WAVE_GTKIFE("/Time/Shift/Shift ->", "<Alt>6", service_right_shift_marshal, WV_MENU_TSSR, "<Item>"),
8127     WAVE_GTKIFE("/Time/Shift/Shift <-", "<Alt>5", service_left_shift_marshal, WV_MENU_TSSL, "<Item>"),
8128     WAVE_GTKIFE("/Time/Page/Page ->", "<Alt>8", service_right_page_marshal, WV_MENU_TPPR, "<Item>"),
8129     WAVE_GTKIFE("/Time/Page/Page <-", "<Alt>7", service_left_page_marshal, WV_MENU_TPPL, "<Item>"),
8130     WAVE_GTKIFE("/Markers/Show-Change Marker Data", "<Alt>M", menu_markerbox, WV_MENU_MSCMD, "<Item>"),
8131       /* 100 */
8132     WAVE_GTKIFE("/Markers/Drop Named Marker", "<Alt>N", drop_named_marker, WV_MENU_MDNM, "<Item>"),
8133     WAVE_GTKIFE("/Markers/Collect Named Marker", "<Shift><Alt>N", collect_named_marker, WV_MENU_MCNM, "<Item>"),
8134     WAVE_GTKIFE("/Markers/Collect All Named Markers", "<Shift><Control><Alt>N", collect_all_named_markers, WV_MENU_MCANM, "<Item>"),
8135 #ifdef MAC_INTEGRATION
8136     WAVE_GTKIFE("/Markers/Copy Primary->B Marker", NULL, copy_pri_b_marker, WV_MENU_MCAB, "<Item>"),
8137 #else
8138     WAVE_GTKIFE("/Markers/Copy Primary->B Marker", "B", copy_pri_b_marker, WV_MENU_MCAB, "<Item>"),
8139 #endif
8140     WAVE_GTKIFE("/Markers/Delete Primary Marker", "<Shift><Alt>M", delete_unnamed_marker, WV_MENU_MDPM, "<Item>"),
8141     WAVE_GTKIFE("/Markers/<separator>", NULL, NULL, WV_MENU_SEP8, "<Separator>"),
8142     WAVE_GTKIFE("/Markers/Find Previous Edge", NULL, service_left_edge_marshal, WV_MENU_SLE, "<Item>"),
8143     WAVE_GTKIFE("/Markers/Find Next Edge", NULL, service_right_edge_marshal, WV_MENU_SRE, "<Item>"),
8144     WAVE_GTKIFE("/Markers/<separator>", NULL, NULL, WV_MENU_SEP8B, "<Separator>"),
8145     WAVE_GTKIFE("/Markers/Alternate Wheel Mode", NULL, menu_altwheel, WV_MENU_HSWM, "<ToggleItem>"),
8146     WAVE_GTKIFE("/Markers/Wave Scrolling", "F9", wave_scrolling_on, WV_MENU_MWSON, "<ToggleItem>"),
8147 
8148     WAVE_GTKIFE("/Markers/Locking/Lock to Lesser Named Marker", "Q", lock_marker_left, WV_MENU_MLKLT, "<Item>"),
8149     WAVE_GTKIFE("/Markers/Locking/Lock to Greater Named Marker", "W", lock_marker_right, WV_MENU_MLKRT, "<Item>"),
8150     WAVE_GTKIFE("/Markers/Locking/Unlock from Named Marker", "O", unlock_marker, WV_MENU_MLKOFF, "<Item>"),
8151 
8152     WAVE_GTKIFE("/View/Show Grid", "<Alt>G", menu_show_grid, WV_MENU_VSG, "<ToggleItem>"),
8153     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP9, "<Separator>"),
8154     WAVE_GTKIFE("/View/Show Wave Highlight", NULL, menu_show_wave_highlight, WV_MENU_SHW, "<ToggleItem>"),
8155     WAVE_GTKIFE("/View/Show Filled High Values", NULL, menu_show_filled_high_values, WV_MENU_FILL1, "<ToggleItem>"),
8156     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP9B, "<Separator>"),
8157     WAVE_GTKIFE("/View/Show Mouseover", NULL, menu_show_mouseover, WV_MENU_VSMO, "<ToggleItem>"),
8158 #ifdef WAVE_USE_GTK2
8159     WAVE_GTKIFE("/View/Mouseover Copies To Clipboard", NULL, menu_clipboard_mouseover, WV_MENU_VSMC, "<ToggleItem>"),
8160 #endif
8161     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP9A, "<Separator>"),
8162     WAVE_GTKIFE("/View/Show Base Symbols", "<Alt>F1", menu_show_base, WV_MENU_VSBS, "<ToggleItem>"),
8163     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP10, "<Separator>"),
8164       /* 110 */
8165     WAVE_GTKIFE("/View/Standard Trace Select", NULL, menu_enable_standard_trace_select, WV_MENU_ESTS, "<ToggleItem>"),
8166     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP10A, "<Separator>"),
8167     WAVE_GTKIFE("/View/Dynamic Resize", "<Alt>9", menu_enable_dynamic_resize, WV_MENU_VDR, "<ToggleItem>"),
8168     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP11, "<Separator>"),
8169     WAVE_GTKIFE("/View/Center Zooms", "F8", menu_center_zooms, WV_MENU_VCZ, "<ToggleItem>"),
8170     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP12, "<Separator>"),
8171     WAVE_GTKIFE("/View/Toggle Delta-Frequency", NULL, menu_toggle_delta_or_frequency, WV_MENU_VTDF, "<Item>"),
8172     WAVE_GTKIFE("/View/Toggle Max-Marker", "F10", menu_toggle_max_or_marker, WV_MENU_VTMM, "<Item>"),
8173     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP13, "<Separator>"),
8174     WAVE_GTKIFE("/View/Constant Marker Update", "F11", menu_enable_constant_marker_update, WV_MENU_VCMU, "<ToggleItem>"),
8175     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP14, "<Separator>"),
8176     WAVE_GTKIFE("/View/Draw Roundcapped Vectors", "<Alt>F2", menu_use_roundcaps, WV_MENU_VDRV, "<ToggleItem>"),
8177       /* 120 */
8178     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP15, "<Separator>"),
8179     WAVE_GTKIFE("/View/Left Justified Signals", "<Shift>Home", menu_left_justify, WV_MENU_VLJS, "<Item>"),
8180     WAVE_GTKIFE("/View/Right Justified Signals", "<Shift>End", menu_right_justify, WV_MENU_VRJS, "<Item>"),
8181     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP16, "<Separator>"),
8182     WAVE_GTKIFE("/View/Zoom Pow10 Snap", "<Shift>Pause", menu_zoom10_snap, WV_MENU_VZPS, "<ToggleItem>"),
8183     WAVE_GTKIFE("/View/Partial VCD Dynamic Zoom Full", NULL, menu_zoom_dynf, WV_MENU_VZDYN, "<ToggleItem>"),
8184     WAVE_GTKIFE("/View/Partial VCD Dynamic Zoom To End", NULL, menu_zoom_dyne, WV_MENU_VZDYNE, "<ToggleItem>"),
8185     WAVE_GTKIFE("/View/Full Precision", "<Alt>Pause", menu_use_full_precision, WV_MENU_VFTP, "<ToggleItem>"),
8186     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP17, "<Separator>"),
8187     WAVE_GTKIFE("/View/Define Time Ruler Marks", NULL, menu_def_ruler, WV_MENU_RULER, "<Item>"),
8188     WAVE_GTKIFE("/View/Remove Pattern Marks", NULL, menu_remove_marked, WV_MENU_RMRKS, "<Item>"),
8189     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP17A, "<Separator>"),
8190     WAVE_GTKIFE("/View/Use Color", NULL, menu_use_color, WV_MENU_USECOLOR, "<Item>"),
8191     WAVE_GTKIFE("/View/Use Black and White", NULL, menu_use_bw, WV_MENU_USEBW, "<Item>"),
8192     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP18, "<Separator>"),
8193     WAVE_GTKIFE("/View/LXT Clock Compress to Z", NULL, menu_lxt_clk_compress, WV_MENU_LXTCC2Z, "<ToggleItem>"),
8194 
8195     WAVE_GTKIFE("/View/<separator>", NULL, NULL, WV_MENU_SEP19, "<Separator>"),
8196     WAVE_GTKIFE("/View/Scale To Time Dimension/None", NULL, menu_scale_to_td_x, WV_MENU_TDSCALEX, "<ToggleItem>"),
8197     WAVE_GTKIFE("/View/Scale To Time Dimension/sec",  NULL, menu_scale_to_td_s, WV_MENU_TDSCALES, "<ToggleItem>"),
8198     WAVE_GTKIFE("/View/Scale To Time Dimension/ms",   NULL, menu_scale_to_td_m, WV_MENU_TDSCALEM, "<ToggleItem>"),
8199     WAVE_GTKIFE("/View/Scale To Time Dimension/us",   NULL, menu_scale_to_td_u, WV_MENU_TDSCALEU, "<ToggleItem>"),
8200     WAVE_GTKIFE("/View/Scale To Time Dimension/ns",   NULL, menu_scale_to_td_n, WV_MENU_TDSCALEN, "<ToggleItem>"),
8201     WAVE_GTKIFE("/View/Scale To Time Dimension/ps",   NULL, menu_scale_to_td_p, WV_MENU_TDSCALEP, "<ToggleItem>"),
8202     WAVE_GTKIFE("/View/Scale To Time Dimension/fs",   NULL, menu_scale_to_td_f, WV_MENU_TDSCALEF, "<ToggleItem>"),
8203 
8204       /* 130 */
8205     WAVE_GTKIFE("/Help/WAVE Help", "<Control>H", menu_help, WV_MENU_HWH, "<Item>"),
8206 #ifdef MAC_INTEGRATION
8207     WAVE_GTKIFE("/Help/WAVE User Manual", NULL, menu_help_manual, WV_MENU_HWM, "<Item>"),
8208 #endif
8209     WAVE_GTKIFE("/Help/Wave Version", NULL, menu_version, WV_MENU_HWV, "<Item>"),
8210 };
8211 
8212 
8213 #ifndef WAVE_USE_MLIST_T
8214 void set_scale_to_time_dimension_toggles(void)
8215 {
8216 int i;
8217 
8218 for(i = WV_MENU_TDSCALEX; i<= WV_MENU_TDSCALEF; i++)
8219 	{
8220 	GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[i].path))->active=FALSE;
8221 	}
8222 
8223 switch(GLOBALS->scale_to_time_dimension)
8224 	{
8225 	case 's':	i = WV_MENU_TDSCALES; break;
8226 	case 'm':	i = WV_MENU_TDSCALEM; break;
8227 	case 'u':	i = WV_MENU_TDSCALEU; break;
8228 	case 'n':	i = WV_MENU_TDSCALEN; break;
8229 	case 'p':	i = WV_MENU_TDSCALEP; break;
8230 	case 'f':	i = WV_MENU_TDSCALEF; break;
8231 	default: 	i = WV_MENU_TDSCALEX; break;
8232 	}
8233 
8234 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[i].path))->active=TRUE;
8235 }
8236 #else
8237 void set_scale_to_time_dimension_toggles(void)
8238 {
8239 int i, ii;
8240 
8241 switch(GLOBALS->scale_to_time_dimension)
8242         {
8243         case 's':       ii = WV_MENU_TDSCALES; break;
8244         case 'm':       ii = WV_MENU_TDSCALEM; break;
8245         case 'u':       ii = WV_MENU_TDSCALEU; break;
8246         case 'n':       ii = WV_MENU_TDSCALEN; break;
8247         case 'p':       ii = WV_MENU_TDSCALEP; break;
8248         case 'f':       ii = WV_MENU_TDSCALEF; break;
8249         default:        ii = WV_MENU_TDSCALEX; break;
8250         }
8251 
8252 for(i = WV_MENU_TDSCALEX; i<= WV_MENU_TDSCALEF; i++)
8253         {
8254         gboolean is_active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[i]));
8255         if(i!=ii)
8256                 {
8257                 if(is_active)
8258                         {
8259                         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[i]), FALSE);
8260                         }
8261                 }
8262                 else
8263                 {
8264                 if(!is_active)
8265                         {
8266                         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[i]), TRUE);
8267                         }
8268                 }
8269         }
8270 }
8271 #endif
8272 
8273 /*
8274  * set toggleitems to their initial states
8275  */
8276 #ifndef WAVE_USE_MLIST_T
8277 static void set_menu_toggles(void)
8278 {
8279 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZPS].path))->active=(GLOBALS->zoom_pow10_snap)?TRUE:FALSE;
8280 
8281 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSG].path))->active=(GLOBALS->display_grid)?TRUE:FALSE;
8282 
8283 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_SHW].path))->active=(GLOBALS->highlight_wavewindow)?TRUE:FALSE;
8284 
8285 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_FILL1].path))->active=(GLOBALS->fill_waveform)?TRUE:FALSE;
8286 
8287 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HSWM].path))->active=(GLOBALS->alt_wheel_mode)?TRUE:FALSE;
8288 
8289 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1,menu_items[WV_MENU_VSMO].path))->active=(GLOBALS->disable_mouseover)?FALSE:TRUE;
8290 
8291 #ifdef WAVE_USE_GTK2
8292 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1,menu_items[WV_MENU_VSMC].path))->active=(GLOBALS->clipboard_mouseover)?TRUE:FALSE;
8293 #endif
8294 
8295 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSBS].path))->active=(GLOBALS->show_base)?TRUE:FALSE;
8296 
8297 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDR].path))->active=(GLOBALS->do_resize_signals)?TRUE:FALSE;
8298 
8299 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ESTS].path))->active=(GLOBALS->use_standard_trace_select)?TRUE:FALSE;
8300 
8301 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCMU].path))->active=(GLOBALS->constant_marker_update)?TRUE:FALSE;
8302 
8303 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCZ].path))->active=(GLOBALS->do_zoom_center)?TRUE:FALSE;
8304 
8305 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDRV].path))->active=(GLOBALS->use_roundcaps)?TRUE:FALSE;
8306 
8307 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_MWSON].path))->active=(GLOBALS->wave_scrolling)?TRUE:FALSE;
8308 
8309 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ABON].path))->active=(GLOBALS->autoname_bundles)?TRUE:FALSE;
8310 
8311 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HTGP].path))->active=(GLOBALS->hier_grouping)?TRUE:FALSE;
8312 
8313 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VFTP].path))->active=(GLOBALS->use_full_precision)?TRUE:FALSE;
8314 
8315 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOL].path))->active=(GLOBALS->autocoalesce)?TRUE:FALSE;
8316 
8317 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOLR].path))->active=(GLOBALS->autocoalesce_reversal)?TRUE:FALSE;
8318 
8319 GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_KEEPXZ].path))->active=(GLOBALS->keep_xz_colors)?TRUE:FALSE;
8320 
8321 if(GLOBALS->partial_vcd)
8322 	{
8323 	GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYN].path))->active=(GLOBALS->zoom_dyn)?TRUE:FALSE;
8324 	GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYNE].path))->active=(GLOBALS->zoom_dyne)?TRUE:FALSE;
8325 	}
8326 
8327 if(GLOBALS->loaded_file_type == LXT_FILE)
8328 	{
8329 	GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LXTCC2Z].path))->active=(GLOBALS->lxt_clock_compress_to_z)?TRUE:FALSE;
8330 	}
8331 
8332 set_scale_to_time_dimension_toggles();
8333 }
8334 #else
8335 void set_menu_toggles(void)
8336 {
8337 GLOBALS->quiet_checkmenu = 1;
8338 
8339 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZPS]), GLOBALS->zoom_pow10_snap);
8340 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSG]), GLOBALS->display_grid);
8341 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_SHW]), GLOBALS->highlight_wavewindow);
8342 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_FILL1]), GLOBALS->fill_waveform);
8343 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HSWM]), GLOBALS->alt_wheel_mode);
8344 
8345 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMO]), !GLOBALS->disable_mouseover);
8346 
8347 #ifdef WAVE_USE_GTK2
8348 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMC]), GLOBALS->clipboard_mouseover);
8349 #endif
8350 
8351 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSBS]), GLOBALS->show_base);
8352 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDR]), GLOBALS->do_resize_signals);
8353 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ESTS]), GLOBALS->use_standard_trace_select);
8354 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCMU]), GLOBALS->constant_marker_update);
8355 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCZ]), GLOBALS->do_zoom_center);
8356 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDRV]), GLOBALS->use_roundcaps);
8357 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_MWSON]), GLOBALS->wave_scrolling);
8358 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ABON]), GLOBALS->autoname_bundles);
8359 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HTGP]), GLOBALS->hier_grouping);
8360 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VFTP]), GLOBALS->use_full_precision);
8361 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOL]), GLOBALS->autocoalesce);
8362 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOLR]), GLOBALS->autocoalesce_reversal);
8363 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_KEEPXZ]), GLOBALS->keep_xz_colors);
8364 
8365 if(GLOBALS->partial_vcd)
8366         {
8367         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYN]), GLOBALS->zoom_dyn);
8368         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYNE]), GLOBALS->zoom_dyne);
8369         }
8370 
8371 if(GLOBALS->loaded_file_type == LXT_FILE)
8372         {
8373         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LXTCC2Z]), GLOBALS->lxt_clock_compress_to_z);
8374         }
8375 
8376 set_scale_to_time_dimension_toggles();
8377 GLOBALS->quiet_checkmenu = 0;
8378 }
8379 #endif
8380 
8381 
8382 /*
8383  * kill accelerator keys (e.g., if using twinwave as focus is sometimes wrong from parent window)
8384  */
8385 void kill_main_menu_accelerators(void)
8386 {
8387 int i;
8388 
8389 for(i=0;i<WV_MENU_NUMITEMS;i++)
8390 	{
8391 	menu_items[i].accelerator = NULL;
8392 	}
8393 }
8394 
8395 
8396 /*
8397  * create the menu through an itemfactory instance
8398  */
8399 #ifndef WAVE_USE_MLIST_T
8400 void get_main_menu(GtkWidget *window, GtkWidget ** menubar)
8401 {
8402     int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
8403     GtkAccelGroup *global_accel;
8404     int i;
8405     GtkWidget *mw;
8406 
8407     GLOBALS->regexp_string_menu_c_1 = calloc_2(1, 129);
8408 
8409     global_accel = gtk_accel_group_new();
8410     GLOBALS->item_factory_menu_c_1 = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", global_accel);
8411     gtk_item_factory_create_items(GLOBALS->item_factory_menu_c_1, nmenu_items, menu_items, NULL);
8412 
8413     if(GLOBALS->loaded_file_type == MISSING_FILE)
8414 	{
8415 	    for(i=0;i<nmenu_items;i++)
8416 		{
8417 		switch(i)
8418 			{
8419 			case WV_MENU_FONVT:
8420 			case WV_MENU_WCLOSE:
8421 #if defined(HAVE_LIBTCL)
8422 	    		case WV_MENU_TCLSCR:
8423 #endif
8424 			case WV_MENU_FQY:
8425 			case WV_MENU_HWH:
8426 #ifdef MAC_INTEGRATION
8427 			case WV_MENU_HWM:
8428 #endif
8429 			case WV_MENU_HWV:
8430 				break;
8431 
8432 			default:
8433 				mw = gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[i].path);
8434 				if(mw) gtk_widget_set_sensitive(mw, FALSE);
8435 				break;
8436 			}
8437 		}
8438 
8439 #ifdef WAVE_USE_MENU_BLACKOUTS
8440 		for(i=0;i<(sizeof(menu_blackouts)/sizeof(char *));i++)
8441 			{
8442 			mw = gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_blackouts[i]);
8443 			if(mw) gtk_widget_set_sensitive(mw, FALSE);
8444 			}
8445 #endif
8446 	}
8447 
8448     if(
8449 #ifdef WAVE_USE_GTK2
8450 	(GLOBALS->socket_xid)||
8451 #endif
8452 	(GLOBALS->partial_vcd))
8453 	{
8454 	gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_FONVT].path);
8455 	}
8456 
8457     if(!GLOBALS->partial_vcd)
8458 	{
8459 	gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYN].path);
8460 	gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYNE].path);
8461 	}
8462 
8463     if(GLOBALS->loaded_file_type == DUMPLESS_FILE)
8464 	{
8465     	gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_FRW].path);
8466 	}
8467 
8468     if(GLOBALS->loaded_file_type != LXT_FILE)
8469 	{
8470 	gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_SEP18].path);
8471     	gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LXTCC2Z].path);
8472 	}
8473 
8474     gtk_window_add_accel_group(GTK_WINDOW(window), global_accel);
8475     if(menubar)
8476 	{
8477 	*menubar = gtk_item_factory_get_widget (GLOBALS->item_factory_menu_c_1, "<main>");
8478         set_menu_toggles();
8479 	}
8480 }
8481 #endif
8482 
8483 
8484 void menu_set_sensitive(void)
8485 {
8486     int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
8487     int i;
8488     GtkWidget *mw;
8489 #ifdef WAVE_USE_MENU_BLACKOUTS
8490     for(i=0;i<(sizeof(menu_blackouts)/sizeof(char *));i++)
8491 	{
8492 	mw = gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_blackouts[i]);
8493 	if(mw) gtk_widget_set_sensitive(mw, TRUE);
8494 	}
8495 #endif
8496 
8497     for(i=0;i<nmenu_items;i++)
8498         {
8499         switch(i)
8500                 {
8501                 case WV_MENU_FONVT:
8502                 case WV_MENU_WCLOSE:
8503 #if defined(HAVE_LIBTCL)
8504     		case WV_MENU_TCLSCR:
8505 #endif
8506                 case WV_MENU_FQY:
8507                 case WV_MENU_HWH:
8508 #ifdef MAC_INTEGRATION
8509 		case WV_MENU_HWM:
8510 #endif
8511                 case WV_MENU_HWV:
8512                         break;
8513 
8514                 default:
8515 #ifdef WAVE_USE_MLIST_T
8516 			mw = menu_wlist[i];
8517 #else
8518                         mw = gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[i].path);
8519 #endif
8520                         if(mw)
8521 				{
8522 #ifdef MAC_INTEGRATION
8523 				if(menu_items[i].callback)
8524 #endif
8525 					{
8526 					gtk_widget_set_sensitive(mw, TRUE);
8527 					}
8528 				}
8529                         break;
8530                 }
8531         }
8532 }
8533 
8534 /*
8535  * bail out
8536  */
8537 int file_quit_cmd_callback (GtkWidget *widget, gpointer data)
8538 {
8539 (void)widget;
8540 (void)data;
8541 
8542 if(GLOBALS->save_on_exit) { menu_write_save_file(NULL, 0, NULL); }
8543 
8544 if(!GLOBALS->enable_fast_exit)
8545 	{
8546 	simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", GTK_SIGNAL_FUNC(menu_quit_callback), 1);
8547 	}
8548 	else
8549 	{
8550 #ifdef __CYGWIN__
8551 	kill_stems_browser();
8552 #endif
8553 	g_print ("WM Destroy\n");
8554 	gtk_exit(0);
8555 	}
8556 
8557 return(TRUE); /* keeps "delete_event" from happening...we'll manually destory later if need be */
8558 }
8559 
8560 
8561 /*
8562  * RPC
8563  */
8564 int execute_script(char *name, int dealloc_name)
8565 {
8566 unsigned int i;
8567 int nlen = strlen(name);
8568 
8569 if(GLOBALS->tcl_running)
8570 	{
8571 	fprintf(stderr, "Could not run script file '%s', as one is already running.\n", name);
8572 
8573 	if(dealloc_name)
8574 		{
8575 		free_2(name);
8576 		}
8577 
8578 	return(0);
8579 	}
8580 
8581 GLOBALS->tcl_running = 1;
8582 
8583 if(1) /* all scripts are Tcl now */
8584 	{
8585 #if defined(HAVE_LIBTCL)
8586 	int tclrc;
8587         char *tcl_cmd = wave_alloca(8 + nlen + 1 + 1); /* originally a malloc, but the script can change the context! */
8588         strcpy(tcl_cmd, "source {");
8589         strcpy(tcl_cmd+8, name);
8590         strcpy(tcl_cmd+8+nlen, "}");
8591 
8592 	fprintf(stderr, "GTKWAVE | Executing Tcl script '%s'\n", name);
8593 
8594 	if(dealloc_name)
8595 		{
8596 		free_2(name);
8597 		}
8598 
8599 #ifdef WIN32
8600 	{
8601 	char *slashfix = tcl_cmd;
8602 	while(*slashfix)
8603 		{
8604 		if(*slashfix=='\\') *slashfix='/';
8605 		slashfix++;
8606 		}
8607 	}
8608 #endif
8609 
8610 	tclrc = Tcl_Eval (GLOBALS->interp, tcl_cmd);
8611 	if(tclrc != TCL_OK) { fprintf (stderr, "GTKWAVE | %s\n", Tcl_GetStringResult (GLOBALS->interp)); }
8612 #else
8613 	fprintf(stderr, "GTKWAVE | Tcl support not compiled into gtkwave, exiting.\n");
8614 	gtk_exit(255);
8615 #endif
8616 	}
8617 
8618 for(i=0;i<GLOBALS->num_notebook_pages;i++)
8619 	{
8620         (*GLOBALS->contexts)[i]->wave_script_args = NULL; /* just in case there was a CTX swap */
8621 	}
8622 
8623 GLOBALS->tcl_running = 0;
8624 return(0);
8625 }
8626 
8627 
8628 gtkwave_mlist_t *retrieve_menu_items_array(int *num_items)
8629 {
8630 *num_items = sizeof(menu_items) / sizeof(menu_items[0]);
8631 
8632 return(menu_items);
8633 }
8634 
8635 
8636 /*
8637  * support for menu accelerator modifications...
8638  */
8639 int set_wave_menu_accelerator(char *str)
8640 {
8641 char *path, *pathend;
8642 char *accel;
8643 int i;
8644 
8645 path = strchr(str, '\"');
8646 if(!path) return(1);
8647 path++;
8648 if(!*path) return(1);
8649 
8650 pathend = strchr(path, '\"');
8651 if(!pathend) return(1);
8652 
8653 *pathend = 0;
8654 
8655 accel = pathend + 1;
8656 while(*accel)
8657 	{
8658 	if(!isspace((int)(unsigned char)*accel)) break;
8659 	accel++;
8660 	}
8661 
8662 if(!*accel) return(1);
8663 
8664 if(strstr(path, "<separator>")) return(1);
8665 if(!strcmp(accel, "(null)"))
8666 	{
8667 	accel = NULL;
8668 	}
8669 	else
8670 	{
8671 	for(i=0;i<WV_MENU_NUMITEMS;i++)
8672 		{
8673 		if(menu_items[i].accelerator)
8674 			{
8675 			if(!strcmp(menu_items[i].accelerator, accel))
8676 				{
8677 				menu_items[i].accelerator = NULL;
8678 				}
8679 			}
8680 		}
8681 	}
8682 
8683 for(i=0;i<WV_MENU_NUMITEMS;i++)
8684 	{
8685 	if(menu_items[i].path)
8686 		{
8687 		if(!strcmp(menu_items[i].path, path))
8688 			{
8689 			menu_items[i].accelerator = accel ? strdup_2(accel) : NULL;
8690 			break;
8691 			}
8692 		}
8693 	}
8694 
8695 return(0);
8696 }
8697 
8698 
8699 /***********************/
8700 /*** popup menu code ***/
8701 /***********************/
8702 
8703 static gtkwave_mlist_t popmenu_items[] =
8704 {
8705     WAVE_GTKIFE("/Data Format/Hex", NULL, menu_dataformat_hex, WV_MENU_EDFH, "<Item>"),
8706     WAVE_GTKIFE("/Data Format/Decimal", NULL, menu_dataformat_dec, WV_MENU_EDFD, "<Item>"),
8707     WAVE_GTKIFE("/Data Format/Signed Decimal", NULL, menu_dataformat_signed, WV_MENU_EDFSD, "<Item>"),
8708     WAVE_GTKIFE("/Data Format/Binary", NULL, menu_dataformat_bin, WV_MENU_EDFB, "<Item>"),
8709     WAVE_GTKIFE("/Data Format/Octal", NULL, menu_dataformat_oct, WV_MENU_EDFO, "<Item>"),
8710     WAVE_GTKIFE("/Data Format/ASCII", NULL, menu_dataformat_ascii, WV_MENU_EDFA, "<Item>"),
8711     WAVE_GTKIFE("/Data Format/Time", NULL, menu_dataformat_time, WV_MENU_TIME, "<Item>"),
8712     WAVE_GTKIFE("/Data Format/Enum", NULL, menu_dataformat_enum, WV_MENU_ENUM, "<Item>"),
8713     WAVE_GTKIFE("/Data Format/BitsToReal", NULL, menu_dataformat_real, WV_MENU_EDRL, "<Item>"),
8714     WAVE_GTKIFE("/Data Format/RealToBits/On", NULL, menu_dataformat_real2bon, WV_MENU_EDR2BON, "<Item>"),
8715     WAVE_GTKIFE("/Data Format/RealToBits/Off", NULL, menu_dataformat_real2boff, WV_MENU_EDR2BOFF, "<Item>"),
8716     WAVE_GTKIFE("/Data Format/Right Justify/On", NULL, menu_dataformat_rjustify_on, WV_MENU_EDFRJON, "<Item>"),
8717     WAVE_GTKIFE("/Data Format/Right Justify/Off", NULL, menu_dataformat_rjustify_off, WV_MENU_EDFRJOFF, "<Item>"),
8718     WAVE_GTKIFE("/Data Format/Invert/On", NULL, menu_dataformat_invert_on, WV_MENU_EDFION, "<Item>"),
8719     WAVE_GTKIFE("/Data Format/Invert/Off", NULL, menu_dataformat_invert_off, WV_MENU_EDFIOFF, "<Item>"),
8720     WAVE_GTKIFE("/Data Format/Reverse Bits/On", NULL, menu_dataformat_reverse_on, WV_MENU_EDFRON, "<Item>"),
8721     WAVE_GTKIFE("/Data Format/Reverse Bits/Off", NULL, menu_dataformat_reverse_off, WV_MENU_EDFROFF, "<Item>"),
8722     WAVE_GTKIFE("/Data Format/Translate Filter File/Disable", NULL, menu_dataformat_xlate_file_0, WV_MENU_XLF_0, "<Item>"),
8723     WAVE_GTKIFE("/Data Format/Translate Filter File/Enable and Select", NULL, menu_dataformat_xlate_file_1, WV_MENU_XLF_1, "<Item>"),
8724     WAVE_GTKIFE("/Data Format/Translate Filter Process/Disable", NULL, menu_dataformat_xlate_proc_0, WV_MENU_XLP_0, "<Item>"),
8725     WAVE_GTKIFE("/Data Format/Translate Filter Process/Enable and Select", NULL, menu_dataformat_xlate_proc_1, WV_MENU_XLP_1, "<Item>"),
8726     WAVE_GTKIFE("/Data Format/Transaction Filter Process/Disable", NULL, menu_dataformat_xlate_ttrans_0, WV_MENU_TTXLP_0, "<Item>"),
8727     WAVE_GTKIFE("/Data Format/Transaction Filter Process/Enable and Select", NULL, menu_dataformat_xlate_ttrans_1, WV_MENU_TTXLP_1, "<Item>"),
8728     WAVE_GTKIFE("/Data Format/Analog/Off", NULL, menu_dataformat_analog_off, WV_MENU_EDFAOFF, "<Item>"),
8729     WAVE_GTKIFE("/Data Format/Analog/Step", NULL, menu_dataformat_analog_step, WV_MENU_EDFASTEP, "<Item>"),
8730     WAVE_GTKIFE("/Data Format/Analog/Interpolated", NULL, menu_dataformat_analog_interpol, WV_MENU_EDFAINTERPOL, "<Item>"),
8731     WAVE_GTKIFE("/Data Format/Analog/Interpolated Annotated", NULL, menu_dataformat_analog_interpol_step, WV_MENU_EDFAINTERPOL2, "<Item>"),
8732     WAVE_GTKIFE("/Data Format/Analog/Resizing/Screen Data", NULL, menu_dataformat_analog_resize_screen, WV_MENU_EDFARSD, "<Item>"),
8733     WAVE_GTKIFE("/Data Format/Analog/Resizing/All Data", NULL, menu_dataformat_analog_resize_all, WV_MENU_EDFARAD, "<Item>"),
8734 
8735     WAVE_GTKIFE("/Data Format/Range Fill/With 0s", NULL, menu_dataformat_rangefill_zero, WV_MENU_RFILL0, "<Item>"),
8736     WAVE_GTKIFE("/Data Format/Range Fill/With 1s", NULL, menu_dataformat_rangefill_one, WV_MENU_RFILL1, "<Item>"),
8737     WAVE_GTKIFE("/Data Format/Range Fill/Off", NULL, menu_dataformat_rangefill_off, WV_MENU_RFILLOFF, "<Item>"),
8738 
8739     WAVE_GTKIFE("/Data Format/Gray Filters/To Gray", NULL, menu_dataformat_bingray_on, WV_MENU_B2G, "<Item>"),
8740     WAVE_GTKIFE("/Data Format/Gray Filters/From Gray", NULL, menu_dataformat_graybin_on, WV_MENU_G2B, "<Item>"),
8741     WAVE_GTKIFE("/Data Format/Gray Filters/None", NULL, menu_dataformat_nogray,    WV_MENU_GBNONE, "<Item>"),
8742     WAVE_GTKIFE("/Data Format/Popcnt/On", NULL, menu_dataformat_popcnt_on, WV_MENU_POPON, "<Item>"),
8743     WAVE_GTKIFE("/Data Format/Popcnt/Off", NULL, menu_dataformat_popcnt_off,    WV_MENU_POPOFF, "<Item>"),
8744     WAVE_GTKIFE("/Data Format/Find First One/On", NULL, menu_dataformat_ffo_on, WV_MENU_FFOON, "<Item>"),
8745     WAVE_GTKIFE("/Data Format/Find First One/Off", NULL, menu_dataformat_ffo_off,    WV_MENU_FFOOFF, "<Item>"),
8746     WAVE_GTKIFE("/Data Format/Fixed Point Shift/On", NULL, menu_dataformat_fpshift_on, WV_MENU_FPSHIFTON, "<Item>"),
8747     WAVE_GTKIFE("/Data Format/Fixed Point Shift/Off", NULL, menu_dataformat_fpshift_off,    WV_MENU_FPSHIFTOFF, "<Item>"),
8748     WAVE_GTKIFE("/Data Format/Fixed Point Shift/Specify", NULL, menu_dataformat_fpshift_specify,    WV_MENU_FPSHIFTVAL, "<Item>"),
8749 
8750     WAVE_GTKIFE("/Color Format/Normal", NULL, menu_colorformat_0,    WV_MENU_CLRFMT0, "<Item>"),
8751     WAVE_GTKIFE("/Color Format/Red", NULL, menu_colorformat_1,    WV_MENU_CLRFMT1, "<Item>"),
8752     WAVE_GTKIFE("/Color Format/Orange", NULL, menu_colorformat_2,    WV_MENU_CLRFMT2, "<Item>"),
8753     WAVE_GTKIFE("/Color Format/Yellow", NULL, menu_colorformat_3,    WV_MENU_CLRFMT3, "<Item>"),
8754     WAVE_GTKIFE("/Color Format/Green", NULL, menu_colorformat_4,    WV_MENU_CLRFMT4, "<Item>"),
8755     WAVE_GTKIFE("/Color Format/Blue", NULL, menu_colorformat_5,    WV_MENU_CLRFMT5, "<Item>"),
8756     WAVE_GTKIFE("/Color Format/Indigo", NULL, menu_colorformat_6,    WV_MENU_CLRFMT6, "<Item>"),
8757     WAVE_GTKIFE("/Color Format/Violet", NULL, menu_colorformat_7,    WV_MENU_CLRFMT7, "<Item>"),
8758     WAVE_GTKIFE("/Color Format/Cycle", NULL, menu_colorformat_cyc,    WV_MENU_CLRFMTC, "<Item>"),
8759     WAVE_GTKIFE("/<separator>", NULL, NULL, WV_MENU_SEP1, "<Separator>"),
8760     WAVE_GTKIFE("/Insert Analog Height Extension", NULL, menu_insert_analog_height_extension, WV_MENU_EIA, "<Item>"),
8761     WAVE_GTKIFE("/<separator>", NULL, NULL, WV_MENU_SEP2, "<Separator>"),
8762 
8763     WAVE_GTKIFE("/Insert Blank", NULL, menu_insert_blank_traces, WV_MENU_EIB, "<Item>"),
8764     WAVE_GTKIFE("/Insert Comment", NULL, menu_insert_comment_traces, WV_MENU_EIC, "<Item>"),
8765     WAVE_GTKIFE("/Alias Highlighted Trace", NULL, menu_alias, WV_MENU_EAHT, "<Item>"),
8766     WAVE_GTKIFE("/Remove Highlighted Aliases", NULL, menu_remove_aliases, WV_MENU_ERHA, "<Item>"),
8767     WAVE_GTKIFE("/<separator>", NULL, NULL, WV_MENU_SEP3, "<Separator>"),
8768     WAVE_GTKIFE("/Cut", NULL, menu_cut_traces, WV_MENU_EC, "<Item>"),
8769     WAVE_GTKIFE("/Copy", NULL, menu_copy_traces, WV_MENU_ECY, "<Item>"),
8770     WAVE_GTKIFE("/Paste", NULL, menu_paste_traces, WV_MENU_EP, "<Item>"),
8771     WAVE_GTKIFE("/Delete", NULL, menu_delete_traces, WV_MENU_DEL, "<Item>"),
8772     WAVE_GTKIFE("/<separator>", NULL, NULL, WV_MENU_SEP4, "<Separator>"),
8773     WAVE_GTKIFE("/Open Scope", NULL, menu_open_hierarchy, WV_MENU_OPENH, "<Item>")
8774 #if !defined __MINGW32__ && !defined _MSC_VER
8775     ,
8776     /* see do_popup_menu() for specific patch for this for if(!GLOBALS->stem_path_string_table) ... */
8777     WAVE_GTKIFE("/Open Source Definition", NULL, menu_open_hierarchy_source, WV_MENU_OPENHS, "<Item>"),
8778     WAVE_GTKIFE("/Open Source Instantiation", NULL, menu_open_hierarchy_isource, WV_MENU_OPENIHS, "<Item>")
8779 #endif
8780 };
8781 
8782 
8783 void do_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
8784 {
8785 (void)my_widget;
8786 
8787   GtkWidget *menu;
8788   int button, event_time;
8789 
8790   if(!GLOBALS->signal_popup_menu)
8791     {
8792     int nmenu_items = sizeof(popmenu_items) / sizeof(popmenu_items[0]);
8793 
8794 #if !defined __MINGW32__ && !defined _MSC_VER
8795     if(!GLOBALS->stem_path_string_table)
8796 	{
8797 	nmenu_items = nmenu_items - 2; /* to remove WV_MENU_OPENHS, WV_MENU_OPENIHS -> keep at end of list! */
8798 	}
8799     else
8800 	{
8801         if(!GLOBALS->istem_struct_base)
8802 		{
8803 		nmenu_items--; /* remove "/Open Source Instantiation" if not present */
8804 		}
8805 	}
8806 #endif
8807 
8808 #ifdef WAVE_USE_MLIST_T
8809     GLOBALS->signal_popup_menu = menu = alt_menu(popmenu_items, nmenu_items, NULL, NULL, FALSE);
8810 #else
8811     GtkItemFactory *item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<main>", NULL);
8812     gtk_item_factory_create_items (item_factory, nmenu_items, popmenu_items, NULL);
8813     GLOBALS->signal_popup_menu = menu = gtk_item_factory_get_widget (item_factory, "<main>");
8814 #endif
8815     }
8816     else
8817     {
8818     menu = GLOBALS->signal_popup_menu;
8819     }
8820 
8821   if (event)
8822     {
8823       button = event->button;
8824       event_time = event->time;
8825     }
8826   else
8827     {
8828       button = 0;
8829 #if WAVE_USE_GTK2
8830       event_time = gtk_get_current_event_time ();
8831 #else
8832       return; /* disabled in GTK1.2 */
8833 #endif
8834     }
8835 
8836   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
8837                   button, event_time);
8838 }
8839 
8840 /***************************/
8841 /*** sst popup menu code ***/
8842 /***************************/
8843 
8844 #if WAVE_USE_GTK2
8845 static gtkwave_mlist_t sst_popmenu_items[] =
8846 {
8847     WAVE_GTKIFE("/Recurse Import/Append", NULL, menu_recurse_import, WV_RECURSE_APPEND, "<Item>"),
8848     WAVE_GTKIFE("/Recurse Import/Insert", NULL, menu_recurse_import, WV_RECURSE_INSERT, "<Item>"),
8849     WAVE_GTKIFE("/Recurse Import/Replace", NULL, menu_recurse_import, WV_RECURSE_REPLACE, "<Item>"),
8850 
8851 #if !defined __MINGW32__ && !defined _MSC_VER
8852     WAVE_GTKIFE("/Open Source Definition", NULL, menu_open_sst_hierarchy_source, WV_MENU_OPENHS, "<Item>"),
8853     WAVE_GTKIFE("/Open Source Instantiation", NULL, menu_open_sst_hierarchy_isource, WV_MENU_OPENIHS, "<Item>"),
8854 #endif
8855 };
8856 
8857 
8858 void do_sst_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
8859 {
8860 (void)my_widget;
8861 
8862   GtkWidget *menu;
8863   int button, event_time;
8864 
8865   if(!GLOBALS->sst_signal_popup_menu)
8866     {
8867     int nmenu_items = sizeof(sst_popmenu_items) / sizeof(sst_popmenu_items[0]);
8868 
8869 #if !defined __MINGW32__ && !defined _MSC_VER
8870     if(!GLOBALS->stem_path_string_table)
8871 	{
8872 	nmenu_items-=2; /* remove all stems popups */
8873 	}
8874     else
8875     if(!GLOBALS->istem_struct_base)
8876 	{
8877 	nmenu_items--; /* remove "/Open Source Instantiation" if not present */
8878 	}
8879     /* still have recurse import popup */
8880 #endif
8881 
8882 #ifdef WAVE_USE_MLIST_T
8883     GLOBALS->sst_signal_popup_menu = menu = alt_menu(sst_popmenu_items, nmenu_items, NULL, NULL, FALSE);
8884 #else
8885     GtkItemFactory *item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "<main>", NULL);
8886     gtk_item_factory_create_items (item_factory, nmenu_items, sst_popmenu_items, NULL);
8887     GLOBALS->sst_signal_popup_menu = menu = gtk_item_factory_get_widget (item_factory, "<main>");
8888 #endif
8889     }
8890     else
8891     {
8892     menu = GLOBALS->sst_signal_popup_menu;
8893     }
8894 
8895   if (event)
8896     {
8897       button = event->button;
8898       event_time = event->time;
8899     }
8900   else
8901     {
8902       button = 0;
8903 #if WAVE_USE_GTK2
8904       event_time = gtk_get_current_event_time ();
8905 #else
8906       return; /* disabled in GTK1.2 */
8907 #endif
8908     }
8909 
8910   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
8911                   button, event_time);
8912 }
8913 
8914 #else
8915 
8916 void do_sst_popup_menu (GtkWidget *my_widget, GdkEventButton *event)
8917 {
8918 /* nothing */
8919 }
8920 #endif
8921 
8922 
8923 void SetTraceScrollbarRowValue(int row, unsigned location)
8924 {
8925   if(row >= 0)
8926     {
8927       GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
8928       int target = row;
8929 
8930       int num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight);
8931       num_traces_displayable--;   /* for the time trace that is always there */
8932 
8933       /* center */
8934       if (location == 1) {
8935 	target = target - num_traces_displayable/2;
8936       }
8937 
8938       /* end */
8939       if (location == 2) {
8940 	target = target - num_traces_displayable;
8941       }
8942 
8943       if(target > GLOBALS->traces.visible - num_traces_displayable) target = GLOBALS->traces.visible - num_traces_displayable;
8944 
8945       if(target < 0) target = 0;
8946 
8947       wadj->value = target;
8948 
8949       gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
8950       gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
8951       gtkwave_main_iteration();
8952 
8953     }
8954 }
8955 
8956 
8957 #ifdef WAVE_USE_MLIST_T
8958 
8959 /*
8960  * the following is for the eventual migration to GtkMenu from the item factory.
8961  * all menu features are implemented.
8962  */
8963 
8964 struct menu_item_t
8965 {
8966 struct menu_item_t *next;
8967 struct menu_item_t *child;
8968 
8969 char *name;
8970 int idx;
8971 unsigned valid : 1;
8972 };
8973 
8974 
8975 static void decompose_path(char *pathname, int *items, char ***parts)
8976 {
8977 char *s, **slashes;
8978 int i;
8979 int slashcount = 0;
8980 char *p_copy = strdup_2(pathname);
8981 
8982 s = p_copy;
8983 while(*s)
8984 	{
8985 	if(*s == '/') slashcount++;
8986 	s++;
8987 	}
8988 
8989 *parts = calloc_2(slashcount, sizeof(char *));
8990 slashes = calloc_2(slashcount, sizeof(char *));
8991 
8992 s = p_copy;
8993 slashcount = 0;
8994 while(*s)
8995 	{
8996 	if(*s == '/') slashes[slashcount++] = s;
8997 	s++;
8998 	}
8999 
9000 for(i=0;i<slashcount;i++)
9001 	{
9002 	if(i != (slashcount-1)) *(slashes[i+1]) = 0;
9003 	(*parts)[i] = strdup_2(slashes[i] + 1);
9004 
9005 	if(i != (slashcount-1)) *(slashes[i+1]) = '/';
9006 	}
9007 
9008 *items = slashcount;
9009 
9010 free_2(slashes);
9011 free_2(p_copy);
9012 }
9013 
9014 
9015 static void free_decomposed_path(int items, char **parts)
9016 {
9017 int i;
9018 for(i=0;i<items;i++)
9019 	{
9020 	free_2(parts[i]);
9021 	}
9022 
9023 free_2(parts);
9024 }
9025 
9026 
9027 static void alt_menu_install_accelerator(GtkAccelGroup *accel, GtkWidget *menuitem, const char *accelerator, const char *path)
9028 {
9029 if(accel && menuitem && path)
9030 	{
9031 	int no_map = 0;
9032 	guint accelerator_key = 0;
9033 	GdkModifierType accelerator_mods = 0;
9034 	char full_path[1024];
9035 	sprintf(full_path, "<main>%s", path);
9036 
9037 	if(accelerator)
9038 		{
9039 		gtk_accelerator_parse(accelerator, &accelerator_key, &accelerator_mods);
9040 
9041 #ifdef MAC_INTEGRATION
9042 		if((accelerator_mods & GDK_MOD1_MASK) ||
9043 			(!accelerator_mods) || (accelerator_mods == GDK_SHIFT_MASK))
9044 			{
9045 			no_map = 1; /* ALT not available with GTK menus on OSX? */
9046 				    /* also remove "normal" keys to avoid conflicts with OSX menubar */
9047 			}
9048 		if(accelerator_mods & GDK_CONTROL_MASK)
9049 			{
9050 			accelerator_mods &= ~GDK_CONTROL_MASK;
9051 			accelerator_mods |= GDK_META_MASK;
9052 			}
9053 #endif
9054 		}
9055 
9056 	if(!no_map)
9057 		{
9058 	        gtk_accel_map_add_entry (full_path, accelerator_key, accelerator_mods);
9059 	        gtk_widget_set_accel_path (menuitem, full_path, accel);
9060 		}
9061 	}
9062 }
9063 
9064 static GtkWidget *alt_menu_walk(gtkwave_mlist_t *mi, GtkWidget **wlist, struct menu_item_t *lst, int depth, GtkAccelGroup *accel)
9065 {
9066 struct menu_item_t *ptr = lst;
9067 struct menu_item_t *optr;
9068 GtkWidget *menu;
9069 GtkWidget *menuitem;
9070 
9071 if(depth)
9072 	{
9073 	menu = gtk_menu_new();
9074 
9075 	if(accel) gtk_menu_set_accel_group (GTK_MENU(menu), accel);
9076 	}
9077 	else
9078 	{
9079 	menu = gtk_menu_bar_new();
9080 	}
9081 
9082 while(ptr)
9083 	{
9084 	/*  mi[ptr->idx] is menu item */
9085 
9086 	if(!strcmp(mi[ptr->idx].item_type, "<Separator>"))
9087 		{
9088 #ifdef MAC_INTEGRATION
9089 		menuitem = gtk_separator_menu_item_new();
9090 #else
9091 		menuitem = gtk_menu_item_new();
9092 #endif
9093 		}
9094 		else
9095 		{
9096 		if((!strcmp(mi[ptr->idx].item_type, "<ToggleItem>")) && !ptr->child)
9097 			{
9098 			menuitem = gtk_check_menu_item_new_with_label(ptr->name);
9099 			}
9100 			else
9101 			{
9102 			menuitem = gtk_menu_item_new_with_label(ptr->name);
9103 			}
9104 
9105 		if(!ptr->child && mi[ptr->idx].callback)
9106 			{
9107 		      	g_signal_connect (menuitem, "activate", G_CALLBACK (mi[ptr->idx].callback), (gpointer)(intptr_t)mi[ptr->idx].callback_action);
9108 			alt_menu_install_accelerator(accel, menuitem, mi[ptr->idx].accelerator, mi[ptr->idx].path);
9109 			}
9110 		}
9111 
9112 	gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem);
9113 	gtk_widget_show (menuitem);
9114 
9115 	if(wlist)
9116 		{
9117 		wlist[ptr->idx] = menuitem;
9118 		}
9119 
9120 	if(ptr->child)
9121 		{
9122 		gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), alt_menu_walk(mi, wlist, ptr->child, depth+1, accel));
9123 		}
9124 
9125 	optr = ptr;
9126 	ptr = ptr->next;
9127 
9128 	free_2(optr->name);
9129 	free_2(optr);
9130 	}
9131 
9132 return(menu);
9133 }
9134 
9135 
9136 GtkWidget *alt_menu(gtkwave_mlist_t *mi, int nmenu_items, GtkWidget **wlist, GtkAccelGroup *accel, gboolean is_menubar)
9137 {
9138 int i, j;
9139 struct menu_item_t *mtree = calloc_2(1, sizeof(struct menu_item_t));
9140 struct menu_item_t *n, *n2 = NULL, *n3;
9141 GtkWidget *menubar;
9142 
9143 for(i=0;i<nmenu_items;i++)
9144 	{
9145 	char **parts;
9146 	int items;
9147 
9148 	decompose_path(mi[i].path, &items, &parts);
9149 
9150 	n = mtree;
9151 	for(j=0;j<items;j++)
9152 		{
9153 		assert(n != NULL); /* scan-build */
9154 		if(n->name && (j != (items-1))) /* 2nd comparison is to let separators through */
9155 			{
9156 			n2 = n;
9157 			while(n2)
9158 				{
9159 				if(!strcmp(n2->name, parts[j])) break;
9160 				n2 = n2->next;
9161 				}
9162 			}
9163 			else
9164 			{
9165 			n2 = NULL;
9166 			}
9167 
9168 
9169 		if(!n2)
9170 			{
9171 			n3 = (j != (items-1)) ? calloc_2(1, sizeof(struct menu_item_t)) : NULL;
9172 
9173 			assert(n != NULL); /* scan-build */
9174 			if(n->name)
9175 				{
9176 				while(n->next) { n = n->next; }
9177 				n->next = calloc_2(1, sizeof(struct menu_item_t));
9178 				n = n->next;
9179 				}
9180 			n->name = strdup_2(parts[j]);
9181 			n->child = n3;
9182 
9183 			n2 = n;
9184 			n = n3;
9185 			}
9186 			else
9187 			{
9188 			n = n2->child;
9189 			}
9190 
9191 		}
9192 
9193 	if(n2) /* scan-build */
9194 		{
9195 		n2->idx = i;
9196 		n2->valid = 1;
9197 		}
9198 
9199 	free_decomposed_path(items, parts);
9200 	}
9201 
9202 menubar = alt_menu_walk(mi, wlist, mtree, is_menubar ? 0 : 1, accel); /* returns a menubar */
9203 
9204 return(menubar);
9205 }
9206 
9207 
9208 GtkWidget *alt_menu_top(GtkWidget *window)
9209 {
9210 gtkwave_mlist_t *mi = menu_items;
9211 int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
9212 GtkWidget *menubar;
9213 GtkAccelGroup *global_accel = gtk_accel_group_new();
9214 int i;
9215 GtkWidget *mw;
9216 
9217 menu_wlist = calloc(nmenu_items, sizeof(GtkWidget *)); /* calloc, not calloc_2() */
9218 
9219 menubar = alt_menu(mi, nmenu_items, menu_wlist, global_accel, TRUE);
9220 
9221 GLOBALS->regexp_string_menu_c_1 = calloc_2(1, 129);
9222 
9223 if(GLOBALS->loaded_file_type == MISSING_FILE)
9224 	{
9225 	for(i=0;i<nmenu_items;i++)
9226 		{
9227 		switch(i)
9228 			{
9229 			case WV_MENU_FONVT:
9230 			case WV_MENU_WCLOSE:
9231 #if defined(HAVE_LIBTCL)
9232 	    		case WV_MENU_TCLSCR:
9233 #endif
9234 			case WV_MENU_FQY:
9235 			case WV_MENU_HWH:
9236 #ifdef MAC_INTEGRATION
9237 			case WV_MENU_HWM:
9238 #endif
9239 			case WV_MENU_HWV:
9240 				break;
9241 
9242 			default:
9243 				mw = menu_wlist[i];
9244 				if(mw)
9245 					{
9246 #ifdef MAC_INTEGRATION
9247 					if(menu_items[i].callback)
9248 #endif
9249 						{
9250 						gtk_widget_set_sensitive(mw, FALSE);
9251 						}
9252 					}
9253 				break;
9254 			}
9255 		}
9256 
9257 #ifdef WAVE_USE_MENU_BLACKOUTS
9258 		for(i=0;i<(sizeof(menu_blackouts)/sizeof(char *));i++)
9259 			{
9260 			mw = menu_wlist[i];
9261 			if(mw)
9262 				{
9263 				gtk_widget_set_sensitive(mw, FALSE);
9264 				}
9265 			}
9266 #endif
9267 	}
9268 
9269 if(
9270   (GLOBALS->socket_xid)||
9271   (GLOBALS->partial_vcd))
9272 	{
9273 	gtk_widget_destroy(menu_wlist[WV_MENU_FONVT]); menu_wlist[WV_MENU_FONVT] = NULL;
9274 	}
9275 
9276 if(!GLOBALS->partial_vcd)
9277 	{
9278 	gtk_widget_destroy(menu_wlist[WV_MENU_VZDYN]); menu_wlist[WV_MENU_VZDYN] = NULL;
9279 	gtk_widget_destroy(menu_wlist[WV_MENU_VZDYNE]); menu_wlist[WV_MENU_VZDYNE] = NULL;
9280 	}
9281 
9282 if(GLOBALS->loaded_file_type == DUMPLESS_FILE)
9283 	{
9284 	gtk_widget_destroy(menu_wlist[WV_MENU_FRW]); menu_wlist[WV_MENU_FRW] = NULL;
9285 	}
9286 
9287 if(GLOBALS->loaded_file_type != LXT_FILE)
9288 	{
9289 	gtk_widget_destroy(menu_wlist[WV_MENU_SEP18]); menu_wlist[WV_MENU_SEP18] = NULL;
9290 	gtk_widget_destroy(menu_wlist[WV_MENU_LXTCC2Z]); menu_wlist[WV_MENU_LXTCC2Z] = NULL;
9291 	}
9292 
9293 gtk_window_add_accel_group(GTK_WINDOW(window), global_accel);
9294 
9295 #ifdef MAC_INTEGRATION
9296 #if defined(HAVE_LIBTCL)
9297 gtk_widget_hide(menu_wlist[WV_MENU_TCLSEP]);
9298 #endif
9299 gtk_widget_hide(menu_wlist[WV_MENU_FQY]);
9300 #endif
9301 
9302 set_menu_toggles();
9303 
9304 return(menubar);
9305 }
9306 
9307 #ifdef MAC_INTEGRATION
9308 void osx_menu_sensitivity(gboolean tr)
9309 {
9310 GtkWidget *mw;
9311 int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
9312 int i;
9313 
9314 for(i=0;i<nmenu_items;i++)
9315 	{
9316 	mw = menu_wlist[i];
9317 	if(mw)
9318 		{
9319 		if(menu_items[i].callback)
9320 			{
9321 			gtk_widget_set_sensitive(mw, tr);
9322 			}
9323 		}
9324 	}
9325 }
9326 #endif
9327 
9328 #endif
9329 
9330 
9331 void wave_gtk_grab_add(GtkWidget *w)
9332 {
9333 gtk_grab_add(w);
9334 
9335 #ifdef MAC_INTEGRATION
9336 osx_menu_sensitivity(FALSE);
9337 #endif
9338 }
9339 
9340 void wave_gtk_grab_remove(GtkWidget *w)
9341 {
9342 gtk_grab_remove(w);
9343 
9344 #ifdef MAC_INTEGRATION
9345 if(GLOBALS->loaded_file_type != MISSING_FILE)
9346 	{
9347 	osx_menu_sensitivity(TRUE);
9348 	}
9349 	else
9350 	{
9351 	int i;
9352 	GtkWidget *mw;
9353 	int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
9354 
9355 	for(i=0;i<nmenu_items;i++)
9356 		{
9357 		switch(i)
9358 			{
9359 			case WV_MENU_FONVT:
9360 			case WV_MENU_WCLOSE:
9361 #if defined(HAVE_LIBTCL)
9362 	    		case WV_MENU_TCLSCR:
9363 #endif
9364 			case WV_MENU_FQY:
9365 			case WV_MENU_HWH:
9366 #ifdef MAC_INTEGRATION
9367 			case WV_MENU_HWM:
9368 #endif
9369 			case WV_MENU_HWV:
9370 				mw = menu_wlist[i];
9371 				if(mw)
9372 					{
9373 #ifdef MAC_INTEGRATION
9374 					if(menu_items[i].callback)
9375 #endif
9376 						{
9377 						gtk_widget_set_sensitive(mw, TRUE);
9378 						}
9379 					}
9380 				break;
9381 
9382 			default:
9383 				break;
9384 			}
9385 		}
9386 	}
9387 #endif
9388 }
9389