1 /*
2 * Copyright (c) Tony Bybell 1999-2013.
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 "globals.h"
11 #include <config.h>
12 #include <gdk/gdkkeysyms.h>
13 #include "gtk12compat.h"
14 #include "currenttime.h"
15 #include "pixmaps.h"
16 #include "symbol.h"
17 #include "debug.h"
18
19 /* GDK_KEY_equal defined from gtk2 2.22 onwards. */
20 #ifndef GDK_KEY_equal
21 #define GDK_KEY_equal GDK_equal
22 #endif
23 #ifndef GDK_KEY_Up
24 #define GDK_KEY_Up GDK_Up
25 #endif
26 #ifndef GDK_KEY_KP_Up
27 #define GDK_KEY_KP_Up GDK_KP_Up
28 #endif
29 #ifndef GDK_KEY_Down
30 #define GDK_KEY_Down GDK_Down
31 #endif
32 #ifndef GDK_KEY_KP_Down
33 #define GDK_KEY_KP_Down GDK_KP_Down
34 #endif
35
36 #undef FOCUS_DEBUG_MSGS
37
38 /*
39 * complain about certain ops conflict with dnd...
40 */
dnd_error(void)41 void dnd_error(void)
42 {
43 status_text("Can't perform that operation when waveform drag and drop is in progress!\n");
44 }
45
46
47 static void
service_hslider(GtkWidget * text,gpointer data)48 service_hslider(GtkWidget *text, gpointer data)
49 {
50 (void)text;
51 (void)data;
52
53 GtkAdjustment *hadj;
54 gint xsrc;
55
56 if(GLOBALS->signalpixmap)
57 {
58 hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
59 xsrc=(gint)hadj->value;
60 DEBUG(printf("Signal HSlider Moved to %d\n",xsrc));
61 GLOBALS->right_align_active = 0;
62
63 gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc.gc_mdgray, TRUE,
64 0, -1, GLOBALS->signal_fill_width, GLOBALS->fontheight);
65 gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_white,
66 0, GLOBALS->fontheight-1, GLOBALS->signal_fill_width-1, GLOBALS->fontheight-1);
67 font_engine_draw_string(GLOBALS->signalpixmap, GLOBALS->signalfont,
68 GLOBALS->gc_black, 3+xsrc, GLOBALS->fontheight-4, "Time");
69
70 if(GLOBALS->signalarea_has_focus)
71 {
72 gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],GLOBALS->signalpixmap,
73 xsrc+1, 0+1,
74 0+1, 0+1,
75 GLOBALS->signalarea->allocation.width-2, GLOBALS->signalarea->allocation.height-2);
76 draw_signalarea_focus();
77 }
78 else
79 {
80 gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],GLOBALS->signalpixmap,xsrc, 0,0, 0,GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height);
81 }
82 }
83 }
84
85
draw_signalarea_focus(void)86 void draw_signalarea_focus(void)
87 {
88 if(GLOBALS->signalarea_has_focus)
89 {
90 gdk_draw_rectangle(GLOBALS->signalarea->window, GLOBALS->gc_black, FALSE, 0, 0,
91 GLOBALS->signalarea->allocation.width-1, GLOBALS->signalarea->allocation.height-1);
92 }
93 }
94
95 /**************************************************************************/
96 /*** standard click routines turned on with "use_standard_clicking"=1 ***/
97
98 /*
99 * DND "drag_begin" handler, this is called whenever a drag starts.
100 */
DNDBeginCB(GtkWidget * widget,GdkDragContext * dc,gpointer data)101 static void DNDBeginCB(
102 GtkWidget *widget, GdkDragContext *dc, gpointer data
103 )
104 {
105 (void)widget;
106 (void)dc;
107 (void)data;
108
109 GLOBALS->dnd_state = 1;
110 }
111
112 /*
113 * DND "drag_failed" handler, this is called when a drag and drop has
114 * failed (e.g., by pressing ESC).
115 */
116 #ifdef WAVE_USE_GTK2
DNDFailedCB(GtkWidget * widget,GdkDragContext * context,GtkDragResult result)117 static gboolean DNDFailedCB(
118 GtkWidget *widget, GdkDragContext *context, GtkDragResult result)
119 {
120 (void)widget;
121 (void)context;
122 (void)result;
123
124 GLOBALS->dnd_cursor_timer = 0;
125 GLOBALS->dnd_state = 0;
126 GLOBALS->standard_trace_dnd_degate = 1;
127
128 MaxSignalLength();
129 signalarea_configure_event(GLOBALS->signalarea, NULL);
130 wavearea_configure_event(GLOBALS->wavearea, NULL);
131
132 return(FALSE);
133 }
134 #endif
135
136 /*
137 * DND "drag_end" handler, this is called when a drag and drop has
138 * completed. So this function is the last one to be called in
139 * any given DND operation.
140 */
DNDEndCB(GtkWidget * widget,GdkDragContext * dc,gpointer data)141 static void DNDEndCB(
142 GtkWidget *widget, GdkDragContext *dc, gpointer data
143 )
144 {
145 (void)widget;
146 (void)dc;
147 (void)data;
148
149 GtkWidget *ddest;
150 int which;
151 gdouble x,y;
152 GdkModifierType state;
153 Trptr t;
154 int trwhich, trtarget;
155 int must_update_screen = 0;
156
157 #ifdef WAVE_USE_GTK2
158 gint xi, yi;
159 #else
160 GdkEventMotion event[1];
161 event[0].deviceid = GDK_CORE_POINTER;
162 #endif
163
164 if(!GLOBALS->dnd_state) goto bot;
165
166 if(GLOBALS->std_dnd_tgt_on_signalarea || GLOBALS->std_dnd_tgt_on_wavearea)
167 {
168 GtkAdjustment *wadj;
169 wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
170
171 WAVE_GDK_GET_POINTER(GLOBALS->std_dnd_tgt_on_signalarea ? GLOBALS->signalarea->window : GLOBALS->wavearea->window, &x, &y, &xi, &yi, &state);
172 WAVE_GDK_GET_POINTER_COPY;
173
174 which=(int)(y);
175 which=(which/GLOBALS->fontheight)-2;
176 if(which < -1) which = -1;
177
178 trtarget=((int)wadj->value)+which;
179
180 ddest = (GLOBALS->std_dnd_tgt_on_signalarea) ? GTK_WIDGET(GLOBALS->signalarea) : GTK_WIDGET(GLOBALS->wavearea);
181 if((x<0)||(x>=ddest->allocation.width)||(y<0)||(y>=ddest->allocation.height))
182 {
183 goto bot;
184 }
185
186 GLOBALS->cachedtrace=t=GLOBALS->traces.first;
187 trwhich=0;
188 while(t)
189 {
190 if((trwhich<trtarget)&&(GiveNextTrace(t)))
191 {
192 trwhich++;
193 t=GiveNextTrace(t);
194 }
195 else
196 {
197 break;
198 }
199 }
200
201 while(t && t->t_next && IsGroupEnd(t->t_next) && IsCollapsed(t->t_next)) { /* added missing "t &&" because of possible while termination above */
202 t = t->t_next;
203 }
204
205 GLOBALS->cachedtrace=t;
206 if(GLOBALS->cachedtrace)
207 {
208 while(t)
209 {
210 if(!(t->flags&TR_HIGHLIGHT))
211 {
212 GLOBALS->cachedtrace = t;
213 if(CutBuffer())
214 {
215 /* char buf[32];
216 sprintf(buf,"Dragging %d trace%s.\n",GLOBALS->traces.buffercount,GLOBALS->traces.buffercount!=1?"s":"");
217 status_text(buf); */
218 must_update_screen = 1;
219 }
220
221 GLOBALS->cachedtrace->flags|=TR_HIGHLIGHT;
222 goto success;
223 }
224
225 t=GivePrevTrace(t);
226 }
227 goto bot;
228 }
229
230 success:
231 if( ((which<0) && (GLOBALS->topmost_trace==GLOBALS->traces.first) && PrependBuffer()) || (PasteBuffer()) ) /* short circuit on special which<0 case */
232 {
233 /* status_text("Drop completed.\n"); */
234
235 if(GLOBALS->cachedtrace)
236 {
237 GLOBALS->cachedtrace->flags&=~TR_HIGHLIGHT;
238 }
239
240 GLOBALS->signalwindow_width_dirty=1;
241 MaxSignalLength();
242 signalarea_configure_event(GLOBALS->signalarea, NULL);
243 wavearea_configure_event(GLOBALS->wavearea, NULL);
244 must_update_screen = 0;
245 }
246 }
247
248 bot:
249
250 if(must_update_screen)
251 {
252 MaxSignalLength();
253 signalarea_configure_event(GLOBALS->signalarea, NULL);
254 wavearea_configure_event(GLOBALS->wavearea, NULL);
255 }
256
257 GLOBALS->dnd_cursor_timer = 0;
258 GLOBALS->dnd_state = 0;
259 GLOBALS->standard_trace_dnd_degate = 1;
260 }
261
262 /*
263 * DND "drag_motion" handler, this is called whenever the
264 * pointer is dragging over the target widget.
265 */
DNDDragMotionCB(GtkWidget * widget,GdkDragContext * dc,gint xx,gint yy,guint tt,gpointer data)266 static gboolean DNDDragMotionCB(
267 GtkWidget *widget, GdkDragContext *dc,
268 gint xx, gint yy, guint tt,
269 gpointer data
270 )
271 {
272 (void)xx;
273 (void)yy;
274 (void)data;
275 #ifndef WAVE_USE_GTK2
276 (void)tt;
277 #endif
278 gboolean same_widget;
279 #ifdef WAVE_USE_GTK2
280 GdkDragAction suggested_action;
281 #endif
282 GtkWidget *src_widget, *tar_widget;
283
284 if((widget == NULL) || (dc == NULL))
285 return(FALSE);
286
287
288 /* Get source widget and target widget. */
289 src_widget = gtk_drag_get_source_widget(dc);
290 tar_widget = widget;
291
292 /* Note if source widget is the same as the target. */
293 same_widget = (src_widget == tar_widget) ? TRUE : FALSE;
294 if(same_widget)
295 {
296 /* nothing */
297 }
298
299 GLOBALS->std_dnd_tgt_on_signalarea = (tar_widget == GLOBALS->signalarea);
300 GLOBALS->std_dnd_tgt_on_wavearea = (tar_widget == GLOBALS->wavearea);
301
302 #ifdef WAVE_USE_GTK2
303 /* If this is the same widget, our suggested action should be
304 * move. For all other case we assume copy.
305 */
306 suggested_action = GDK_ACTION_MOVE;
307
308 /* Respond with default drag action (status). First we check
309 * the dc's list of actions. If the list only contains
310 * move, copy, or link then we select just that, otherwise we
311 * return with our default suggested action.
312 * If no valid actions are listed then we respond with 0.
313 */
314
315 /* Only move? */
316 if(dc->actions == GDK_ACTION_MOVE)
317 gdk_drag_status(dc, GDK_ACTION_MOVE, tt);
318 /* Only copy? */
319 else if(dc->actions == GDK_ACTION_COPY)
320 gdk_drag_status(dc, GDK_ACTION_COPY, tt);
321 /* Only link? */
322 else if(dc->actions == GDK_ACTION_LINK)
323 gdk_drag_status(dc, GDK_ACTION_LINK, tt);
324 /* Other action, check if listed in our actions list? */
325 else if(dc->actions & suggested_action)
326 gdk_drag_status(dc, suggested_action, tt);
327 /* All else respond with 0. */
328 else
329 gdk_drag_status(dc, 0, tt);
330 #endif
331
332 if(GLOBALS->std_dnd_tgt_on_signalarea || GLOBALS->std_dnd_tgt_on_wavearea)
333 {
334 GtkAdjustment *wadj;
335 GtkWidget *ddest;
336 int which;
337 gdouble x,y;
338 GdkModifierType state;
339 Trptr t;
340 int trwhich, trtarget;
341
342 #ifdef WAVE_USE_GTK2
343 gint xi, yi;
344 #else
345 GdkEventMotion event[1];
346 event[0].deviceid = GDK_CORE_POINTER;
347 #endif
348
349 wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
350
351 WAVE_GDK_GET_POINTER(GLOBALS->std_dnd_tgt_on_signalarea ? GLOBALS->signalarea->window : GLOBALS->wavearea->window, &x, &y, &xi, &yi, &state);
352 WAVE_GDK_GET_POINTER_COPY;
353
354 which=(int)(y);
355 which=(which/GLOBALS->fontheight)-2;
356 if(which < -1) which = -1;
357
358 trtarget=((int)wadj->value)+which;
359
360 ddest = (GLOBALS->std_dnd_tgt_on_signalarea) ? GTK_WIDGET(GLOBALS->signalarea) : GTK_WIDGET(GLOBALS->wavearea);
361 if((x<0)||(x>=ddest->allocation.width)||(y<0)||(y>=ddest->allocation.height))
362 {
363 goto bot;
364 }
365
366 t=GLOBALS->traces.first;
367 trwhich=0;
368 while(t)
369 {
370 if((trwhich<trtarget)&&(GiveNextTrace(t)))
371 {
372 trwhich++;
373 t=GiveNextTrace(t);
374 }
375 else
376 {
377 break;
378 }
379 }
380
381 while(t && t->t_next && IsGroupEnd(t->t_next) && IsCollapsed(t->t_next)) {
382 t = t->t_next;
383 }
384
385 /* if(t) */
386 /* { */
387 /* while(t) */
388 /* { */
389 /* if(t->flags & TR_HIGHLIGHT) */
390 /* { */
391 /* t=GivePrevTrace(t); */
392 /* which--; */
393 /* } */
394 /* else */
395 /* { */
396 /* break; */
397 /* } */
398 /* } */
399 /* } */
400
401 if(1)
402 {
403 GtkAdjustment *hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
404 GtkAdjustment *sadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
405 int rsig_trtarget=(int)(sadj->value);
406 gint xsrc=(gint)hadj->value;
407 gint ylin;
408
409 gdk_draw_rectangle(GLOBALS->signalpixmap,
410 GLOBALS->gc.gc_ltgray, TRUE, 0, 0,
411 GLOBALS->signal_fill_width, GLOBALS->signalarea->allocation.height);
412
413 RenderSigs(rsig_trtarget, 0);
414
415 GLOBALS->dnd_cursor_timer = 1;
416 if((t)&&(which >= -1))
417 {
418 if(which >= GLOBALS->traces.total) { which = GLOBALS->traces.total-1; }
419 ylin = ((which + 2) * GLOBALS->fontheight) - 2;
420
421 gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_black,
422 0, ylin, GLOBALS->signal_fill_width-1, ylin);
423 }
424 else
425 {
426 int i;
427
428 which = -1;
429 ylin = ((which + 2) * GLOBALS->fontheight) - 2;
430
431 for(i=0;i<GLOBALS->signal_fill_width-1; i+=16)
432 {
433 gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_black,
434 i, ylin, i+7, ylin);
435 gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_white,
436 i+8, ylin, i+15, ylin);
437 }
438 }
439
440 gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],
441 GLOBALS->signalpixmap,
442 xsrc, 0,
443 0, 0,
444 GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height);
445
446 /* printf("drop to %d of %d: '%s'\n", which, GLOBALS->traces.total, t ? t->name : "undef"); */
447 }
448 bot: return(FALSE);
449 }
450
451 return(FALSE);
452 }
453
ignoreAccelerators(GdkEventKey * event)454 static gboolean ignoreAccelerators(GdkEventKey *event)
455 {
456 if(!GLOBALS || !GLOBALS->filter_entry || !event)
457 {
458 return(FALSE);
459 }
460 else
461 {
462 #ifdef MAC_INTEGRATION
463 return (GTK_WIDGET_HAS_FOCUS(GLOBALS->filter_entry));
464 #else
465 return (GTK_WIDGET_HAS_FOCUS(GLOBALS->filter_entry) &&
466 !(event->state & GDK_CONTROL_MASK) &&
467 !(event->state & GDK_MOD1_MASK));
468 #endif
469 }
470 }
471
472 /*
473 * keypress processing, return TRUE to block the event from gtk
474 */
keypress_local(GtkWidget * widget,GdkEventKey * event,gpointer data)475 static gint keypress_local(GtkWidget *widget, GdkEventKey *event, gpointer data)
476 {
477 (void)widget;
478 (void)data;
479
480 GtkAdjustment *wadj;
481 int num_traces_displayable;
482 int target;
483 int which;
484 gint rc = FALSE;
485 int yscroll;
486 int ud_kill = 0;
487
488 #ifdef FOCUS_DEBUG_MSGS
489 printf("focus: %d %08x %08x %08x\n", GTK_WIDGET_HAS_FOCUS(GLOBALS->signalarea_event_box),
490 GLOBALS->signalarea_event_box, widget, data);
491 #endif
492
493 #ifdef WAVE_USE_GTK2
494 if ( (event->keyval == GDK_KEY_equal) &&
495 #ifdef MAC_INTEGRATION
496 (event->state & GDK_META_MASK)
497 #else
498 (event->state & GDK_CONTROL_MASK)
499 #endif
500 )
501 {
502 service_zoom_in(NULL, NULL);
503 rc = TRUE;
504 }
505 else
506 #endif
507 if(GTK_WIDGET_HAS_FOCUS(GLOBALS->signalarea_event_box))
508 {
509 switch(event->keyval)
510 {
511 #ifdef MAC_INTEGRATION
512 /* need to do this, otherwise if a menu accelerator it steals the key from gtk */
513 case GDK_a:
514 if(event->state & GDK_MOD2_MASK)
515 {
516 menu_dataformat_highlight_all(NULL, 0, NULL);
517 rc = TRUE;
518 }
519 break;
520
521 case GDK_A:
522 if(event->state & GDK_MOD2_MASK)
523 {
524 menu_dataformat_unhighlight_all(NULL, 0, NULL);
525 rc = TRUE;
526 }
527 break;
528
529 case GDK_x:
530 if(event->state & GDK_MOD2_MASK)
531 {
532 menu_cut_traces(NULL, 0, NULL);
533 rc = TRUE;
534 }
535 break;
536
537 case GDK_c:
538 if(event->state & GDK_MOD2_MASK)
539 {
540 menu_copy_traces(NULL, 0, NULL);
541 rc = TRUE;
542 }
543 break;
544
545 case GDK_v:
546 if(event->state & GDK_MOD2_MASK)
547 {
548 menu_paste_traces(NULL, 0, NULL);
549 rc = TRUE;
550 }
551 break;
552 #endif
553 case GDK_Page_Up:
554 case GDK_KP_Page_Up:
555 case GDK_Page_Down:
556 case GDK_KP_Page_Down:
557 case GDK_Up:
558 case GDK_KP_Up:
559 case GDK_Down:
560 case GDK_KP_Down:
561 wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
562 num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight);
563 num_traces_displayable--; /* for the time trace that is always there */
564
565 if(event->state & GDK_SHIFT_MASK)
566 {
567 Trptr t = NULL, t2 = NULL;
568 Trptr tc = NULL, th = NULL;
569 int num_high = 0;
570
571 if((event->keyval == GDK_KEY_Up) || (event->keyval == GDK_KEY_KP_Up))
572 {
573 ud_kill = 1;
574 for(t=GLOBALS->traces.first;t;t=t->t_next)
575 {
576 if(t->flags&TR_HIGHLIGHT)
577 {
578 if(!th) th = t;
579 num_high++;
580 }
581
582 if(t->is_cursor)
583 {
584 tc = t;
585 }
586 }
587
588 if(num_high <= 1)
589 {
590 t = th ? GivePrevTrace(th) : GLOBALS->topmost_trace;
591 }
592 else
593 {
594 t = tc ? GivePrevTrace(tc) : GLOBALS->topmost_trace;
595 }
596
597 MarkTraceCursor(t);
598 }
599 else
600 if((event->keyval == GDK_KEY_Down) || (event->keyval == GDK_KEY_KP_Down))
601 {
602 ud_kill = 1;
603 for(t=GLOBALS->traces.first;t;t=t->t_next)
604 {
605 if(t->flags&TR_HIGHLIGHT)
606 {
607 th = t;
608 num_high++;
609 }
610 if(t->is_cursor)
611 {
612 tc = t;
613 }
614 }
615
616 if(num_high <= 1)
617 {
618 t = th ? GiveNextTrace(th) : GLOBALS->topmost_trace;
619 }
620 else
621 {
622 if(tc)
623 {
624 t = GiveNextTrace(tc);
625 }
626 else
627 {
628 t = th ? GiveNextTrace(th) : GLOBALS->topmost_trace;
629 }
630 }
631
632 MarkTraceCursor(t);
633 }
634
635 if(t)
636 {
637 int top_target = 0;
638 target = 0;
639 which=num_traces_displayable-1;
640
641 ClearTraces();
642 t->flags |= TR_HIGHLIGHT;
643 t2 = t;
644
645 for(t=GLOBALS->traces.first;t;t=GiveNextTrace(t))
646 {
647 if(t == GLOBALS->topmost_trace) break;
648 top_target++;
649 }
650
651 for(t=GLOBALS->traces.first;t;t=GiveNextTrace(t))
652 {
653 if(t2 == t) break;
654 target++;
655 }
656
657 if((target >= top_target) && (target <= top_target+which))
658 {
659 /* nothing */
660 }
661 else
662 {
663 if((event->keyval == GDK_KEY_Up) || (event->keyval == GDK_KEY_KP_Up))
664 {
665 if(target<0) target=0;
666 }
667 else
668 if((event->keyval == GDK_KEY_Down) || (event->keyval == GDK_KEY_KP_Down))
669 {
670 target = target - which;
671 if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1;
672 }
673
674 wadj->value = target;
675 }
676
677 if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */
678
679 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
680 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
681 signalarea_configure_event(GLOBALS->signalarea, NULL);
682 wavearea_configure_event(GLOBALS->wavearea, NULL);
683 }
684 }
685
686 if((num_traces_displayable<GLOBALS->traces.visible) && (!ud_kill))
687 {
688 switch(event->keyval)
689 {
690 case GDK_Down:
691 case GDK_KP_Down:
692 case GDK_Page_Down:
693 case GDK_KP_Page_Down:
694 yscroll = ((event->keyval == GDK_Page_Down) || (event->keyval == GDK_KP_Page_Down)) ? num_traces_displayable : 1;
695 target=((int)wadj->value)+yscroll;
696 which=num_traces_displayable-1;
697
698 if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1;
699 wadj->value=target;
700
701 if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */
702
703 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
704 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
705 signalarea_configure_event(GLOBALS->signalarea, NULL);
706 wavearea_configure_event(GLOBALS->wavearea, NULL);
707 break;
708
709 case GDK_Up:
710 case GDK_KP_Up:
711 case GDK_Page_Up:
712 case GDK_KP_Page_Up:
713 yscroll = ((event->keyval == GDK_Page_Up) || (event->keyval == GDK_KP_Page_Up)) ? num_traces_displayable : 1;
714 target=((int)wadj->value)-yscroll;
715 if(target<0) target=0;
716 wadj->value=target;
717
718 which=0;
719 if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=-1; /* force update */
720
721 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
722 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
723 break;
724 }
725 }
726 rc = TRUE;
727 break;
728
729 case GDK_Left:
730 case GDK_KP_Left:
731
732 service_left_edge(NULL, 0);
733 /*
734 hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
735
736 if(hadj->value < hadj->page_increment)
737 {
738 hadj->value = (gfloat)0.0;
739 }
740 else
741 {
742 hadj->value = hadj->value - hadj->page_increment;
743 }
744
745 gtk_signal_emit_by_name (GTK_OBJECT (hadj), "changed");
746 gtk_signal_emit_by_name (GTK_OBJECT (hadj), "value_changed");
747 signalarea_configure_event(GLOBALS->signalarea, NULL);
748 */
749
750 rc = TRUE;
751 break;
752
753 case GDK_Right:
754 case GDK_KP_Right:
755
756 service_right_edge(NULL, 0);
757 /*
758 hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
759
760 if( ((int) hadj->value + hadj->page_increment) >= hadj->upper)
761 {
762 hadj->value = (gfloat)(hadj->upper)-hadj->page_increment;
763 }
764 else
765 {
766 hadj->value = hadj->value + hadj->page_increment;
767 }
768
769 gtk_signal_emit_by_name (GTK_OBJECT (hadj), "changed");
770 gtk_signal_emit_by_name (GTK_OBJECT (hadj), "value_changed");
771 signalarea_configure_event(GLOBALS->signalarea, NULL);
772 */
773
774 rc = TRUE;
775 break;
776
777 default:
778 #ifdef FOCUS_DEBUG_MSGS
779 printf("key %x, widget: %08x\n", event->keyval, widget);
780 #endif
781 break;
782 }
783 }
784 else
785 if(GLOBALS->dnd_sigview)
786 {
787 if(GTK_WIDGET_HAS_FOCUS(GLOBALS->dnd_sigview) || GTK_WIDGET_HAS_FOCUS(GLOBALS->filter_entry))
788 {
789 switch(event->keyval)
790 {
791 case GDK_a:
792 #ifdef MAC_INTEGRATION
793 if(event->state & GDK_META_MASK)
794 #else
795 if(event->state & GDK_CONTROL_MASK)
796 #endif
797 {
798 treeview_select_all_callback();
799 rc = TRUE;
800 }
801 break;
802
803 case GDK_A:
804 #ifdef MAC_INTEGRATION
805 if(event->state & GDK_META_MASK)
806 #else
807 if(event->state & GDK_CONTROL_MASK)
808 #endif
809 {
810 treeview_unselect_all_callback();
811 rc = TRUE;
812 }
813 default:
814 break;
815 }
816 }
817 else
818 if(GTK_WIDGET_HAS_FOCUS(GLOBALS->tree_treesearch_gtk2_c_1))
819 {
820 switch(event->keyval)
821 {
822 case GDK_a:
823 #ifdef MAC_INTEGRATION
824 if(event->state & GDK_META_MASK)
825 #else
826 if(event->state & GDK_CONTROL_MASK)
827 #endif
828 {
829 /* eat keystroke */
830 rc = TRUE;
831 }
832 break;
833
834 case GDK_A:
835 #ifdef MAC_INTEGRATION
836 if(event->state & GDK_META_MASK)
837 #else
838 if(event->state & GDK_CONTROL_MASK)
839 #endif
840 {
841 /* eat keystroke */
842 rc = TRUE;
843 }
844 default:
845 break;
846 }
847 }
848 }
849 if (ignoreAccelerators(event)) {
850 gtk_widget_event(GLOBALS->filter_entry, (GdkEvent *)event);
851 /* eat keystroke */
852 rc = TRUE;
853 }
854
855 return(rc);
856 }
857
858 #ifdef WAVE_USE_GTK2
859 static gint
scroll_event(GtkWidget * widget,GdkEventScroll * event)860 scroll_event( GtkWidget * widget, GdkEventScroll * event )
861 {
862 GdkEventKey ev_fake;
863
864 DEBUG(printf("Mouse Scroll Event\n"));
865 switch ( event->direction )
866 {
867 case GDK_SCROLL_UP:
868 ev_fake.keyval = GDK_Up;
869 keypress_local(widget, &ev_fake, GLOBALS->signalarea_event_box);
870 break;
871 case GDK_SCROLL_DOWN:
872 ev_fake.keyval = GDK_Down;
873 keypress_local(widget, &ev_fake, GLOBALS->signalarea_event_box);
874
875 default:
876 break;
877 }
878 return(TRUE);
879 }
880 #endif
881
882
883 #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND
884 #ifdef MAC_INTEGRATION
osx_timer(gpointer dummy)885 static gboolean osx_timer(gpointer dummy)
886 {
887 if(GLOBALS)
888 {
889 if(GLOBALS->force_hide_show == 2)
890 {
891 if((GLOBALS->signalarea)&&(GLOBALS->wavearea))
892 {
893 gtk_widget_hide(GLOBALS->signalarea);
894 gtk_widget_show(GLOBALS->signalarea);
895 gtk_widget_hide(GLOBALS->wavearea);
896 gtk_widget_show(GLOBALS->wavearea);
897 }
898 }
899
900 if(GLOBALS->force_hide_show)
901 {
902 GLOBALS->force_hide_show--;
903 }
904 }
905
906 return(TRUE);
907 }
908 #endif
909 #endif
910
911
mouseover_timer(gpointer dummy)912 static gboolean mouseover_timer(gpointer dummy)
913 {
914 (void)dummy;
915
916 static gboolean run_once = FALSE;
917 gdouble x,y;
918 GdkModifierType state;
919 TraceEnt t_trans;
920
921 #ifdef WAVE_USE_GTK2
922 gint xi, yi;
923 #else
924 GdkEventMotion event[1];
925 event[0].deviceid = GDK_CORE_POINTER;
926 #endif
927
928 if(GLOBALS->button2_debounce_flag)
929 {
930 GLOBALS->button2_debounce_flag = 0;
931 }
932
933 if((GLOBALS->dnd_state)||(GLOBALS->tree_dnd_begin)) /* drag scroll on DnD */
934 {
935 GtkAdjustment *wadj;
936 int num_traces_displayable;
937 int target;
938 int which;
939 int yscroll;
940
941 WAVE_GDK_GET_POINTER(GLOBALS->signalarea->window, &x, &y, &xi, &yi, &state);
942 WAVE_GDK_GET_POINTER_COPY;
943
944 if(y > GLOBALS->signalarea->allocation.height)
945 {
946 wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
947 num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight);
948 num_traces_displayable--; /* for the time trace that is always there */
949
950 if(num_traces_displayable<GLOBALS->traces.visible)
951 {
952 yscroll = 1;
953 target=((int)wadj->value)+yscroll;
954 which=num_traces_displayable-1;
955
956 if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1;
957 wadj->value=target;
958
959 if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */
960
961 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
962 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
963 }
964 }
965 else
966 if(y < 0)
967 {
968 wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
969 num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight);
970 num_traces_displayable--; /* for the time trace that is always there */
971
972 if(num_traces_displayable<GLOBALS->traces.visible)
973 {
974 yscroll = 1;
975 target=((int)wadj->value)-yscroll;
976 if(target<0) target=0;
977 wadj->value=target;
978
979 which=0;
980 if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=-1; /* force update */
981
982 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
983 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
984 }
985 }
986 }
987
988 if(in_main_iteration()) return(TRUE);
989
990 if(GLOBALS->splash_is_loading)
991 {
992 return(TRUE);
993 }
994
995 if(GLOBALS->splash_fix_win_title)
996 {
997 GLOBALS->splash_fix_win_title = 0;
998 wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0);
999 }
1000
1001 if(GLOBALS->window_entry_c_1)
1002 {
1003 GLOBALS->entry_raise_timer++;
1004 if(GLOBALS->entry_raise_timer > 50)
1005 {
1006 gdk_window_raise(GLOBALS->window_entry_c_1->window);
1007 GLOBALS->entry_raise_timer = 0;
1008 }
1009 }
1010
1011 #ifdef WAVE_USE_GTK2
1012 #ifdef MAC_INTEGRATION
1013 if(GLOBALS->dnd_helper_quartz)
1014 {
1015 char *dhq = g_malloc(strlen(GLOBALS->dnd_helper_quartz)+1);
1016 strcpy(dhq, GLOBALS->dnd_helper_quartz);
1017 free_2(GLOBALS->dnd_helper_quartz);
1018 GLOBALS->dnd_helper_quartz = NULL;
1019 DND_helper_quartz(dhq);
1020 g_free(dhq);
1021 }
1022 #endif
1023 #endif
1024
1025 if(process_finder_names_queued())
1026 {
1027 #if GTK_CHECK_VERSION(2,4,0)
1028 if(GLOBALS->pFileChoose)
1029 #endif
1030 {
1031 if(!GLOBALS->window_simplereq_c_9)
1032 {
1033 char *qn = process_finder_extract_queued_name();
1034 if(qn)
1035 {
1036 int qn_len = strlen(qn);
1037 const int mlen = 30;
1038 if(qn_len < mlen)
1039 {
1040 simplereqbox("File queued for loading",300,qn,"OK", NULL, NULL, 1);
1041 }
1042 else
1043 {
1044 char *qn_2 = wave_alloca(mlen + 4);
1045 strcpy(qn_2, "...");
1046 strcat(qn_2, qn + qn_len - mlen);
1047 simplereqbox("File queued for loading",300,qn_2,"OK", NULL, NULL, 1);
1048 }
1049 return(TRUE);
1050 }
1051 }
1052 }
1053 #if GTK_CHECK_VERSION(2,4,0)
1054 else
1055 {
1056 if(process_finder_name_integration())
1057 {
1058 return(TRUE);
1059 }
1060 }
1061 #endif
1062 }
1063
1064 if(GLOBALS->loaded_file_type == MISSING_FILE)
1065 {
1066 return(TRUE);
1067 }
1068
1069 if(run_once == FALSE) /* avoid any race conditions with the toolkit for uninitialized data */
1070 {
1071 run_once = TRUE;
1072 return(TRUE);
1073 }
1074
1075 if((!GLOBALS->signalarea) || (!GLOBALS->signalarea->window))
1076 {
1077 return(TRUE);
1078 }
1079
1080 if(GLOBALS->dnd_cursor_timer)
1081 {
1082 GLOBALS->dnd_cursor_timer++;
1083 if(GLOBALS->dnd_cursor_timer == 50)
1084 {
1085 GLOBALS->dnd_cursor_timer = 0;
1086 signalarea_configure_event(GLOBALS->signalarea, NULL);
1087 }
1088 }
1089
1090 if(GLOBALS->mouseover_counter < 0) return(TRUE); /* mouseover is up in wave window so don't bother */
1091
1092 WAVE_GDK_GET_POINTER(GLOBALS->signalarea->window, &x, &y, &xi, &yi, &state);
1093 WAVE_GDK_GET_POINTER_COPY;
1094
1095 GLOBALS->mouseover_counter++;
1096
1097 if(!((x>=0)&&(x<GLOBALS->signalarea->allocation.width)&&(y>=0)&&(y<GLOBALS->signalarea->allocation.height)))
1098 {
1099 move_mouseover_sigs(NULL, 0, 0, LLDescriptor(0));
1100 }
1101 else
1102 if(GLOBALS->mouseover_counter == 10)
1103 {
1104 int num_traces_displayable=GLOBALS->wavearea->allocation.height/(GLOBALS->fontheight);
1105 int yr = GLOBALS->cached_mouseover_y;
1106 int i;
1107 Trptr t=NULL;
1108
1109 num_traces_displayable--; /* for the time trace that is always there */
1110
1111 yr-=GLOBALS->fontheight;
1112 if(yr<0) goto bot;
1113 yr/=GLOBALS->fontheight; /* y now indicates the trace in question */
1114 if(yr>num_traces_displayable) goto bot;
1115
1116 t=GLOBALS->topmost_trace;
1117
1118 for(i=0;i<yr;i++)
1119 {
1120 if(!t) goto bot;
1121 t=GiveNextTrace(t);
1122 }
1123
1124 if(!t) goto bot;
1125 if((t->flags&(/*TR_BLANK|*/TR_EXCLUDE))) /* TR_BLANK removed because of transaction handling below... */
1126 {
1127 t = NULL;
1128 goto bot;
1129 }
1130
1131 if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */
1132 {
1133 Trptr tscan = t;
1134 int bcnt = 0;
1135 while((tscan) && (tscan = GivePrevTrace(tscan)))
1136 {
1137 if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
1138 {
1139 if(tscan->flags & TR_TTRANSLATED)
1140 {
1141 break; /* found it */
1142 }
1143 else
1144 {
1145 tscan = NULL;
1146 }
1147 }
1148 else
1149 {
1150 bcnt++; /* bcnt is number of blank traces */
1151 }
1152 }
1153
1154 if((tscan)&&(tscan->vector))
1155 {
1156 bvptr bv = tscan->n.vec;
1157 do
1158 {
1159 bv = bv->transaction_chain; /* correlate to blank trace */
1160 } while(bv && (bcnt--));
1161 if(bv)
1162 {
1163 memcpy(&t_trans, tscan, sizeof(TraceEnt)); /* substitute into a synthetic trace */
1164 t_trans.n.vec = bv;
1165 t_trans.vector = 1;
1166
1167 t_trans.name = bv->bvname;
1168 if(GLOBALS->hier_max_level)
1169 t_trans.name = hier_extract(t_trans.name, GLOBALS->hier_max_level);
1170
1171 t = &t_trans;
1172 goto bot; /* is goto process_trace; in wavewindow.c */
1173 }
1174 }
1175 }
1176
1177 if((t->flags&TR_BLANK))
1178 {
1179 t = NULL;
1180 goto bot;
1181 }
1182
1183 if(t->flags & TR_ANALOG_BLANK_STRETCH) /* seek to real analog trace is present... */
1184 {
1185 while((t) && (t = t->t_prev))
1186 {
1187 if(!(t->flags & TR_ANALOG_BLANK_STRETCH))
1188 {
1189 if(t->flags & TR_ANALOGMASK)
1190 {
1191 break; /* found it */
1192 }
1193 else
1194 {
1195 t = NULL;
1196 }
1197 }
1198 }
1199 }
1200
1201 bot:
1202 if(t)
1203 {
1204 move_mouseover_sigs(t, GLOBALS->cached_mouseover_x, GLOBALS->cached_mouseover_y, GLOBALS->tims.marker);
1205 }
1206 else
1207 {
1208 move_mouseover_sigs(NULL, 0, 0, LLDescriptor(0));
1209 }
1210 }
1211
1212 return(TRUE);
1213 }
1214
motion_notify_event_std(GtkWidget * widget,GdkEventMotion * event)1215 static gint motion_notify_event_std(GtkWidget *widget, GdkEventMotion *event)
1216 {
1217 (void)widget;
1218
1219 gdouble x,y;
1220 GdkModifierType state;
1221
1222 #ifdef WAVE_USE_GTK2
1223 gint xi, yi;
1224 #endif
1225
1226 if(event->is_hint)
1227 {
1228 WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state);
1229 WAVE_GDK_GET_POINTER_COPY;
1230 }
1231 else
1232 {
1233 x = event->x;
1234 y = event->y;
1235 state = event->state;
1236 }
1237
1238 GLOBALS->cached_mouseover_x = x;
1239 GLOBALS->cached_mouseover_y = y;
1240 GLOBALS->mouseover_counter = 0;
1241
1242 move_mouseover_sigs(NULL, 0, 0, LLDescriptor(0));
1243
1244 return(TRUE);
1245 }
1246
1247
button_release_event_std(GtkWidget * widget,GdkEventButton * event)1248 static gint button_release_event_std(GtkWidget *widget, GdkEventButton *event)
1249 {
1250 (void)widget;
1251 (void)event;
1252
1253 if(GLOBALS->std_collapse_pressed)
1254 {
1255 GLOBALS->std_collapse_pressed = 0;
1256 }
1257
1258 return(TRUE);
1259 }
1260
1261
button_press_event_std(GtkWidget * widget,GdkEventButton * event)1262 static gint button_press_event_std(GtkWidget *widget, GdkEventButton *event)
1263 {
1264 int num_traces_displayable;
1265 int which;
1266 int trwhich, trtarget;
1267 GtkAdjustment *wadj;
1268 Trptr t, t2;
1269
1270 if(GLOBALS->signalarea_event_box)
1271 {
1272
1273 /* Don't mess with highlights with button 2 (save for dnd) */
1274 if((event->button == 2) && (event->type == GDK_BUTTON_PRESS))
1275 {
1276 return(TRUE);
1277 }
1278
1279 /* Don't mess with highlights with button 3 (save for menu_check) */
1280 if((event->button == 3) && (event->type == GDK_BUTTON_PRESS))
1281 {
1282 goto menu_chk;
1283 }
1284 if((event->x<0)||(event->x>=widget->allocation.width)||(event->y<0)||(event->y>=widget->allocation.height))
1285 {
1286 /* let gtk take focus from us with focus out event */
1287 }
1288 else
1289 {
1290 if(!GLOBALS->signalarea_has_focus)
1291 {
1292 GLOBALS->signalarea_has_focus = TRUE;
1293 gtk_widget_grab_focus(GTK_WIDGET(GLOBALS->signalarea_event_box));
1294 }
1295 }
1296 }
1297
1298 if((GLOBALS->traces.visible)&&(GLOBALS->signalpixmap))
1299 {
1300 num_traces_displayable=widget->allocation.height/(GLOBALS->fontheight);
1301 num_traces_displayable--; /* for the time trace that is always there */
1302
1303 which=(int)(event->y);
1304 which=(which/GLOBALS->fontheight)-1;
1305
1306 if(which>=GLOBALS->traces.visible)
1307 {
1308 #ifdef MAC_INTEGRATION
1309 if((event->state&(GDK_MOD2_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK))
1310 #else
1311 if((event->state&(GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK))
1312 #endif
1313 {
1314 /* ok for plain-vanilla shift click only */
1315 which = GLOBALS->traces.visible-1;
1316 }
1317 else
1318 {
1319 ClearTraces();
1320 goto redraw; /* off in no man's land */
1321 }
1322 }
1323
1324 if((which>=num_traces_displayable)||(which<0))
1325 {
1326 ClearTraces();
1327 goto redraw; /* off in no man's land */
1328 }
1329
1330 wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
1331 trtarget=((int)wadj->value)+which;
1332
1333 t=GLOBALS->traces.first;
1334 trwhich=0;
1335 while(t)
1336 {
1337 if((trwhich<trtarget)&&(GiveNextTrace(t)))
1338 {
1339 trwhich++;
1340 t=GiveNextTrace(t);
1341 }
1342 else
1343 {
1344 break;
1345 }
1346 }
1347
1348
1349 #ifdef MAC_INTEGRATION
1350 if(event->state & GDK_MOD2_MASK)
1351 #else
1352 if(event->state&GDK_CONTROL_MASK)
1353 #endif
1354 {
1355 if(t) /* scan-build */
1356 {
1357 if(IsGroupBegin(t) && IsSelected(t))
1358 {
1359 ClearGroupTraces(t);
1360 }
1361 else if(IsGroupEnd(t) && IsSelected(t))
1362 {
1363 ClearGroupTraces(t->t_match);
1364 }
1365 else
1366 {
1367 t->flags ^= TR_HIGHLIGHT; MarkTraceCursor(t);
1368 }
1369 }
1370 }
1371 else
1372 if((event->state&GDK_SHIFT_MASK)&&(GLOBALS->starting_unshifted_trace))
1373 {
1374 int src = -1, dst = -1, dsto = -1;
1375 int cnt = 0;
1376
1377 t2=GLOBALS->traces.first;
1378 while(t2)
1379 {
1380 if(t2 == t) { dst = cnt; }
1381 if(t2 == GLOBALS->starting_unshifted_trace) { src = cnt; }
1382
1383 cnt++;
1384
1385 /* t2->flags &= ~TR_HIGHLIGHT; */
1386 t2 = t2->t_next;
1387 }
1388
1389 if(src != -1)
1390 {
1391 cnt = 0;
1392 t2=GLOBALS->traces.first;
1393 while(t2)
1394 {
1395 if ((cnt == src) && (cnt == dst) && IsSelected(t2))
1396 {
1397 GLOBALS->starting_unshifted_trace = NULL;
1398 }
1399 t2->flags &= ~TR_HIGHLIGHT;
1400 t2=t2->t_next;
1401 cnt++;
1402 }
1403
1404 dsto = dst;
1405 if(src > dst) { int cpy; cpy = src; src = dst; dst = cpy; }
1406 cnt = 0;
1407 t2=GLOBALS->traces.first;
1408 while(t2 && GLOBALS->starting_unshifted_trace)
1409 {
1410 if((cnt >= src) && (cnt <= dst))
1411 {
1412 t2->flags |= TR_HIGHLIGHT;
1413 }
1414
1415 if(cnt == dsto) { MarkTraceCursor(t2); }
1416
1417 cnt++;
1418 t2=t2->t_next;
1419 }
1420 }
1421 else
1422 {
1423 GLOBALS->starting_unshifted_trace = t;
1424 if(t) { t->flags |= TR_HIGHLIGHT; } /* scan-build */
1425 }
1426 }
1427 /* else if(!(t->flags & TR_HIGHLIGHT)) Ben Sferrazza suggested fix rather than a regular "else" 11aug08 */
1428 /* changed to add use_standard_trace_select below to make this selectable, Sophana K request 08oct12 */
1429 else if( (!GLOBALS->use_standard_trace_select) || (GLOBALS->standard_trace_dnd_degate) || ((t)&&(!(t->flags & TR_HIGHLIGHT))) )
1430 {
1431 GLOBALS->starting_unshifted_trace = t;
1432
1433 t2=GLOBALS->traces.first;
1434 while(t2)
1435 {
1436 t2->flags &= ~TR_HIGHLIGHT;
1437 t2 = t2->t_next;
1438 }
1439
1440 if(t) { t->flags |= TR_HIGHLIGHT; MarkTraceCursor(t); } /* scan-build */
1441 }
1442
1443 GLOBALS->standard_trace_dnd_degate = 0;
1444
1445 if(event->type == GDK_2BUTTON_PRESS)
1446 {
1447 menu_toggle_group(NULL, 0, widget);
1448 goto menu_chk;
1449 }
1450
1451 redraw:
1452
1453 GLOBALS->signalwindow_width_dirty=1;
1454 MaxSignalLength();
1455 signalarea_configure_event(GLOBALS->signalarea, NULL);
1456 wavearea_configure_event(GLOBALS->wavearea, NULL);
1457 }
1458
1459
1460 menu_chk:
1461 if((event->button == 3) && (event->type == GDK_BUTTON_PRESS))
1462 {
1463 do_popup_menu (widget, event);
1464 }
1465
1466 return(TRUE);
1467 }
1468
1469 /*** standard click routines turned on with "use_standard_clicking"=1 ***/
1470 /**************************************************************************/
1471
1472
1473 /**************************************************************************/
1474 /*** standard click routines turned on with "use_standard_clicking"=0 ***/
1475 /*** ***/
1476 /*** no longer supported ***/
1477 /*** ***/
1478 /*** gtkwave click routines turned on with "use_standard_clicking"=0 ***/
1479 /**************************************************************************/
1480
1481
signalarea_configure_event(GtkWidget * widget,GdkEventConfigure * event)1482 gint signalarea_configure_event(GtkWidget *widget, GdkEventConfigure *event)
1483 {
1484 (void)event;
1485
1486 GtkAdjustment *wadj, *hadj;
1487 int num_traces_displayable;
1488 int width;
1489
1490 if((!widget)||(!widget->window)) return(TRUE);
1491
1492 #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND
1493 #ifdef MAC_INTEGRATION
1494 if(!GLOBALS->force_hide_show)
1495 {
1496 GLOBALS->force_hide_show = 2;
1497 }
1498 #endif
1499 #endif
1500
1501 make_sigarea_gcs(widget);
1502 UpdateTracesVisible();
1503
1504 num_traces_displayable=widget->allocation.height/(GLOBALS->fontheight);
1505 num_traces_displayable--; /* for the time trace that is always there */
1506
1507
1508 DEBUG(printf("SigWin Configure Event h: %d, w: %d\n",
1509 widget->allocation.height,
1510 widget->allocation.width));
1511
1512 GLOBALS->old_signal_fill_width=GLOBALS->signal_fill_width;
1513 GLOBALS->signal_fill_width = ((width=widget->allocation.width) > GLOBALS->signal_pixmap_width)
1514 ? widget->allocation.width : GLOBALS->signal_pixmap_width;
1515
1516 if(GLOBALS->signalpixmap)
1517 {
1518 if((GLOBALS->old_signal_fill_width!=GLOBALS->signal_fill_width)||(GLOBALS->old_signal_fill_height!=widget->allocation.height))
1519 {
1520 gdk_pixmap_unref(GLOBALS->signalpixmap);
1521 GLOBALS->signalpixmap=gdk_pixmap_new(widget->window,
1522 GLOBALS->signal_fill_width, widget->allocation.height, -1);
1523 }
1524 }
1525 else
1526 {
1527 GLOBALS->signalpixmap=gdk_pixmap_new(widget->window,
1528 GLOBALS->signal_fill_width, widget->allocation.height, -1);
1529 }
1530
1531 if (!GLOBALS->left_justify_sigs && !GLOBALS->do_resize_signals)
1532 {
1533 if (width < GLOBALS->max_signal_name_pixel_width+15)
1534 {
1535 int delta = GLOBALS->max_signal_name_pixel_width+15 - width;
1536
1537 if(GLOBALS->signalpixmap)
1538 {
1539
1540 hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
1541
1542 /* int pos = GLOBALS->max_signal_name_pixel_width+15 - (gint)hadj->value; */
1543
1544 if ((gint) hadj->value > delta)
1545 {
1546 GLOBALS->right_align_active = 1;
1547 delta = (gint)hadj->value;
1548 }
1549 if (GLOBALS->right_align_active)
1550 hadj->value = (gint)delta;
1551 }
1552 } else {
1553 GLOBALS->right_align_active = 1;
1554 }
1555 }
1556
1557 GLOBALS->old_signal_fill_height= widget->allocation.height;
1558 gdk_draw_rectangle(GLOBALS->signalpixmap, widget->style->bg_gc[GTK_STATE_PRELIGHT], TRUE, 0, 0,
1559 GLOBALS->signal_fill_width, widget->allocation.height);
1560
1561 hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
1562 hadj->page_size=hadj->page_increment=(gfloat)width;
1563 hadj->step_increment=(gfloat)10.0; /* approx 1ch at a time */
1564 hadj->lower=(gfloat)0.0;
1565 hadj->upper=(gfloat)GLOBALS->signal_pixmap_width;
1566
1567 if( ((int)hadj->value)+width > GLOBALS->signal_fill_width)
1568 {
1569 hadj->value = (gfloat)(GLOBALS->signal_fill_width-width);
1570 }
1571
1572
1573 wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider);
1574 wadj->page_size=wadj->page_increment=(gfloat) num_traces_displayable;
1575 wadj->step_increment=(gfloat)1.0;
1576 wadj->lower=(gfloat)0.0;
1577 wadj->upper=(gfloat)(GLOBALS->traces.visible ? GLOBALS->traces.visible : 1);
1578
1579 if(GLOBALS->traces.scroll_bottom)
1580 {
1581 Trptr t = GLOBALS->traces.first;
1582 int which = 0;
1583 int scroll_top = -1, scroll_bottom = -1;
1584 int cur_top = wadj->value;
1585 int cur_bottom = cur_top + num_traces_displayable - 1;
1586
1587 while(t)
1588 {
1589 if(t == GLOBALS->traces.scroll_top)
1590 {
1591 scroll_top = which;
1592 }
1593
1594 if(t == GLOBALS->traces.scroll_bottom)
1595 {
1596 scroll_bottom = which;
1597 break;
1598 }
1599
1600 t = GiveNextTrace(t);
1601 which++;
1602 }
1603
1604 GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = NULL;
1605
1606 if((scroll_top >= 0) && (scroll_bottom >= 0))
1607 {
1608 if((scroll_top > cur_top) && (scroll_bottom <= cur_bottom))
1609 {
1610 /* nothing */
1611 }
1612 else
1613 {
1614 if((scroll_bottom - scroll_top + 1) >= num_traces_displayable)
1615 {
1616 wadj->value=(gfloat)(scroll_bottom - num_traces_displayable + 1);
1617 }
1618 else
1619 {
1620 int midpoint = (cur_top + cur_bottom) / 2;
1621
1622 if(scroll_top <= cur_top)
1623 {
1624 wadj->value=(gfloat)scroll_top-1;
1625 }
1626 else if(scroll_top >= cur_bottom)
1627 {
1628 wadj->value=(gfloat)(scroll_bottom - num_traces_displayable + 1);
1629 }
1630 else
1631 if(scroll_top < midpoint)
1632 {
1633 wadj->value=(gfloat)scroll_top-1;
1634 }
1635 else
1636 {
1637 wadj->value=(gfloat)(scroll_bottom - num_traces_displayable + 1);
1638 }
1639 }
1640
1641 if(wadj->value < 0.0) wadj->value = 0.0;
1642 }
1643 }
1644 }
1645
1646 if(num_traces_displayable>GLOBALS->traces.visible)
1647 {
1648 wadj->value=(gfloat)(GLOBALS->trtarget_signalwindow_c_1=0);
1649 }
1650 else
1651 if (wadj->value + num_traces_displayable > GLOBALS->traces.visible)
1652 {
1653 wadj->value=(gfloat)(GLOBALS->trtarget_signalwindow_c_1=GLOBALS->traces.visible-num_traces_displayable);
1654 }
1655
1656 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */
1657 gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */
1658
1659 gtk_signal_emit_by_name (GTK_OBJECT (hadj), "changed"); /* force bar update */
1660
1661 return(TRUE);
1662 }
1663
signalarea_configure_event_local(GtkWidget * widget,GdkEventConfigure * event)1664 static gint signalarea_configure_event_local(GtkWidget *widget, GdkEventConfigure *event)
1665 {
1666 gint rc;
1667 gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook));
1668 struct Global *g_old = GLOBALS;
1669
1670 set_GLOBALS((*GLOBALS->contexts)[page_num]);
1671
1672 rc = signalarea_configure_event(widget, event);
1673
1674 set_GLOBALS(g_old);
1675
1676 return(rc);
1677 }
1678
1679
expose_event(GtkWidget * widget,GdkEventExpose * event)1680 static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
1681 {
1682 GtkAdjustment *hadj;
1683 int xsrc;
1684
1685 hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider);
1686 xsrc=(gint)hadj->value;
1687
1688 gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
1689 GLOBALS->signalpixmap,
1690 xsrc+event->area.x, event->area.y,
1691 event->area.x, event->area.y,
1692 event->area.width, event->area.height);
1693
1694 draw_signalarea_focus();
1695
1696 return(FALSE);
1697 }
1698
expose_event_local(GtkWidget * widget,GdkEventExpose * event)1699 static gint expose_event_local(GtkWidget *widget, GdkEventExpose *event)
1700 {
1701 gint rc;
1702 gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook));
1703 /* struct Global *g_old = GLOBALS; */
1704
1705 set_GLOBALS((*GLOBALS->contexts)[page_num]);
1706
1707 rc = expose_event(widget, event);
1708
1709 /* seems to cause a conflict flipping back so don't! */
1710 /* set_GLOBALS(g_old); */
1711
1712 return(rc);
1713 }
1714
1715
focus_in_local(GtkWidget * widget,GdkEventFocus * event)1716 static int focus_in_local(GtkWidget *widget, GdkEventFocus *event)
1717 {
1718 #ifdef FOCUS_DEBUG_MSGS
1719 (void)event;
1720
1721 printf("Focus in: %08x %08x\n", widget, GLOBALS->signalarea_event_box);
1722 #else
1723 (void)widget;
1724 (void)event;
1725 #endif
1726
1727 GLOBALS->signalarea_has_focus = TRUE;
1728
1729 signalarea_configure_event(GLOBALS->signalarea, NULL);
1730
1731 return(FALSE);
1732 }
1733
focus_out_local(GtkWidget * widget,GdkEventFocus * event)1734 static int focus_out_local(GtkWidget *widget, GdkEventFocus *event)
1735 {
1736 #ifdef FOCUS_DEBUG_MSGS
1737 (void)event;
1738
1739 printf("Focus out: %08x\n", widget);
1740 #else
1741 (void)widget;
1742 (void)event;
1743 #endif
1744
1745 GLOBALS->signalarea_has_focus = FALSE;
1746
1747 signalarea_configure_event(GLOBALS->signalarea, NULL);
1748
1749 return(FALSE);
1750 }
1751
1752 GtkWidget *
create_signalwindow(void)1753 create_signalwindow(void)
1754 {
1755 GtkWidget *table;
1756 GtkWidget *frame;
1757 char do_focusing = 0;
1758
1759 table = gtk_table_new(10, 10, FALSE);
1760
1761 GLOBALS->signalarea=gtk_drawing_area_new();
1762
1763 gtk_widget_show(GLOBALS->signalarea);
1764 MaxSignalLength();
1765
1766 gtk_widget_set_events(GLOBALS->signalarea,
1767 #ifdef WAVE_USE_GTK2
1768 GDK_SCROLL_MASK |
1769 #endif
1770 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
1771 GDK_BUTTON_RELEASE_MASK |
1772 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK
1773 );
1774
1775 gtk_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "configure_event", GTK_SIGNAL_FUNC(signalarea_configure_event_local), NULL);
1776 gtk_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "expose_event",GTK_SIGNAL_FUNC(expose_event_local), NULL);
1777
1778 sclick:
1779 if(GLOBALS->use_standard_clicking)
1780 {
1781 GtkTargetEntry target_entry[3];
1782
1783 target_entry[0].target = WAVE_DRAG_TAR_NAME_0;
1784 target_entry[0].flags = 0;
1785 target_entry[0].info = WAVE_DRAG_TAR_INFO_0;
1786 target_entry[1].target = WAVE_DRAG_TAR_NAME_1;
1787 target_entry[1].flags = 0;
1788 target_entry[1].info = WAVE_DRAG_TAR_INFO_1;
1789 target_entry[2].target = WAVE_DRAG_TAR_NAME_2;
1790 target_entry[2].flags = 0;
1791 target_entry[2].info = WAVE_DRAG_TAR_INFO_2;
1792
1793 gtk_drag_dest_set(
1794 GTK_WIDGET(GLOBALS->signalarea),
1795 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
1796 GTK_DEST_DEFAULT_DROP,
1797 target_entry,
1798 sizeof(target_entry) / sizeof(GtkTargetEntry),
1799 GDK_ACTION_MOVE
1800 );
1801
1802 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "drag_motion", GTK_SIGNAL_FUNC(DNDDragMotionCB), GTK_WIDGET(GLOBALS->signalarea));
1803 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "drag_begin", GTK_SIGNAL_FUNC(DNDBeginCB), GTK_WIDGET(GLOBALS->signalarea));
1804 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "drag_end", GTK_SIGNAL_FUNC(DNDEndCB), GTK_WIDGET(GLOBALS->signalarea));
1805 #ifdef WAVE_USE_GTK2
1806 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "drag_failed", GTK_SIGNAL_FUNC(DNDFailedCB), GTK_WIDGET(GLOBALS->signalarea));
1807 #endif
1808
1809 gtk_drag_dest_set(
1810 GTK_WIDGET(GLOBALS->wavearea),
1811 GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT |
1812 GTK_DEST_DEFAULT_DROP,
1813 target_entry,
1814 sizeof(target_entry) / sizeof(GtkTargetEntry),
1815 GDK_ACTION_MOVE
1816 );
1817
1818 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "drag_motion", GTK_SIGNAL_FUNC(DNDDragMotionCB), GTK_WIDGET(GLOBALS->wavearea));
1819 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "drag_begin", GTK_SIGNAL_FUNC(DNDBeginCB), GTK_WIDGET(GLOBALS->wavearea));
1820 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "drag_end", GTK_SIGNAL_FUNC(DNDEndCB), GTK_WIDGET(GLOBALS->wavearea));
1821 #ifdef WAVE_USE_GTK2
1822 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "drag_failed", GTK_SIGNAL_FUNC(DNDFailedCB), GTK_WIDGET(GLOBALS->wavearea));
1823 #endif
1824
1825 gtk_drag_source_set(GTK_WIDGET(GLOBALS->signalarea),
1826 GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
1827 target_entry,
1828 sizeof(target_entry) / sizeof(GtkTargetEntry),
1829 GDK_ACTION_PRIVATE);
1830
1831 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "button_press_event",GTK_SIGNAL_FUNC(button_press_event_std), NULL);
1832 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "button_release_event", GTK_SIGNAL_FUNC(button_release_event_std), NULL);
1833 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "motion_notify_event",GTK_SIGNAL_FUNC(motion_notify_event_std), NULL);
1834 g_timeout_add(100, mouseover_timer, NULL);
1835 #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND
1836 #ifdef MAC_INTEGRATION
1837 g_timeout_add(100, osx_timer, NULL);
1838 #endif
1839 #endif
1840
1841 #ifdef WAVE_USE_GTK2
1842 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "scroll_event",GTK_SIGNAL_FUNC(scroll_event), NULL);
1843 #endif
1844 do_focusing = 1;
1845 }
1846 else
1847 {
1848 fprintf(stderr, "GTKWAVE | \"use_standard_clicking off\" has been removed.\n");
1849 fprintf(stderr, "GTKWAVE | Please update your rc files accordingly.\n");
1850 GLOBALS->use_standard_clicking = 1;
1851 goto sclick;
1852 }
1853
1854 gtk_table_attach (GTK_TABLE (table), GLOBALS->signalarea, 0, 10, 0, 9,
1855 GTK_FILL | GTK_EXPAND,
1856 GTK_FILL | GTK_EXPAND | GTK_SHRINK, 3, 2);
1857
1858 GLOBALS->signal_hslider=gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
1859 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signal_hslider), "value_changed",GTK_SIGNAL_FUNC(service_hslider), NULL);
1860 GLOBALS->hscroll_signalwindow_c_1=gtk_hscrollbar_new(GTK_ADJUSTMENT(GLOBALS->signal_hslider));
1861 gtk_widget_show(GLOBALS->hscroll_signalwindow_c_1);
1862 gtk_table_attach (GTK_TABLE (table), GLOBALS->hscroll_signalwindow_c_1, 0, 10, 9, 10,
1863 GTK_FILL,
1864 GTK_FILL | GTK_SHRINK, 3, 4);
1865 gtk_widget_show(table);
1866
1867 frame=gtk_frame_new("Signals");
1868 gtk_container_border_width(GTK_CONTAINER(frame),2);
1869
1870 gtk_container_add(GTK_CONTAINER(frame),table);
1871
1872 if(do_focusing)
1873 {
1874 GLOBALS->signalarea_event_box = gtk_event_box_new();
1875 gtk_container_add (GTK_CONTAINER (GLOBALS->signalarea_event_box), frame);
1876 gtk_widget_show(frame);
1877 GTK_WIDGET_SET_FLAGS (GTK_WIDGET(GLOBALS->signalarea_event_box), GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT);
1878 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea_event_box), "focus_in_event", GTK_SIGNAL_FUNC(focus_in_local), NULL);
1879 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea_event_box), "focus_out_event", GTK_SIGNAL_FUNC(focus_out_local), NULL);
1880
1881 /* not necessary for now... */
1882 /* gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea_event_box), "popup_menu",GTK_SIGNAL_FUNC(popup_event), NULL); */
1883
1884 if(!GLOBALS->second_page_created)
1885 {
1886 if(!GLOBALS->keypress_handler_id)
1887 {
1888 GLOBALS->keypress_handler_id = install_keypress_handler();
1889 }
1890 }
1891
1892 return(GLOBALS->signalarea_event_box);
1893 }
1894 else
1895 {
1896 return(frame);
1897 }
1898 }
1899
1900
install_keypress_handler(void)1901 gint install_keypress_handler(void)
1902 {
1903 gint rc =
1904 gtk_signal_connect(GTK_OBJECT(GLOBALS->mainwindow),
1905 "key_press_event",GTK_SIGNAL_FUNC(keypress_local), NULL);
1906
1907 return(rc);
1908 }
1909
1910
remove_keypress_handler(gint id)1911 void remove_keypress_handler(gint id)
1912 {
1913 gtk_signal_disconnect(GTK_OBJECT(GLOBALS->mainwindow), id);
1914 }
1915
1916
1917