From 7ba5392809e3f2e71e90089c542dfbf752dff21a Mon Sep 17 00:00:00 2001
From: edgrif <edgrif>
Date: Wed, 5 May 2010 15:30:05 +0000
Subject: [PATCH] make sure button releases are passed through as other
 routines need them.

---
 src/zmapWindow/zmapWindow.c | 259 +++++++++++++++++++++---------------
 1 file changed, 154 insertions(+), 105 deletions(-)

diff --git a/src/zmapWindow/zmapWindow.c b/src/zmapWindow/zmapWindow.c
index 5920a63b7..a7c94980a 100755
--- a/src/zmapWindow/zmapWindow.c
+++ b/src/zmapWindow/zmapWindow.c
@@ -26,9 +26,9 @@
  *              
  * Exported functions: See ZMap/zmapWindow.h
  * HISTORY:
- * Last edited: Apr 30 10:38 2010 (edgrif)
+ * Last edited: May  5 16:28 2010 (edgrif)
  * Created: Thu Jul 24 14:36:27 2003 (edgrif)
- * CVS info:   $Id: zmapWindow.c,v 1.318 2010-04-30 10:10:13 edgrif Exp $
+ * CVS info:   $Id: zmapWindow.c,v 1.319 2010-05-05 15:30:05 edgrif Exp $
  *-------------------------------------------------------------------
  */
 
@@ -2509,6 +2509,22 @@ static gboolean dataEventCB(GtkWidget *widget, GdkEventClient *event, gpointer c
        * foocanvas/gtk to get an event run _after_ the canvas handlers, you cannot for instance
        * just use  g_signal_connect_after(). */
 
+#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
+      {
+        /* we've had problems with event handling so I'm leaving these here for now in
+         * case there is more trouble. */
+	gpointer obj = window->canvas ;
+
+	gtk_widget_add_events(GTK_WIDGET(window->toplevel), GDK_POINTER_MOTION_MASK) ;
+	g_signal_connect(obj, "button-press-event",
+			 pressCB, (gpointer)window) ;
+	g_signal_connect(obj, "motion-notify-event",
+			 motionCB, (gpointer)window) ;
+	g_signal_connect(obj, "button-release-event",
+			 releaseCB, (gpointer)window) ;
+
+      }
+#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
 
       /* adding G_SIGNAL_MATCH_DETAIL to mask results in failure here, despite using the same detail! */
       signal_detail = g_quark_from_string("event");
@@ -2539,23 +2555,6 @@ static gboolean dataEventCB(GtkWidget *widget, GdkEventClient *event, gpointer c
 	zMapLogMessage("%s", "event handler for canvas already registered.");
 
 
-#ifdef NEVER_EVER
-      {
-        /* we've had problems with event handling so I'm leaving these here for now in
-         * case there is more trouble. */
-	gpointer obj = window->canvas ;
-
-	gtk_widget_add_events(GTK_WIDGET(window->toplevel), GDK_POINTER_MOTION_MASK) ;
-	g_signal_connect(obj, "button-press-event",
-			 pressCB, (gpointer)window) ;
-	g_signal_connect(obj, "motion-notify-event",
-			 motionCB, (gpointer)window) ;
-	g_signal_connect(obj, "button-release-event",
-			 releaseCB, (gpointer)window) ;
-
-      }
-#endif	
-
       zMapStyleDestroyStyles(&(feature_sets->all_styles)) ;
       zMapStyleDestroyStyles(&(feature_sets->new_styles)) ;
       g_free(feature_sets) ;
@@ -2691,6 +2690,19 @@ static gboolean windowGeneralEventCB(GtkWidget *wigdet, GdkEvent *event, gpointe
  * to _select_ a feature or column, _not_ lasso. In this case we have to reissue the original
  * button press event, when we then receive that event we just ignore it so that its passed
  * through to the object select code.
+ *
+ * A note from Roy (!): 
+ *
+ * PLEASE be very careful when altering this function, as I've
+ * already messed stuff up when working on it! The event_handled
+ * boolean _SHOULD_ be set to true any time we handle the event.
+ * While this sounds obvious I fell over it when implementing the
+ * motion as well as button down and release. If there is a track 
+ * of events, such as button/key down .. motion .. button release
+ * then the event_handled should be true for the whole of the life
+ * of the track of events.  All of the statics above could/probably
+ * should be replaced with a struct... please think about this if 
+ * adding any more!
  * 
  */
 static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer data)
@@ -2705,22 +2717,10 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 							       or rubber banding ? */
   double wx, wy;					    /* These hold the current world coords of the event */
   static double window_x, window_y ;			    /* Track number of pixels user moves mouse. */
-  static GdkEventButton *but_copy = NULL ;		    /* Used to implement both lasso _and_ object
+  static GdkEventButton *but_press_copy = NULL ;		    /* Used to implement both lasso _and_ object
 							       select with left button click. */
   static MarkRegionUpdateStruct mark_updater = {0};
 
-  /* PLEASE be very careful when altering this function, as I've
-   * already messed stuff up when working on it! The event_handled
-   * boolean _SHOULD_ be set to true any time we handle the event.
-   * While this sounds obvious I fell over it when implementing the
-   * motion as well as button down and release. If there is a track 
-   * of events, such as button/key down .. motion .. button release
-   * then the event_handled should be true for the whole of the life
-   * of the track of events.  All of the statics above could/probably
-   * should be replaced with a struct... please think about this if 
-   * adding any more!
-   */
-
   /* We need to check that canvas is mapped here (slow connections) */
 
 
@@ -2731,18 +2731,14 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
   else if (event->type == GDK_LEAVE_NOTIFY)
     in_window = FALSE ;
 
-
-
   switch (event->type)
     {
-
     case GDK_BUTTON_PRESS:
       {
 	GdkEventButton *but_event = (GdkEventButton *)event ;
 	FooCanvasItem *item ;
 
-	zMapDebugPrint(mouse_debug_G, "Start: button_press %d\n", but_event->button) ;
-
+	zMapDebugPrint(mouse_debug_G, "Start: button_press %d", but_event->button) ;
 
 	/* We want the canvas to be the focus widget of its "window" otherwise keyboard input
 	 * (i.e. short cuts) will be delivered to some other widget. */
@@ -2752,7 +2748,7 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 	 * because that is what this is for.... */
 	(*(window_cbs_G->focus))(window, window->app_data, NULL) ;
 
-	if(TRUE)
+	if (TRUE)
 	  {
 	    invokeVisibilityChange(window);
 	  }
@@ -2771,54 +2767,65 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 	  case 1:
 	    {
 
-	      /* If we receive a button press event where send_event == TRUE, its the one we sent ourselves
-	       * to do feature select so don't process it. */
 	      if (but_event->send_event)
 		{
-		  return FALSE ;
-		}
-
+		  /* If we receive a button press event where send_event == TRUE, its the one we sent ourselves
+		   * to do feature select so don't process it. */
 
-	      /* Don't handle if its text because the text item callbacks handle lasso'ing of
-	       * text. */
-	      if ((item = foo_canvas_get_item_at(window->canvas, origin_x, origin_y))
-		  && ZMAP_IS_WINDOW_TEXT_ITEM(item))
-		return FALSE ;
-	
+		  zMapDebugPrint(mouse_debug_G, "button_press %d was sent by us - don't process", but_event->button) ;
 
-	      /* Take a copy of the initial event in case we need to resend it to do feature select. */
-	      but_copy = (GdkEventButton *)gdk_event_copy((GdkEvent *)event) ;
+		  event_handled = FALSE ;
+		}
+	      else if ((item = foo_canvas_get_item_at(window->canvas, origin_x, origin_y))
+		       && ZMAP_IS_WINDOW_TEXT_ITEM(item))
+		{
+		  /* Don't handle if its text because the text item callbacks handle lasso'ing of
+		   * text. */
 
+		  zMapDebugPrint(mouse_debug_G, "button_press %d is for text item - don't process",
+				 but_event->button) ;
 
-	      /* Record where are we in the window at the start of mouse/button movement. */
-	      window_x = but_event->x ;
-	      window_y = but_event->y ;
-	      
-	      if(mark_updater.in_mark_move_region)
-		{
-		  mark_updater.activated = TRUE;
-		  /* work out the world of where we are */
-		  foo_canvas_window_to_world(window->canvas,
-					     but_event->x, but_event->y,
-					     &wx, &wy);
-		  setupRuler(window, &(window->mark_guide_line), NULL, wy);
+		  event_handled = FALSE ;
 		}
 	      else
 		{
-		  /* Show a rubber band for zooming/marking. */
-		  dragging = TRUE;
+		  /* Pucka button press that we need to handle. */
+
+		  /* Take a copy of the initial event in case we need to resend it to do feature select. */
+		  but_press_copy = (GdkEventButton *)gdk_event_copy((GdkEvent *)event) ;
+
+		  /* Record where are we in the window at the start of mouse/button movement. */
+		  window_x = but_event->x ;
+		  window_y = but_event->y ;
+	      
+		  if(mark_updater.in_mark_move_region)
+		    {
+		      mark_updater.activated = TRUE;
+		      /* work out the world of where we are */
+		      foo_canvas_window_to_world(window->canvas,
+						 but_event->x, but_event->y,
+						 &wx, &wy);
+		      setupRuler(window, &(window->mark_guide_line), NULL, wy);
+		    }
+		  else
+		    {
+		      /* Show a rubber band for zooming/marking. */
+		      dragging = TRUE;
 		  
-		  if (!window->rubberband)
-		    window->rubberband = zMapDrawRubberbandCreate(window->canvas);
+		      if (!window->rubberband)
+			window->rubberband = zMapDrawRubberbandCreate(window->canvas);
+		    }
+
+		  event_handled = TRUE ;
 		}
-	      event_handled = TRUE ;
 
 	      break ;
 	    }
 	  case 2:
 	    {
 	      /* Show a ruler and our exact position. */
-	      guide = TRUE;
+	      guide = TRUE ;
+
 	      /* always clear this if set. */
 	      if(mark_updater.in_mark_move_region)
 		{
@@ -2856,7 +2863,7 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 	    {
 	      /* Nothing to do, menu callbacks are set on canvas items, not here. */
 		
-	      if(mark_updater.in_mark_move_region)
+	      if (mark_updater.in_mark_move_region)
 		{
 		  mark_updater.in_mark_move_region = FALSE;
 		  mark_updater.closest_to = NULL;
@@ -2878,21 +2885,38 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 	  }
 
 
-	zMapDebugPrint(mouse_debug_G, "Leave: button_press %d\n", but_event->button) ;
+	zMapDebugPrint(mouse_debug_G, "Leave: button_press %d - return %s",
+		       but_event->button,
+		       event_handled ? "TRUE" : "FALSE") ;
 
 	break ;
       }
+    case GDK_2BUTTON_PRESS:
+      {
+	/* We don't currently do anything with double clicks but the debug info. is useful. */
+	GdkEventButton *but_event = (GdkEventButton *)event ;
+	FooCanvasItem *item ;
+
+	event_handled = FALSE ;
+
+	zMapDebugPrint(mouse_debug_G, "Start: button_2press %d", but_event->button) ;
 
+	zMapDebugPrint(mouse_debug_G, "Leave: button_2press %d - return %s",
+		       but_event->button,
+		       event_handled ? "TRUE" : "FALSE") ;
+	break ;
+      }
     case GDK_MOTION_NOTIFY:
       {
+
+	/* interestingly we don't check the button number here.... */
+
 	if (dragging || guide)
 	  {
 	    GdkEventMotion *mot_event = (GdkEventMotion *)event ;
 
 
-	    zMapDebugPrint(mouse_debug_G, "%s", "Start: motion\n") ;
-
-	    event_handled = FALSE ;
+	    zMapDebugPrint(mouse_debug_G, "%s", "Start: motion") ;
 
 	    /* work out the world of where we are */
 	    foo_canvas_window_to_world(window->canvas,
@@ -2952,11 +2976,14 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 	      
 		event_handled = TRUE ;			    /* We _ARE_ handling */
 	      }
+	    else
+	      {
+		event_handled = FALSE ;
+	      }
 
-	    zMapDebugPrint(mouse_debug_G, "%s", "End: motion\n") ;
-
+	    zMapDebugPrint(mouse_debug_G, "%s", "End: motion") ;
 	  }
-	else if((!mark_updater.in_mark_move_region) && zmapWindowMarkIsSet(window->mark))
+	else if ((!mark_updater.in_mark_move_region) && zmapWindowMarkIsSet(window->mark))
 	  {
 	    GdkEventMotion *mot_event = (GdkEventMotion *)event;
 	    double world_dy;
@@ -2974,6 +3001,7 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 					&(mark_updater.mark_y2));
 	    
 	    world_dy = canvas_dy / window->canvas->pixels_per_unit_y;
+
 	    if((wy > mark_updater.mark_y1 - world_dy) && (wy < mark_updater.mark_y1 + world_dy))
 	      {
 		mark_updater.in_mark_move_region = TRUE;
@@ -2992,13 +3020,15 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 		event_handled = TRUE;
 	      }
 	    else
-	      event_handled = FALSE;
+	      {
+		event_handled = FALSE;
+	      }
 	  }
-	else if(mark_updater.in_mark_move_region &&
-		mark_updater.activated)
+	else if(mark_updater.in_mark_move_region && mark_updater.activated)
 	  {
 	    /* Now we can move... But must return TRUE. */
 	    GdkEventMotion *mot_event = (GdkEventMotion *)event;
+
 	    foo_canvas_window_to_world(window->canvas,
 				       mot_event->x, mot_event->y,
 				       &wx, mark_updater.closest_to);
@@ -3006,13 +3036,14 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 	    moveRuler(window->mark_guide_line, NULL, NULL, wx, wy);
 	    event_handled = TRUE;
 	  }
-	else if(mark_updater.in_mark_move_region &&
-		(!mark_updater.activated) &&
-		zmapWindowMarkIsSet(window->mark))
+	else if (mark_updater.in_mark_move_region &&
+		 (!mark_updater.activated) &&
+		 zmapWindowMarkIsSet(window->mark))
 	  {
 	    GdkEventMotion *mot_event = (GdkEventMotion *)event;
 	    double world_dy;
 	    int canvas_dy = 5;
+
 	    /* work out the world of where we are */
 	    foo_canvas_window_to_world(window->canvas,
 				       mot_event->x, mot_event->y,
@@ -3039,9 +3070,10 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 		event_handled = TRUE;
 	      }
 	    else
-	      event_handled = FALSE;
+	      {
+		event_handled = FALSE;
+	      }
 	  }
-
 	
         break;
       }
@@ -3050,8 +3082,9 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
       {
 	GdkEventButton *but_event = (GdkEventButton *)event ;
 
-	zMapDebugPrint(mouse_debug_G, "%s",  "start release\n") ;
+	/* interestingly we don't check the button number here.... */
 
+	zMapDebugPrint(mouse_debug_G, "Start: button_release %d", but_event->button) ;
 
         if (dragging)
           {
@@ -3070,13 +3103,15 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 		    zoomToRubberBandArea(window) ;
 
 		    /* If there was a previous copy of a button press event we _know_ we
-		     * can throw it away at this point because if will have been processed by
+		     * can throw it away at this point because it will have been processed by
 		     * a previous call to this routine. */
-		    if (but_copy)
+		    if (but_press_copy)
 		      {
-			gdk_event_free((GdkEvent *)but_copy) ;
-			but_copy = NULL ;
+			gdk_event_free((GdkEvent *)but_press_copy) ;
+			but_press_copy = NULL ;
 		      }
+
+		    event_handled = TRUE;		    /* We _ARE_ handling */
 		  }
 		else
 		  {
@@ -3088,15 +3123,18 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 		    gtk_object_destroy(GTK_OBJECT(window->rubberband)) ;
 		    window->rubberband = NULL ;
 
-		    but_copy->send_event = TRUE ;	    /* Vital for use to detect that we
+		    but_press_copy->send_event = TRUE ;	    /* Vital for use to detect that we
 							       sent this event. */
-		    but_copy->time = but_event->time ;
-		    gdk_event_put((GdkEvent *)but_copy) ; 
+		    but_press_copy->time = but_event->time ;
+		    gdk_event_put((GdkEvent *)but_press_copy) ; 
+
+		    zMapDebugPrint(mouse_debug_G, "Resending original button_press %d", but_event->button) ;
+
+		    event_handled = FALSE ;
 		  }
 	      }
 
 	    dragging = FALSE ;
-            event_handled = TRUE;			    /* We _ARE_ handling */
           }
         else if (guide)
           {
@@ -3160,10 +3198,13 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
 	    gdk_cursor_unref(mark_updater.arrow_cursor);
 	    mark_updater.arrow_cursor = NULL;	     
 	    mark_updater.closest_to = NULL;
+
 	    event_handled = TRUE;
 	  }
-	
-	zMapDebugPrint(mouse_debug_G, "%s",  "end release\n") ;
+
+	zMapDebugPrint(mouse_debug_G, "Leave: button_release %d - return %s",
+		       but_event->button,
+		       event_handled ? "TRUE" : "FALSE") ;	
 
         break;
       }
@@ -3187,22 +3228,24 @@ static gboolean canvasWindowEventCB(GtkWidget *widget, GdkEvent *event, gpointer
     }
 
 
-  return event_handled ;
-}
+  if (mouse_debug_G)
+    fflush(stdout) ;
 
 
+  return event_handled ;
+}
 
 
 
 gboolean pressCB(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 {
-  gboolean event_handled = TRUE ;
+  gboolean event_handled = FALSE ;
   ZMapWindow window = (ZMapWindow)user_data ;
   static double origin_x, origin_y;			    /* The world coords of the source of
 							       the button 1 event */
   FooCanvasItem *item ;
 
-  zMapDebugPrint(mouse_debug_G, "%s",  "in press\n") ;
+  zMapDebugPrint(mouse_debug_G, "%s",  "in press") ;
 
   foo_canvas_window_to_world(window->canvas, 
 			     event->x, event->y, 
@@ -3210,11 +3253,13 @@ gboolean pressCB(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
 
 
+#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
   /* Don't handle if its text because the text item callbacks handle lasso'ing of
    * text. */
   if ((item = foo_canvas_get_item_at(window->canvas, origin_x, origin_y))
       && ZMAP_IS_WINDOW_TEXT_ITEM(item))
     return FALSE ;
+#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
 
 
   return event_handled ;
@@ -3222,12 +3267,16 @@ gboolean pressCB(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 
 gboolean motionCB(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
 {
-  gboolean event_handled = TRUE ;
+  gboolean event_handled = FALSE ;
+
+
+#ifdef ED_G_NEVER_INCLUDE_THIS_CODE
+  zMapDebugPrint(mouse_debug_G, "%s",  "in motion") ;
+#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */
 
-  zMapDebugPrint(mouse_debug_G, "%s",  "in motion\n") ;
 
   if (event->state & GDK_BUTTON1_MASK)
-    zMapDebugPrint(mouse_debug_G, "%s",  "in motion with button press\n") ;
+    zMapDebugPrint(mouse_debug_G, "%s",  "in motion with button press") ;
 
 
   return event_handled ;
@@ -3235,9 +3284,9 @@ gboolean motionCB(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
 
 gboolean releaseCB(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 {
-  gboolean event_handled = TRUE ;
+  gboolean event_handled = FALSE ;
 
-  zMapDebugPrint(mouse_debug_G, "%s",  "in release\n") ;
+  zMapDebugPrint(mouse_debug_G, "%s",  "in release") ;
 
 
   return event_handled ;
-- 
GitLab