1 /*
2  * Copyright (c) Tony Bybell 1999-2019.
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 #include <config.h>
11 #include "globals.h"
12 #include "gtk12compat.h"
13 #include "currenttime.h"
14 #include "pixmaps.h"
15 #include "symbol.h"
16 #include "bsearch.h"
17 #include "color.h"
18 #include "rc.h"
19 #include "strace.h"
20 #include "debug.h"
21 #include "main.h"
22 
23 #if !defined _ISOC99_SOURCE
24 #define _ISOC99_SOURCE 1
25 #endif
26 #include <math.h>
27 
28 static void rendertimebar(void);
29 static void draw_hptr_trace(Trptr t, hptr h, int which, int dodraw, int kill_grid);
30 static void draw_hptr_trace_vector(Trptr t, hptr h, int which);
31 static void draw_vptr_trace(Trptr t, vptr v, int which);
32 static void rendertraces(void);
33 static void rendertimes(void);
34 
35 static const GdkModifierType   bmask[4]= {0, GDK_BUTTON1_MASK, 0, GDK_BUTTON3_MASK };                   /* button 1, 3 press/rel encodings */
36 static const GdkEventMask    m_bmask[4]= {0, GDK_BUTTON1_MOTION_MASK, 0, GDK_BUTTON3_MOTION_MASK };     /* button 1, 3 motion encodings */
37 
38 /******************************************************************/
39 
update_dual(void)40 static void update_dual(void)
41 {
42 if(GLOBALS->dual_ctx && !GLOBALS->dual_race_lock)
43         {
44         GLOBALS->dual_ctx[GLOBALS->dual_id].zoom = GLOBALS->tims.zoom;
45         GLOBALS->dual_ctx[GLOBALS->dual_id].marker = GLOBALS->tims.marker;
46         GLOBALS->dual_ctx[GLOBALS->dual_id].baseline = GLOBALS->tims.baseline;
47         GLOBALS->dual_ctx[GLOBALS->dual_id].left_margin_time = GLOBALS->tims.start;
48         GLOBALS->dual_ctx[GLOBALS->dual_id].use_new_times = 1;
49         }
50 }
51 
52 /******************************************************************/
53 
54 #ifdef WAVE_USE_GTK2
55 
56 static void (*draw_slider_p)    (GtkStyle               *style,
57                                  GdkWindow              *window,
58                                  GtkStateType            state_type,
59                                  GtkShadowType           shadow_type,
60                                  GdkRectangle           *area,
61                                  GtkWidget              *widget,
62                                  const gchar            *detail,
63                                  gint                    x,
64                                  gint                    y,
65                                  gint                    width,
66                                  gint                    height,
67                                  GtkOrientation          orientation) = NULL; /* This is intended to be global...only needed once per toolkit */
68 
69 
draw_slider(GtkStyle * style,GdkWindow * window,GtkStateType state_type,GtkShadowType shadow_type,GdkRectangle * area,GtkWidget * widget,const gchar * detail,gint x,gint y,gint width,gint height,GtkOrientation orientation)70 static void draw_slider         (GtkStyle               *style,
71                                  GdkWindow              *window,
72                                  GtkStateType            state_type,
73                                  GtkShadowType           shadow_type,
74                                  GdkRectangle           *area,
75                                  GtkWidget              *widget,
76                                  const gchar            *detail,
77                                  gint                    x,
78                                  gint                    y,
79                                  gint                    width,
80                                  gint                    height,
81                                  GtkOrientation          orientation)
82 {
83 if((GLOBALS)&&(widget == GLOBALS->hscroll_wavewindow_c_2))
84 	{
85 	GLOBALS->str_wid_x = x - widget->allocation.x;
86 	GLOBALS->str_wid_width = width;
87 	GLOBALS->str_wid_bigw = widget->allocation.width;
88 	GLOBALS->str_wid_height = height;
89 	}
90 
91 draw_slider_p(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
92 }
93 
94 
slider_bpr(GtkWidget * widget,GdkEventButton * event)95 static gint slider_bpr(GtkWidget *widget, GdkEventButton *event)
96 {
97 (void)widget;
98 
99 int xi = event->x;
100 int xl = GLOBALS->str_wid_x;
101 int xr = GLOBALS->str_wid_x + GLOBALS->str_wid_width;
102 
103 if((xi > (xr-8)) && (xi < (xr+8)))
104 	{
105 	GLOBALS->str_wid_state = 1;
106 	return(TRUE);
107 	}
108 else if((xi < (xl+8)) && (xi > (xl-8)))
109 	{
110 	GLOBALS->str_wid_state = -1;
111 	return(TRUE);
112 	}
113 
114 return(FALSE);
115 }
116 
117 
slider_brr(GtkWidget * widget,GdkEventButton * event)118 static gint slider_brr(GtkWidget *widget, GdkEventButton *event)
119 {
120 (void)widget;
121 (void)event;
122 
123 GLOBALS->str_wid_state = 0;
124 return(FALSE);
125 }
126 
127 
slider_mnr(GtkWidget * widget,GdkEventMotion * event)128 static gint slider_mnr(GtkWidget *widget, GdkEventMotion *event)
129 {
130 (void)widget;
131 
132 #ifndef WAVE_USE_GTK2
133 gdouble x, y;
134 #endif
135 GdkModifierType state;
136 gdouble my_x, xmax, ratio;
137 TimeType l_margin, r_margin;
138 
139 #ifdef WAVE_USE_GTK2
140 gint xi, yi;
141 #endif
142 
143 int dummy_x, dummy_y;
144 get_window_xypos(&dummy_x, &dummy_y);
145 
146 if(event->is_hint)
147         {
148         WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state);
149 #ifndef WAVE_USE_GTK2
150         WAVE_GDK_GET_POINTER_COPY;
151 #endif
152         }
153         else
154         {
155         /* x = event->x; */ /* scan-build */
156         /* y = event->y; */ /* scan-build */
157         state = event->state;
158         }
159 
160 if((GLOBALS->str_wid_state)&&(!(state & (GDK_BUTTON1_MASK|GDK_BUTTON3_MASK))))
161 	{
162 	GLOBALS->str_wid_state = 0;
163 	}
164 
165 if(GLOBALS->str_wid_state == 1)
166 	{
167 	my_x = event->x - GLOBALS->str_wid_height;
168 	xmax = GLOBALS->str_wid_bigw - (2*GLOBALS->str_wid_height) - GLOBALS->str_wid_slider;
169 	if(xmax > 1.0)
170 		{
171 		ratio = my_x/xmax;
172 		r_margin = (gdouble)(GLOBALS->tims.last - GLOBALS->tims.first) * ratio + GLOBALS->tims.first;
173 		if((r_margin > GLOBALS->tims.start) && (r_margin <= GLOBALS->tims.last))
174 			{
175 			service_dragzoom(GLOBALS->tims.start, r_margin);
176 			}
177 		return(TRUE);
178 		}
179 	}
180 else
181 if(GLOBALS->str_wid_state == -1)
182 	{
183 	my_x = event->x - GLOBALS->str_wid_height;
184 	xmax = GLOBALS->str_wid_bigw - (2*GLOBALS->str_wid_height) - GLOBALS->str_wid_slider;
185 	if(xmax > 1.0)
186 		{
187 		ratio = my_x/xmax;
188 		l_margin = (gdouble)(GLOBALS->tims.last - GLOBALS->tims.first) * ratio + GLOBALS->tims.first;
189 		r_margin = GLOBALS->tims.end;
190 		if((l_margin >= GLOBALS->tims.first) && (l_margin < GLOBALS->tims.end))
191 			{
192 			if(r_margin > GLOBALS->tims.last) r_margin = GLOBALS->tims.last;
193 			service_dragzoom(l_margin, r_margin);
194 			}
195 		return(TRUE);
196 		}
197 	}
198 
199 return(FALSE);
200 }
201 
202 #endif
203 
204 /******************************************************************/
205 
206 /*
207  * gtk_draw_line() acceleration for win32 by doing draw combining
208  * now always enabled.  if there need to be an exact correlation
209  * between this and the printed data, this needs to be disabled.
210  */
211 #if 1
212 
213 #define WAVE_SEG_BUF_CNT 1024
214 
215 static int seg_trans_cnt = 0, seg_low_cnt = 0, seg_high_cnt = 0, seg_mid_cnt = 0, seg_x_cnt = 0, seg_vtrans_cnt
216 = 0, seg_0_cnt = 0, seg_1_cnt = 0, seg_vbox_cnt = 0;
217 
218 static GdkSegment seg_trans[WAVE_SEG_BUF_CNT], seg_low[WAVE_SEG_BUF_CNT], seg_high[WAVE_SEG_BUF_CNT],
219 seg_mid[WAVE_SEG_BUF_CNT], seg_x[WAVE_SEG_BUF_CNT], seg_vtrans[WAVE_SEG_BUF_CNT], seg_0[WAVE_SEG_BUF_CNT],
220 seg_1[WAVE_SEG_BUF_CNT], seg_vbox[WAVE_SEG_BUF_CNT];
221 
222 
wave_gdk_draw_line(GdkDrawable * drawable,GdkGC * gc,gint _x1,gint _y1,gint _x2,gint _y2)223 static void wave_gdk_draw_line(GdkDrawable *drawable, GdkGC *gc, gint _x1, gint _y1, gint _x2, gint _y2)
224 {
225 GdkSegment *seg;
226 int *seg_cnt;
227 
228 if(gc==GLOBALS->gc.gc_trans_wavewindow_c_1) 	{ seg = seg_trans; seg_cnt = &seg_trans_cnt; }
229 else if(gc==GLOBALS->gc.gc_low_wavewindow_c_1) 	{ seg = seg_low; seg_cnt = &seg_low_cnt; }
230 else if(gc==GLOBALS->gc.gc_high_wavewindow_c_1) { seg = seg_high; seg_cnt = &seg_high_cnt; }
231 else if(gc==GLOBALS->gc.gc_mid_wavewindow_c_1) 	{ seg = seg_mid; seg_cnt = &seg_mid_cnt; }
232 else if(gc == GLOBALS->gc.gc_x_wavewindow_c_1)	{ seg = seg_x; seg_cnt = &seg_x_cnt; }
233 else if(gc == GLOBALS->gc.gc_vtrans_wavewindow_c_1){ seg = seg_vtrans; seg_cnt = &seg_vtrans_cnt; }
234 else if(gc == GLOBALS->gc.gc_0_wavewindow_c_1) 	{ seg = seg_0;  seg_cnt = &seg_0_cnt; }
235 else if(gc == GLOBALS->gc.gc_1_wavewindow_c_1)	{ seg = seg_1; seg_cnt = &seg_1_cnt; }
236 else if(gc == GLOBALS->gc.gc_vbox_wavewindow_c_1){ seg = seg_vbox; seg_cnt = &seg_vbox_cnt; }
237 else 						{ gdk_draw_line(drawable, gc, _x1, _y1, _x2, _y2); return; }
238 
239 seg[*seg_cnt].x1 = _x1;
240 seg[*seg_cnt].y1 = _y1;
241 seg[*seg_cnt].x2 = _x2;
242 seg[*seg_cnt].y2 = _y2;
243 (*seg_cnt)++;
244 
245 if(*seg_cnt == WAVE_SEG_BUF_CNT)
246 	{
247 	gdk_draw_segments(drawable, gc, seg, *seg_cnt);
248 	*seg_cnt = 0;
249 	}
250 }
251 
wave_gdk_draw_line_flush(GdkDrawable * drawable)252 static void wave_gdk_draw_line_flush(GdkDrawable *drawable)
253 {
254 if(seg_vtrans_cnt)
255 	{
256 	gdk_draw_segments (drawable, GLOBALS->gc.gc_vtrans_wavewindow_c_1, seg_vtrans, seg_vtrans_cnt);
257 	seg_vtrans_cnt = 0;
258 	}
259 
260 if(seg_mid_cnt)
261 	{
262 	gdk_draw_segments(drawable, GLOBALS->gc.gc_mid_wavewindow_c_1, seg_mid, seg_mid_cnt);
263 	seg_mid_cnt = 0;
264 	}
265 
266 if(seg_high_cnt)
267 	{
268 	gdk_draw_segments(drawable, GLOBALS->gc.gc_high_wavewindow_c_1, seg_high, seg_high_cnt);
269 	seg_high_cnt = 0;
270 	}
271 
272 if(seg_low_cnt)
273 	{
274 	gdk_draw_segments(drawable, GLOBALS->gc.gc_low_wavewindow_c_1, seg_low, seg_low_cnt);
275 	seg_low_cnt = 0;
276 	}
277 
278 if(seg_trans_cnt)
279 	{
280 	gdk_draw_segments(drawable, GLOBALS->gc.gc_trans_wavewindow_c_1, seg_trans, seg_trans_cnt);
281 	seg_trans_cnt = 0;
282 	}
283 
284 if(seg_0_cnt)
285 	{
286 	gdk_draw_segments (drawable, GLOBALS->gc.gc_0_wavewindow_c_1, seg_0, seg_0_cnt);
287 	seg_0_cnt = 0;
288 	}
289 
290 if(seg_1_cnt)
291 	{
292 	gdk_draw_segments (drawable, GLOBALS->gc.gc_1_wavewindow_c_1, seg_1, seg_1_cnt);
293 	seg_1_cnt = 0;
294 	}
295 
296 /* place x down here to propagate them over low/high transitions */
297 
298 if(seg_x_cnt)
299 	{
300 	gdk_draw_segments (drawable, GLOBALS->gc.gc_x_wavewindow_c_1, seg_x, seg_x_cnt);
301 	seg_x_cnt = 0;
302 	}
303 
304 if(seg_vbox_cnt)
305 	{
306 	gdk_draw_segments (drawable, GLOBALS->gc.gc_vbox_wavewindow_c_1, seg_vbox, seg_vbox_cnt);
307 	seg_vbox_cnt = 0;
308 	}
309 }
310 
311 #else
312 
313 /* completely unnecessary for linux ... unless there are extremely dense traces */
314 
315 #define wave_gdk_draw_line(a,b,c,d,e,f) gdk_draw_line(a,b,c,d,e,f)
316 #define wave_gdk_draw_line_flush(x)
317 
318 #endif
319 
320 /******************************************************************/
321 
322 
323 /*
324  * aldec-like "snap" feature...
325  */
cook_markertime(TimeType marker,gint x,gint y)326 TimeType cook_markertime(TimeType marker, gint x, gint y)
327 {
328 int i, num_traces_displayable;
329 Trptr t = NULL;
330 TimeType lft, rgh;
331 char lftinv, rghinv;
332 gdouble xlft, xrgh;
333 gdouble xlftd, xrghd;
334 TimeType closest_named = MAX_HISTENT_TIME;
335 int closest_which = -1;
336 gint xold = x, yold = y;
337 TraceEnt t_trans;
338 
339 if(!GLOBALS->cursor_snap) return(marker);
340 
341 /* potential snapping to a named marker time */
342 for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
343 	{
344 	if(GLOBALS->named_markers[i] != -1)
345 		{
346 		TimeType dlt;
347 
348 		if((GLOBALS->named_markers[i]>=GLOBALS->tims.start)&&(GLOBALS->named_markers[i]<=GLOBALS->tims.end)&&(GLOBALS->named_markers[i]<=GLOBALS->tims.last))
349 			{
350 			if(marker < GLOBALS->named_markers[i])
351 				{
352 				dlt = GLOBALS->named_markers[i] - marker;
353 				}
354 				else
355 				{
356 				dlt = marker - GLOBALS->named_markers[i];
357 				}
358 
359 			if(dlt < closest_named)
360 				{
361 				closest_named = dlt;
362 				closest_which = i;
363 				}
364 			}
365 		}
366 	}
367 
368 num_traces_displayable=GLOBALS->wavearea->allocation.height/(GLOBALS->fontheight);
369 num_traces_displayable--;   /* for the time trace that is always there */
370 
371 y-=GLOBALS->fontheight;
372 if(y<0) y=0;
373 y/=GLOBALS->fontheight;		    /* y now indicates the trace in question */
374 if(y>num_traces_displayable) y=num_traces_displayable;
375 
376 t=GLOBALS->topmost_trace;
377 for(i=0;i<y;i++)
378 	{
379 	if(!t) goto bot;
380 	t=GiveNextTrace(t);
381 	}
382 
383 if(!t) goto bot;
384 if((t->flags&(/*TR_BLANK|*/TR_EXCLUDE))) /* TR_BLANK removed because of transaction handling below... */
385 	{
386 	t = NULL;
387 	goto bot;
388 	}
389 
390 if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))  /* seek to real xact trace if present... */
391         {
392 	Trptr tscan = t;
393 	int bcnt = 0;
394         while((tscan) && (tscan = GivePrevTrace(tscan)))
395                 {
396                 if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
397                         {
398                         if(tscan->flags & TR_TTRANSLATED)
399                                 {
400                                 break; /* found it */
401                                 }
402                                 else
403                                 {
404                                 tscan = NULL;
405                                 }
406                         }
407 			else
408 			{
409 			bcnt++; /* bcnt is number of blank traces */
410 			}
411                 }
412 
413 	if((tscan)&&(tscan->vector))
414 		{
415 		bvptr bv = tscan->n.vec;
416 		do
417 			{
418 			bv = bv->transaction_chain; /* correlate to blank trace */
419 			} while(bv && (bcnt--));
420 		if(bv)
421 			{
422 			memcpy(&t_trans, tscan, sizeof(TraceEnt)); /* substitute into a synthetic trace */
423 			t_trans.n.vec = bv;
424 			t_trans.vector = 1;
425 
426                         t_trans.name = bv->bvname;
427                         if(GLOBALS->hier_max_level)
428                         	t_trans.name = hier_extract(t_trans.name, GLOBALS->hier_max_level);
429 
430 			t = &t_trans;
431 			goto process_trace;
432 			}
433 		}
434         }
435 
436 if((t->flags&TR_BLANK))
437         {
438         t = NULL;
439         goto bot;
440         }
441 
442 if(t->flags & TR_ANALOG_BLANK_STRETCH)	/* seek to real analog trace if present... */
443 	{
444 	while((t) && (t = GivePrevTrace(t)))
445 		{
446 		if(!(t->flags & TR_ANALOG_BLANK_STRETCH))
447 			{
448 			if(t->flags & TR_ANALOGMASK)
449 				{
450 				break; /* found it */
451 				}
452 				else
453 				{
454 				t = NULL;
455 				}
456 			}
457 		}
458 	}
459 if(!t) goto bot;
460 
461 process_trace:
462 if(t->vector)
463 	{
464 	vptr v = bsearch_vector(t->n.vec, marker - t->shift);
465 	vptr v2 = v ? v->next : NULL;
466 
467 	if((!v)||(!v2)) goto bot;	/* should never happen */
468 
469 	lft = v->time;
470 	rgh = v2->time;
471 	}
472 	else
473 	{
474 	hptr h = bsearch_node(t->n.nd, marker - t->shift);
475 	hptr h2 = h ? h->next : NULL;
476 
477 	if((!h)||(!h2)) goto bot;	/* should never happen */
478 
479 	lft = h->time;
480 	rgh = h2->time;
481 	}
482 
483 
484 lftinv = (lft < (GLOBALS->tims.start - t->shift))||(lft >= (GLOBALS->tims.end - t->shift))||(lft >= (GLOBALS->tims.last - t->shift));
485 rghinv = (rgh < (GLOBALS->tims.start - t->shift))||(rgh >= (GLOBALS->tims.end - t->shift))||(rgh >= (GLOBALS->tims.last - t->shift));
486 
487 xlft = (lft + t->shift - GLOBALS->tims.start) * GLOBALS->pxns;
488 xrgh = (rgh + t->shift - GLOBALS->tims.start) * GLOBALS->pxns;
489 
490 xlftd = xlft - x;
491 if(xlftd<(gdouble)0.0) xlftd = ((gdouble)0.0) - xlftd;
492 
493 xrghd = xrgh - x;
494 if(xrghd<(gdouble)0.0) xrghd = ((gdouble)0.0) - xrghd;
495 
496 if(xlftd<=xrghd)
497 	{
498 	if((!lftinv)&&(xlftd<=GLOBALS->cursor_snap))
499 		{
500 		if(closest_which >= 0)
501 		        {
502         		if((closest_named * GLOBALS->pxns) < xlftd)
503                 		{
504                 		marker = GLOBALS->named_markers[closest_which];
505 				goto xit;
506                 		}
507 			}
508 
509 		marker = lft + t->shift;
510 		goto xit;
511 		}
512 	}
513 	else
514 	{
515 	if((!rghinv)&&(xrghd<=GLOBALS->cursor_snap))
516 		{
517 		if(closest_which >= 0)
518 		        {
519         		if((closest_named * GLOBALS->pxns) < xrghd)
520                 		{
521                 		marker = GLOBALS->named_markers[closest_which];
522 				goto xit;
523                 		}
524 			}
525 
526 		marker = rgh + t->shift;
527 		goto xit;
528 		}
529 	}
530 
531 bot:
532 if(closest_which >= 0)
533 	{
534 	if((closest_named * GLOBALS->pxns) <= GLOBALS->cursor_snap)
535 		{
536 		marker = GLOBALS->named_markers[closest_which];
537 		}
538 	}
539 
540 xit:
541 GLOBALS->mouseover_counter = -1;
542 move_mouseover(t, xold, yold, marker);
543 return(marker);
544 }
545 
render_individual_named_marker(int i,GdkGC * gc,int blackout)546 static void render_individual_named_marker(int i, GdkGC *gc, int blackout)
547 {
548 gdouble pixstep;
549 gint xl, y;
550 TimeType t;
551 
552 if((t=GLOBALS->named_markers[i])!=-1)
553 	{
554 	if((t>=GLOBALS->tims.start)&&(t<=GLOBALS->tims.last)
555 		&&(t<=GLOBALS->tims.end))
556 		{
557 		/* this needs to be here rather than outside the loop as gcc does some
558 		   optimizations that cause it to calculate slightly different from the marker if it's not here */
559 		pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe);
560 
561 		xl=((gdouble)(t-GLOBALS->tims.start))/pixstep;     /* snap to integer */
562 		if((xl>=0)&&(xl<GLOBALS->wavewidth))
563 			{
564 			char nbuff[16];
565 			make_bijective_marker_id_string(nbuff, i);
566 
567 			for(y=GLOBALS->fontheight-1;y<=GLOBALS->waveheight-1;y+=8)
568 				{
569 				gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1,
570 					gc,
571         	        		xl, y, xl, y+5);
572 				}
573 
574 			if((!GLOBALS->marker_names[i])||(!GLOBALS->marker_names[i][0]))
575 				{
576 				font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->wavefont_smaller,
577 					gc,
578 					xl-(font_engine_string_measure(GLOBALS->wavefont_smaller, nbuff)>>1),
579 					GLOBALS->fontheight-2, nbuff);
580 				}
581 				else
582 				{
583 				int width = font_engine_string_measure(GLOBALS->wavefont_smaller, GLOBALS->marker_names[i]);
584 				if(blackout) /* blackout background so text is legible if overlaid with other marker labels */
585 					{
586 					gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_timeb_wavewindow_c_1, TRUE,
587 						xl-(width>>1), GLOBALS->fontheight-2-GLOBALS->wavefont_smaller->ascent,
588 						width, GLOBALS->wavefont_smaller->ascent + GLOBALS->wavefont_smaller->descent);
589 					}
590 
591 				font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->wavefont_smaller,
592 					gc,
593 					xl-(width>>1),
594 					GLOBALS->fontheight-2, GLOBALS->marker_names[i]);
595 				}
596 			}
597 		}
598 	}
599 }
600 
draw_named_markers(void)601 static void draw_named_markers(void)
602 {
603 int i;
604 
605 if(!GLOBALS->wavepixmap_wavewindow_c_1) return;
606 
607 for(i=0;i<WAVE_NUM_NAMED_MARKERS;i++)
608 	{
609 	if(i != GLOBALS->named_marker_lock_idx)
610 		{
611 		render_individual_named_marker(i, GLOBALS->gc.gc_mark_wavewindow_c_1, 0);
612 		}
613 	}
614 
615 if(GLOBALS->named_marker_lock_idx >= 0)
616 	{
617 	render_individual_named_marker(GLOBALS->named_marker_lock_idx, GLOBALS->gc.gc_umark_wavewindow_c_1, 1);
618 	}
619 }
620 
621 
sync_marker(void)622 static void sync_marker(void)
623 {
624 if((GLOBALS->tims.prevmarker==-1)&&(GLOBALS->tims.marker!=-1))
625 	{
626 	GLOBALS->signalwindow_width_dirty=1;
627 	}
628 	else
629 if((GLOBALS->tims.marker==-1)&&(GLOBALS->tims.prevmarker!=-1))
630 	{
631 	GLOBALS->signalwindow_width_dirty=1;
632 	}
633 GLOBALS->tims.prevmarker=GLOBALS->tims.marker;
634 
635 /* additional case for race conditions with MaxSignalLength */
636 if(((GLOBALS->tims.resizemarker==-1)||(GLOBALS->tims.resizemarker2==-1)) && (GLOBALS->tims.resizemarker!=GLOBALS->tims.resizemarker2))
637 	{
638 	GLOBALS->signalwindow_width_dirty=1;
639 	}
640 }
641 
642 
draw_marker(void)643 static void draw_marker(void)
644 {
645 gdouble pixstep;
646 gint xl;
647 
648 if(!GLOBALS->wavearea->window) return;
649 
650 GLOBALS->m1x_wavewindow_c_1=GLOBALS->m2x_wavewindow_c_1=-1;
651 
652 if(GLOBALS->tims.baseline>=0)
653 	{
654 	if((GLOBALS->tims.baseline>=GLOBALS->tims.start)&&(GLOBALS->tims.baseline<=GLOBALS->tims.last)
655 		&&(GLOBALS->tims.baseline<=GLOBALS->tims.end))
656 		{
657 		pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe);
658 		xl=((gdouble)(GLOBALS->tims.baseline-GLOBALS->tims.start))/pixstep;     /* snap to integer */
659 		if((xl>=0)&&(xl<GLOBALS->wavewidth))
660 			{
661 			gdk_draw_line(GLOBALS->wavearea->window,GLOBALS->gc.gc_baseline_wavewindow_c_1,xl, GLOBALS->fontheight-1, xl, GLOBALS->waveheight-1);
662 			}
663 		}
664 	}
665 
666 if(GLOBALS->tims.marker>=0)
667 	{
668 	if((GLOBALS->tims.marker>=GLOBALS->tims.start)&&(GLOBALS->tims.marker<=GLOBALS->tims.last)
669 		&&(GLOBALS->tims.marker<=GLOBALS->tims.end))
670 		{
671 		pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe);
672 		xl=((gdouble)(GLOBALS->tims.marker-GLOBALS->tims.start))/pixstep;     /* snap to integer */
673 		if((xl>=0)&&(xl<GLOBALS->wavewidth))
674 			{
675 			gdk_draw_line(GLOBALS->wavearea->window,GLOBALS->gc.gc_umark_wavewindow_c_1,xl, GLOBALS->fontheight-1, xl, GLOBALS->waveheight-1);
676 			GLOBALS->m1x_wavewindow_c_1=xl;
677 			}
678 		}
679 	}
680 
681 
682 if((GLOBALS->enable_ghost_marker)&&(GLOBALS->in_button_press_wavewindow_c_1)&&(GLOBALS->tims.lmbcache>=0))
683 	{
684 	if((GLOBALS->tims.lmbcache>=GLOBALS->tims.start)&&(GLOBALS->tims.lmbcache<=GLOBALS->tims.last)
685 		&&(GLOBALS->tims.lmbcache<=GLOBALS->tims.end))
686 		{
687 		pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe);
688 		xl=((gdouble)(GLOBALS->tims.lmbcache-GLOBALS->tims.start))/pixstep;     /* snap to integer */
689 		if((xl>=0)&&(xl<GLOBALS->wavewidth))
690 			{
691 			gdk_draw_line(GLOBALS->wavearea->window,GLOBALS->gc.gc_umark_wavewindow_c_1,xl, GLOBALS->fontheight-1, xl, GLOBALS->waveheight-1);
692 			GLOBALS->m2x_wavewindow_c_1=xl;
693 			}
694 		}
695 	}
696 
697 if(GLOBALS->m1x_wavewindow_c_1>GLOBALS->m2x_wavewindow_c_1)		/* ensure m1x <= m2x for partitioned refresh */
698 	{
699 	gint t;
700 
701 	t=GLOBALS->m1x_wavewindow_c_1;
702 	GLOBALS->m1x_wavewindow_c_1=GLOBALS->m2x_wavewindow_c_1;
703 	GLOBALS->m2x_wavewindow_c_1=t;
704 	}
705 
706 if(GLOBALS->m1x_wavewindow_c_1==-1) GLOBALS->m1x_wavewindow_c_1=GLOBALS->m2x_wavewindow_c_1;	/* make both markers same if no ghost marker or v.v. */
707 
708 update_dual();
709 }
710 
711 
draw_marker_partitions(void)712 static void draw_marker_partitions(void)
713 {
714 draw_marker();
715 
716 if(GLOBALS->m1x_wavewindow_c_1==GLOBALS->m2x_wavewindow_c_1)
717 	{
718 	gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1, 0, GLOBALS->m1x_wavewindow_c_1, 0, 1, GLOBALS->fontheight-2);
719 
720 	if(GLOBALS->m1x_wavewindow_c_1<0)
721 		{
722 		gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->wavewidth, GLOBALS->waveheight);
723 		}
724 		else
725 		{
726 		if(GLOBALS->m1x_wavewindow_c_1==0)
727 			{
728 			gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 1, 0, 1, 0, GLOBALS->wavewidth-1, GLOBALS->waveheight);
729 			}
730 		else
731 		if(GLOBALS->m1x_wavewindow_c_1==GLOBALS->wavewidth-1)
732 			{
733 
734 			gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->wavewidth-1, GLOBALS->waveheight);
735 			}
736 		else
737 			{
738 			gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->m1x_wavewindow_c_1, GLOBALS->waveheight);
739 			gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->wavewidth-GLOBALS->m1x_wavewindow_c_1-1, GLOBALS->waveheight);
740 			}
741 		}
742 	}
743 	else
744 	{
745 	gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1, 0, GLOBALS->m1x_wavewindow_c_1, 0, 1, GLOBALS->fontheight-2);
746 	gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m2x_wavewindow_c_1, 0, GLOBALS->m2x_wavewindow_c_1, 0, 1, GLOBALS->fontheight-2);
747 
748 	if(GLOBALS->m1x_wavewindow_c_1>0)
749 		{
750 		gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->m1x_wavewindow_c_1, GLOBALS->waveheight);
751 		}
752 
753 	if(GLOBALS->m2x_wavewindow_c_1-GLOBALS->m1x_wavewindow_c_1>1)
754 		{
755 		gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->m2x_wavewindow_c_1-GLOBALS->m1x_wavewindow_c_1-1, GLOBALS->waveheight);
756 		}
757 
758 	if(GLOBALS->m2x_wavewindow_c_1!=GLOBALS->wavewidth-1)
759 		{
760 		gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m2x_wavewindow_c_1+1, 0, GLOBALS->m2x_wavewindow_c_1+1, 0, GLOBALS->wavewidth-GLOBALS->m2x_wavewindow_c_1-1, GLOBALS->waveheight);
761 		}
762 	}
763 
764 /* keep baseline from getting obliterated */
765 #ifndef WAVE_DOUBLE_LINE_WIDTH_MODE
766 if(GLOBALS->tims.baseline>=0)
767 #endif
768 	{
769 	draw_marker();
770 	}
771 }
772 
renderblackout(void)773 static void renderblackout(void)
774 {
775 gfloat pageinc;
776 TimeType lhs, rhs, lclip, rclip;
777 struct blackout_region_t *bt = GLOBALS->blackout_regions;
778 
779 if(bt)
780 	{
781 	pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
782 	lhs = GLOBALS->tims.start;
783 	rhs = pageinc + lhs;
784 
785 	while(bt)
786 		{
787 		if((bt->bend < lhs) || (bt->bstart > rhs))
788 			{
789 			/* nothing, out of bounds */
790 			}
791 			else
792 			{
793 			lclip = bt->bstart; rclip = bt->bend;
794 
795 			if(lclip < lhs) lclip = lhs;
796 				else if (lclip > rhs) lclip = rhs;
797 
798 			if(rclip < lhs) rclip = lhs;
799 
800 			lclip -= lhs;
801 			rclip -= lhs;
802 			if(rclip>((GLOBALS->wavewidth+1)*GLOBALS->nspx)) rclip = (GLOBALS->wavewidth+1)*(GLOBALS->nspx);
803 
804 			gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_xfill_wavewindow_c_1, TRUE, (((gdouble)lclip)*GLOBALS->pxns), GLOBALS->fontheight,(((gdouble)(rclip-lclip))*GLOBALS->pxns), GLOBALS->waveheight-GLOBALS->fontheight);
805 			}
806 
807 		bt=bt->next;
808 		}
809 	}
810 }
811 
812 static void
service_hslider(GtkWidget * text,gpointer data)813 service_hslider(GtkWidget *text, gpointer data)
814 {
815 (void)text;
816 (void)data;
817 
818 DEBUG(printf("Wave HSlider Moved\n"));
819 
820 if((GLOBALS->wavepixmap_wavewindow_c_1)&&(GLOBALS->wavewidth>1))
821 	{
822 	GtkAdjustment *hadj;
823 
824 	hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider);
825 
826 	if(!GLOBALS->tims.timecache)
827 		{
828 		GLOBALS->tims.start=time_trunc(hadj->value);
829 		}
830 		else
831 		{
832 		GLOBALS->tims.start=time_trunc(GLOBALS->tims.timecache);
833 		GLOBALS->tims.timecache=0;	/* reset */
834 		}
835 
836 	if(GLOBALS->tims.start<GLOBALS->tims.first) GLOBALS->tims.start=GLOBALS->tims.first;
837 		else if(GLOBALS->tims.start>GLOBALS->tims.last) GLOBALS->tims.start=GLOBALS->tims.last;
838 
839 	GLOBALS->tims.laststart=GLOBALS->tims.start;
840 
841 	gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_back_wavewindow_c_1, TRUE, 0, 0,GLOBALS->wavewidth, GLOBALS->waveheight);
842 	rendertimebar();
843 	}
844 }
845 
846 static void
service_vslider(GtkWidget * text,gpointer data)847 service_vslider(GtkWidget *text, gpointer data)
848 {
849 (void)text;
850 (void)data;
851 
852 GtkAdjustment *sadj, *hadj;
853 int trtarget;
854 int xsrc;
855 
856 if(GLOBALS->signalpixmap)
857 	{
858 	hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
859 	sadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
860 	xsrc=(gint)hadj->value;
861 
862 	trtarget=(int)(sadj->value);
863 	DEBUG(printf("Wave VSlider Moved to %d\n",trtarget));
864 
865 		gdk_draw_rectangle(GLOBALS->signalpixmap,
866 			GLOBALS->gc.gc_ltgray, TRUE, 0, 0,
867 	            	GLOBALS->signal_fill_width, GLOBALS->signalarea->allocation.height);
868 
869 		sync_marker();
870 		RenderSigs(trtarget,(GLOBALS->old_wvalue==sadj->value)?0:1);
871 
872 	GLOBALS->old_wvalue=sadj->value;
873 
874 		draw_named_markers();
875 
876 		if(GLOBALS->signalarea_has_focus)
877 			{
878 			gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],
879 		                GLOBALS->signalpixmap,
880 				xsrc+1, 0+1,
881 				0+1, 0+1,
882 		                GLOBALS->signalarea->allocation.width-2, GLOBALS->signalarea->allocation.height-2);
883 			draw_signalarea_focus();
884 			}
885 			else
886 			{
887 			gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],
888 		                GLOBALS->signalpixmap,
889 				xsrc, 0,
890 				0, 0,
891 		                GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height);
892 			}
893 
894 		draw_marker();
895 	}
896 }
897 
button_press_release_common(void)898 void button_press_release_common(void)
899 {
900 MaxSignalLength();
901 
902 gdk_draw_rectangle(GLOBALS->signalpixmap,
903 	GLOBALS->gc.gc_ltgray, TRUE, 0, 0,
904         GLOBALS->signal_fill_width, GLOBALS->signalarea->allocation.height);
905 
906 {
907 char signalwindow_width_dirty = GLOBALS->signalwindow_width_dirty;
908 sync_marker();
909 if(!signalwindow_width_dirty && GLOBALS->signalwindow_width_dirty)
910 	{
911 	MaxSignalLength_2(1);
912 	}
913 }
914 
915 RenderSigs((int)(GTK_ADJUSTMENT(GLOBALS->wave_vslider)->value),0);
916 
917 if(GLOBALS->signalarea_has_focus)
918 	{
919 	gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],
920 	      	GLOBALS->signalpixmap,
921 		(gint)(GTK_ADJUSTMENT(GLOBALS->signal_hslider)->value)+1, 0+1,
922 		0+1, 0+1,
923 	        GLOBALS->signalarea->allocation.width-2, GLOBALS->signalarea->allocation.height-2);
924 
925 	draw_signalarea_focus();
926 	}
927 	else
928 	{
929 	gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],
930 	      	GLOBALS->signalpixmap,
931 		(gint)(GTK_ADJUSTMENT(GLOBALS->signal_hslider)->value), 0,
932 		0, 0,
933 	        GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height);
934 	}
935 }
936 
button_motion_common(gint xin,gint yin,int pressrel,int is_button_2)937 static void button_motion_common(gint xin, gint yin, int pressrel, int is_button_2)
938 {
939 gdouble x,offset,pixstep;
940 TimeType newcurr;
941 
942 if(xin<0) xin=0;
943 if(xin>(GLOBALS->wavewidth-1)) xin=(GLOBALS->wavewidth-1);
944 
945 x=xin;	/* for pix time calc */
946 
947 pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe);
948 newcurr=(TimeType)(offset=((gdouble)GLOBALS->tims.start)+(x*pixstep));
949 
950 if(offset-newcurr>0.5)	/* round to nearest integer ns */
951 	{
952 	newcurr++;
953 	}
954 
955 if(newcurr>GLOBALS->tims.last) 		/* sanity checking */
956 	{
957 	newcurr=GLOBALS->tims.last;
958 	}
959 if(newcurr>GLOBALS->tims.end)
960 	{
961 	newcurr=GLOBALS->tims.end;
962 	}
963 if(newcurr<GLOBALS->tims.start)
964 	{
965 	newcurr=GLOBALS->tims.start;
966 	}
967 
968 newcurr = time_trunc(newcurr);
969 if(newcurr < 0) newcurr = GLOBALS->min_time; /* prevents marker from disappearing? */
970 
971 if(!is_button_2)
972 	{
973 	update_markertime(GLOBALS->tims.marker=cook_markertime(newcurr, xin, yin));
974 	if(GLOBALS->tims.lmbcache<0) GLOBALS->tims.lmbcache=time_trunc(newcurr);
975 
976 	draw_marker_partitions();
977 
978 	if((pressrel)||(GLOBALS->constant_marker_update))
979 		{
980 		button_press_release_common();
981 		}
982 	}
983 	else
984 	{
985 	GLOBALS->tims.baseline = ((GLOBALS->tims.baseline<0)||(is_button_2<0)) ? cook_markertime(newcurr, xin, yin) : -1;
986 	update_basetime(GLOBALS->tims.baseline);
987 	update_markertime(GLOBALS->tims.marker);
988 	wavearea_configure_event(GLOBALS->wavearea, NULL);
989 	}
990 }
991 
motion_notify_event(GtkWidget * widget,GdkEventMotion * event)992 static gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event)
993 {
994 (void)widget;
995 
996 gdouble x, y, pixstep, offset;
997 GdkModifierType state;
998 TimeType newcurr;
999 int scrolled;
1000 
1001 #ifdef WAVE_USE_GTK2
1002 gint xi, yi;
1003 #endif
1004 
1005 int dummy_x, dummy_y;
1006 get_window_xypos(&dummy_x, &dummy_y);
1007 
1008 if(event->is_hint)
1009         {
1010 	WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state);
1011 	WAVE_GDK_GET_POINTER_COPY;
1012         }
1013         else
1014         {
1015         x = event->x;
1016         y = event->y;
1017         state = event->state;
1018         }
1019 
1020 do
1021 	{
1022 	scrolled=0;
1023 	if(state&bmask[GLOBALS->in_button_press_wavewindow_c_1]) /* needed for retargeting in AIX/X11 */
1024 		{
1025 		if(x<0)
1026 			{
1027 			if(GLOBALS->wave_scrolling)
1028 			if(GLOBALS->tims.start>GLOBALS->tims.first)
1029 				{
1030 				if(GLOBALS->nsperframe<10)
1031 					{
1032 					GLOBALS->tims.start-=GLOBALS->nsperframe;
1033 					}
1034 					else
1035 					{
1036 					GLOBALS->tims.start-=(GLOBALS->nsperframe/10);
1037 					}
1038 				if(GLOBALS->tims.start<GLOBALS->tims.first) GLOBALS->tims.start=GLOBALS->tims.first;
1039 				GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.marker=time_trunc(GLOBALS->tims.timecache=GLOBALS->tims.start);
1040 
1041 				gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed");
1042 				gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed");
1043 				scrolled=1;
1044 				}
1045 			x=0;
1046 			}
1047 		else
1048 		if(x>GLOBALS->wavewidth)
1049 			{
1050 			if(GLOBALS->wave_scrolling)
1051 			if(GLOBALS->tims.start!=GLOBALS->tims.last)
1052 				{
1053 				gfloat pageinc;
1054 
1055 				pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
1056 
1057 				if(GLOBALS->nsperframe<10)
1058 					{
1059 					GLOBALS->tims.start+=GLOBALS->nsperframe;
1060 					}
1061 					else
1062 					{
1063 					GLOBALS->tims.start+=(GLOBALS->nsperframe/10);
1064 					}
1065 
1066 				if(GLOBALS->tims.start>GLOBALS->tims.last-pageinc+1) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-pageinc+1);
1067 				if(GLOBALS->tims.start<GLOBALS->tims.first) GLOBALS->tims.start=GLOBALS->tims.first;
1068 
1069 				GLOBALS->tims.marker=time_trunc(GLOBALS->tims.start+pageinc);
1070 				if(GLOBALS->tims.marker>GLOBALS->tims.last) GLOBALS->tims.marker=GLOBALS->tims.last;
1071 
1072 				GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start;
1073 
1074 				gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed");
1075 				gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed");
1076 				scrolled=1;
1077 				}
1078 			x=GLOBALS->wavewidth-1;
1079 			}
1080 		}
1081 	else if((state&GDK_BUTTON2_MASK)&&(GLOBALS->tims.baseline>=0))
1082 		{
1083 		button_motion_common(x,y,0,-1); /* neg one says don't clear tims.baseline */
1084 		}
1085 
1086 	pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe);
1087 	newcurr=GLOBALS->tims.start+(offset=x*pixstep);
1088 	if((offset-((int)offset))>0.5)  /* round to nearest integer ns */
1089 	        {
1090 	        newcurr++;
1091 	        }
1092 
1093 	if(newcurr>GLOBALS->tims.last) newcurr=GLOBALS->tims.last;
1094 
1095 	if(newcurr!=GLOBALS->prevtim_wavewindow_c_1)
1096 		{
1097 		update_currenttime(time_trunc(newcurr));
1098 		GLOBALS->prevtim_wavewindow_c_1=newcurr;
1099 		}
1100 
1101 	if(state&bmask[GLOBALS->in_button_press_wavewindow_c_1])
1102 		{
1103 		button_motion_common(x,y,0,0);
1104 		}
1105 
1106 	/* warp selected signals if CTRL is pressed */
1107 #ifdef MAC_INTEGRATION
1108         if((event->state & GDK_MOD2_MASK)&&(state&GDK_BUTTON1_MASK))
1109 #else
1110         if((event->state & GDK_CONTROL_MASK)&&(state&GDK_BUTTON1_MASK))
1111 #endif
1112 		{
1113 	  	int warp = 0;
1114           	Trptr t = GLOBALS->traces.first;
1115 		TimeType gt, delta;
1116 
1117           	while ( t )
1118           		{
1119             		if ( t->flags & TR_HIGHLIGHT )
1120             			{
1121 	      			warp++;
1122 
1123 				if(!t->shift_drag_valid)
1124 					{
1125 					t->shift_drag = t->shift;
1126 					t->shift_drag_valid = 1;
1127 					}
1128 
1129               			gt = t->shift_drag + (GLOBALS->tims.marker - GLOBALS->tims.lmbcache);
1130 
1131 		        	if(gt<0)
1132         		        	{
1133 		                	delta=GLOBALS->tims.first-GLOBALS->tims.last;
1134 		                	if(gt<delta) gt=delta;
1135 		                	}
1136 		       		else
1137 				if(gt>0)
1138 		                	{
1139 		                	delta=GLOBALS->tims.last-GLOBALS->tims.first;
1140 		                	if(gt>delta) gt=delta;
1141 		                	}
1142 				t->shift = gt;
1143             			}
1144 
1145             		t = t->t_next;
1146           		}
1147 
1148 	  	if( warp )
1149 	  		{
1150 /* commented out to reduce on visual noise...
1151 
1152             		GLOBALS->signalwindow_width_dirty = 1;
1153             		MaxSignalLength(  );
1154 
1155 ...commented out to reduce on visual noise */
1156 
1157             		signalarea_configure_event( GLOBALS->signalarea, NULL );
1158             		wavearea_configure_event( GLOBALS->wavearea, NULL );
1159           		}
1160 		}
1161 
1162 	if(scrolled)	/* make sure counters up top update.. */
1163 		{
1164 		gtk_events_pending_gtk_main_iteration();
1165 		}
1166 
1167 	WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state);
1168 	WAVE_GDK_GET_POINTER_COPY;
1169 
1170 	} while((scrolled)&&(state&bmask[GLOBALS->in_button_press_wavewindow_c_1]));
1171 
1172 return(TRUE);
1173 }
1174 
1175 #ifdef WAVE_USE_GTK2
alternate_y_scroll(int delta)1176 static void alternate_y_scroll(int delta)
1177 {
1178 GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
1179 int value = (int)wadj->value;
1180 int target = value + delta;
1181 
1182 int num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight);
1183 num_traces_displayable--;   /* for the time trace that is always there */
1184 
1185 if(target > GLOBALS->traces.visible - num_traces_displayable) target = GLOBALS->traces.visible - num_traces_displayable;
1186 
1187 if(target < 0) target = 0;
1188 
1189 wadj->value = target;
1190 
1191 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
1192 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
1193 }
1194 
1195 
1196 /*
1197  * Sane code starts here... :)
1198  * TomB 05Feb2012
1199  */
1200 
1201 #define SANE_INCREMENT 0.25
1202 /* don't want to increment a whole page thereby completely losing where I am... */
1203 
1204 void
alt_move_left(gboolean fine_scroll)1205 alt_move_left(gboolean fine_scroll)
1206 {
1207   TimeType ntinc, ntfrac;
1208 
1209   ntinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);	/* really don't need this var but the speed of ui code is human dependent.. */
1210   ntfrac=ntinc*GLOBALS->page_divisor*(SANE_INCREMENT / (fine_scroll ? 8.0 : 1.0));
1211   if(!ntfrac) ntfrac = 1;
1212 
1213   if((GLOBALS->tims.start-ntfrac)>GLOBALS->tims.first)
1214     GLOBALS->tims.timecache=GLOBALS->tims.start-ntfrac;
1215   else
1216     GLOBALS->tims.timecache=GLOBALS->tims.first;
1217 
1218   GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache;
1219   time_update();
1220 
1221   DEBUG(printf("Alternate move left\n"));
1222 }
1223 
1224 void
alt_move_right(gboolean fine_scroll)1225 alt_move_right(gboolean fine_scroll)
1226 {
1227   TimeType ntinc, ntfrac;
1228 
1229   ntinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
1230   ntfrac=ntinc*GLOBALS->page_divisor*(SANE_INCREMENT / (fine_scroll ? 8.0 : 1.0));
1231   if(!ntfrac) ntfrac = 1;
1232 
1233   if((GLOBALS->tims.start+ntfrac)<(GLOBALS->tims.last-ntinc+1))
1234   {
1235     GLOBALS->tims.timecache=GLOBALS->tims.start+ntfrac;
1236   }
1237   else
1238   {
1239     GLOBALS->tims.timecache=GLOBALS->tims.last-ntinc+1;
1240     if(GLOBALS->tims.timecache<GLOBALS->tims.first)
1241       GLOBALS->tims.timecache=GLOBALS->tims.first;
1242   }
1243 
1244   GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache;
1245   time_update();
1246 
1247   DEBUG(printf("Alternate move right\n"));
1248 }
1249 
1250 
alt_zoom_out(GtkWidget * text,gpointer data)1251 void alt_zoom_out(GtkWidget *text, gpointer data)
1252 {
1253 (void)text;
1254 (void)data;
1255 
1256   TimeType middle=0, width;
1257   TimeType marker = GLOBALS->cached_currenttimeval_currenttime_c_1;
1258   /* Zoom on mouse cursor, not marker */
1259 
1260   if(GLOBALS->do_zoom_center)
1261   {
1262     if((marker<0)||(marker<GLOBALS->tims.first)||(marker>GLOBALS->tims.last))
1263     {
1264       if(GLOBALS->tims.end>GLOBALS->tims.last)
1265         GLOBALS->tims.end=GLOBALS->tims.last;
1266 
1267       middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2);
1268       if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1))
1269         middle++;
1270     }
1271     else
1272     {
1273       middle=marker;
1274     }
1275   }
1276 
1277   GLOBALS->tims.prevzoom=GLOBALS->tims.zoom;
1278 
1279   GLOBALS->tims.zoom--;
1280   calczoom(GLOBALS->tims.zoom);
1281 
1282   if(GLOBALS->do_zoom_center)
1283   {
1284     width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
1285     GLOBALS->tims.start=time_trunc(middle-(width/2));
1286     if(GLOBALS->tims.start+width>GLOBALS->tims.last)
1287       GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width);
1288 
1289     if(GLOBALS->tims.start<GLOBALS->tims.first)
1290       GLOBALS->tims.start=GLOBALS->tims.first;
1291 
1292     GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start;
1293   }
1294   else
1295   {
1296     GLOBALS->tims.timecache=0;
1297   }
1298 
1299   fix_wavehadj();
1300 
1301   gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */
1302   gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */
1303 
1304   DEBUG(printf("Alternate Zoom out\n"));
1305 }
1306 
alt_zoom_in(GtkWidget * text,gpointer data)1307 void alt_zoom_in(GtkWidget *text, gpointer data)
1308 {
1309 (void)text;
1310 (void)data;
1311 
1312   if(GLOBALS->tims.zoom<0)		/* otherwise it's ridiculous and can cause */
1313   {		/* overflow problems in the scope          */
1314     TimeType middle=0, width;
1315     TimeType marker = GLOBALS->cached_currenttimeval_currenttime_c_1;
1316     /* Zoom on mouse cursor, not marker */
1317 
1318     if(GLOBALS->do_zoom_center)
1319     {
1320       if((marker<0)||(marker<GLOBALS->tims.first)||(marker>GLOBALS->tims.last))
1321       {
1322         if(GLOBALS->tims.end>GLOBALS->tims.last)
1323           GLOBALS->tims.end=GLOBALS->tims.last;
1324 
1325         middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2);
1326         if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1))
1327           middle++;
1328       }
1329       else
1330       {
1331         middle=marker;
1332       }
1333     }
1334 
1335     GLOBALS->tims.prevzoom=GLOBALS->tims.zoom;
1336 
1337     GLOBALS->tims.zoom++;
1338     calczoom(GLOBALS->tims.zoom);
1339 
1340     if(GLOBALS->do_zoom_center)
1341     {
1342       width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
1343       GLOBALS->tims.start=time_trunc(middle-(width/2));
1344       if(GLOBALS->tims.start+width>GLOBALS->tims.last)
1345         GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width);
1346 
1347       if(GLOBALS->tims.start<GLOBALS->tims.first)
1348         GLOBALS->tims.start=GLOBALS->tims.first;
1349 
1350       GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start;
1351     }
1352     else
1353     {
1354     GLOBALS->tims.timecache=0;
1355     }
1356 
1357     fix_wavehadj();
1358 
1359     gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */
1360     gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */
1361 
1362     DEBUG(printf("Alternate zoom in\n"));
1363   }
1364 }
1365 
1366 
1367 
1368 
1369 static        gint
scroll_event(GtkWidget * widget,GdkEventScroll * event)1370 scroll_event( GtkWidget * widget, GdkEventScroll * event )
1371 {
1372 (void)widget;
1373 
1374 int num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight);
1375 num_traces_displayable--;
1376 
1377   DEBUG(printf("Mouse Scroll Event\n"));
1378 
1379   if(GLOBALS->alt_wheel_mode)
1380   {
1381     /* TomB mouse wheel handling */
1382 #ifdef MAC_INTEGRATION
1383       if ( event->state & GDK_MOD2_MASK )
1384 #else
1385       if ( event->state & GDK_CONTROL_MASK )
1386 #endif
1387       {
1388         /* CTRL+wheel - zoom in/out around current mouse cursor position */
1389         if(event->direction == GDK_SCROLL_UP)
1390           alt_zoom_in(NULL, 0);
1391         else if(event->direction == GDK_SCROLL_DOWN)
1392           alt_zoom_out(NULL, 0);
1393       }
1394       else if( event->state & GDK_MOD1_MASK )
1395       {
1396         /* ALT+wheel - edge left/right mode */
1397         if(event->direction == GDK_SCROLL_UP)
1398           service_left_edge(NULL, 0);
1399         else if(event->direction == GDK_SCROLL_DOWN)
1400           service_right_edge(NULL, 0);
1401       }
1402       else
1403       {
1404         /* wheel alone - scroll part of a page along */
1405         if(event->direction == GDK_SCROLL_UP)
1406           alt_move_left((event->state & GDK_SHIFT_MASK) != 0);  /* finer scroll if shift */
1407         else if(event->direction == GDK_SCROLL_DOWN)
1408           alt_move_right((event->state & GDK_SHIFT_MASK) != 0); /* finer scroll if shift */
1409       }
1410   }
1411   else
1412   {
1413     /* Original 3.3.31 mouse wheel handling */
1414   switch ( event->direction )
1415   {
1416     case GDK_SCROLL_UP:
1417       if (GLOBALS->use_scrollwheel_as_y)
1418 	{
1419 	if(event->state & GDK_SHIFT_MASK)
1420 		{
1421 		alternate_y_scroll(-num_traces_displayable);
1422 		}
1423 		else
1424 		{
1425 		alternate_y_scroll(-1);
1426 		}
1427 	}
1428 	else
1429 	{
1430 #ifdef MAC_INTEGRATION
1431       	if ( event->state & GDK_MOD2_MASK )
1432 #else
1433       	if ( event->state & GDK_CONTROL_MASK )
1434 #endif
1435         	service_left_shift(NULL, 0);
1436       	else if ( event->state & GDK_MOD1_MASK )
1437 		service_zoom_out(NULL, 0);
1438       	else
1439         	service_left_page(NULL, 0);
1440 	}
1441       break;
1442     case GDK_SCROLL_DOWN:
1443       if (GLOBALS->use_scrollwheel_as_y)
1444 	{
1445 	if(event->state & GDK_SHIFT_MASK)
1446 		{
1447 		alternate_y_scroll(num_traces_displayable);
1448 		}
1449 		else
1450 		{
1451 		alternate_y_scroll(1);
1452 		}
1453 	}
1454 
1455 	{
1456 #ifdef MAC_INTEGRATION
1457       	if ( event->state & GDK_MOD2_MASK )
1458 #else
1459       	if ( event->state & GDK_CONTROL_MASK )
1460 #endif
1461         	service_right_shift(NULL, 0);
1462       	else if ( event->state & GDK_MOD1_MASK )
1463 		service_zoom_in(NULL, 0);
1464       	else
1465         	service_right_page(NULL, 0);
1466 	}
1467       break;
1468 
1469     default:
1470       break;
1471   }
1472   }
1473   return(TRUE);
1474 }
1475 #endif
1476 
button_press_event(GtkWidget * widget,GdkEventButton * event)1477 static gint button_press_event(GtkWidget *widget, GdkEventButton *event)
1478 {
1479 if((event->button==1)||((event->button==3)&&(!GLOBALS->in_button_press_wavewindow_c_1)))
1480 	{
1481 	GLOBALS->in_button_press_wavewindow_c_1=event->button;
1482 
1483 	DEBUG(printf("Button Press Event\n"));
1484 	GLOBALS->prev_markertime = GLOBALS->tims.marker;
1485 	button_motion_common(event->x,event->y,1,0);
1486 	GLOBALS->tims.timecache=GLOBALS->tims.start;
1487 
1488 	gdk_pointer_grab(widget->window, FALSE,
1489 		m_bmask[GLOBALS->in_button_press_wavewindow_c_1] | /* key up on motion for button pressed ONLY */
1490 		GDK_POINTER_MOTION_HINT_MASK |
1491 	      	GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time);
1492 
1493 #ifdef MAC_INTEGRATION
1494 	if ((event->state & GDK_MOD2_MASK) && (event->button==1))
1495 #else
1496 	if ((event->state & GDK_CONTROL_MASK) && (event->button==1))
1497 #endif
1498 		{
1499 		Trptr t = GLOBALS->traces.first;
1500 
1501 		while(t)
1502 			{
1503 			if((t->flags & TR_HIGHLIGHT)&&(!t->shift_drag_valid))
1504 				{
1505 				t->shift_drag = t->shift; /* cache old value */
1506 				t->shift_drag_valid = 1;
1507 				}
1508 			t=t->t_next;
1509 			}
1510 		}
1511 	}
1512 else
1513 if(event->button==2)
1514 	{
1515 	if(!GLOBALS->button2_debounce_flag)
1516 		{
1517 		GLOBALS->button2_debounce_flag = 1; /* cleared by mouseover_timer() interrupt */
1518 		button_motion_common(event->x,event->y,1,1);
1519 		}
1520 	}
1521 
1522 return(TRUE);
1523 }
1524 
button_release_event(GtkWidget * widget,GdkEventButton * event)1525 static gint button_release_event(GtkWidget *widget, GdkEventButton *event)
1526 {
1527 (void)widget;
1528 
1529 if((event->button)&&(event->button==GLOBALS->in_button_press_wavewindow_c_1))
1530 	{
1531 	GLOBALS->in_button_press_wavewindow_c_1=0;
1532 
1533 	DEBUG(printf("Button Release Event\n"));
1534 	button_motion_common(event->x,event->y,1,0);
1535 
1536 	/* warp selected signals if CTRL is pressed */
1537         if(event->button==1)
1538 		{
1539 	  	int warp = 0;
1540           	Trptr t = GLOBALS->traces.first;
1541 
1542 #ifdef MAC_INTEGRATION
1543 		if(event->state & GDK_MOD2_MASK)
1544 #else
1545 		if(event->state & GDK_CONTROL_MASK)
1546 #endif
1547 			{
1548 			TimeType gt, delta;
1549 
1550 	          	while ( t )
1551 	          		{
1552 	            		if ( t->flags & TR_HIGHLIGHT )
1553 	            			{
1554 		      			warp++;
1555 	              			gt = (t->shift_drag_valid ? t-> shift_drag : t->shift) + (GLOBALS->tims.marker - GLOBALS->tims.lmbcache);
1556 
1557 			        	if(gt<0)
1558 	        		        	{
1559 			                	delta=GLOBALS->tims.first-GLOBALS->tims.last;
1560 			                	if(gt<delta) gt=delta;
1561 			                	}
1562 			       		else
1563 					if(gt>0)
1564 			                	{
1565 			                	delta=GLOBALS->tims.last-GLOBALS->tims.first;
1566 			                	if(gt>delta) gt=delta;
1567 			                	}
1568 					t->shift = gt;
1569 
1570 	              			t->flags &= ( ~TR_HIGHLIGHT );
1571 	            			}
1572 
1573 				t->shift_drag_valid = 0;
1574 	            		t = t->t_next;
1575 	          		}
1576 			}
1577 			else	/* back out warp and keep highlighting */
1578 			{
1579 			while(t)
1580 				{
1581 				if(t->shift_drag_valid)
1582 					{
1583 					t->shift = t->shift_drag;
1584 					t->shift_drag_valid = 0;
1585 					warp++;
1586 					}
1587 				t=t->t_next;
1588 				}
1589 			}
1590 
1591 	  	if( warp )
1592 	  		{
1593             		GLOBALS->signalwindow_width_dirty = 1;
1594             		MaxSignalLength(  );
1595             		signalarea_configure_event( GLOBALS->signalarea, NULL );
1596             		wavearea_configure_event( GLOBALS->wavearea, NULL );
1597           		}
1598 		}
1599 
1600 	GLOBALS->tims.timecache=GLOBALS->tims.start;
1601 
1602 	gdk_pointer_ungrab(event->time);
1603 
1604 	if(event->button==3)	/* oh yeah, dragzoooooooom! */
1605 		{
1606 		service_dragzoom(GLOBALS->tims.lmbcache, GLOBALS->tims.marker);
1607 		}
1608 
1609 	GLOBALS->tims.lmbcache=-1;
1610 	update_markertime(GLOBALS->tims.marker);
1611 	}
1612 
1613 GLOBALS->mouseover_counter = 11;
1614 move_mouseover(NULL, 0, 0, LLDescriptor(0));
1615 GLOBALS->tims.timecache=0;
1616 
1617 if(GLOBALS->prev_markertime == LLDescriptor(-1))
1618 	{
1619 	signalarea_configure_event( GLOBALS->signalarea, NULL );
1620 	}
1621 
1622 return(TRUE);
1623 }
1624 
1625 
make_sigarea_gcs(GtkWidget * signalarea)1626 void make_sigarea_gcs(GtkWidget *signalarea)
1627 {
1628 if(!GLOBALS->made_sgc_contexts_wavewindow_c_1)
1629 	{
1630 	GLOBALS->gc_white = alloc_color(signalarea, GLOBALS->color_white, signalarea->style->white_gc);
1631 	GLOBALS->gc_black = alloc_color(signalarea, GLOBALS->color_black, signalarea->style->black_gc);
1632 	GLOBALS->gc.gc_ltgray= alloc_color(signalarea, GLOBALS->color_ltgray, signalarea->style->bg_gc[GTK_STATE_PRELIGHT]);
1633 	GLOBALS->gc.gc_normal= alloc_color(signalarea, GLOBALS->color_normal, signalarea->style->bg_gc[GTK_STATE_NORMAL]);
1634 	GLOBALS->gc.gc_mdgray= alloc_color(signalarea, GLOBALS->color_mdgray, signalarea->style->bg_gc[GTK_STATE_INSENSITIVE]);
1635 	GLOBALS->gc.gc_dkgray= alloc_color(signalarea, GLOBALS->color_dkgray, signalarea->style->bg_gc[GTK_STATE_ACTIVE]);
1636 	GLOBALS->gc.gc_dkblue= alloc_color(signalarea, GLOBALS->color_dkblue, signalarea->style->bg_gc[GTK_STATE_SELECTED]);
1637 	GLOBALS->gc.gc_brkred= alloc_color(signalarea, GLOBALS->color_brkred, signalarea->style->bg_gc[GTK_STATE_SELECTED]);
1638 	GLOBALS->gc.gc_ltblue= alloc_color(signalarea, GLOBALS->color_ltblue, signalarea->style->bg_gc[GTK_STATE_SELECTED]);
1639 	GLOBALS->gc.gc_gmstrd= alloc_color(signalarea, GLOBALS->color_gmstrd, signalarea->style->bg_gc[GTK_STATE_SELECTED]);
1640 
1641 	GLOBALS->made_sgc_contexts_wavewindow_c_1=~0;
1642 	}
1643 }
1644 
1645 
1646 static const int wave_rgb_rainbow[WAVE_NUM_RAINBOW] = WAVE_RAINBOW_RGB;
1647 
wavearea_configure_event(GtkWidget * widget,GdkEventConfigure * event)1648 gint wavearea_configure_event(GtkWidget *widget, GdkEventConfigure *event)
1649 {
1650 (void)event;
1651 
1652 if((!widget)||(!widget->window)) return(TRUE);
1653 
1654 DEBUG(printf("WaveWin Configure Event h: %d, w: %d\n",widget->allocation.height,
1655 		widget->allocation.width));
1656 
1657 if(GLOBALS->wavepixmap_wavewindow_c_1)
1658 	{
1659 	if((GLOBALS->wavewidth!=widget->allocation.width)||(GLOBALS->waveheight!=widget->allocation.height))
1660 		{
1661 		gdk_pixmap_unref(GLOBALS->wavepixmap_wavewindow_c_1);
1662 		GLOBALS->wavepixmap_wavewindow_c_1=gdk_pixmap_new(widget->window, GLOBALS->wavewidth=widget->allocation.width,
1663 			GLOBALS->waveheight=widget->allocation.height, -1);
1664 		}
1665 	GLOBALS->old_wvalue=-1.0;
1666 	}
1667 	else
1668 	{
1669 	GLOBALS->wavepixmap_wavewindow_c_1=gdk_pixmap_new(widget->window, GLOBALS->wavewidth=widget->allocation.width,
1670 		GLOBALS->waveheight=widget->allocation.height, -1);
1671 	}
1672 
1673 if(!GLOBALS->made_gc_contexts_wavewindow_c_1)
1674 	{
1675 	int i;
1676 
1677 	GLOBALS->gc.gc_back_wavewindow_c_1   = alloc_color(GLOBALS->wavearea, GLOBALS->color_back, GLOBALS->wavearea->style->white_gc);
1678 	GLOBALS->gc.gc_baseline_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_baseline, GLOBALS->wavearea->style->bg_gc[GTK_STATE_SELECTED]);
1679 	GLOBALS->gc.gc_grid_wavewindow_c_1   = alloc_color(GLOBALS->wavearea, GLOBALS->color_grid, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]);
1680 	GLOBALS->gc.gc_grid2_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_grid2, GLOBALS->wavearea->style->bg_gc[GTK_STATE_ACTIVE]);
1681 	GLOBALS->gc.gc_time_wavewindow_c_1   = alloc_color(GLOBALS->wavearea, GLOBALS->color_time, GLOBALS->wavearea->style->black_gc);
1682 	GLOBALS->gc.gc_timeb_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_timeb, GLOBALS->wavearea->style->bg_gc[GTK_STATE_ACTIVE]);
1683 	GLOBALS->gc.gc_value_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_value, GLOBALS->wavearea->style->black_gc);
1684 	GLOBALS->gc.gc_low_wavewindow_c_1    = alloc_color(GLOBALS->wavearea, GLOBALS->color_low, GLOBALS->wavearea->style->black_gc);
1685 	GLOBALS->gc.gc_highfill_wavewindow_c_1=alloc_color(GLOBALS->wavearea, GLOBALS->color_highfill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]);
1686 	GLOBALS->gc.gc_high_wavewindow_c_1   = alloc_color(GLOBALS->wavearea, GLOBALS->color_high, GLOBALS->wavearea->style->black_gc);
1687 	GLOBALS->gc.gc_trans_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_trans, GLOBALS->wavearea->style->black_gc);
1688 	GLOBALS->gc.gc_mid_wavewindow_c_1    = alloc_color(GLOBALS->wavearea, GLOBALS->color_mid, GLOBALS->wavearea->style->black_gc);
1689 	GLOBALS->gc.gc_xfill_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_xfill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]);
1690 	GLOBALS->gc.gc_x_wavewindow_c_1      = alloc_color(GLOBALS->wavearea, GLOBALS->color_x, GLOBALS->wavearea->style->black_gc);
1691 	GLOBALS->gc.gc_vbox_wavewindow_c_1   = alloc_color(GLOBALS->wavearea, GLOBALS->color_vbox, GLOBALS->wavearea->style->black_gc);
1692 	GLOBALS->gc.gc_vtrans_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_vtrans, GLOBALS->wavearea->style->black_gc);
1693 	GLOBALS->gc.gc_mark_wavewindow_c_1   = alloc_color(GLOBALS->wavearea, GLOBALS->color_mark, GLOBALS->wavearea->style->bg_gc[GTK_STATE_SELECTED]);
1694 	GLOBALS->gc.gc_umark_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_umark, GLOBALS->wavearea->style->bg_gc[GTK_STATE_SELECTED]);
1695 
1696 #ifdef WAVE_DOUBLE_LINE_WIDTH_MODE
1697 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_value_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1698 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_low_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1699 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_high_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1700 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_trans_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1701 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_mid_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1702 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_xfill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1703 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_x_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1704 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_vbox_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1705 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_vtrans_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1706 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_mark_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1707 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_umark_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1708 #endif
1709 
1710         GLOBALS->gc.gc_0_wavewindow_c_1      = alloc_color(GLOBALS->wavearea, GLOBALS->color_0, GLOBALS->wavearea->style->black_gc);
1711         GLOBALS->gc.gc_1fill_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_1fill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]);
1712         GLOBALS->gc.gc_1_wavewindow_c_1      = alloc_color(GLOBALS->wavearea, GLOBALS->color_1, GLOBALS->wavearea->style->black_gc);
1713         GLOBALS->gc.gc_ufill_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_ufill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]);
1714         GLOBALS->gc.gc_u_wavewindow_c_1      = alloc_color(GLOBALS->wavearea, GLOBALS->color_u, GLOBALS->wavearea->style->black_gc);
1715         GLOBALS->gc.gc_wfill_wavewindow_c_1  = alloc_color(GLOBALS->wavearea, GLOBALS->color_wfill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]);
1716         GLOBALS->gc.gc_w_wavewindow_c_1      = alloc_color(GLOBALS->wavearea, GLOBALS->color_w, GLOBALS->wavearea->style->black_gc);
1717         GLOBALS->gc.gc_dashfill_wavewindow_c_1= alloc_color(GLOBALS->wavearea, GLOBALS->color_dashfill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]);
1718         GLOBALS->gc.gc_dash_wavewindow_c_1   = alloc_color(GLOBALS->wavearea, GLOBALS->color_dash, GLOBALS->wavearea->style->black_gc);
1719 
1720 #ifdef WAVE_DOUBLE_LINE_WIDTH_MODE
1721 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_0_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1722 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_1fill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1723 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_1_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1724 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_ufill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1725 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_u_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1726 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_wfill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1727 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_w_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1728 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_dashfill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1729 	gdk_gc_set_line_attributes(GLOBALS->gc.gc_dash_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1730 #endif
1731 
1732 	GLOBALS->made_gc_contexts_wavewindow_c_1=~0;
1733 
1734 	memcpy(&GLOBALS->gccache, &GLOBALS->gc, sizeof(struct wave_gcmaster_t));
1735 
1736 	/* add rainbow colors */
1737 	for(i=0;i<WAVE_NUM_RAINBOW;i++)
1738 		{
1739 		int col = wave_rgb_rainbow[i];
1740 
1741 		GLOBALS->gc_rainbow[i*2] = alloc_color(GLOBALS->wavearea, col, GLOBALS->wavearea->style->black_gc);
1742 		col >>= 1;
1743 		col &= 0x007F7F7F;
1744 		GLOBALS->gc_rainbow[i*2+1] = alloc_color(GLOBALS->wavearea, col, GLOBALS->wavearea->style->black_gc);
1745 
1746 #ifdef WAVE_DOUBLE_LINE_WIDTH_MODE
1747 		gdk_gc_set_line_attributes(GLOBALS->gc_rainbow[i*2], 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1748 		gdk_gc_set_line_attributes(GLOBALS->gc_rainbow[i*2+1], 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
1749 #endif
1750 		}
1751 	}
1752 
1753 if(GLOBALS->timestart_from_savefile_valid)
1754 	{
1755 	gfloat pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
1756 
1757 	if((GLOBALS->timestart_from_savefile >= GLOBALS->tims.first) && (GLOBALS->timestart_from_savefile <= (GLOBALS->tims.last-pageinc)))
1758 		{
1759 		GtkAdjustment *hadj = GTK_ADJUSTMENT(GLOBALS->wave_hslider);
1760 		hadj->value = GLOBALS->timestart_from_savefile;
1761 		fix_wavehadj();
1762 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */
1763 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */
1764 		}
1765 	GLOBALS->timestart_from_savefile_valid = 0;
1766 	}
1767 
1768 if(GLOBALS->wavewidth>1)
1769 	{
1770 	if((!GLOBALS->do_initial_zoom_fit)||(GLOBALS->do_initial_zoom_fit_used))
1771 		{
1772 		calczoom(GLOBALS->tims.zoom);
1773 		fix_wavehadj();
1774 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */
1775 		gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */
1776 		}
1777 		else
1778 		{
1779 		GLOBALS->do_initial_zoom_fit_used=1;
1780 		service_zoom_fit(NULL,NULL);
1781 		}
1782 	}
1783 
1784 /* tims.timecache=tims.laststart; */
1785 return(TRUE);
1786 }
1787 
1788 /*
1789  * screengrab vs normal rendering gcs...
1790  */
force_screengrab_gcs(void)1791 void force_screengrab_gcs(void)
1792 {
1793 GLOBALS->black_and_white = 1;
1794 
1795 GLOBALS->gc.gc_ltgray= GLOBALS->gc_white ;
1796 GLOBALS->gc.gc_normal= GLOBALS->gc_white ;
1797 GLOBALS->gc.gc_mdgray= GLOBALS->gc_white ;
1798 GLOBALS->gc.gc_dkgray= GLOBALS->gc_white ;
1799 GLOBALS->gc.gc_dkblue= GLOBALS->gc_black ;
1800 GLOBALS->gc.gc_brkred= GLOBALS->gc_black ;
1801 GLOBALS->gc.gc_ltblue= GLOBALS->gc_black ;
1802 GLOBALS->gc.gc_gmstrd= GLOBALS->gc_black ;
1803 GLOBALS->gc.gc_back_wavewindow_c_1   = GLOBALS->gc_white ;
1804 GLOBALS->gc.gc_baseline_wavewindow_c_1 = GLOBALS->gc_black;
1805 GLOBALS->gc.gc_grid_wavewindow_c_1   = GLOBALS->gc_black;
1806 GLOBALS->gc.gc_grid2_wavewindow_c_1  = GLOBALS->gc_black;
1807 GLOBALS->gc.gc_time_wavewindow_c_1   = GLOBALS->gc_black;
1808 GLOBALS->gc.gc_timeb_wavewindow_c_1  = GLOBALS->gc_white;
1809 GLOBALS->gc.gc_value_wavewindow_c_1  = GLOBALS->gc_black;
1810 GLOBALS->gc.gc_low_wavewindow_c_1    = GLOBALS->gc_black;
1811 GLOBALS->gc.gc_highfill_wavewindow_c_1= GLOBALS->gc_black;
1812 GLOBALS->gc.gc_high_wavewindow_c_1   = GLOBALS->gc_black;
1813 GLOBALS->gc.gc_trans_wavewindow_c_1  = GLOBALS->gc_black;
1814 GLOBALS->gc.gc_mid_wavewindow_c_1    = GLOBALS->gc_black;
1815 GLOBALS->gc.gc_xfill_wavewindow_c_1  = GLOBALS->gc_black;
1816 GLOBALS->gc.gc_x_wavewindow_c_1      = GLOBALS->gc_black;
1817 GLOBALS->gc.gc_vbox_wavewindow_c_1   = GLOBALS->gc_black;
1818 GLOBALS->gc.gc_vtrans_wavewindow_c_1 = GLOBALS->gc_black;
1819 GLOBALS->gc.gc_mark_wavewindow_c_1   = GLOBALS->gc_black;
1820 GLOBALS->gc.gc_umark_wavewindow_c_1  = GLOBALS->gc_black;
1821 GLOBALS->gc.gc_0_wavewindow_c_1      = GLOBALS->gc_black;
1822 GLOBALS->gc.gc_1fill_wavewindow_c_1  = GLOBALS->gc_black;
1823 GLOBALS->gc.gc_1_wavewindow_c_1      = GLOBALS->gc_black;
1824 GLOBALS->gc.gc_ufill_wavewindow_c_1  = GLOBALS->gc_black;
1825 GLOBALS->gc.gc_u_wavewindow_c_1      = GLOBALS->gc_black;
1826 GLOBALS->gc.gc_wfill_wavewindow_c_1  = GLOBALS->gc_black;
1827 GLOBALS->gc.gc_w_wavewindow_c_1      = GLOBALS->gc_black;
1828 GLOBALS->gc.gc_dashfill_wavewindow_c_1= GLOBALS->gc_black;
1829 GLOBALS->gc.gc_dash_wavewindow_c_1   = GLOBALS->gc_black;
1830 }
1831 
force_normal_gcs(void)1832 void force_normal_gcs(void)
1833 {
1834 GLOBALS->black_and_white = 0;
1835 
1836 memcpy(&GLOBALS->gc, &GLOBALS->gccache, sizeof(struct wave_gcmaster_t));
1837 }
1838 
wavearea_configure_event_local(GtkWidget * widget,GdkEventConfigure * event)1839 static gint wavearea_configure_event_local(GtkWidget *widget, GdkEventConfigure *event)
1840 {
1841 gint rc;
1842 gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook));
1843 struct Global *g_old = GLOBALS;
1844 
1845 set_GLOBALS((*GLOBALS->contexts)[page_num]);
1846 
1847 rc = wavearea_configure_event(widget, event);
1848 
1849 set_GLOBALS(g_old);
1850 
1851 return(rc);
1852 }
1853 
1854 
expose_event(GtkWidget * widget,GdkEventExpose * event)1855 static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
1856 {
1857 gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],GLOBALS->wavepixmap_wavewindow_c_1, event->area.x, event->area.y,event->area.x, event->area.y,event->area.width, event->area.height);
1858 draw_marker();
1859 
1860 return(FALSE);
1861 }
1862 
1863 
expose_event_local(GtkWidget * widget,GdkEventExpose * event)1864 static gint expose_event_local(GtkWidget *widget, GdkEventExpose *event)
1865 {
1866 gint rc;
1867 gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook));
1868 /* struct Global *g_old = GLOBALS; */
1869 
1870 set_GLOBALS((*GLOBALS->contexts)[page_num]);
1871 
1872 rc = expose_event(widget, event);
1873 
1874 /* seems to cause a conflict flipping back so don't! */
1875 /* set_GLOBALS(g_old); */
1876 
1877 return(rc);
1878 }
1879 
1880 
1881 GtkWidget *
create_wavewindow(void)1882 create_wavewindow(void)
1883 {
1884 GtkWidget *table;
1885 GtkWidget *frame;
1886 GtkAdjustment *hadj, *vadj;
1887 
1888 table = gtk_table_new(10, 10, FALSE);
1889 GLOBALS->wavearea=gtk_drawing_area_new();
1890 gtk_widget_show(GLOBALS->wavearea);
1891 
1892 gtk_widget_set_events(GLOBALS->wavearea,
1893 #ifdef WAVE_USE_GTK2
1894 		GDK_SCROLL_MASK |
1895 #endif
1896                 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
1897                 GDK_BUTTON_RELEASE_MASK |
1898                 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK
1899                 );
1900 
1901 gtk_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "configure_event",GTK_SIGNAL_FUNC(wavearea_configure_event_local), NULL);
1902 gtk_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "expose_event",GTK_SIGNAL_FUNC(expose_event_local), NULL);
1903 
1904 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "motion_notify_event",GTK_SIGNAL_FUNC(motion_notify_event), NULL);
1905 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "button_press_event",GTK_SIGNAL_FUNC(button_press_event), NULL);
1906 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "button_release_event",GTK_SIGNAL_FUNC(button_release_event), NULL);
1907 
1908 #ifdef WAVE_USE_GTK2
1909 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "scroll_event",GTK_SIGNAL_FUNC(scroll_event), NULL);
1910 GTK_WIDGET_SET_FLAGS( GLOBALS->wavearea, GTK_CAN_FOCUS );
1911 #endif
1912 
1913 gtk_table_attach (GTK_TABLE (table), GLOBALS->wavearea, 0, 9, 0, 9,GTK_FILL | GTK_EXPAND,GTK_FILL | GTK_EXPAND, 3, 2);
1914 
1915 GLOBALS->wave_vslider=gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
1916 vadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
1917 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wave_vslider), "value_changed",GTK_SIGNAL_FUNC(service_vslider), NULL);
1918 GLOBALS->vscroll_wavewindow_c_1=gtk_vscrollbar_new(vadj);
1919 /* GTK_WIDGET_SET_FLAGS(GLOBALS->vscroll_wavewindow_c_1, GTK_CAN_FOCUS); */
1920 gtk_widget_show(GLOBALS->vscroll_wavewindow_c_1);
1921 gtk_table_attach (GTK_TABLE (table), GLOBALS->vscroll_wavewindow_c_1, 9, 10, 0, 9,
1922                         GTK_FILL,
1923                         GTK_FILL | GTK_SHRINK, 3, 3);
1924 
1925 GLOBALS->wave_hslider=gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
1926 hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider);
1927 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wave_hslider), "value_changed",GTK_SIGNAL_FUNC(service_hslider), NULL);
1928 GLOBALS->hscroll_wavewindow_c_2=gtk_hscrollbar_new(hadj);
1929 /* GTK_WIDGET_SET_FLAGS(GLOBALS->hscroll_wavewindow_c_2, GTK_CAN_FOCUS); */
1930 gtk_widget_show(GLOBALS->hscroll_wavewindow_c_2);
1931 
1932 
1933 #if WAVE_USE_GTK2
1934 if(GLOBALS->enable_slider_zoom)
1935 	{
1936 	GValue gvalue;
1937 
1938 	if(!draw_slider_p)
1939 		{
1940 		GtkStyle *gs = gtk_widget_get_style(GLOBALS->hscroll_wavewindow_c_2);
1941 		draw_slider_p = GTK_STYLE_GET_CLASS(gs)->draw_slider;
1942 		GTK_STYLE_GET_CLASS(gs)->draw_slider = draw_slider;
1943 		}
1944 
1945 	memset(&gvalue, 0, sizeof(GValue));
1946 	g_value_init(&gvalue, G_TYPE_INT);
1947 	gtk_widget_style_get_property(GLOBALS->hscroll_wavewindow_c_2, "min-slider-length", &gvalue);
1948 
1949 	gtkwave_signal_connect(GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "button_press_event",GTK_SIGNAL_FUNC(slider_bpr), NULL);
1950 	gtkwave_signal_connect(GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "button_release_event",GTK_SIGNAL_FUNC(slider_brr), NULL);
1951 	gtkwave_signal_connect(GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "motion_notify_event",GTK_SIGNAL_FUNC(slider_mnr), NULL);
1952 	}
1953 #endif
1954 
1955 
1956 gtk_table_attach (GTK_TABLE (table), GLOBALS->hscroll_wavewindow_c_2, 0, 9, 9, 10,
1957                         GTK_FILL,
1958                         GTK_FILL | GTK_SHRINK, 3, 4);
1959 gtk_widget_show(table);
1960 
1961 frame=gtk_frame_new("Waves");
1962 gtk_container_border_width(GTK_CONTAINER(frame),2);
1963 
1964 gtk_container_add(GTK_CONTAINER(frame),table);
1965 return(frame);
1966 }
1967 
1968 
1969 /**********************************************/
1970 
RenderSigs(int trtarget,int update_waves)1971 void RenderSigs(int trtarget, int update_waves)
1972 {
1973 Trptr t;
1974 int i, trwhich;
1975 int num_traces_displayable;
1976 GtkAdjustment *hadj;
1977 int xsrc;
1978 
1979 hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
1980 xsrc=(gint)hadj->value;
1981 
1982 num_traces_displayable=GLOBALS->signalarea->allocation.height/(GLOBALS->fontheight);
1983 num_traces_displayable--;   /* for the time trace that is always there */
1984 
1985 gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc.gc_mdgray, TRUE, 0, -1, GLOBALS->signal_fill_width, GLOBALS->fontheight);
1986 gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_white, 0, GLOBALS->fontheight-1, GLOBALS->signal_fill_width-1, GLOBALS->fontheight-1);
1987 font_engine_draw_string(GLOBALS->signalpixmap, GLOBALS->signalfont, GLOBALS->gc_black,
1988 	3+xsrc, GLOBALS->fontheight-4, "Time");
1989 
1990 t=GLOBALS->traces.first;
1991 trwhich=0;
1992 while(t)
1993         {
1994         if((trwhich<trtarget)&&(GiveNextTrace(t)))
1995                 {
1996 		trwhich++;
1997                 t=GiveNextTrace(t);
1998                 }
1999                 else
2000                 {
2001                 break;
2002                 }
2003         }
2004 
2005 GLOBALS->topmost_trace=t;
2006 if(t)
2007         {
2008         for(i=0;(i<num_traces_displayable)&&(t);i++)
2009                 {
2010 		RenderSig(t, i, 0);
2011                 t=GiveNextTrace(t);
2012                 }
2013         }
2014 
2015 if(GLOBALS->signalarea_has_focus)
2016 	{
2017 	gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc_black, FALSE, 0, 0, GLOBALS->signal_fill_width-1, GLOBALS->signalarea->allocation.height-1);
2018 	}
2019 
2020 if((GLOBALS->wavepixmap_wavewindow_c_1)&&(update_waves))
2021 	{
2022         gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_back_wavewindow_c_1, TRUE, 0, 0,GLOBALS->wavewidth, GLOBALS->waveheight);
2023 
2024 	/* if(GLOBALS->display_grid) */ rendertimes();
2025 
2026 	rendertraces();
2027 	}
2028 }
2029 
2030 
populateBuffer(Trptr t,char * altname,char * buf)2031 void populateBuffer (Trptr t, char *altname, char* buf)
2032 {
2033   char* ptr = buf;
2034   char *tname = altname ? altname : t->name;
2035 
2036   if (HasWave(t))
2037     {
2038       if (tname)
2039 	{
2040 	  strcpy(ptr, tname);
2041 	  ptr = ptr + strlen(ptr);
2042 
2043 	  if((tname)&&(t->shift))
2044 	    {
2045 	      ptr[0]='`';
2046 	      reformat_time(ptr+1, t->shift, GLOBALS->time_dimension);
2047 	      ptr = ptr + strlen(ptr+1) + 1;
2048 	      strcpy(ptr,"\'");
2049 #ifdef WAVE_ARRAY_SUPPORT
2050 	      ptr = ptr + strlen(ptr); /* really needed for aet2 only */
2051 #endif
2052 	    }
2053 
2054 #ifdef WAVE_ARRAY_SUPPORT
2055 	  if((!t->vector)&&(t->n.nd)&&(t->n.nd->array_height))
2056 	    {
2057 	      sprintf(ptr, "{%d}", t->n.nd->this_row);
2058 	      /* ptr = ptr + strlen(ptr); */ /* scan-build */
2059 	    }
2060 #endif
2061 	}
2062 
2063       if (IsGroupBegin(t))
2064 	{
2065 	  char * pch;
2066 	  ptr = buf;
2067 	  if (IsClosed(t)) {
2068 	    pch = strstr (ptr,"[-]");
2069 	    if(pch) {memcpy (pch,"[+]", 3); }
2070 	  } else {
2071 	    pch = strstr (ptr,"[+]");
2072 	    if(pch) {memcpy (pch,"[-]", 3); }
2073 	  }
2074 	}
2075     }
2076   else
2077     {
2078       if (tname)
2079 	{
2080 
2081 	  if (IsGroupEnd(t))
2082 	    {
2083 	      strcpy(ptr, "} ");
2084 	      ptr = ptr + strlen(ptr);
2085 	    }
2086 
2087 	  strcpy(ptr, tname);
2088 	  ptr = ptr + strlen(ptr);
2089 
2090 	  if (IsGroupBegin(t))
2091 	    {
2092 	      if (IsClosed(t) && IsCollapsed(t->t_match))
2093 		{
2094 		  strcpy(ptr, " {}");
2095 		}
2096 	      else
2097 		{
2098 		  strcpy(ptr, " {");
2099 		}
2100 	      /* ptr = ptr + strlen(ptr); */ /* scan-build */
2101 	    }
2102 	}
2103     }
2104 }
2105 
2106 /***************************************************************************/
2107 
RenderSig(Trptr t,int i,int dobackground)2108 int RenderSig(Trptr t, int i, int dobackground)
2109 {
2110   int texty, liney;
2111   int retval;
2112   char buf[2048];
2113   GdkGC *clr_comment;
2114   GdkGC *clr_group;
2115   GdkGC *clr_shadowed;
2116   GdkGC *clr_signal;
2117   GdkGC* bg_color;
2118   GdkGC* text_color;
2119   unsigned left_justify;
2120   char *subname = NULL;
2121   bvptr bv = NULL;
2122 
2123   buf[0] = 0;
2124 
2125   if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))  /* seek to real xact trace if present... */
2126         {
2127         Trptr tscan = t;
2128         int bcnt = 0;
2129         while((tscan) && (tscan = GivePrevTrace(tscan)))
2130                 {
2131                 if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
2132                         {
2133                         if(tscan->flags & TR_TTRANSLATED)
2134                                 {
2135                                 break; /* found it */
2136                                 }
2137                                 else
2138                                 {
2139                                 tscan = NULL;
2140                                 }
2141                         }
2142                         else
2143                         {
2144                         bcnt++; /* bcnt is number of blank traces */
2145                         }
2146                 }
2147 
2148         if((tscan)&&(tscan->vector))
2149                 {
2150                 bv = tscan->n.vec;
2151                 do
2152                         {
2153                         bv = bv->transaction_chain; /* correlate to blank trace */
2154                         } while(bv && (bcnt--));
2155                 if(bv)
2156                         {
2157                         subname = bv->bvname;
2158                         if(GLOBALS->hier_max_level)
2159                                 subname = hier_extract(subname, GLOBALS->hier_max_level);
2160                         }
2161                 }
2162         }
2163 
2164   populateBuffer(t, subname, buf);
2165 
2166   clr_comment  = GLOBALS->gc.gc_brkred;
2167   clr_group    = GLOBALS->gc.gc_gmstrd;
2168   clr_shadowed = GLOBALS->gc.gc_ltblue;
2169   clr_signal   = GLOBALS->gc.gc_dkblue;
2170 
2171   UpdateSigValue(t); /* in case it's stale on nonprop */
2172 
2173   liney=((i+2)*GLOBALS->fontheight)-2;
2174   texty=liney-(GLOBALS->signalfont->descent);
2175 
2176   retval=liney-GLOBALS->fontheight+1;
2177 
2178   left_justify = ((IsGroupBegin(t) || IsGroupEnd(t)) && !HasWave(t))|| GLOBALS->left_justify_sigs;
2179 
2180   if (IsSelected(t))
2181     {
2182       bg_color = (!HasWave(t))
2183 	? ((IsGroupBegin(t) || IsGroupEnd(t)) ? clr_group : clr_comment)
2184 	: ((IsShadowed(t)) ? clr_shadowed : clr_signal);
2185       text_color = GLOBALS->gc_white;
2186     }
2187   else
2188     {
2189       bg_color = (dobackground==2) ?  GLOBALS->gc.gc_normal : GLOBALS->gc.gc_ltgray;
2190       if(HasWave(t))
2191 	{ text_color = GLOBALS->gc_black; }
2192       else
2193 	{ text_color = (IsGroupBegin(t) || IsGroupEnd(t)) ? clr_group : clr_comment; }
2194     }
2195 
2196   if (dobackground || IsSelected(t))
2197     {
2198 
2199       gdk_draw_rectangle(GLOBALS->signalpixmap, bg_color, TRUE,
2200 			 0, retval,
2201 			 GLOBALS->signal_fill_width, GLOBALS->fontheight-1);
2202 
2203     }
2204 
2205   gdk_draw_line(GLOBALS->signalpixmap,
2206 		GLOBALS->gc_white,
2207 		0, liney,
2208 		GLOBALS->signal_fill_width-1, liney);
2209 
2210   if((t->name)||(subname))
2211     {
2212       font_engine_draw_string(GLOBALS->signalpixmap,
2213 			      GLOBALS->signalfont,
2214 			      text_color,
2215 			      left_justify?3:3+GLOBALS->max_signal_name_pixel_width-
2216 			      font_engine_string_measure(GLOBALS->signalfont, buf),
2217 			      texty,
2218 			      buf);
2219 
2220 
2221     }
2222 
2223   if (HasWave(t) || bv)
2224     {
2225       if((t->asciivalue)&&(!(t->flags&TR_EXCLUDE)))
2226 	font_engine_draw_string(GLOBALS->signalpixmap,
2227 				GLOBALS->signalfont,
2228 				text_color,
2229 				GLOBALS->max_signal_name_pixel_width+6,
2230 				texty,
2231 				t->asciivalue);
2232     }
2233 
2234   return(retval);
2235 }
2236 
2237 
2238 /***************************************************************************/
2239 
MaxSignalLength(void)2240 void MaxSignalLength(void)
2241 {
2242 Trptr t;
2243 int len=0,maxlen=0;
2244 int vlen=0, vmaxlen=0;
2245 char buf[2048];
2246 char dirty_kick;
2247 bvptr bv;
2248 Trptr tscan;
2249 
2250 DEBUG(printf("signalwindow_width_dirty: %d\n",GLOBALS->signalwindow_width_dirty));
2251 
2252 if((!GLOBALS->signalwindow_width_dirty)&&(GLOBALS->use_nonprop_fonts)) return;
2253 
2254 dirty_kick = GLOBALS->signalwindow_width_dirty;
2255 GLOBALS->signalwindow_width_dirty=0;
2256 
2257 t=GLOBALS->traces.first;
2258 
2259 
2260 while(t)
2261   {
2262   char *subname = NULL;
2263   bv = NULL;
2264   tscan = NULL;
2265 
2266   if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))  /* seek to real xact trace if present... */
2267         {
2268         int bcnt = 0;
2269         tscan = t;
2270         while((tscan) && (tscan = GivePrevTrace(tscan)))
2271                 {
2272                 if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
2273                         {
2274                         if(tscan->flags & TR_TTRANSLATED)
2275                                 {
2276                                 break; /* found it */
2277                                 }
2278                                 else
2279                                 {
2280                                 tscan = NULL;
2281                                 }
2282                         }
2283                         else
2284                         {
2285                         bcnt++; /* bcnt is number of blank traces */
2286                         }
2287                 }
2288 
2289         if((tscan)&&(tscan->vector))
2290                 {
2291                 bv = tscan->n.vec;
2292                 do
2293                         {
2294                         bv = bv->transaction_chain; /* correlate to blank trace */
2295                         } while(bv && (bcnt--));
2296                 if(bv)
2297                         {
2298                         subname = bv->bvname;
2299                         if(GLOBALS->hier_max_level)
2300                                 subname = hier_extract(subname, GLOBALS->hier_max_level);
2301                         }
2302                 }
2303         }
2304 
2305     populateBuffer(t, subname, buf);
2306 
2307     if(!bv && (t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))	/* for "comment" style blank traces */
2308       {
2309 	if(t->name || subname)
2310 	  {
2311 	    len=font_engine_string_measure(GLOBALS->signalfont, buf);
2312 	    if(len>maxlen) maxlen=len;
2313 	  }
2314 
2315 	if(t->asciivalue)
2316 		{
2317 		free_2(t->asciivalue); t->asciivalue = NULL;
2318 		}
2319 	t=GiveNextTrace(t);
2320       }
2321     else
2322       if(t->name || subname)
2323 	{
2324 	  len=font_engine_string_measure(GLOBALS->signalfont, buf);
2325 	  if(len>maxlen) maxlen=len;
2326 
2327 	  if((GLOBALS->tims.marker!=-1)&&(!(t->flags&TR_EXCLUDE)))
2328 		{
2329 		t->asciitime=GLOBALS->tims.marker;
2330 		if(t->asciivalue) { free_2(t->asciivalue); } t->asciivalue = NULL;
2331 
2332 		if(bv || t->vector)
2333 			{
2334 			char *str, *str2;
2335 			vptr v;
2336 			Trptr ts;
2337 			TraceEnt t_temp;
2338 
2339 			if(bv)
2340 				{
2341 				ts = &t_temp;
2342 				memcpy(ts, tscan, sizeof(TraceEnt));
2343 				ts->vector = 1;
2344 				ts->n.vec = bv;
2345 				}
2346 				else
2347 				{
2348 				ts = t;
2349 				bv = t->n.vec;
2350 				}
2351 
2352 
2353                         v=bsearch_vector(bv, GLOBALS->tims.marker - ts->shift);
2354                         str=convert_ascii(ts,v);
2355 			if(str)
2356 				{
2357 				str2=(char *)malloc_2(strlen(str)+2);
2358 				*str2='=';
2359 				strcpy(str2+1,str);
2360 				free_2(str);
2361 
2362 				vlen=font_engine_string_measure(GLOBALS->signalfont,str2);
2363 				t->asciivalue=str2;
2364 				}
2365 				else
2366 				{
2367 				vlen=0;
2368 				t->asciivalue=NULL;
2369 				}
2370 			}
2371 			else
2372 			{
2373 			char *str;
2374 			hptr h_ptr;
2375 			if((h_ptr=bsearch_node(t->n.nd,GLOBALS->tims.marker - t->shift)))
2376 				{
2377 				if(!t->n.nd->extvals)
2378 					{
2379 					unsigned char h_val = h_ptr->v.h_val;
2380 
2381 					str=(char *)calloc_2(1,3*sizeof(char));
2382 					str[0]='=';
2383 					if(t->n.nd->vartype == ND_VCD_EVENT)
2384 						{
2385 						h_val = (h_ptr->time >= GLOBALS->tims.first) && ((GLOBALS->tims.marker-GLOBALS->shift_timebase) == h_ptr->time) ? AN_1 : AN_0; /* generate impulse */
2386 						}
2387 
2388 					if(t->flags&TR_INVERT)
2389 						{
2390 						str[1]=AN_STR_INV[h_val];
2391 						}
2392 						else
2393 						{
2394 						str[1]=AN_STR[h_val];
2395 						}
2396 					t->asciivalue=str;
2397 					vlen=font_engine_string_measure(GLOBALS->signalfont,str);
2398 					}
2399 					else
2400 					{
2401 					char *str2;
2402 
2403 					if(h_ptr->flags&HIST_REAL)
2404 						{
2405 						if(!(h_ptr->flags&HIST_STRING))
2406 							{
2407 #ifdef WAVE_HAS_H_DOUBLE
2408 							str=convert_ascii_real(t, &h_ptr->v.h_double);
2409 #else
2410 							str=convert_ascii_real(t, (double *)h_ptr->v.h_vector);
2411 #endif
2412 							}
2413 							else
2414 							{
2415 							str=convert_ascii_string((char *)h_ptr->v.h_vector);
2416 							}
2417 						}
2418 						else
2419 						{
2420 		                        	str=convert_ascii_vec(t,h_ptr->v.h_vector);
2421 						}
2422 
2423 					if(str)
2424 						{
2425 						str2=(char *)malloc_2(strlen(str)+2);
2426 						*str2='=';
2427 						strcpy(str2+1,str);
2428 
2429 						free_2(str);
2430 
2431 						vlen=font_engine_string_measure(GLOBALS->signalfont,str2);
2432 						t->asciivalue=str2;
2433 						}
2434 						else
2435 						{
2436 						vlen=0;
2437 						t->asciivalue=NULL;
2438 						}
2439 					}
2440 				}
2441 				else
2442 				{
2443 				vlen=0;
2444 				t->asciivalue=NULL;
2445 				}
2446 			}
2447 
2448 		if(vlen>vmaxlen)
2449 			{
2450 			vmaxlen=vlen;
2451 			}
2452 		}
2453 
2454 	t=GiveNextTrace(t);
2455 	}
2456 	else
2457 	{
2458 	t=GiveNextTrace(t);
2459 	}
2460 }
2461 
2462 GLOBALS->max_signal_name_pixel_width = maxlen;
2463 GLOBALS->signal_pixmap_width=maxlen+6; 		/* 2 * 3 pixel pad */
2464 if(GLOBALS->tims.marker!=-1)
2465 	{
2466 	GLOBALS->signal_pixmap_width+=(vmaxlen+6);
2467 	if(GLOBALS->signal_pixmap_width > 32767) GLOBALS->signal_pixmap_width = 32767; /* fixes X11 protocol limitation crash */
2468 	}
2469 
2470 GLOBALS->tims.resizemarker2 = GLOBALS->tims.resizemarker;
2471 GLOBALS->tims.resizemarker = GLOBALS->tims.marker;
2472 
2473 if(GLOBALS->signal_pixmap_width<60) GLOBALS->signal_pixmap_width=60;
2474 
2475 MaxSignalLength_2(dirty_kick);
2476 }
2477 
2478 
MaxSignalLength_2(char dirty_kick)2479 void MaxSignalLength_2(char dirty_kick)
2480 {
2481 if(!GLOBALS->in_button_press_wavewindow_c_1)
2482 	{
2483 	if(!GLOBALS->do_resize_signals)
2484 		{
2485 		int os;
2486 		os=48;
2487 		if(GLOBALS->initial_signal_window_width > os)
2488 			{
2489 			os = GLOBALS->initial_signal_window_width;
2490 			}
2491 
2492 		if(GLOBALS->signalwindow)
2493 			{
2494 			  /* printf("VALUES: %d %d %d\n", GLOBALS->initial_signal_window_width, GLOBALS->signalwindow->allocation.width, GLOBALS->max_signal_name_pixel_width); */
2495 			  if (GLOBALS->first_unsized_signals && GLOBALS->max_signal_name_pixel_width !=0)
2496 			    {
2497 			      GLOBALS->first_unsized_signals = 0;
2498 			      gtk_paned_set_position(GTK_PANED(GLOBALS->panedwindow), GLOBALS->max_signal_name_pixel_width+30);
2499 			    } else {
2500 			      gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1);
2501 		            }
2502 			}
2503 		}
2504 	else
2505 	if((GLOBALS->do_resize_signals)&&(GLOBALS->signalwindow))
2506 		{
2507 		int oldusize;
2508 		int rs;
2509 
2510                 if(GLOBALS->initial_signal_window_width > GLOBALS->max_signal_name_pixel_width)
2511                         {
2512                         rs=GLOBALS->initial_signal_window_width;
2513                         }
2514                         else
2515                         {
2516                         rs=GLOBALS->max_signal_name_pixel_width;
2517                         }
2518 
2519 
2520 		oldusize=GLOBALS->signalwindow->allocation.width;
2521 		if((oldusize!=rs)||(dirty_kick))
2522 			{ /* keep signalwindow from expanding arbitrarily large */
2523 #ifdef WAVE_USE_GTK2
2524 			int wx, wy;
2525 			get_window_size(&wx, &wy);
2526 
2527 			if((3*rs) < (2*wx))	/* 2/3 width max */
2528 #else
2529 			if((3*rs) < (2*(GLOBALS->wavewidth + GLOBALS->signalwindow->allocation.width)))
2530 #endif
2531 				{
2532 				int os;
2533 				os=rs;
2534 				os=(os<48)?48:os;
2535 				gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow),
2536 						os+30, -1);
2537 				}
2538 				else
2539 				{
2540 				int os;
2541 				os=48;
2542 		                if(GLOBALS->initial_signal_window_width > os)
2543                 		        {
2544 		                        os = GLOBALS->initial_signal_window_width;
2545 		                        }
2546 
2547 				gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow),
2548 						os+30, -1);
2549 				}
2550 			}
2551 		}
2552 	}
2553 }
2554 
2555 /***************************************************************************/
2556 
UpdateSigValue(Trptr t)2557 void UpdateSigValue(Trptr t)
2558 {
2559 bvptr bv = NULL;
2560 Trptr tscan = NULL;
2561 
2562 if(!t) return;
2563 if((t->asciivalue)&&(t->asciitime==GLOBALS->tims.marker))return;
2564 
2565 if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))  /* seek to real xact trace if present... */
2566         {
2567         int bcnt = 0;
2568         tscan = t;
2569         while((tscan) && (tscan = GivePrevTrace(tscan)))
2570                 {
2571                 if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
2572                         {
2573                         if(tscan->flags & TR_TTRANSLATED)
2574                                 {
2575                                 break; /* found it */
2576                                 }
2577                                 else
2578                                 {
2579                                 tscan = NULL;
2580                                 }
2581                         }
2582                         else
2583                         {
2584                         bcnt++; /* bcnt is number of blank traces */
2585                         }
2586                 }
2587 
2588         if((tscan)&&(tscan->vector))
2589                 {
2590                 bv = tscan->n.vec;
2591                 do
2592                         {
2593                         bv = bv->transaction_chain; /* correlate to blank trace */
2594                         } while(bv && (bcnt--));
2595                 if(bv)
2596                         {
2597 			/* nothing, we just want to set bv */
2598                         }
2599                 }
2600         }
2601 
2602 
2603 if((t->name || bv)&&(bv || !(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))))
2604 	{
2605 	GLOBALS->shift_timebase=t->shift;
2606 	DEBUG(printf("UpdateSigValue: %s\n",t->name));
2607 
2608 	if((GLOBALS->tims.marker!=-1)&&(!(t->flags&TR_EXCLUDE)))
2609 		{
2610 		t->asciitime=GLOBALS->tims.marker;
2611 		if(t->asciivalue) free_2(t->asciivalue);
2612 
2613 		if(bv || t->vector)
2614 			{
2615 			char *str, *str2;
2616 			vptr v;
2617                         Trptr ts;
2618                         TraceEnt t_temp;
2619 
2620                         if(bv)
2621                                 {
2622                                 ts = &t_temp;
2623                                 memcpy(ts, tscan, sizeof(TraceEnt));
2624                                 ts->vector = 1;
2625                                 ts->n.vec = bv;
2626                                 }
2627                                 else
2628                                 {
2629                                 ts = t;
2630                                 bv = t->n.vec;
2631 				}
2632 
2633                         v=bsearch_vector(bv,GLOBALS->tims.marker - ts->shift);
2634                         str=convert_ascii(ts,v);
2635 			if(str)
2636 				{
2637 				str2=(char *)malloc_2(strlen(str)+2);
2638 				*str2='=';
2639 				strcpy(str2+1,str);
2640 				free_2(str);
2641 
2642 				t->asciivalue=str2;
2643 				}
2644 				else
2645 				{
2646 				t->asciivalue=NULL;
2647 				}
2648 			}
2649 			else
2650 			{
2651 			char *str;
2652 			hptr h_ptr;
2653 			if((h_ptr=bsearch_node(t->n.nd,GLOBALS->tims.marker - t->shift)))
2654 				{
2655 				if(!t->n.nd->extvals)
2656 					{
2657 					unsigned char h_val = h_ptr->v.h_val;
2658 					if(t->n.nd->vartype == ND_VCD_EVENT)
2659 						{
2660 						h_val = (h_ptr->time >= GLOBALS->tims.first) && ((GLOBALS->tims.marker-GLOBALS->shift_timebase) == h_ptr->time) ? AN_1 : AN_0; /* generate impulse */
2661 						}
2662 
2663 					str=(char *)calloc_2(1,3*sizeof(char));
2664 					str[0]='=';
2665 					if(t->flags&TR_INVERT)
2666 						{
2667 						str[1]=AN_STR_INV[h_val];
2668 						}
2669 						else
2670 						{
2671 						str[1]=AN_STR[h_val];
2672 						}
2673 					t->asciivalue=str;
2674 					}
2675 					else
2676 					{
2677 					char *str2;
2678 
2679 					if(h_ptr->flags&HIST_REAL)
2680 						{
2681 						if(!(h_ptr->flags&HIST_STRING))
2682 							{
2683 #ifdef WAVE_HAS_H_DOUBLE
2684 							str=convert_ascii_real(t, &h_ptr->v.h_double);
2685 #else
2686 							str=convert_ascii_real(t, (double *)h_ptr->v.h_vector);
2687 #endif
2688 							}
2689 							else
2690 							{
2691 							str=convert_ascii_string((char *)h_ptr->v.h_vector);
2692 							}
2693 						}
2694 						else
2695 						{
2696 		                        	str=convert_ascii_vec(t,h_ptr->v.h_vector);
2697 						}
2698 
2699 					if(str)
2700 						{
2701 						str2=(char *)malloc_2(strlen(str)+2);
2702 						*str2='=';
2703 						strcpy(str2+1,str);
2704 						free_2(str);
2705 
2706 						t->asciivalue=str2;
2707 						}
2708 						else
2709 						{
2710 						t->asciivalue=NULL;
2711 						}
2712 					}
2713 				}
2714 				else
2715 				{
2716 				t->asciivalue=NULL;
2717 				}
2718 			}
2719 		}
2720 	}
2721 }
2722 
2723 /***************************************************************************/
2724 
calczoom(gdouble z0)2725 void calczoom(gdouble z0)
2726 {
2727 gdouble ppf, frame;
2728 ppf=((gdouble)(GLOBALS->pixelsperframe=200));
2729 frame=pow(GLOBALS->zoombase,-z0);
2730 
2731 if(frame>((gdouble)MAX_HISTENT_TIME/(gdouble)4.0))
2732 	{
2733 	GLOBALS->nsperframe=((gdouble)MAX_HISTENT_TIME/(gdouble)4.0);
2734 	}
2735 	else
2736 	if(frame<(gdouble)1.0)
2737 	{
2738 	GLOBALS->nsperframe=1.0;
2739 	}
2740 	else
2741 	{
2742 	GLOBALS->nsperframe=frame;
2743 	}
2744 
2745 GLOBALS->hashstep=10.0;
2746 
2747 if(GLOBALS->zoom_pow10_snap)
2748 if(GLOBALS->nsperframe>10.0)
2749 	{
2750 	TimeType nsperframe2;
2751 	gdouble p=10.0;
2752 	gdouble scale;
2753 	int l;
2754 	l=(int)((log(GLOBALS->nsperframe)/log(p))+0.5);	/* nearest power of 10 */
2755 	nsperframe2=pow(p, (gdouble)l);
2756 
2757 	scale = (gdouble)nsperframe2 / (gdouble)GLOBALS->nsperframe;
2758 	ppf *= scale;
2759 	GLOBALS->pixelsperframe = ppf;
2760 
2761 	GLOBALS->nsperframe = nsperframe2;
2762 	GLOBALS->hashstep = ppf / 10.0;
2763 	}
2764 
2765 GLOBALS->nspx=GLOBALS->nsperframe/ppf;
2766 GLOBALS->pxns=ppf/GLOBALS->nsperframe;
2767 
2768 time_trunc_set();	/* map nspx to rounding value */
2769 
2770 DEBUG(printf("Zoom: %e Pixelsperframe: %d, nsperframe: %e\n",z0, (int)GLOBALS->pixelsperframe,(float)GLOBALS->nsperframe));
2771 }
2772 
renderhash(int x,TimeType tim)2773 static void renderhash(int x, TimeType tim)
2774 {
2775 TimeType rborder;
2776 int fhminus2;
2777 int rhs;
2778 gdouble dx;
2779 gdouble hashoffset;
2780 int iter = 0;
2781 int s_ctx_iter;
2782 int timearray_encountered = (GLOBALS->ruler_step != 0);
2783 
2784 fhminus2=GLOBALS->fontheight-2;
2785 
2786 WAVE_STRACE_ITERATOR(s_ctx_iter)
2787 	{
2788 	GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter];
2789 	if(GLOBALS->strace_ctx->timearray)
2790 		{
2791 		timearray_encountered = 1;
2792 		break;
2793 		}
2794 	}
2795 
2796 gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,x, 0,x,
2797 	((!timearray_encountered)&&(GLOBALS->display_grid)&&(GLOBALS->enable_vert_grid))?GLOBALS->waveheight:fhminus2);
2798 
2799 if(tim==GLOBALS->tims.last) return;
2800 
2801 rborder=(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns;
2802 DEBUG(printf("Rborder: %lld, Wavewidth: %d\n", rborder, GLOBALS->wavewidth));
2803 if(rborder>GLOBALS->wavewidth) rborder=GLOBALS->wavewidth;
2804 if((rhs=x+GLOBALS->pixelsperframe)>rborder) rhs=rborder;
2805 
2806 gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,x, GLOBALS->wavecrosspiece,rhs, GLOBALS->wavecrosspiece);
2807 
2808 dx = x + (hashoffset=GLOBALS->hashstep);
2809 x  = dx;
2810 
2811 while((hashoffset<GLOBALS->pixelsperframe)&&(x<=rhs)&&(iter<9))
2812 	{
2813 	gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,x, GLOBALS->wavecrosspiece,x, fhminus2);
2814 
2815 	hashoffset+=GLOBALS->hashstep;
2816 	dx=dx+GLOBALS->hashstep;
2817 	if((GLOBALS->pixelsperframe!=200)||(GLOBALS->hashstep!=10.0)) iter++; /* fix any roundoff errors */
2818 	x = dx;
2819 	}
2820 
2821 }
2822 
rendertimes(void)2823 static void rendertimes(void)
2824 {
2825 int lastx = -1000; /* arbitrary */
2826 int x, lenhalf;
2827 TimeType tim, rem;
2828 char timebuff[32];
2829 char prevover=0;
2830 gdouble realx;
2831 int s_ctx_iter;
2832 int timearray_encountered = 0;
2833 
2834 renderblackout();
2835 
2836 tim=GLOBALS->tims.start;
2837 GLOBALS->tims.end=GLOBALS->tims.start+(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
2838 
2839 wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */
2840 
2841 /***********/
2842 WAVE_STRACE_ITERATOR_FWD(s_ctx_iter)
2843 	{
2844 	GdkGC * gc;
2845 
2846 	if(!s_ctx_iter)
2847 		{
2848 		gc = GLOBALS->gc.gc_grid_wavewindow_c_1;
2849 		}
2850 		else
2851 		{
2852 		gc = GLOBALS->gc.gc_grid2_wavewindow_c_1;
2853 		gdk_gc_set_line_attributes(gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_BEVEL);
2854 		}
2855 
2856 	GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter];
2857 
2858 	if(GLOBALS->strace_ctx->timearray)
2859 		{
2860 		int pos, pos2;
2861 		TimeType *t, tm;
2862 		int y=GLOBALS->fontheight+2;
2863 		int oldx=-1;
2864 
2865 		timearray_encountered = 1;
2866 
2867 		pos=bsearch_timechain(GLOBALS->tims.start);
2868 		top:
2869 		if((pos>=0)&&(pos<GLOBALS->strace_ctx->timearray_size))
2870 			{
2871 			t=GLOBALS->strace_ctx->timearray+pos;
2872 			for(;pos<GLOBALS->strace_ctx->timearray_size;t++, pos++)
2873 				{
2874 				tm=*t;
2875 				if(tm>=GLOBALS->tims.start)
2876 					{
2877 					if(tm<=GLOBALS->tims.end)
2878 						{
2879 						x=(tm-GLOBALS->tims.start)*GLOBALS->pxns;
2880 						if(oldx==x)
2881 							{
2882 							pos2=bsearch_timechain(GLOBALS->tims.start+(((gdouble)(x+1))*GLOBALS->nspx));
2883 							if(pos2>pos) { pos=pos2; goto top; } else continue;
2884 							}
2885 						oldx=x;
2886 						gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gc, x, y, x, GLOBALS->waveheight);
2887 						}
2888 						else
2889 						{
2890 						break;
2891 						}
2892 					}
2893 				}
2894 			}
2895 		}
2896 
2897 
2898 	wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */
2899 
2900 	if(s_ctx_iter)
2901 		{
2902 		gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_BEVEL);
2903 		}
2904 	}
2905 
2906 GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = 0];
2907 /***********/
2908 
2909 if(GLOBALS->ruler_step && !timearray_encountered)
2910 	{
2911 	TimeType rhs = (GLOBALS->tims.end > GLOBALS->tims.last) ? GLOBALS->tims.last : GLOBALS->tims.end;
2912 	TimeType low_x = (GLOBALS->tims.start - GLOBALS->ruler_origin) / GLOBALS->ruler_step;
2913 	TimeType high_x = (rhs - GLOBALS->ruler_origin) / GLOBALS->ruler_step;
2914 	TimeType iter_x, tm;
2915         int y=GLOBALS->fontheight+2;
2916         int oldx=-1;
2917 
2918 	for(iter_x = low_x; iter_x <= high_x; iter_x++)
2919 		{
2920 		tm = GLOBALS->ruler_step * iter_x +  GLOBALS->ruler_origin;
2921 		x=(tm-GLOBALS->tims.start)*GLOBALS->pxns;
2922 		if(oldx==x)
2923 			{
2924 			gdouble xd,offset,pixstep;
2925 			TimeType newcurr;
2926 
2927 			xd=x+1;  /* for pix time calc */
2928 
2929 			pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe);
2930 			newcurr=(TimeType)(offset=((gdouble)GLOBALS->tims.start)+(xd*pixstep));
2931 
2932 			if(offset-newcurr>0.5)  /* round to nearest integer ns */
2933 			        {
2934 			        newcurr++;
2935 			        }
2936 
2937 			low_x = (newcurr - GLOBALS->ruler_origin) / GLOBALS->ruler_step;
2938 			if(low_x <= iter_x) low_x = (iter_x+1);
2939 			iter_x = low_x;
2940 			tm = GLOBALS->ruler_step * iter_x +  GLOBALS->ruler_origin;
2941 			x=(tm-GLOBALS->tims.start)*GLOBALS->pxns;
2942 			}
2943 
2944 		if(x>=GLOBALS->wavewidth) break;
2945 		oldx=x;
2946 		gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, x, y, x, GLOBALS->waveheight);
2947 		}
2948 	}
2949 
2950 wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */
2951 
2952 /***********/
2953 
2954 DEBUG(printf("Ruler Start time: "TTFormat", Finish time: "TTFormat"\n",GLOBALS->tims.start, GLOBALS->tims.end));
2955 
2956 x=0;
2957 realx=0;
2958 if(tim)
2959 	{
2960 	rem=tim%((TimeType)GLOBALS->nsperframe);
2961 	if(rem)
2962 		{
2963 		tim=tim-GLOBALS->nsperframe-rem;
2964 		x=-GLOBALS->pixelsperframe-((rem*GLOBALS->pixelsperframe)/GLOBALS->nsperframe);
2965 		realx=-GLOBALS->pixelsperframe-((rem*GLOBALS->pixelsperframe)/GLOBALS->nsperframe);
2966 		}
2967 	}
2968 
2969 for(;;)
2970 	{
2971 	renderhash(realx, tim);
2972 
2973 	if(tim + GLOBALS->global_time_offset)
2974 		{
2975 		if(tim != GLOBALS->min_time)
2976 			{
2977 			reformat_time(timebuff, time_trunc(tim) + GLOBALS->global_time_offset, GLOBALS->time_dimension);
2978 			}
2979 			else
2980 			{
2981 			timebuff[0] = 0;
2982 			}
2983 		}
2984 		else
2985 		{
2986 		strcpy(timebuff, "0");
2987 		}
2988 
2989 	lenhalf=font_engine_string_measure(GLOBALS->wavefont, timebuff) >> 1;
2990 
2991 	if((x-lenhalf >= lastx) || (GLOBALS->pixelsperframe >= 200))
2992 		{
2993 		font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_time_wavewindow_c_1,x-lenhalf, GLOBALS->wavefont->ascent-1,timebuff);
2994 
2995 		lastx = x+lenhalf;
2996 		}
2997 
2998 	tim+=GLOBALS->nsperframe;
2999 	x+=GLOBALS->pixelsperframe;
3000 	realx+=GLOBALS->pixelsperframe;
3001 	if((prevover)||(tim>GLOBALS->tims.last)) break;
3002 	if(x>=GLOBALS->wavewidth) prevover=1;
3003 	}
3004 }
3005 
3006 /***************************************************************************/
3007 
rendertimebar(void)3008 static void rendertimebar(void)
3009 {
3010 gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_timeb_wavewindow_c_1, TRUE,0, -1, GLOBALS->wavewidth, GLOBALS->fontheight);
3011 rendertimes();
3012 rendertraces();
3013 
3014 update_dual();
3015 }
3016 
3017 
gc_save(Trptr t,struct wave_gcmaster_t * gc_sav)3018 static void gc_save(Trptr t, struct wave_gcmaster_t *gc_sav)
3019 {
3020 if((!GLOBALS->black_and_white) && (t->t_color))
3021 	{
3022 	int color = t->t_color;
3023 
3024 	color--;
3025 
3026 	memcpy(gc_sav, &GLOBALS->gc, sizeof(struct wave_gcmaster_t));
3027 
3028 	if(color < WAVE_NUM_RAINBOW)
3029 		{
3030 		set_alternate_gcs(GLOBALS->gc_rainbow[2*color], GLOBALS->gc_rainbow[2*color+1]);
3031 		}
3032 	}
3033 }
3034 
gc_restore(Trptr t,struct wave_gcmaster_t * gc_sav)3035 static void gc_restore(Trptr t, struct wave_gcmaster_t *gc_sav)
3036 {
3037 if((!GLOBALS->black_and_white) && (t->t_color))
3038 	{
3039 	memcpy(&GLOBALS->gc, gc_sav, sizeof(struct wave_gcmaster_t));
3040 	}
3041 }
3042 
3043 
rendertraces(void)3044 static void rendertraces(void)
3045 {
3046 struct wave_gcmaster_t gc_sav;
3047 
3048 if(!GLOBALS->topmost_trace)
3049 	{
3050 	GLOBALS->topmost_trace=GLOBALS->traces.first;
3051 	}
3052 
3053 if(GLOBALS->topmost_trace)
3054 	{
3055 	Trptr t = GLOBALS->topmost_trace;
3056 	Trptr tback = t;
3057 	hptr h;
3058 	vptr v;
3059 	int i = 0, num_traces_displayable;
3060 	int iback = 0;
3061 
3062 	num_traces_displayable=GLOBALS->wavearea->allocation.height/(GLOBALS->fontheight);
3063 	num_traces_displayable--;   /* for the time trace that is always there */
3064 
3065 	/* ensure that transaction traces are visible even if the topmost traces are blanks */
3066 	while(tback)
3067 		{
3068 		if(tback->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))
3069 			{
3070 			tback = GivePrevTrace(tback);
3071 			iback--;
3072 			}
3073 		else if(tback->flags & TR_TTRANSLATED)
3074 			{
3075 			if(tback != t)
3076 				{
3077 				t = tback;
3078 				i = iback;
3079 				}
3080 			break;
3081 			}
3082 		else
3083 			{
3084 			break;
3085 			}
3086 		}
3087 
3088 	for(;((i<num_traces_displayable)&&(t));i++)
3089 		{
3090 		if(!(t->flags&(TR_EXCLUDE|TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
3091 			{
3092 			GLOBALS->shift_timebase=t->shift;
3093 			if(!t->vector)
3094 				{
3095 				h=bsearch_node(t->n.nd, GLOBALS->tims.start - t->shift);
3096 				DEBUG(printf("Start time: "TTFormat", Histent time: "TTFormat"\n", GLOBALS->tims.start,(h->time+GLOBALS->shift_timebase)));
3097 
3098 				if(!t->n.nd->extvals)
3099 					{
3100 					if(i>=0)
3101 						{
3102 						gc_save(t, &gc_sav);
3103 						draw_hptr_trace(t,h,i,1,0);
3104 						gc_restore(t, &gc_sav);
3105 						}
3106 					}
3107 					else
3108 					{
3109 					if(i>=0)
3110 						{
3111 						gc_save(t, &gc_sav);
3112 						draw_hptr_trace_vector(t,h,i);
3113 						gc_restore(t, &gc_sav);
3114 						}
3115 					}
3116 				}
3117 				else
3118 				{
3119 				Trptr t_orig, tn;
3120 				bvptr bv = t->n.vec;
3121 
3122 				v=bsearch_vector(bv, GLOBALS->tims.start - t->shift);
3123 				DEBUG(printf("Vector Trace: %s, %s\n", t->name, bv->bvname));
3124 				DEBUG(printf("Start time: "TTFormat", Vectorent time: "TTFormat"\n", GLOBALS->tims.start,(v->time+GLOBALS->shift_timebase)));
3125 				if(i>=0)
3126 					{
3127 					gc_save(t, &gc_sav);
3128 					draw_vptr_trace(t,v,i);
3129 					gc_restore(t, &gc_sav);
3130 					}
3131 
3132 				if((bv->transaction_chain) && (t->flags & TR_TTRANSLATED))
3133 					{
3134 					t_orig = t;
3135 					for(;;)
3136 						{
3137 						tn = GiveNextTrace(t);
3138 						bv = bv->transaction_chain;
3139 
3140 						if(bv && tn && (tn->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
3141 							{
3142 							i++;
3143 							if(i<num_traces_displayable)
3144 								{
3145 								v=bsearch_vector(bv, GLOBALS->tims.start - t->shift);
3146 								if(i>=0)
3147 									{
3148 									gc_save(t, &gc_sav);
3149 									draw_vptr_trace(t_orig,v,i);
3150 									gc_restore(t, &gc_sav);
3151 									}
3152 								t = tn;
3153 								continue;
3154 								}
3155 							}
3156 						break;
3157 						}
3158 					}
3159 				}
3160 			}
3161 			else
3162 			{
3163 			int kill_dodraw_grid = t->flags & TR_ANALOG_BLANK_STRETCH;
3164 
3165 			if(kill_dodraw_grid)
3166 				{
3167 				Trptr tn = GiveNextTrace(t);
3168 				if(!tn)
3169 					{
3170 					kill_dodraw_grid = 0;
3171 					}
3172 				else
3173 				if(!(tn->flags & TR_ANALOG_BLANK_STRETCH))
3174 					{
3175 					kill_dodraw_grid = 0;
3176 					}
3177 				}
3178 
3179 			if(i>=0)
3180 				{
3181 				gc_save(t, &gc_sav);
3182 				draw_hptr_trace(NULL,NULL,i,0,kill_dodraw_grid);
3183 				gc_restore(t, &gc_sav);
3184 				}
3185 			}
3186 		t=GiveNextTrace(t);
3187 /* bot:		1; */
3188 		}
3189 	}
3190 
3191 
3192 draw_named_markers();
3193 draw_marker_partitions();
3194 
3195 if(GLOBALS->traces.dirty)
3196 	{
3197 	char dbuf[32];
3198 	sprintf(dbuf, "%d", GLOBALS->traces.total);
3199 	GLOBALS->traces.dirty = 0;
3200 	gtkwavetcl_setvar(WAVE_TCLCB_TRACES_UPDATED, dbuf, WAVE_TCLCB_TRACES_UPDATED_FLAGS);
3201 	}
3202 }
3203 
3204 
3205 /*
3206  * draw single traces and use this for rendering the grid lines
3207  * for "excluded" traces
3208  */
draw_hptr_trace(Trptr t,hptr h,int which,int dodraw,int kill_grid)3209 static void draw_hptr_trace(Trptr t, hptr h, int which, int dodraw, int kill_grid)
3210 {
3211 TimeType _x0, _x1, newtime;
3212 int _y0, _y1, yu, liney, ytext;
3213 TimeType tim, h2tim;
3214 hptr h2, h3;
3215 char hval, h2val, invert;
3216 GdkGC    *c;
3217 GdkGC    *gcx, *gcxf;
3218 char identifier_str[2];
3219 int is_event = t && t->n.nd && (t->n.nd->vartype == ND_VCD_EVENT);
3220 
3221 GLOBALS->tims.start-=GLOBALS->shift_timebase;
3222 GLOBALS->tims.end-=GLOBALS->shift_timebase;
3223 
3224 liney=((which+2)*GLOBALS->fontheight)-2;
3225 if(((t)&&(t->flags&TR_INVERT))&&(!is_event))
3226 	{
3227 	_y0=((which+1)*GLOBALS->fontheight)+2;
3228 	_y1=liney-2;
3229 	invert=1;
3230 	}
3231 	else
3232 	{
3233 	_y1=((which+1)*GLOBALS->fontheight)+2;
3234 	_y0=liney-2;
3235 	invert=0;
3236 	}
3237 yu=(_y0+_y1)/2;
3238 ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent;
3239 
3240 if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)&&(!kill_grid))
3241 	{
3242 	gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
3243 		TRUE,0, liney - GLOBALS->fontheight,
3244 		GLOBALS->wavewidth, GLOBALS->fontheight);
3245 	}
3246 else
3247 if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid)&&(!kill_grid))
3248 	{
3249 	gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
3250 		(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
3251 	}
3252 
3253 if((h)&&(GLOBALS->tims.start==h->time))
3254 	if (h->v.h_val != AN_Z) {
3255 
3256 	switch(h->v.h_val)
3257 		{
3258 		case AN_X:	c = GLOBALS->gc.gc_x_wavewindow_c_1; break;
3259 		case AN_U:	c = GLOBALS->gc.gc_u_wavewindow_c_1; break;
3260 		case AN_W:	c = GLOBALS->gc.gc_w_wavewindow_c_1; break;
3261 		case AN_DASH:	c = GLOBALS->gc.gc_dash_wavewindow_c_1; break;
3262 		default:	c = (h->v.h_val == AN_X) ? GLOBALS->gc.gc_x_wavewindow_c_1: GLOBALS->gc.gc_trans_wavewindow_c_1;
3263 		}
3264 	gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, 0, _y0, 0, _y1);
3265 	}
3266 
3267 if(dodraw && t)
3268 for(;;)
3269 {
3270 if(!h) break;
3271 tim=(h->time);
3272 
3273 if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break;
3274 
3275 _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
3276 if(_x0<-1)
3277 	{
3278 	_x0=-1;
3279 	}
3280 	else
3281 if(_x0>GLOBALS->wavewidth)
3282 	{
3283 	break;
3284 	}
3285 
3286 h2=h->next;
3287 if(!h2) break;
3288 h2tim=tim=(h2->time);
3289 if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last;
3290 	else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1;
3291 _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
3292 if(_x1<-1)
3293 	{
3294 	_x1=-1;
3295 	}
3296 	else
3297 if(_x1>GLOBALS->wavewidth)
3298 	{
3299 	_x1=GLOBALS->wavewidth;
3300 	}
3301 
3302 if(_x0!=_x1)
3303 	{
3304 	if(is_event)
3305 		{
3306 		if(h->time >= GLOBALS->tims.first)
3307 			{
3308 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y0, _x0, _y1);
3309 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0+2, _y1+2);
3310 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0-2, _y1+2);
3311 			}
3312 		h=h->next;
3313 		continue;
3314 		}
3315 
3316 	hval=h->v.h_val;
3317 	h2val=h2->v.h_val;
3318 
3319 	switch(h2val)
3320 		{
3321 		case AN_X:	c = GLOBALS->gc.gc_x_wavewindow_c_1; break;
3322 		case AN_U:	c = GLOBALS->gc.gc_u_wavewindow_c_1; break;
3323 		case AN_W:	c = GLOBALS->gc.gc_w_wavewindow_c_1; break;
3324 		case AN_DASH:	c = GLOBALS->gc.gc_dash_wavewindow_c_1; break;
3325 		default:	c = (hval == AN_X) ? GLOBALS->gc.gc_x_wavewindow_c_1: GLOBALS->gc.gc_trans_wavewindow_c_1;
3326 		}
3327 
3328 	switch(hval)
3329 		{
3330 		case AN_0:	/* 0 */
3331 		case AN_L:	/* L */
3332 		if(GLOBALS->fill_waveform && invert)
3333 		{
3334 			switch(hval)
3335 				{
3336 				case AN_0: gcxf = GLOBALS->gc.gc_1fill_wavewindow_c_1; break;
3337 				case AN_L: gcxf = GLOBALS->gc.gc_highfill_wavewindow_c_1; break;
3338 				}
3339 			gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, gcxf, TRUE,_x0+1, _y0, _x1-_x0, _y1-_y0+1);
3340 		}
3341 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, (hval==AN_0) ? GLOBALS->gc.gc_0_wavewindow_c_1 : GLOBALS->gc.gc_low_wavewindow_c_1,_x0, _y0,_x1, _y0);
3342 
3343 		if(h2tim<=GLOBALS->tims.end)
3344 		switch(h2val)
3345 			{
3346 			case AN_0:
3347 			case AN_L:	break;
3348 
3349 			case AN_Z:	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, yu); break;
3350 			default:	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break;
3351 			}
3352 		break;
3353 
3354 		case AN_X: /* X */
3355 		case AN_W: /* W */
3356 		case AN_U: /* U */
3357 		case AN_DASH: /* - */
3358 
3359 		identifier_str[1] = 0;
3360 		switch(hval)
3361 			{
3362 			case AN_X:	c = gcx = GLOBALS->gc.gc_x_wavewindow_c_1; gcxf = GLOBALS->gc.gc_xfill_wavewindow_c_1; identifier_str[0] = 0; break;
3363 			case AN_W:	c = gcx = GLOBALS->gc.gc_w_wavewindow_c_1; gcxf = GLOBALS->gc.gc_wfill_wavewindow_c_1; identifier_str[0] = 'W'; break;
3364 			case AN_U:	c = gcx = GLOBALS->gc.gc_u_wavewindow_c_1; gcxf = GLOBALS->gc.gc_ufill_wavewindow_c_1; identifier_str[0] = 'U'; break;
3365 			default:	c = gcx = GLOBALS->gc.gc_dash_wavewindow_c_1; gcxf = GLOBALS->gc.gc_dashfill_wavewindow_c_1; identifier_str[0] = '-'; break;
3366 			}
3367 
3368 		if(invert)
3369 			{
3370 			gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, gcx, TRUE,_x0+1, _y0, _x1-_x0, _y1-_y0+1);
3371 			}
3372 			else
3373 			{
3374 			gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, gcxf, TRUE,_x0+1, _y1, _x1-_x0, _y0-_y1+1);
3375 			}
3376 
3377 		if(identifier_str[0])
3378 			{
3379 			int _x0_new = (_x0>=0) ? _x0 : 0;
3380 			int width;
3381 
3382 			if((width=_x1-_x0_new)>GLOBALS->vector_padding)
3383 				{
3384 				if((_x1>=GLOBALS->wavewidth)||(font_engine_string_measure(GLOBALS->wavefont, identifier_str)+GLOBALS->vector_padding<=width))
3385 					{
3386 		                        font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,  GLOBALS->gc.gc_value_wavewindow_c_1,  _x0+2,ytext,identifier_str);
3387 					}
3388 				}
3389 			}
3390 
3391 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gcx,_x0, _y0,_x1, _y0);
3392 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gcx,_x0, _y1,_x1, _y1);
3393 		if(h2tim<=GLOBALS->tims.end) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1);
3394 		break;
3395 
3396 		case AN_Z: /* Z */
3397 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu);
3398 		if(h2tim<=GLOBALS->tims.end)
3399 		switch(h2val)
3400 			{
3401 			case AN_0:
3402 			case AN_L:
3403 					wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, yu, _x1, _y0); break;
3404 			case AN_1:
3405 			case AN_H:
3406 					wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, yu, _x1, _y1); break;
3407 			default:	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break;
3408 			}
3409 		break;
3410 
3411 		case AN_1: /* 1 */
3412 		case AN_H: /* 1 */
3413 		if(GLOBALS->fill_waveform && !invert)
3414 		{
3415 			switch(hval)
3416 				{
3417 				case AN_1: gcxf = GLOBALS->gc.gc_1fill_wavewindow_c_1; break;
3418 				case AN_H: gcxf = GLOBALS->gc.gc_highfill_wavewindow_c_1; break;
3419 				}
3420 			gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, gcxf, TRUE,_x0+1, _y1, _x1-_x0, _y0-_y1+1);
3421 		}
3422 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, (hval==AN_1) ? GLOBALS->gc.gc_1_wavewindow_c_1 : GLOBALS->gc.gc_high_wavewindow_c_1,_x0, _y1,_x1, _y1);
3423 		if(h2tim<=GLOBALS->tims.end)
3424 		switch(h2val)
3425 			{
3426 			case AN_1:
3427 			case AN_H:	break;
3428 
3429 			case AN_0:
3430 			case AN_L:
3431 					wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y1, _x1, _y0); break;
3432 			case AN_Z:	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y1, _x1, yu); break;
3433 			default:	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break;
3434 			}
3435 		break;
3436 
3437 		default:
3438 		break;
3439 		}
3440 	}
3441 	else
3442 	{
3443 	if(!is_event)
3444 		{
3445 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_trans_wavewindow_c_1, _x1, _y0, _x1, _y1);
3446 		}
3447 		else
3448 		{
3449 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x1, _y0, _x1, _y1);
3450 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0+2, _y1+2);
3451 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0-2, _y1+2);
3452 		}
3453 	newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/;	/* skip to next pixel */
3454 	h3=bsearch_node(t->n.nd,newtime);
3455 	if(h3->time>h->time)
3456 		{
3457 		h=h3;
3458 		continue;
3459 		}
3460 	}
3461 
3462 if((h->flags & HIST_GLITCH) && (GLOBALS->vcd_preserve_glitches))
3463 	{
3464 	gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,
3465 			TRUE,_x1-1, yu-1,
3466 			3, 3);
3467 	}
3468 
3469 h=h->next;
3470 }
3471 
3472 wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */
3473 
3474 GLOBALS->tims.start+=GLOBALS->shift_timebase;
3475 GLOBALS->tims.end+=GLOBALS->shift_timebase;
3476 }
3477 
3478 /********************************************************************************************************/
3479 
draw_hptr_trace_vector_analog(Trptr t,hptr h,int which,int num_extension)3480 static void draw_hptr_trace_vector_analog(Trptr t, hptr h, int which, int num_extension)
3481 {
3482 TimeType _x0, _x1, newtime;
3483 int _y0, _y1, yu, liney, yt0, yt1;
3484 TimeType tim, h2tim;
3485 hptr h2, h3;
3486 int endcnt = 0;
3487 int type;
3488 /* int lasttype=-1; */ /* scan-build */
3489 GdkGC    *c, *ci;
3490 GdkGC    *cnan = GLOBALS->gc.gc_u_wavewindow_c_1;
3491 GdkGC    *cinf = GLOBALS->gc.gc_w_wavewindow_c_1;
3492 GdkGC    *cfixed;
3493 double mynan = strtod("NaN", NULL);
3494 double tmin = mynan, tmax = mynan, tv, tv2;
3495 gint rmargin;
3496 int is_nan = 0, is_nan2 = 0, is_inf = 0, is_inf2 = 0;
3497 int any_infs = 0, any_infp = 0, any_infm = 0;
3498 int skipcnt = 0;
3499 
3500 ci = GLOBALS->gc.gc_baseline_wavewindow_c_1;
3501 
3502 liney=((which+2+num_extension)*GLOBALS->fontheight)-2;
3503 _y1=((which+1)*GLOBALS->fontheight)+2;
3504 _y0=liney-2;
3505 yu=(_y0+_y1)/2;
3506 
3507 if(t->flags & TR_ANALOG_FULLSCALE) /* otherwise use dynamic */
3508 	{
3509 	if((!t->minmax_valid)||(t->d_num_ext != num_extension))
3510 		{
3511 		h3 = &t->n.nd->head;
3512 		for(;;)
3513 			{
3514 			if(!h3) break;
3515 
3516 			if((h3->time >= GLOBALS->tims.first) && (h3->time <= GLOBALS->tims.last))
3517 				{
3518 				tv = mynan;
3519 				if(h3->flags&HIST_REAL)
3520 					{
3521 #ifdef WAVE_HAS_H_DOUBLE
3522 					if(!(h3->flags&HIST_STRING)) tv = h3->v.h_double;
3523 #else
3524 					if(!(h3->flags&HIST_STRING) && h3->v.h_vector)
3525 						tv = *(double *)h3->v.h_vector;
3526 #endif
3527 					}
3528 					else
3529 					{
3530 					if(h3->time <= GLOBALS->tims.last) tv=convert_real_vec(t,h3->v.h_vector);
3531 					}
3532 
3533 
3534 				if (!isnan(tv) && !isinf(tv))
3535 					{
3536 					if (isnan(tmin) || tv < tmin)
3537 						tmin = tv;
3538 					if (isnan(tmax) || tv > tmax)
3539 						tmax = tv;
3540 					}
3541 				else
3542 				if(isinf(tv))
3543 					{
3544 					any_infs = 1;
3545 
3546 					if(tv > 0)
3547 						{
3548 						any_infp = 1;
3549 						}
3550 						else
3551 						{
3552 						any_infm = 1;
3553 						}
3554 					}
3555 				}
3556 			h3 = h3->next;
3557 			}
3558 
3559 		if (isnan(tmin) || isnan(tmax))
3560 			{
3561 			tmin = tmax = 0;
3562 			}
3563 
3564 		if(any_infs)
3565 			{
3566 			double tdelta = (tmax - tmin) * WAVE_INF_SCALING;
3567 
3568 			if(any_infp) tmax = tmax + tdelta;
3569 			if(any_infm) tmin = tmin - tdelta;
3570 			}
3571 
3572 		if ((tmax - tmin) < 1e-20)
3573 			{
3574 			tmax = 1;
3575 			tmin -= 0.5 * (_y1 - _y0);
3576 			}
3577 			else
3578 			{
3579 			tmax = (_y1 - _y0) / (tmax - tmin);
3580 			}
3581 
3582 		t->minmax_valid = 1;
3583 		t->d_minval = tmin;
3584 		t->d_maxval = tmax;
3585 		t->d_num_ext = num_extension;
3586 		}
3587 		else
3588 		{
3589 		tmin = t->d_minval;
3590 		tmax = t->d_maxval;
3591 		}
3592 	}
3593 	else
3594 	{
3595 	h3 = h;
3596 	for(;;)
3597 	{
3598 	if(!h3) break;
3599 	tim=(h3->time);
3600 	if(tim>GLOBALS->tims.end) { endcnt++; if(endcnt==2) break; }
3601 	if(tim>GLOBALS->tims.last) break;
3602 
3603 	_x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
3604 	if((_x0>GLOBALS->wavewidth)&&(endcnt==2))
3605 		{
3606 		break;
3607 		}
3608 
3609 	tv = mynan;
3610 	if(h3->flags&HIST_REAL)
3611 		{
3612 #ifdef WAVE_HAS_H_DOUBLE
3613 		if(!(h3->flags&HIST_STRING)) tv = h3->v.h_double;
3614 #else
3615 		if(!(h3->flags&HIST_STRING) && h3->v.h_vector)
3616 			tv = *(double *)h3->v.h_vector;
3617 #endif
3618 		}
3619 		else
3620 		{
3621 		if(h3->time <= GLOBALS->tims.last) tv=convert_real_vec(t,h3->v.h_vector);
3622 		}
3623 
3624 	if (!isnan(tv) && !isinf(tv))
3625 		{
3626 		if (isnan(tmin) || tv < tmin)
3627 			tmin = tv;
3628 		if (isnan(tmax) || tv > tmax)
3629 			tmax = tv;
3630 		}
3631 	else
3632 	if(isinf(tv))
3633 		{
3634 		any_infs = 1;
3635 		if(tv > 0)
3636 			{
3637 			any_infp = 1;
3638 			}
3639 			else
3640 			{
3641 			any_infm = 1;
3642 			}
3643 		}
3644 
3645 	h3 = h3->next;
3646 	}
3647 
3648 	if (isnan(tmin) || isnan(tmax))
3649 		tmin = tmax = 0;
3650 
3651 	if(any_infs)
3652 		{
3653 		double tdelta = (tmax - tmin) * WAVE_INF_SCALING;
3654 
3655 		if(any_infp) tmax = tmax + tdelta;
3656 		if(any_infm) tmin = tmin - tdelta;
3657 		}
3658 
3659 	if ((tmax - tmin) < 1e-20)
3660 		{
3661 		tmax = 1;
3662 		tmin -= 0.5 * (_y1 - _y0);
3663 		}
3664 		else
3665 		{
3666 		tmax = (_y1 - _y0) / (tmax - tmin);
3667 		}
3668 	}
3669 
3670 if(GLOBALS->tims.last - GLOBALS->tims.start < GLOBALS->wavewidth)
3671 	{
3672 	rmargin=(GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns;
3673 	}
3674 	else
3675 	{
3676 	rmargin = GLOBALS->wavewidth;
3677 	}
3678 
3679 /* now do the actual drawing */
3680 h3 = NULL;
3681 for(;;)
3682 {
3683 if(!h) break;
3684 tim=(h->time);
3685 if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break;
3686 
3687 _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
3688 
3689 /*
3690 if(_x0<-1)
3691 	{
3692 	_x0=-1;
3693 	}
3694 	else
3695 if(_x0>GLOBALS->wavewidth)
3696 	{
3697 	break;
3698 	}
3699 */
3700 
3701 h2=h->next;
3702 if(!h2) break;
3703 h2tim=tim=(h2->time);
3704 if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last;
3705 /*	else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1; */
3706 _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
3707 
3708 /*
3709 if(_x1<-1)
3710 	{
3711 	_x1=-1;
3712 	}
3713 	else
3714 if(_x1>GLOBALS->wavewidth)
3715 	{
3716 	_x1=GLOBALS->wavewidth;
3717 	}
3718 */
3719 
3720 /* draw trans */
3721 type = (!(h->flags&(HIST_REAL|HIST_STRING))) ? vtype(t,h->v.h_vector) : AN_COUNT;
3722 tv = tv2 = mynan;
3723 
3724 if(h->flags&HIST_REAL)
3725 	{
3726 #ifdef WAVE_HAS_H_DOUBLE
3727 	if(!(h->flags&HIST_STRING)) tv = h->v.h_double;
3728 #else
3729 	if(!(h->flags&HIST_STRING) && h->v.h_vector)
3730 		tv = *(double *)h->v.h_vector;
3731 #endif
3732 	}
3733 	else
3734 	{
3735 	if(h->time <= GLOBALS->tims.last) tv=convert_real_vec(t,h->v.h_vector);
3736 	}
3737 
3738 if(h2->flags&HIST_REAL)
3739 	{
3740 #ifdef WAVE_HAS_H_DOUBLE
3741 	if(!(h2->flags&HIST_STRING)) tv2 = h2->v.h_double;
3742 #else
3743 	if(!(h2->flags&HIST_STRING) && h2->v.h_vector)
3744 		tv2 = *(double *)h2->v.h_vector;
3745 #endif
3746 	}
3747 	else
3748 	{
3749 	if(h2->time <= GLOBALS->tims.last) tv2=convert_real_vec(t,h2->v.h_vector);
3750 	}
3751 
3752 if((is_inf = isinf(tv)))
3753 	{
3754 	if(tv < 0)
3755 		{
3756 		yt0 = _y0;
3757 		}
3758 		else
3759 		{
3760 		yt0 = _y1;
3761 		}
3762 	}
3763 else
3764 if((is_nan = isnan(tv)))
3765 	{
3766 	yt0 = yu;
3767 	}
3768 	else
3769 	{
3770 	yt0 = _y0 + (tv - tmin) * tmax;
3771 	}
3772 
3773 if((is_inf2 = isinf(tv2)))
3774 	{
3775 	if(tv2 < 0)
3776 		{
3777 		yt1 = _y0;
3778 		}
3779 		else
3780 		{
3781 		yt1 = _y1;
3782 		}
3783 	}
3784 else
3785 if((is_nan2 = isnan(tv2)))
3786 	{
3787 	yt1 = yu;
3788 	}
3789 	else
3790 	{
3791 	yt1 = _y0 + (tv2 - tmin) * tmax;
3792 	}
3793 
3794 if((_x0!=_x1)||(skipcnt < GLOBALS->analog_redraw_skip_count)) /* lower number = better performance */
3795 	{
3796 	if(_x0==_x1)
3797 		{
3798 		skipcnt++;
3799 		}
3800 		else
3801 		{
3802 		skipcnt = 0;
3803 		}
3804 
3805 	if(type != AN_X)
3806 		{
3807 		c = GLOBALS->gc.gc_vbox_wavewindow_c_1;
3808 		}
3809 		else
3810 		{
3811 		c = GLOBALS->gc.gc_x_wavewindow_c_1;
3812 		}
3813 
3814 	if(h->next)
3815 		{
3816 		if(h->next->time > GLOBALS->max_time)
3817 			{
3818 			yt1 = yt0;
3819 			}
3820 		}
3821 
3822 	cfixed = is_inf ? cinf : c;
3823 	if((is_nan2) && (h2tim > GLOBALS->max_time)) is_nan2 = 0;
3824 
3825 /* clamp to top/bottom because of integer rounding errors */
3826 
3827 if(yt0 < _y1) yt0 = _y1;
3828 else if(yt0 > _y0) yt0 = _y0;
3829 
3830 if(yt1 < _y1) yt1 = _y1;
3831 else if(yt1 > _y0) yt1 = _y0;
3832 
3833 /* clipping... */
3834 {
3835 int coords[4];
3836 int rect[4];
3837 
3838 if(_x0 < INT_MIN) { coords[0] = INT_MIN; }
3839 else if(_x0 > INT_MAX) { coords[0] = INT_MAX; }
3840 else { coords[0] = _x0; }
3841 
3842 if(_x1 < INT_MIN) { coords[2] = INT_MIN; }
3843 else if(_x1 > INT_MAX) { coords[2] = INT_MAX; }
3844 else { coords[2] = _x1; }
3845 
3846 coords[1] = yt0;
3847 coords[3] = yt1;
3848 
3849 
3850 rect[0] = -10;
3851 rect[1] = _y1;
3852 rect[2] = GLOBALS->wavewidth + 10;
3853 rect[3] = _y0;
3854 
3855 if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) != TR_ANALOG_STEP)
3856 	{
3857 	wave_lineclip(coords, rect);
3858 	}
3859 	else
3860 	{
3861 	if(coords[0] < rect[0]) coords[0] = rect[0];
3862 	if(coords[2] < rect[0]) coords[2] = rect[0];
3863 
3864 	if(coords[0] > rect[2]) coords[0] = rect[2];
3865 	if(coords[2] > rect[2]) coords[2] = rect[2];
3866 
3867 	if(coords[1] < rect[1]) coords[1] = rect[1];
3868 	if(coords[3] < rect[1]) coords[3] = rect[1];
3869 
3870 	if(coords[1] > rect[3]) coords[1] = rect[3];
3871 	if(coords[3] > rect[3]) coords[3] = rect[3];
3872 	}
3873 
3874 _x0 = coords[0];
3875 yt0 = coords[1];
3876 _x1 = coords[2];
3877 yt1 = coords[3];
3878 }
3879 /* ...clipping */
3880 
3881 	if(is_nan || is_nan2)
3882 		{
3883 		if(is_nan)
3884 			{
3885 			gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cnan, TRUE, _x0, _y1, _x1-_x0, _y0-_y1);
3886 
3887 			if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP))
3888 				{
3889 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, yt1,_x1+1, yt1);
3890 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, yt1-1,_x1, yt1+1);
3891 
3892 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y0,_x0+1, _y0);
3893 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y0-1,_x0, _y0+1);
3894 
3895 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y1,_x0+1, _y1);
3896 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y1-1,_x0, _y1+1);
3897 				}
3898 			}
3899 		if(is_nan2)
3900 			{
3901 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0, _x1, yt0);
3902 
3903 			if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP))
3904 				{
3905 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cnan,_x1, yt1,_x1, yt0);
3906 
3907 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y0,_x1+1, _y0);
3908 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y0-1,_x1, _y0+1);
3909 
3910 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y1,_x1+1, _y1);
3911 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y1-1,_x1, _y1+1);
3912 				}
3913 			}
3914 		}
3915 	else
3916 	if((t->flags & TR_ANALOG_INTERPOLATED) && !is_inf && !is_inf2)
3917 		{
3918 		if(t->flags & TR_ANALOG_STEP)
3919 			{
3920 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0);
3921 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1);
3922 			}
3923 
3924 		if(rmargin != GLOBALS->wavewidth)	/* the window is clipped in postscript */
3925 			{
3926 			if((yt0==yt1)&&((_x0 > _x1)||(_x0 < 0)))
3927 				{
3928 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,0, yt0,_x1,yt1);
3929 				}
3930 				else
3931 				{
3932 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1);
3933 				}
3934 			}
3935 			else
3936 			{
3937 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1);
3938 			}
3939 		}
3940 	else
3941 	/* if(t->flags & TR_ANALOG_STEP) */
3942 		{
3943 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1, yt0);
3944 
3945 		if(is_inf2) cfixed = cinf;
3946 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x1, yt0,_x1, yt1);
3947 
3948 		if ((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP))
3949 			{
3950 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0);
3951 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1);
3952 			}
3953 		}
3954 	}
3955 	else
3956 	{
3957 	newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/;	/* skip to next pixel */
3958 	h3=bsearch_node(t->n.nd,newtime);
3959 	if(h3->time>h->time)
3960 		{
3961 		h=h3;
3962 		/* lasttype=type; */ /* scan-build */
3963 		continue;
3964 		}
3965 	}
3966 
3967 h=h->next;
3968 /* lasttype=type; */ /* scan-build */
3969 }
3970 
3971 wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1);
3972 }
3973 
3974 /*
3975  * draw hptr vectors (integer+real)
3976  */
draw_hptr_trace_vector(Trptr t,hptr h,int which)3977 static void draw_hptr_trace_vector(Trptr t, hptr h, int which)
3978 {
3979 TimeType _x0, _x1, newtime, width;
3980 int _y0, _y1, yu, liney, ytext;
3981 TimeType tim /* , h2tim */; /* scan-build */
3982 hptr h2, h3;
3983 char *ascii=NULL;
3984 int type;
3985 int lasttype=-1;
3986 GdkGC    *c;
3987 
3988 GLOBALS->tims.start-=GLOBALS->shift_timebase;
3989 GLOBALS->tims.end-=GLOBALS->shift_timebase;
3990 
3991 liney=((which+2)*GLOBALS->fontheight)-2;
3992 _y1=((which+1)*GLOBALS->fontheight)+2;
3993 _y0=liney-2;
3994 yu=(_y0+_y1)/2;
3995 ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent;
3996 
3997 if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
3998 	{
3999 	Trptr tn = GiveNextTrace(t);
4000 	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
4001 		{
4002                 gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4003                         TRUE,0, liney - GLOBALS->fontheight,
4004                         GLOBALS->wavewidth, GLOBALS->fontheight);
4005 		}
4006 		else
4007                 {
4008                 gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4009                         TRUE,0, liney - GLOBALS->fontheight,
4010                         GLOBALS->wavewidth, GLOBALS->fontheight);
4011                 }
4012 	}
4013 else
4014 if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid))
4015 	{
4016 	Trptr tn = GiveNextTrace(t);
4017 	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
4018 		{
4019 		}
4020 		else
4021 		{
4022 		gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4023 			(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
4024 		}
4025 	}
4026 
4027 if((t->flags & TR_ANALOGMASK) && (!(h->flags&HIST_STRING) || !(h->flags&HIST_REAL)))
4028 	{
4029 	Trptr te = GiveNextTrace(t);
4030 	int ext = 0;
4031 
4032 	while(te)
4033 		{
4034 		if(te->flags & TR_ANALOG_BLANK_STRETCH)
4035 			{
4036 			ext++;
4037 			te = GiveNextTrace(te);
4038 			}
4039 			else
4040 			{
4041 			break;
4042 			}
4043 		}
4044 
4045  	if((ext) && (GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
4046                 {
4047                 gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4048                         TRUE,0, liney,
4049                         GLOBALS->wavewidth, GLOBALS->fontheight * ext);
4050                 }
4051 
4052 	draw_hptr_trace_vector_analog(t, h, which, ext);
4053 	GLOBALS->tims.start+=GLOBALS->shift_timebase;
4054 	GLOBALS->tims.end+=GLOBALS->shift_timebase;
4055 	return;
4056 	}
4057 
4058 GLOBALS->color_active_in_filter = 1;
4059 
4060 for(;;)
4061 {
4062 if(!h) break;
4063 tim=(h->time);
4064 if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break;
4065 
4066 _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
4067 if(_x0<-1)
4068 	{
4069 	_x0=-1;
4070 	}
4071 	else
4072 if(_x0>GLOBALS->wavewidth)
4073 	{
4074 	break;
4075 	}
4076 
4077 h2=h->next;
4078 if(!h2) break;
4079 /* h2tim= */ tim=(h2->time); /* scan-build */
4080 if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last;
4081 	else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1;
4082 _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
4083 if(_x1<-1)
4084 	{
4085 	_x1=-1;
4086 	}
4087 	else
4088 if(_x1>GLOBALS->wavewidth)
4089 	{
4090 	_x1=GLOBALS->wavewidth;
4091 	}
4092 
4093 /* draw trans */
4094 if(!(h->flags&(HIST_REAL|HIST_STRING)))
4095         {
4096         type = vtype(t,h->v.h_vector);
4097         }
4098         else
4099         {
4100 	/* s\000 ID is special "z" case */
4101 	type = AN_COUNT;
4102 
4103         if(h->flags&HIST_STRING)
4104                 {
4105 		if(h->v.h_vector)
4106 			{
4107 			if(!h->v.h_vector[0])
4108 				{
4109 				type = AN_Z;
4110 				}
4111 			else
4112 				{
4113 				if(!strcmp(h->v.h_vector, "UNDEF"))
4114 					{
4115 					type = AN_X;
4116 					}
4117 				}
4118 			}
4119 			else
4120 			{
4121 			type = AN_X;
4122 			}
4123                 }
4124         }
4125 /* type = (!(h->flags&(HIST_REAL|HIST_STRING))) ? vtype(t,h->v.h_vector) : AN_COUNT; */
4126 if(_x0>-1) {
4127 GdkGC *gltype, *gtype;
4128 
4129 switch(lasttype)
4130 	{
4131 	case AN_X:	gltype = GLOBALS->gc.gc_x_wavewindow_c_1; break;
4132 	case AN_U:	gltype = GLOBALS->gc.gc_u_wavewindow_c_1; break;
4133 	default:	gltype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break;
4134 	}
4135 switch(type)
4136 	{
4137 	case AN_X:	gtype = GLOBALS->gc.gc_x_wavewindow_c_1; break;
4138 	case AN_U:	gtype = GLOBALS->gc.gc_u_wavewindow_c_1; break;
4139 	default:	gtype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break;
4140 	}
4141 
4142 if(GLOBALS->use_roundcaps)
4143 	{
4144 
4145 	if (type == AN_Z) {
4146 		if (lasttype != -1) {
4147 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0,   yu);
4148 		if(lasttype != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1);
4149 		}
4150 	} else
4151 	if (lasttype==AN_Z) {
4152 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0,   yu);
4153 		if(    type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1);
4154 	} else {
4155 		if (lasttype != type) {
4156 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0,   yu);
4157 		if(lasttype != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1);
4158 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0,   yu);
4159 		if(    type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1);
4160 		} else {
4161 	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0-2, _y0,_x0+2, _y1);
4162 	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+2, _y0,_x0-2, _y1);
4163 		}
4164 	}
4165 	}
4166 	else
4167 	{
4168 	wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, _y0,_x0, _y1);
4169 	}
4170 }
4171 
4172 if(_x0!=_x1)
4173 	{
4174 	if (type == AN_Z)
4175 		{
4176 		if(GLOBALS->use_roundcaps)
4177 			{
4178 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0+1, yu,_x1-1, yu);
4179 			}
4180 			else
4181 			{
4182 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu);
4183 			}
4184 		}
4185 		else
4186 		{
4187 		if((type != AN_X) && (type != AN_U))
4188 			{
4189 			c = GLOBALS->gc.gc_vbox_wavewindow_c_1;
4190 			}
4191 			else
4192 			{
4193 			c = GLOBALS->gc.gc_x_wavewindow_c_1;
4194 			}
4195 
4196 	if(GLOBALS->use_roundcaps)
4197 		{
4198 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y0,_x1-2, _y0);
4199 		if(type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y1,_x1-2, _y1);
4200 		if(type == AN_1) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y1+1,_x1-2, _y1+1);
4201 		}
4202 		else
4203 		{
4204 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y0,_x1, _y0);
4205 		if(type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y1,_x1, _y1);
4206 		if(type == AN_1) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y1+1,_x1, _y1+1);
4207 		}
4208 
4209 if(_x0<0) _x0=0;	/* fixup left margin */
4210 
4211 	if((width=_x1-_x0)>GLOBALS->vector_padding)
4212 		{
4213 		char *ascii2;
4214 
4215 		if(h->flags&HIST_REAL)
4216 			{
4217 			if(!(h->flags&HIST_STRING))
4218 				{
4219 #ifdef WAVE_HAS_H_DOUBLE
4220 				ascii=convert_ascii_real(t, &h->v.h_double);
4221 #else
4222 				ascii=convert_ascii_real(t, (double *)h->v.h_vector);
4223 #endif
4224 				}
4225 				else
4226 				{
4227 				ascii=convert_ascii_string((char *)h->v.h_vector);
4228 				}
4229 			}
4230 			else
4231 			{
4232 			ascii=convert_ascii_vec(t,h->v.h_vector);
4233 			}
4234 
4235 		ascii2 = ascii;
4236 		if(*ascii == '?')
4237 			{
4238 			GdkGC *cb;
4239 			char *srch_for_color = strchr(ascii+1, '?');
4240 			if(srch_for_color)
4241 				{
4242 				*srch_for_color = 0;
4243 				cb = get_gc_from_name(ascii+1);
4244 				if(cb)
4245 					{
4246 					ascii2 =  srch_for_color + 1;
4247 					if(GLOBALS->gc.gc_back_wavewindow_c_1 != GLOBALS->gc_white)
4248 						{
4249 						if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0+1, _y1+1, width-1, (_y0-1) - (_y1+1) + 1);
4250 						}
4251 					GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1 = 1;
4252 					}
4253 					else
4254 					{
4255 					*srch_for_color = '?'; /* replace name as color is a miss */
4256 					}
4257 				}
4258 			}
4259 
4260 		if((_x1>=GLOBALS->wavewidth)||(font_engine_string_measure(GLOBALS->wavefont, ascii2)+GLOBALS->vector_padding<=width))
4261 			{
4262 			font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2);
4263 			}
4264 		else
4265 			{
4266 			char *mod;
4267 
4268 			mod=bsearch_trunc(ascii2,width-GLOBALS->vector_padding);
4269 			if(mod)
4270 				{
4271 				*mod='+';
4272 				*(mod+1)=0;
4273 
4274 				font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2);
4275 				}
4276 			}
4277 		}
4278 		else if(GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1)
4279 		{
4280 		/* char *ascii2; */ /* scan-build */
4281 
4282 		if(h->flags&HIST_REAL)
4283 			{
4284 			if(!(h->flags&HIST_STRING))
4285 				{
4286 #ifdef WAVE_HAS_H_DOUBLE
4287 				ascii=convert_ascii_real(t, &h->v.h_double);
4288 #else
4289 				ascii=convert_ascii_real(t, (double *)h->v.h_vector);
4290 #endif
4291 				}
4292 				else
4293 				{
4294 				ascii=convert_ascii_string((char *)h->v.h_vector);
4295 				}
4296 			}
4297 			else
4298 			{
4299 			ascii=convert_ascii_vec(t,h->v.h_vector);
4300 			}
4301 
4302 		/* ascii2 = ascii; */ /* scan-build */
4303 		if(*ascii == '?')
4304 			{
4305 			GdkGC *cb;
4306 			char *srch_for_color = strchr(ascii+1, '?');
4307 			if(srch_for_color)
4308 				{
4309 				*srch_for_color = 0;
4310 				cb = get_gc_from_name(ascii+1);
4311 				if(cb)
4312 					{
4313 					/* ascii2 =  srch_for_color + 1; */ /* scan-build */
4314 					if(GLOBALS->gc.gc_back_wavewindow_c_1 != GLOBALS->gc_white)
4315 						{
4316 						if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0, _y1+1, width, (_y0-1) - (_y1+1) + 1);
4317 						}
4318 					}
4319 					else
4320 					{
4321 					*srch_for_color = '?'; /* replace name as color is a miss */
4322 					}
4323 				}
4324 			}
4325 
4326 		}
4327 	    }
4328 	}
4329 	else
4330 	{
4331 	newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/;	/* skip to next pixel */
4332 	h3=bsearch_node(t->n.nd,newtime);
4333 	if(h3->time>h->time)
4334 		{
4335 		h=h3;
4336 		lasttype=type;
4337 		continue;
4338 		}
4339 	}
4340 
4341 if(ascii) { free_2(ascii); ascii=NULL; }
4342 h=h->next;
4343 lasttype=type;
4344 }
4345 
4346 GLOBALS->color_active_in_filter = 0;
4347 
4348 wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1);
4349 
4350 GLOBALS->tims.start+=GLOBALS->shift_timebase;
4351 GLOBALS->tims.end+=GLOBALS->shift_timebase;
4352 }
4353 
4354 /********************************************************************************************************/
4355 
draw_vptr_trace_analog(Trptr t,vptr v,int which,int num_extension)4356 static void draw_vptr_trace_analog(Trptr t, vptr v, int which, int num_extension)
4357 {
4358 TimeType _x0, _x1, newtime;
4359 int _y0, _y1, yu, liney, yt0, yt1;
4360 TimeType tim, h2tim;
4361 vptr h, h2, h3;
4362 int endcnt = 0;
4363 int type;
4364 /* int lasttype=-1; */ /* scan-build */
4365 GdkGC    *c, *ci;
4366 GdkGC    *cnan = GLOBALS->gc.gc_u_wavewindow_c_1;
4367 GdkGC    *cinf = GLOBALS->gc.gc_w_wavewindow_c_1;
4368 GdkGC    *cfixed;
4369 double mynan = strtod("NaN", NULL);
4370 double tmin = mynan, tmax = mynan, tv=0.0, tv2;
4371 gint rmargin;
4372 int is_nan = 0, is_nan2 = 0, is_inf = 0, is_inf2 = 0;
4373 int any_infs = 0, any_infp = 0, any_infm = 0;
4374 int skipcnt = 0;
4375 
4376 ci = GLOBALS->gc.gc_baseline_wavewindow_c_1;
4377 
4378 h=v;
4379 liney=((which+2+num_extension)*GLOBALS->fontheight)-2;
4380 _y1=((which+1)*GLOBALS->fontheight)+2;
4381 _y0=liney-2;
4382 yu=(_y0+_y1)/2;
4383 
4384 if(t->flags & TR_ANALOG_FULLSCALE) /* otherwise use dynamic */
4385         {
4386 	if((!t->minmax_valid)||(t->d_num_ext != num_extension))
4387                 {
4388                 h3 = t->n.vec->vectors[0];
4389                 for(;;)
4390                         {
4391                         if(!h3) break;
4392 
4393                         if((h3->time >= GLOBALS->tims.first) && (h3->time <= GLOBALS->tims.last))
4394                                 {
4395                                 /* tv = mynan; */ /* scan-build */
4396 
4397 				tv=convert_real(t,h3);
4398 				if (!isnan(tv) && !isinf(tv))
4399 					{
4400 					if (isnan(tmin) || tv < tmin)
4401 						tmin = tv;
4402 					if (isnan(tmax) || tv > tmax)
4403 						tmax = tv;
4404 					}
4405 				}
4406                                 else
4407                                 if(isinf(tv))
4408                                         {
4409                                         any_infs = 1;
4410 
4411                                         if(tv > 0)
4412                                                 {
4413                                                 any_infp = 1;
4414                                                 }
4415                                                 else
4416                                                 {
4417                                                 any_infm = 1;
4418                                                 }
4419                                         }
4420 
4421 			h3 = h3->next;
4422 			}
4423 
4424 		if (isnan(tmin) || isnan(tmax))
4425 		tmin = tmax = 0;
4426 
4427                 if(any_infs)
4428                         {
4429 			double tdelta = (tmax - tmin) * WAVE_INF_SCALING;
4430 
4431                         if(any_infp) tmax = tmax + tdelta;
4432                         if(any_infm) tmin = tmin - tdelta;
4433                         }
4434 
4435 		if ((tmax - tmin) < 1e-20)
4436 			{
4437 			tmax = 1;
4438 			tmin -= 0.5 * (_y1 - _y0);
4439 			}
4440 			else
4441 			{
4442 			tmax = (_y1 - _y0) / (tmax - tmin);
4443 			}
4444 
4445                 t->minmax_valid = 1;
4446                 t->d_minval = tmin;
4447                 t->d_maxval = tmax;
4448 		t->d_num_ext = num_extension;
4449                 }
4450                 else
4451                 {
4452                 tmin = t->d_minval;
4453                 tmax = t->d_maxval;
4454                 }
4455 	}
4456 	else
4457 	{
4458 	h3 = h;
4459 	for(;;)
4460 	{
4461 	if(!h3) break;
4462 	tim=(h3->time);
4463 
4464 	if(tim>GLOBALS->tims.end) { endcnt++; if(endcnt==2) break; }
4465 	if(tim>GLOBALS->tims.last) break;
4466 
4467 	_x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
4468 	if((_x0>GLOBALS->wavewidth)&&(endcnt==2))
4469 	        {
4470 	        break;
4471 	        }
4472 
4473 	tv=convert_real(t,h3);
4474 	if (!isnan(tv) && !isinf(tv))
4475 		{
4476 		if (isnan(tmin) || tv < tmin)
4477 			tmin = tv;
4478 		if (isnan(tmax) || tv > tmax)
4479 			tmax = tv;
4480 		}
4481         else
4482         if(isinf(tv))
4483                 {
4484                 any_infs = 1;
4485                 if(tv > 0)
4486                         {
4487                         any_infp = 1;
4488                         }
4489                         else
4490                         {
4491                         any_infm = 1;
4492                         }
4493                 }
4494 
4495 	h3 = h3->next;
4496 	}
4497 	if (isnan(tmin) || isnan(tmax))
4498 		tmin = tmax = 0;
4499 
4500         if(any_infs)
4501                 {
4502 		double tdelta = (tmax - tmin) * WAVE_INF_SCALING;
4503 
4504                 if(any_infp) tmax = tmax + tdelta;
4505                 if(any_infm) tmin = tmin - tdelta;
4506                 }
4507 
4508 	if ((tmax - tmin) < 1e-20)
4509 		{
4510 		tmax = 1;
4511 		tmin -= 0.5 * (_y1 - _y0);
4512 		}
4513 		else
4514 		{
4515 		tmax = (_y1 - _y0) / (tmax - tmin);
4516 		}
4517 	}
4518 
4519 if(GLOBALS->tims.last - GLOBALS->tims.start < GLOBALS->wavewidth)
4520 	{
4521 	rmargin=(GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns;
4522 	}
4523 	else
4524 	{
4525 	rmargin = GLOBALS->wavewidth;
4526 	}
4527 
4528 h3 = NULL;
4529 for(;;)
4530 {
4531 if(!h) break;
4532 tim=(h->time);
4533 if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break;
4534 
4535 _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
4536 
4537 /*
4538 if(_x0<-1)
4539 	{
4540 	_x0=-1;
4541 	}
4542 	else
4543 if(_x0>GLOBALS->wavewidth)
4544 	{
4545 	break;
4546 	}
4547 */
4548 
4549 h2=h->next;
4550 if(!h2) break;
4551 h2tim=tim=(h2->time);
4552 if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last;
4553 /*	else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1; */
4554 _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
4555 
4556 /*
4557 if(_x1<-1)
4558 	{
4559 	_x1=-1;
4560 	}
4561 	else
4562 if(_x1>GLOBALS->wavewidth)
4563 	{
4564 	_x1=GLOBALS->wavewidth;
4565 	}
4566 */
4567 /* draw trans */
4568 type = vtype2(t,h);
4569 tv=convert_real(t,h);
4570 tv2=convert_real(t,h2);
4571 
4572 if((is_inf = isinf(tv)))
4573 	{
4574 	if(tv < 0)
4575 		{
4576 		yt0 = _y0;
4577 		}
4578 		else
4579 		{
4580 		yt0 = _y1;
4581 		}
4582 	}
4583 else
4584 if((is_nan = isnan(tv)))
4585 	{
4586 	yt0 = yu;
4587 	}
4588 	else
4589 	{
4590 	yt0 = _y0 + (tv - tmin) * tmax;
4591 	}
4592 
4593 if((is_inf2 = isinf(tv2)))
4594 	{
4595 	if(tv2 < 0)
4596 		{
4597 		yt1 = _y0;
4598 		}
4599 		else
4600 		{
4601 		yt1 = _y1;
4602 		}
4603 	}
4604 else
4605 if((is_nan2 = isnan(tv2)))
4606 	{
4607 	yt1 = yu;
4608 	}
4609 	else
4610 	{
4611 	yt1 = _y0 + (tv2 - tmin) * tmax;
4612 	}
4613 
4614 if((_x0!=_x1)||(skipcnt < GLOBALS->analog_redraw_skip_count)) /* lower number = better performance */
4615 	{
4616         if(_x0==_x1)
4617                 {
4618                 skipcnt++;
4619                 }
4620                 else
4621                 {
4622                 skipcnt = 0;
4623                 }
4624 
4625 	if(type != AN_X)
4626 		{
4627 		c = GLOBALS->gc.gc_vbox_wavewindow_c_1;
4628 		}
4629 		else
4630 		{
4631 		c = GLOBALS->gc.gc_x_wavewindow_c_1;
4632 		}
4633 
4634 	if(h->next)
4635 		{
4636 		if(h->next->time > GLOBALS->max_time)
4637 			{
4638 			yt1 = yt0;
4639 			}
4640 		}
4641 
4642 	cfixed = is_inf ? cinf : c;
4643 	if((is_nan2) && (h2tim > GLOBALS->max_time)) is_nan2 = 0;
4644 
4645 /* clamp to top/bottom because of integer rounding errors */
4646 
4647 if(yt0 < _y1) yt0 = _y1;
4648 else if(yt0 > _y0) yt0 = _y0;
4649 
4650 if(yt1 < _y1) yt1 = _y1;
4651 else if(yt1 > _y0) yt1 = _y0;
4652 
4653 /* clipping... */
4654 {
4655 int coords[4];
4656 int rect[4];
4657 
4658 if(_x0 < INT_MIN) { coords[0] = INT_MIN; }
4659 else if(_x0 > INT_MAX) { coords[0] = INT_MAX; }
4660 else { coords[0] = _x0; }
4661 
4662 if(_x1 < INT_MIN) { coords[2] = INT_MIN; }
4663 else if(_x1 > INT_MAX) { coords[2] = INT_MAX; }
4664 else { coords[2] = _x1; }
4665 
4666 coords[1] = yt0;
4667 coords[3] = yt1;
4668 
4669 
4670 rect[0] = -10;
4671 rect[1] = _y1;
4672 rect[2] = GLOBALS->wavewidth + 10;
4673 rect[3] = _y0;
4674 
4675 if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) != TR_ANALOG_STEP)
4676 	{
4677 	wave_lineclip(coords, rect);
4678 	}
4679 	else
4680 	{
4681 	if(coords[0] < rect[0]) coords[0] = rect[0];
4682 	if(coords[2] < rect[0]) coords[2] = rect[0];
4683 
4684 	if(coords[0] > rect[2]) coords[0] = rect[2];
4685 	if(coords[2] > rect[2]) coords[2] = rect[2];
4686 
4687 	if(coords[1] < rect[1]) coords[1] = rect[1];
4688 	if(coords[3] < rect[1]) coords[3] = rect[1];
4689 
4690 	if(coords[1] > rect[3]) coords[1] = rect[3];
4691 	if(coords[3] > rect[3]) coords[3] = rect[3];
4692 	}
4693 
4694 _x0 = coords[0];
4695 yt0 = coords[1];
4696 _x1 = coords[2];
4697 yt1 = coords[3];
4698 }
4699 /* ...clipping */
4700 
4701         if(is_nan || is_nan2)
4702                 {
4703 		if(is_nan)
4704 			{
4705 			gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cnan, TRUE, _x0, _y1, _x1-_x0, _y0-_y1);
4706 
4707 			if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP))
4708 				{
4709 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, yt1,_x1+1, yt1);
4710 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, yt1-1,_x1, yt1+1);
4711 
4712 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y0,_x0+1, _y0);
4713 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y0-1,_x0, _y0+1);
4714 
4715 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y1,_x0+1, _y1);
4716 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y1-1,_x0, _y1+1);
4717 				}
4718 			}
4719 		if(is_nan2)
4720 			{
4721 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0, _x1, yt0);
4722 
4723 			if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP))
4724 				{
4725 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cnan,_x1, yt1,_x1, yt0);
4726 
4727 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y0,_x1+1, _y0);
4728 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y0-1,_x1, _y0+1);
4729 
4730 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y1,_x1+1, _y1);
4731 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y1-1,_x1, _y1+1);
4732 				}
4733 			}
4734                 }
4735         else
4736 	if((t->flags & TR_ANALOG_INTERPOLATED) && !is_inf && !is_inf2)
4737 		{
4738 		if(t->flags & TR_ANALOG_STEP)
4739 			{
4740 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0);
4741 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1);
4742 			}
4743 
4744 		if(rmargin != GLOBALS->wavewidth)	/* the window is clipped in postscript */
4745 			{
4746 			if((yt0==yt1)&&((_x0 > _x1)||(_x0 < 0)))
4747 				{
4748 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,0, yt0,_x1,yt1);
4749 				}
4750 				else
4751 				{
4752 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1);
4753 				}
4754 			}
4755 			else
4756 			{
4757 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1);
4758 			}
4759 		}
4760 	else
4761 	/* if(t->flags & TR_ANALOG_STEP) */
4762 		{
4763 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1, yt0);
4764 
4765 		if(is_inf2) cfixed = cinf;
4766 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x1, yt0,_x1, yt1);
4767 
4768 		if ((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP))
4769 			{
4770 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0);
4771 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1);
4772 			}
4773 		}
4774 	}
4775 	else
4776 	{
4777 	newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/;	/* skip to next pixel */
4778 	h3=bsearch_vector(t->n.vec,newtime);
4779 	if(h3->time>h->time)
4780 		{
4781 		h=h3;
4782 		/* lasttype=type; */
4783 		continue;
4784 		}
4785 	}
4786 
4787 h=h->next;
4788 /* lasttype=type; */
4789 }
4790 
4791 wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1);
4792 
4793 GLOBALS->tims.start+=GLOBALS->shift_timebase;
4794 GLOBALS->tims.end+=GLOBALS->shift_timebase;
4795 }
4796 
4797 /*
4798  * draw vector traces
4799  */
draw_vptr_trace(Trptr t,vptr v,int which)4800 static void draw_vptr_trace(Trptr t, vptr v, int which)
4801 {
4802 TimeType _x0, _x1, newtime, width;
4803 int _y0, _y1, yu, liney, ytext;
4804 TimeType tim /* , h2tim */; /* scan-build */
4805 vptr h, h2, h3;
4806 char *ascii=NULL;
4807 int type;
4808 int lasttype=-1;
4809 GdkGC    *c;
4810 
4811 GLOBALS->tims.start-=GLOBALS->shift_timebase;
4812 GLOBALS->tims.end-=GLOBALS->shift_timebase;
4813 
4814 liney=((which+2)*GLOBALS->fontheight)-2;
4815 _y1=((which+1)*GLOBALS->fontheight)+2;
4816 _y0=liney-2;
4817 yu=(_y0+_y1)/2;
4818 ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent;
4819 
4820 if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
4821 	{
4822 	Trptr tn = GiveNextTrace(t);
4823 	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
4824 		{
4825                 gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4826                         TRUE,0, liney - GLOBALS->fontheight,
4827                         GLOBALS->wavewidth, GLOBALS->fontheight);
4828 		}
4829 		else
4830                 {
4831                 gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4832                         TRUE,0, liney - GLOBALS->fontheight,
4833                         GLOBALS->wavewidth, GLOBALS->fontheight);
4834                 }
4835 	}
4836 else
4837 if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid))
4838 	{
4839 	Trptr tn = GiveNextTrace(t);
4840 	if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH))
4841 		{
4842 		}
4843 		else
4844 		{
4845 		gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4846 			(GLOBALS->tims.start<GLOBALS->tims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney);
4847 		}
4848 	}
4849 
4850 h = v;
4851 /* obsolete:
4852 if(t->flags & TR_TTRANSLATED)
4853 	{
4854 	traverse_vector_nodes(t);
4855 	h=v=bsearch_vector(t->n.vec, GLOBALS->tims.start);
4856 	}
4857 	else
4858 	{
4859 	h=v;
4860 	}
4861 */
4862 
4863 if(t->flags & TR_ANALOGMASK)
4864 	{
4865         Trptr te = GiveNextTrace(t);
4866         int ext = 0;
4867 
4868         while(te)
4869                 {
4870                 if(te->flags & TR_ANALOG_BLANK_STRETCH)
4871                         {
4872                         ext++;
4873                         te = GiveNextTrace(te);
4874                         }
4875 		else
4876                         {
4877                         break;
4878                         }
4879                 }
4880 
4881  	if((ext) && (GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white))
4882                 {
4883                 gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,
4884                         TRUE,0, liney,
4885                         GLOBALS->wavewidth, GLOBALS->fontheight * ext);
4886                 }
4887 
4888 	draw_vptr_trace_analog(t, v, which, ext);
4889 
4890 	GLOBALS->tims.start+=GLOBALS->shift_timebase;
4891 	GLOBALS->tims.end+=GLOBALS->shift_timebase;
4892 	return;
4893 	}
4894 
4895 GLOBALS->color_active_in_filter = 1;
4896 
4897 for(;;)
4898 {
4899 if(!h) break;
4900 tim=(h->time);
4901 if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break;
4902 
4903 _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
4904 if(_x0<-1)
4905 	{
4906 	_x0=-1;
4907 	}
4908 	else
4909 if(_x0>GLOBALS->wavewidth)
4910 	{
4911 	break;
4912 	}
4913 
4914 h2=h->next;
4915 if(!h2) break;
4916 /* h2tim= */ tim=(h2->time); /* scan-build */
4917 if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last;
4918 	else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1;
4919 _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns;
4920 if(_x1<-1)
4921 	{
4922 	_x1=-1;
4923 	}
4924 	else
4925 if(_x1>GLOBALS->wavewidth)
4926 	{
4927 	_x1=GLOBALS->wavewidth;
4928 	}
4929 
4930 /* draw trans */
4931 type = vtype2(t,h);
4932 
4933 if(_x0>-1) {
4934 GdkGC *gltype, *gtype;
4935 
4936 switch(lasttype)
4937 	{
4938 	case AN_X:	gltype = GLOBALS->gc.gc_x_wavewindow_c_1; break;
4939 	case AN_U:	gltype = GLOBALS->gc.gc_u_wavewindow_c_1; break;
4940 	default:	gltype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break;
4941 	}
4942 switch(type)
4943 	{
4944 	case AN_X:	gtype = GLOBALS->gc.gc_x_wavewindow_c_1; break;
4945 	case AN_U:	gtype = GLOBALS->gc.gc_u_wavewindow_c_1; break;
4946 	default:	gtype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break;
4947 	}
4948 
4949 if(GLOBALS->use_roundcaps)
4950 	{
4951 	if (type == AN_Z)
4952 		{
4953 		if (lasttype != -1)
4954 			{
4955 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0,   yu);
4956 			if(lasttype != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1);
4957 			}
4958 		}
4959 		else
4960 		if (lasttype==AN_Z)
4961 			{
4962 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0,   yu);
4963 			if(    type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1);
4964 			}
4965 			else
4966 			{
4967 			if (lasttype != type)
4968 				{
4969 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0,   yu);
4970 				if(lasttype != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1);
4971 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0,   yu);
4972 				if(    type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1);
4973 				}
4974 				else
4975 				{
4976 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0-2, _y0,_x0+2, _y1);
4977 				wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+2, _y0,_x0-2, _y1);
4978 				}
4979 			}
4980 		}
4981 		else
4982 		{
4983 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, _y0,_x0, _y1);
4984 		}
4985 }
4986 
4987 if(_x0!=_x1)
4988 	{
4989 	if (type == AN_Z)
4990 		{
4991 		if(GLOBALS->use_roundcaps)
4992 			{
4993 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0+1, yu,_x1-1, yu);
4994 			}
4995 			else
4996 			{
4997 			wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu);
4998 			}
4999 		}
5000 		else
5001 		{
5002 		if((type != AN_X) && (type != AN_U))
5003 			{
5004 			c = GLOBALS->gc.gc_vbox_wavewindow_c_1;
5005 			}
5006 			else
5007 			{
5008 			c = GLOBALS->gc.gc_x_wavewindow_c_1;
5009 			}
5010 
5011 	if(GLOBALS->use_roundcaps)
5012 		{
5013 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y0,_x1-2, _y0);
5014 		if(type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y1,_x1-2, _y1);
5015 		if(type == AN_1) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y1+1,_x1-2, _y1+1);
5016 		}
5017 		else
5018 		{
5019 		wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y0,_x1, _y0);
5020 		if(type != AN_0) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y1,_x1, _y1);
5021 		if(type == AN_1) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y1+1,_x1, _y1+1);
5022 		}
5023 
5024 
5025 if(_x0<0) _x0=0;	/* fixup left margin */
5026 
5027 	if((width=_x1-_x0)>GLOBALS->vector_padding)
5028 		{
5029 		char *ascii2;
5030 
5031 		ascii=convert_ascii(t,h);
5032 
5033 		ascii2 = ascii;
5034 		if(*ascii == '?')
5035 			{
5036 			GdkGC *cb;
5037 			char *srch_for_color = strchr(ascii+1, '?');
5038 			if(srch_for_color)
5039 				{
5040 				*srch_for_color = 0;
5041 				cb = get_gc_from_name(ascii+1);
5042 				if(cb)
5043 					{
5044 					ascii2 =  srch_for_color + 1;
5045 					if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0+1, _y1+1, width-1, (_y0-1) - (_y1+1) + 1);
5046 					GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1 = 1;
5047 					}
5048 					else
5049 					{
5050 					*srch_for_color = '?'; /* replace name as color is a miss */
5051 					}
5052 				}
5053 			}
5054 
5055 		if((_x1>=GLOBALS->wavewidth)||(font_engine_string_measure(GLOBALS->wavefont, ascii2)+GLOBALS->vector_padding<=width))
5056 			{
5057 			font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2);
5058 			}
5059 		else
5060 			{
5061 			char *mod;
5062 
5063 			mod=bsearch_trunc(ascii2,width-GLOBALS->vector_padding);
5064 			if(mod)
5065 				{
5066 				*mod='+';
5067 				*(mod+1)=0;
5068 
5069 				font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2);
5070 				}
5071 			}
5072 
5073 		}
5074 		else if(GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1)
5075 		{
5076 		/* char *ascii2; */ /* scan-build */
5077 
5078 		ascii=convert_ascii(t,h);
5079 
5080 		/* ascii2 = ascii; */ /* scan-build */
5081 		if(*ascii == '?')
5082 			{
5083 			GdkGC *cb;
5084 			char *srch_for_color = strchr(ascii+1, '?');
5085 			if(srch_for_color)
5086 				{
5087 				*srch_for_color = 0;
5088 				cb = get_gc_from_name(ascii+1);
5089 				if(cb)
5090 					{
5091 					/* ascii2 =  srch_for_color + 1; */
5092 					if(GLOBALS->gc.gc_back_wavewindow_c_1 != GLOBALS->gc_white)
5093 						{
5094 						if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0, _y1+1, width, (_y0-1) - (_y1+1) + 1);
5095 						}
5096 					}
5097 					else
5098 					{
5099 					*srch_for_color = '?'; /* replace name as color is a miss */
5100 					}
5101 				}
5102 			}
5103 		}
5104 	}
5105 	}
5106 	else
5107 	{
5108 	newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/;	/* skip to next pixel */
5109 	h3=bsearch_vector(t->n.vec,newtime);
5110 	if(h3->time>h->time)
5111 		{
5112 		h=h3;
5113 		lasttype=type;
5114 		continue;
5115 		}
5116 	}
5117 
5118 if(ascii) { free_2(ascii); ascii=NULL; }
5119 lasttype=type;
5120 h=h->next;
5121 }
5122 
5123 GLOBALS->color_active_in_filter = 0;
5124 
5125 wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1);
5126 
5127 GLOBALS->tims.start+=GLOBALS->shift_timebase;
5128 GLOBALS->tims.end+=GLOBALS->shift_timebase;
5129 }
5130 
5131