Пример #1
0
/* Starts the selection state in the icon text item */
static void
iti_start_selecting (GnomeIconTextItem *iti, int idx, guint32 event_time)
{
	GnomeIconTextItemPrivate *priv;
	GtkEditable *e;
	GdkCursor *ibeam;

	priv = iti->_priv;
	e = GTK_EDITABLE (priv->entry);

	gtk_editable_select_region (e, idx, idx);
	gtk_editable_set_position (e, idx);
	ibeam = gdk_cursor_new (GDK_XTERM);
	gnome_canvas_item_grab (GNOME_CANVAS_ITEM (iti),
				GDK_BUTTON_RELEASE_MASK |
				GDK_POINTER_MOTION_MASK,
				ibeam, event_time);
	gdk_cursor_unref (ibeam);

	gtk_editable_select_region (e, idx, idx);
	priv->selecting = TRUE;
	priv->selection_start = idx;

	gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));

	g_signal_emit (iti, iti_signals[SELECTION_STARTED], 0);
}
Пример #2
0
int
e_canvas_item_grab (ECanvas *canvas,
		    GnomeCanvasItem *item,
		    guint event_mask,
		    GdkCursor *cursor,
		    guint32 etime,
		    ECanvasItemGrabCancelled cancelled_cb,
		    gpointer cancelled_data)
{
	if (gtk_grab_get_current ()) {
		return GDK_GRAB_ALREADY_GRABBED;
	} else {
		int ret_val = gnome_canvas_item_grab (item, event_mask, cursor, etime);
		if (ret_val == GDK_GRAB_SUCCESS) {
			canvas->grab_cancelled_cb = cancelled_cb;
			canvas->grab_cancelled_check_id =
				g_timeout_add_full (G_PRIORITY_LOW,
						    100,
						    grab_cancelled_check,
						    canvas,
						    NULL);
			canvas->grab_cancelled_time = etime;
			canvas->grab_cancelled_data = cancelled_data;
		}

		return ret_val;
	}
}
Пример #3
0
static gboolean
bst_canvas_source_event (GnomeCanvasItem *item,
			 GdkEvent        *event)
{
  BstCanvasSource *csource = BST_CANVAS_SOURCE (item);
  gboolean handled = FALSE;
  
  switch (event->type)
    {
    case GDK_BUTTON_PRESS:
      if (!csource->in_move && event->button.button == 2)
	{
	  GdkCursor *fleur = gdk_cursor_new (GDK_FLEUR);
	  if (gnome_canvas_item_grab (item,
                                      GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
                                      fleur,
                                      event->button.time) == 0)
            {
              gdouble x = event->button.x, y = event->button.y;
              gnome_canvas_item_w2i (item, &x, &y);
              csource->move_dx = x;
              csource->move_dy = y;
              csource->in_move = TRUE;
              bse_item_group_undo (csource->source, "Move");
            }
	  gdk_cursor_destroy (fleur);
	  handled = TRUE;
	}
      break;
    case GDK_MOTION_NOTIFY:
      if (csource->in_move)
	{
	  gdouble x = event->motion.x, y = event->motion.y;
	  
	  gnome_canvas_item_w2i (item, &x, &y);
	  gnome_canvas_item_move (item, x - csource->move_dx, y - csource->move_dy);
	  GNOME_CANVAS_NOTIFY (item);
	  handled = TRUE;
	}
      else
	{
	  guint channel;
	  const gchar *label = NULL, *prefix = NULL, *ident = NULL;

	  /* set i/o channel hints */
	  channel = bst_canvas_source_ichannel_at (csource, event->motion.x, event->motion.y);
	  if (channel != ~0)
	    {
	      label = bse_source_ichannel_label (csource->source, channel);
	      ident = bse_source_ichannel_ident (csource->source, channel);
	      prefix = _("Input");
	    }
	  else
	    {
	      channel = bst_canvas_source_ochannel_at (csource, event->motion.x, event->motion.y);
	      if (channel != ~0)
		{
		  label = bse_source_ochannel_label (csource->source, channel);
		  ident = bse_source_ochannel_ident (csource->source, channel);
		  prefix = _("Output");
		}
	    }
	  if (label)
	    gxk_status_printf (GXK_STATUS_IDLE_HINT, _("(Hint)"), "%s[%s]: %s", prefix, ident, label);
	  else
	    gxk_status_set (GXK_STATUS_IDLE_HINT, NULL, NULL);
	}
      break;
    case GDK_BUTTON_RELEASE:
      if (event->button.button == 2 && csource->in_move)
	{
          bse_item_ungroup_undo (csource->source);
	  csource->in_move = FALSE;
	  gnome_canvas_item_ungrab (item, event->button.time);
	  handled = TRUE;
	}
      break;
    default:
      break;
    }
  
  if (!handled && GNOME_CANVAS_ITEM_CLASS (bst_canvas_source_parent_class)->event)
    handled = GNOME_CANVAS_ITEM_CLASS (bst_canvas_source_parent_class)->event (item, event);
  
  return handled;
}
Пример #4
0
static gint
gnc_header_event (GnomeCanvasItem *item, GdkEvent *event)
{
    GncHeader *header = GNC_HEADER(item);
    GnomeCanvas *canvas = item->canvas;
    int x, y;
    int col;

    switch (event->type)
    {
    case GDK_MOTION_NOTIFY:

        gnome_canvas_w2c (canvas, event->motion.x, event->motion.y,
                          &x, &y);

        if (header->in_resize)
        {
            int change = x - header->resize_x;
            int new_width;

            if (!header->needs_ungrab)
            {
                gnome_canvas_item_grab (item,
                                        GDK_POINTER_MOTION_MASK |
                                        GDK_BUTTON_RELEASE_MASK,
                                        header->resize_cursor,
                                        event->button.time);
                header->needs_ungrab = TRUE;
            }

            new_width = header->resize_col_width + change;

            if (new_width >= 0)
            {
                header->resize_x = x;
                header->resize_col_width = new_width;
                gnc_header_request_redraw (header);
            }

            break;
        }

        if (pointer_on_resize_line(header, x, y, &col) &&
                gnucash_style_col_is_resizable (header->style, col))
            gdk_window_set_cursor (GTK_WIDGET(canvas)->window,
                                   header->resize_cursor);
        else
            gdk_window_set_cursor (GTK_WIDGET(canvas)->window,
                                   header->normal_cursor);
        break;

    case GDK_BUTTON_PRESS:
    {
        int col;

        if (event->button.button != 1)
            break;

        gnome_canvas_w2c (canvas, event->button.x, event->button.y,
                          &x, &y);

        if (pointer_on_resize_line (header, x, y, &col))
            col = find_resize_col (header, col);
        else
            col = -1;

        if (col > -1)
        {
            CellDimensions *cd;

            cd = gnucash_style_get_cell_dimensions
                 (header->style, 0, col);

            header->in_resize = TRUE;
            header->resize_col = col;
            header->resize_col_width = cd->pixel_width;
            header->resize_x = x;
        }

        break;
    }
    case GDK_BUTTON_RELEASE:
    {
        if (event->button.button != 1)
            break;

        gnome_canvas_w2c (canvas, event->button.x, event->button.y,
                          &x, &y);

        if (header->in_resize)
        {
            if (header->needs_ungrab)
            {
                gnome_canvas_item_ungrab (item,
                                          event->button.time);
                header->needs_ungrab = FALSE;

                gnc_header_resize_column
                (header,
                 header->resize_col,
                 header->resize_col_width);
            }
            header->in_resize = FALSE;
            header->resize_col = -1;
        }

        break;
    }

    case GDK_2BUTTON_PRESS:
    {
        gboolean on_line;
        int ptr_col;
        int resize_col;

        if (event->button.button != 1)
            break;

        gnome_canvas_w2c (canvas, event->button.x, event->button.y,
                          &x, &y);

        on_line = pointer_on_resize_line (header, x, y, &ptr_col);

        /* If we're on a resize line and the column to the right is zero
           width, resize that one. */
        if (on_line)
            resize_col = find_resize_col (header, ptr_col);
        else
            resize_col = ptr_col;

        if (resize_col > -1)
        {
            header->in_resize = FALSE;
            header->resize_col = -1;
            if (header->needs_ungrab)
            {
                gnome_canvas_item_ungrab (item,
                                          event->button.time);
                header->needs_ungrab = FALSE;
            }

            gnc_header_auto_resize_column (header, resize_col);
        }

    }
    break;

    default:
        break;
    }

    return TRUE;
}
Пример #5
0
static gint handle_callback (GnomeCanvasItem *item, GdkEvent *event, gpointer _data) {
	struct channel_data *data=(struct channel_data *)_data;
	GdkCursor	*fleur;

	switch(event->type) {
		case GDK_ENTER_NOTIFY:
			gnome_canvas_item_set(data->handle1,"fill_color","black",NULL);
			gnome_canvas_item_set(data->handle2,"fill_color","black",NULL);
			gnome_canvas_item_set(data->handle3,"fill_color","black",NULL);
			break;
		
		case GDK_LEAVE_NOTIFY:
			gnome_canvas_item_set(data->handle1,"fill_color",NULL,NULL);
			gnome_canvas_item_set(data->handle2,"fill_color",NULL,NULL);
			gnome_canvas_item_set(data->handle3,"fill_color",NULL,NULL);
			break;
		
		case GDK_BUTTON_PRESS:
			switch(event->button.button) {
				case 1:		// Left Mousebutton
					fleur = gdk_cursor_new (GDK_FLEUR);
					press_x=event->button.x;
					press_y=event->button.y;
			                gnome_canvas_item_grab (item,
        	                                GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
	                                        fleur, event->button.time);
			                gdk_cursor_destroy (fleur);

					break;
				case 2:		// Middle Mousebutton
					break;
				case 3:		// Right Mousebutton
					break;
				default:	// Unkown Mousebutton
					break;
			}
			break;
		
		case GDK_BUTTON_RELEASE:
			gnome_canvas_item_ungrab (item, event->button.time);
			break;
		
		case GDK_MOTION_NOTIFY:
			if (event->motion.state & GDK_BUTTON1_MASK){
				if (item==data->handle1) {
					data->t1=CHARTER_RX(event->motion.x);
					data->v1=CHARTER_RY(event->motion.y);
					reset_from_data(data);
				}
				if (item==data->handle2) {
					data->t2=CHARTER_RX(event->motion.x);
					data->v2=CHARTER_RY(event->motion.y);
					reset_from_data(data);
				}
				if (item==data->handle3) {
					// Calc new dist
				
					data->dist=-CHARTER_RX(sqrt(pow((press_x-data->line3_points->coords[0]),2)+pow((press_y-data->line3_points->coords[1]),2)));
					reset_from_data(data);
				}

				press_x=event->motion.x;
				press_y=event->motion.y;
			}
			break;
		default: break;
		
	}
	return FALSE;
}
Пример #6
0
static gint channel_callback (GnomeCanvasItem *item, GdkEvent *event, gpointer _data) {
	GdkCursor	*fleur;
	struct channel_data *data=(struct channel_data *)_data;
	
	switch(event->type) {
		case GDK_ENTER_NOTIFY:
			gnome_canvas_item_set(data->handle1,"fill_color","#909090",NULL);
			gnome_canvas_item_set(data->handle2,"fill_color","#909090",NULL);
			gnome_canvas_item_set(data->handle3,"fill_color","#909090",NULL);
			break;
		
		case GDK_LEAVE_NOTIFY:
			gnome_canvas_item_set(data->handle1,"fill_color",NULL,NULL);
			gnome_canvas_item_set(data->handle2,"fill_color",NULL,NULL);
			gnome_canvas_item_set(data->handle3,"fill_color",NULL,NULL);
			break;
		
		case GDK_BUTTON_PRESS:
			switch(event->button.button) {
				case 1:		// Left Mousebutton
					fleur = gdk_cursor_new (GDK_FLEUR);
					press_x=event->button.x;
					press_y=event->button.y;
					
			                gnome_canvas_item_grab (item,
        	                                GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
	                                        fleur, event->button.time);
			                gdk_cursor_destroy (fleur);

					break;
				case 2:		// Middle Mousebutton
					break;
				case 3:		// Right Mousebutton
					break;
				default:	// Unkown Mousebutton
					break;
			}
			break;
		
		case GDK_BUTTON_RELEASE:
			gnome_canvas_item_ungrab (item, event->button.time);
			break;
		
		case GDK_MOTION_NOTIFY:
			if (event->motion.state & GDK_BUTTON1_MASK){
				// Do some delta-magic to move the points relatively to pointer motion

				data->t1-=CHARTER_RX(press_x-event->motion.x);
				data->v1-=CHARTER_RY(press_y-event->motion.y);
				data->t2-=CHARTER_RX(press_x-event->motion.x);
				data->v2-=CHARTER_RY(press_y-event->motion.y);
				reset_from_data(data);

				press_x=event->motion.x;
				press_y=event->motion.y;
			}
			break;
		default:break;
		
	}
	return FALSE;
}
Пример #7
0
static gboolean
e_reflow_event (GnomeCanvasItem *item, GdkEvent *event)
{
	EReflow *reflow;
	int return_val = FALSE;

	reflow = E_REFLOW (item);

	switch( event->type )
		{
		case GDK_KEY_PRESS:
			return_val = e_selection_model_key_press(reflow->selection, (GdkEventKey *) event);
			break;
#if 0
			if (event->key.keyval == GDK_Tab ||
			    event->key.keyval == GDK_KP_Tab ||
			    event->key.keyval == GDK_ISO_Left_Tab) {
				int i;
				int count;
				count = reflow->count;
				for (i = 0; i < count; i++) {
					int unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i);
					GnomeCanvasItem *item = reflow->items[unsorted];
					EFocus has_focus;
					if (item) {
						g_object_get(item,
							     "has_focus", &has_focus,
							     NULL);
						if (has_focus) {
							if (event->key.state & GDK_SHIFT_MASK) {
								if (i == 0)
									return FALSE;
								i--;
							} else {
								if (i == count - 1)
									return FALSE;
								i++;
							}

							unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), i);
							if (reflow->items[unsorted] == NULL) {
								reflow->items[unsorted] = e_reflow_model_incarnate (reflow->model, unsorted, GNOME_CANVAS_GROUP (reflow));
							}

							item = reflow->items[unsorted];
							gnome_canvas_item_set(item,
									      "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
									      NULL);
							return TRUE;
						}
					}
				}
			}
#endif
		case GDK_BUTTON_PRESS:
			switch(event->button.button)
				{
				case 1:
					{
						GdkEventButton *button = (GdkEventButton *) event;
						double n_x, max_x;
						n_x = button->x;
						n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
						n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));

						max_x = E_REFLOW_BORDER_WIDTH;
						max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count;
						if ( button->y >= E_REFLOW_BORDER_WIDTH && button->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > button->x ) {
							/* don't allow to drag the first line*/
							if (e_reflow_pick_line(reflow, button->x) == 0)
								return TRUE;
							reflow->which_column_dragged = e_reflow_pick_line(reflow, button->x);
							reflow->start_x = reflow->which_column_dragged * (reflow->column_width + E_REFLOW_FULL_GUTTER) - E_REFLOW_DIVIDER_WIDTH / 2;
							reflow->temp_column_width = reflow->column_width;
							reflow->column_drag = TRUE;

							gnome_canvas_item_grab (item,
										GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
										reflow->arrow_cursor,
										button->time);

							reflow->previous_temp_column_width = -1;
							reflow->need_column_resize = TRUE;
							gnome_canvas_item_request_update(item);
							return TRUE;
						}
					}
					break;
				case 4:
					{
						GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
						gdouble new_value = adjustment->value;
						new_value -= adjustment->step_increment;
						gtk_adjustment_set_value(adjustment, new_value);
					}
					break;
				case 5:
					{
						GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
						gdouble new_value = adjustment->value;
						new_value += adjustment->step_increment;
						if ( new_value > adjustment->upper - adjustment->page_size )
							new_value = adjustment->upper - adjustment->page_size;
						gtk_adjustment_set_value(adjustment, new_value);
					}
					break;
				}
			break;
		case GDK_BUTTON_RELEASE:
			if (reflow->column_drag) {
				gdouble old_width = reflow->column_width;
				GdkEventButton *button = (GdkEventButton *) event;
				GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
				reflow->temp_column_width = reflow->column_width +
					(button->x - reflow->start_x)/(reflow->which_column_dragged - e_reflow_pick_line(reflow, adjustment->value));
				if ( reflow->temp_column_width < 50 )
					reflow->temp_column_width = 50;
				reflow->column_drag = FALSE;
				if ( old_width != reflow->temp_column_width ) {
					gtk_adjustment_set_value(adjustment, adjustment->value + e_reflow_pick_line(reflow, adjustment->value) * (reflow->temp_column_width - reflow->column_width));
					reflow->column_width = reflow->temp_column_width;
					adjustment->step_increment = (reflow->column_width + E_REFLOW_FULL_GUTTER) / 2;
					adjustment->page_increment = adjustment->page_size - adjustment->step_increment;
					gtk_adjustment_changed(adjustment);
					e_reflow_resize_children(item);
					e_canvas_item_request_reflow(item);
					gnome_canvas_request_redraw(item->canvas, 0, 0, reflow->width, reflow->height);
					column_width_changed (reflow);
				}
				reflow->need_column_resize = TRUE;
				gnome_canvas_item_request_update(item);
				gnome_canvas_item_ungrab (item, button->time);
				return TRUE;
			}
			break;
		case GDK_MOTION_NOTIFY:
			if (reflow->column_drag) {
				double old_width = reflow->temp_column_width;
				GdkEventMotion *motion = (GdkEventMotion *) event;
				GtkAdjustment *adjustment = gtk_layout_get_hadjustment(GTK_LAYOUT(item->canvas));
				reflow->temp_column_width = reflow->column_width +
					(motion->x - reflow->start_x)/(reflow->which_column_dragged - e_reflow_pick_line(reflow, adjustment->value));
				if (reflow->temp_column_width < 50)
					reflow->temp_column_width = 50;
				if (old_width != reflow->temp_column_width) {
					reflow->need_column_resize = TRUE;
					gnome_canvas_item_request_update(item);
				}
				return TRUE;
			} else {
				GdkEventMotion *motion = (GdkEventMotion *) event;
				double n_x, max_x;

				n_x = motion->x;
				n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
				n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));

				max_x = E_REFLOW_BORDER_WIDTH;
				max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count;

				if ( motion->y >= E_REFLOW_BORDER_WIDTH && motion->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > motion->x) {
					if ( reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor);
						reflow->default_cursor_shown = FALSE;
					}
				} else
					if ( ! reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->default_cursor);
						reflow->default_cursor_shown = TRUE;
					}

			}
			break;
		case GDK_ENTER_NOTIFY:
			if (!reflow->column_drag) {
				GdkEventCrossing *crossing = (GdkEventCrossing *) event;
				double n_x, max_x;
				n_x = crossing->x;
				n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
				n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));

				max_x = E_REFLOW_BORDER_WIDTH;
				max_x += (reflow->column_width + E_REFLOW_FULL_GUTTER) * reflow->column_count;
				if ( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER && max_x > crossing->x) {
					if ( reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->arrow_cursor);
						reflow->default_cursor_shown = FALSE;
					}
				}
			}
			break;
		case GDK_LEAVE_NOTIFY:
			if (!reflow->column_drag) {
				GdkEventCrossing *crossing = (GdkEventCrossing *) event;
				double n_x;
				n_x = crossing->x;
				n_x += E_REFLOW_BORDER_WIDTH + E_REFLOW_DIVIDER_WIDTH;
				n_x = fmod(n_x,(reflow->column_width + E_REFLOW_FULL_GUTTER));
				if ( !( crossing->y >= E_REFLOW_BORDER_WIDTH && crossing->y <= reflow->height - E_REFLOW_BORDER_WIDTH && n_x < E_REFLOW_FULL_GUTTER ) ) {
					if ( ! reflow->default_cursor_shown ) {
						gdk_window_set_cursor(GTK_WIDGET(item->canvas)->window, reflow->default_cursor);
						reflow->default_cursor_shown = TRUE;
					}
				}
			}
			break;
		default:
			break;
		}
	if (return_val)
		return return_val;
	else if (GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event)
		return (* GNOME_CANVAS_ITEM_CLASS( e_reflow_parent_class )->event) (item, event);
	else
		return FALSE;
}
Пример #8
0
static gboolean
bst_canvas_link_event (GnomeCanvasItem *item,
		       GdkEvent        *event)
{
  BstCanvasLink *clink = BST_CANVAS_LINK (item);
  gboolean handled = FALSE;
  
  switch (event->type)
    {
    case GDK_BUTTON_PRESS:
      if (event->button.button == 2)
	{
	  GdkCursor *fleur;
	  
	  if (clink->ocsource)
	    {
	      clink->start_move_dx = event->button.x;
	      clink->start_move_dy = event->button.y;
	      gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (clink->ocsource),
				     &clink->start_move_dx,
				     &clink->start_move_dy);
	    }
	  if (clink->icsource)
	    {
	      clink->end_move_dx = event->button.x;
	      clink->end_move_dy = event->button.y;
	      gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (clink->icsource),
				     &clink->end_move_dx,
				     &clink->end_move_dy);
	    }
	  clink->in_move = TRUE;
	  
	  fleur = gdk_cursor_new (GDK_FLEUR);
	  gnome_canvas_item_grab (item,
				  GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
				  fleur,
				  event->button.time);
	  gdk_cursor_destroy (fleur);
	  handled = TRUE;
	}
      break;
    case GDK_MOTION_NOTIFY:
      if (clink->in_move && clink->ocsource)
	{
	  gdouble x = event->motion.x, y = event->motion.y;
	  
	  gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (clink->ocsource), &x, &y);
	  gnome_canvas_item_move (GNOME_CANVAS_ITEM (clink->ocsource),
				  x - clink->start_move_dx,
				  y - clink->start_move_dy);
	  GNOME_CANVAS_NOTIFY (clink->ocsource);
	  handled = TRUE;
	}
      if (clink->in_move && clink->icsource)
	{
	  gdouble x = event->motion.x, y = event->motion.y;
	  
	  gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (clink->icsource), &x, &y);
	  gnome_canvas_item_move (GNOME_CANVAS_ITEM (clink->icsource),
				  x - clink->end_move_dx,
				  y - clink->end_move_dy);
	  GNOME_CANVAS_NOTIFY (clink->icsource);
	  handled = TRUE;
	}
      break;
    case GDK_BUTTON_RELEASE:
      if (event->button.button == 2 && clink->in_move)
	{
	  clink->in_move = FALSE;
	  gnome_canvas_item_ungrab (item, event->button.time);
	  handled = TRUE;
	}
      break;
    default:
      break;
    }
  
  if (!handled && GNOME_CANVAS_ITEM_CLASS (bst_canvas_link_parent_class)->event)
    handled |= GNOME_CANVAS_ITEM_CLASS (bst_canvas_link_parent_class)->event (item, event);
  
  return handled;
}