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