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