Ejemplo n.º 1
0
static void
gimp_paint_tool_cursor_update (GimpTool         *tool,
                               const GimpCoords *coords,
                               GdkModifierType   state,
                               GimpDisplay      *display)
{
  GimpPaintTool      *paint_tool = GIMP_PAINT_TOOL (tool);
  GimpCursorModifier  modifier;
  GimpCursorModifier  toggle_modifier;
  GimpCursorModifier  old_modifier;
  GimpCursorModifier  old_toggle_modifier;

  modifier        = tool->control->cursor_modifier;
  toggle_modifier = tool->control->toggle_cursor_modifier;

  old_modifier        = modifier;
  old_toggle_modifier = toggle_modifier;

  if (! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool)))
    {
      GimpImage    *image    = gimp_display_get_image (display);
      GimpDrawable *drawable = gimp_image_get_active_drawable (image);

      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
          gimp_item_is_content_locked (GIMP_ITEM (drawable))    ||
          ! gimp_item_is_visible (GIMP_ITEM (drawable)))
        {
          modifier        = GIMP_CURSOR_MODIFIER_BAD;
          toggle_modifier = GIMP_CURSOR_MODIFIER_BAD;
        }

      if (! paint_tool->show_cursor &&
          modifier != GIMP_CURSOR_MODIFIER_BAD)
        {
          gimp_tool_set_cursor (tool, display,
                                GIMP_CURSOR_NONE,
                                GIMP_TOOL_CURSOR_NONE,
                                GIMP_CURSOR_MODIFIER_NONE);
          return;
        }

      gimp_tool_control_set_cursor_modifier        (tool->control,
                                                    modifier);
      gimp_tool_control_set_toggle_cursor_modifier (tool->control,
                                                    toggle_modifier);
    }

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state,
                                                 display);

  /*  reset old stuff here so we are not interferring with the modifiers
   *  set by our subclasses
   */
  gimp_tool_control_set_cursor_modifier        (tool->control,
                                                old_modifier);
  gimp_tool_control_set_toggle_cursor_modifier (tool->control,
                                                old_toggle_modifier);
}
Ejemplo n.º 2
0
static void
gimp_source_tool_cursor_update (GimpTool        *tool,
                                GimpCoords      *coords,
                                GdkModifierType  state,
                                GimpDisplay     *display)
{
  GimpSourceOptions  *options  = GIMP_SOURCE_TOOL_GET_OPTIONS (tool);
  GimpCursorType      cursor   = GIMP_CURSOR_MOUSE;
  GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_NONE;

  if (options->use_source)
    {
      if ((state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == GDK_CONTROL_MASK)
        {
          cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
        }
      else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawable)
        {
          modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor          (tool->control, cursor);
  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 3
0
static void
gimp_blend_tool_cursor_update (GimpTool         *tool,
                               const GimpCoords *coords,
                               GdkModifierType   state,
                               GimpDisplay      *display)
{
  GimpBlendTool      *blend_tool = GIMP_BLEND_TOOL (tool);
  GimpImage          *image      = gimp_display_get_image (display);
  GimpDrawable       *drawable   = gimp_image_get_active_drawable (image);
  GimpCursorModifier  modifier   = GIMP_CURSOR_MODIFIER_NONE;

  blend_tool->mouse_x = coords->x;
  blend_tool->mouse_y = coords->y;

  if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
      gimp_item_is_content_locked (GIMP_ITEM (drawable))    ||
      ! gimp_item_is_visible (GIMP_ITEM (drawable)))
    {
      modifier = GIMP_CURSOR_MODIFIER_BAD;
    }
  else if (gimp_blend_tool_is_shapeburst (blend_tool))
    {
      modifier = GIMP_CURSOR_MODIFIER_PLUS;
    }
  else if (gimp_blend_tool_get_point_under_cursor (blend_tool))
    {
      modifier = GIMP_CURSOR_MODIFIER_MOVE;
    }

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 4
0
static void
gimp_source_tool_cursor_update (GimpTool         *tool,
                                const GimpCoords *coords,
                                GdkModifierType   state,
                                GimpDisplay      *display)
{
  GimpPaintTool      *paint_tool = GIMP_PAINT_TOOL (tool);
  GimpSourceOptions  *options    = GIMP_SOURCE_TOOL_GET_OPTIONS (tool);
  GimpCursorType      cursor     = GIMP_CURSOR_MOUSE;
  GimpCursorModifier  modifier   = GIMP_CURSOR_MODIFIER_NONE;

  if (gimp_source_core_use_source (GIMP_SOURCE_CORE (paint_tool->core),
                                   options))
    {
      GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();

      if ((state & (toggle_mask | GDK_SHIFT_MASK)) == toggle_mask)
        {
          cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
        }
      else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawable)
        {
          modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor          (tool->control, cursor);
  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 5
0
/* Mouse cursor policy:
 * - Always use the move cursor
 * - While dragging the paste, use a move modified
 * - Else, While hovering above it, display no modifier
 * - Else, display a "bad" modifier
 */
static void
gimp_seamless_clone_tool_cursor_update (GimpTool         *tool,
                                        const GimpCoords *coords,
                                        GdkModifierType   state,
                                        GimpDisplay      *display)
{
  GimpSeamlessCloneTool *sc       = GIMP_SEAMLESS_CLONE_TOOL (tool);
  GimpCursorModifier     modifier = GIMP_CURSOR_MODIFIER_BAD;

  /* Only update if the tool is actually active on some display */
  if (tool->display)
    {
      if (sc->tool_state == SC_STATE_RENDER_MOTION)
        {
          modifier = GIMP_CURSOR_MODIFIER_MOVE;
        }
      else if (sc->tool_state == SC_STATE_RENDER_WAIT &&
               gimp_seamless_clone_tool_is_in_paste_c (sc, coords))
        {
          modifier = GIMP_CURSOR_MODIFIER_NONE;
        }

      gimp_tool_control_set_cursor_modifier (tool->control, modifier);
    }

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 6
0
static void
gimp_cage_tool_cursor_update (GimpTool         *tool,
                              const GimpCoords *coords,
                              GdkModifierType   state,
                              GimpDisplay      *display)
{
  GimpCageTool       *ct       = GIMP_CAGE_TOOL (tool);
  GimpCageOptions    *options  = GIMP_CAGE_TOOL_GET_OPTIONS (ct);
  GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_PLUS;

  if (tool->display)
    {
      if (ct->hovering_handle != -1)
        {
          modifier = GIMP_CURSOR_MODIFIER_MOVE;
        }
      else if (ct->hovering_edge != -1 && options->cage_mode == GIMP_CAGE_MODE_CAGE_CHANGE)
        {
          modifier = GIMP_CURSOR_MODIFIER_PLUS;
        }
      else
        {
          if (gimp_cage_tool_is_complete (ct))
            modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 7
0
static void
gimp_warp_tool_cursor_update (GimpTool         *tool,
                              const GimpCoords *coords,
                              GdkModifierType   state,
                              GimpDisplay      *display)
{
  GimpWarpOptions    *options  = GIMP_WARP_TOOL_GET_OPTIONS (tool);
  GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_PLUS;

  if (tool->display)
    {
      /* FIXME have better cursors  */

      switch (options->behavior)
        {
        case GIMP_WARP_BEHAVIOR_MOVE:
        case GEGL_WARP_BEHAVIOR_GROW:
        case GEGL_WARP_BEHAVIOR_SHRINK:
        case GEGL_WARP_BEHAVIOR_SWIRL_CW:
        case GEGL_WARP_BEHAVIOR_SWIRL_CCW:
        case GEGL_WARP_BEHAVIOR_ERASE:
        case GEGL_WARP_BEHAVIOR_SMOOTH:
          modifier = GIMP_CURSOR_MODIFIER_MOVE;
          break;
        }
    }

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 8
0
static void
gimp_align_tool_cursor_update (GimpTool        *tool,
                               GimpCoords      *coords,
                               GdkModifierType  state,
                               GimpDisplay     *display)
{
  GimpAlignTool      *align_tool  = GIMP_ALIGN_TOOL (tool);
  GimpToolCursorType  tool_cursor = GIMP_TOOL_CURSOR_NONE;
  GimpCursorModifier  modifier    = GIMP_CURSOR_MODIFIER_NONE;

  if (state & GDK_SHIFT_MASK)
    {
      /* always add '+' when Shift is pressed, even if nothing is selected */
      modifier = GIMP_CURSOR_MODIFIER_PLUS;
    }

  switch (align_tool->function)
    {
    case ALIGN_TOOL_IDLE:
      tool_cursor = GIMP_TOOL_CURSOR_RECT_SELECT;
      break;

    case ALIGN_TOOL_PICK_LAYER:
    case ALIGN_TOOL_ADD_LAYER:
      tool_cursor = GIMP_TOOL_CURSOR_HAND;
      break;

    case ALIGN_TOOL_PICK_GUIDE:
    case ALIGN_TOOL_ADD_GUIDE:
      tool_cursor = GIMP_TOOL_CURSOR_MOVE;
      break;

    case ALIGN_TOOL_PICK_PATH:
    case ALIGN_TOOL_ADD_PATH:
      tool_cursor = GIMP_TOOL_CURSOR_PATHS;
      break;

    case ALIGN_TOOL_DRAG_BOX:
      /* FIXME: it would be nice to add something here, but we cannot easily
         detect when the tool is in this mode (the draw tool is always active)
         so this state is not used for the moment.
      */
      break;
    }

  gimp_tool_control_set_cursor          (tool->control, GIMP_CURSOR_MOUSE);
  gimp_tool_control_set_tool_cursor     (tool->control, tool_cursor);
  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 9
0
static void
gimp_region_select_tool_cursor_update (GimpTool        *tool,
                                       GimpCoords      *coords,
                                       GdkModifierType  state,
                                       GimpDisplay     *display)
{
  GimpRegionSelectOptions *options  = GIMP_REGION_SELECT_TOOL_GET_OPTIONS (tool);
  GimpCursorModifier       modifier = GIMP_CURSOR_MODIFIER_NONE;

  if (! gimp_image_coords_in_active_pickable (display->image, coords,
                                              options->sample_merged, FALSE))
    modifier = GIMP_CURSOR_MODIFIER_BAD;

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 10
0
static void
gimp_align_tool_cursor_update (GimpTool         *tool,
                               const GimpCoords *coords,
                               GdkModifierType   state,
                               GimpDisplay      *display)
{
    GimpAlignTool      *align_tool  = GIMP_ALIGN_TOOL (tool);
    GimpToolCursorType  tool_cursor = GIMP_TOOL_CURSOR_NONE;
    GimpCursorModifier  modifier    = GIMP_CURSOR_MODIFIER_NONE;

    /* always add '+' when Shift is pressed, even if nothing is selected */
    if (state & gimp_get_extend_selection_mask ())
        modifier = GIMP_CURSOR_MODIFIER_PLUS;

    switch (align_tool->function)
    {
    case ALIGN_TOOL_IDLE:
        tool_cursor = GIMP_TOOL_CURSOR_RECT_SELECT;
        break;

    case ALIGN_TOOL_PICK_LAYER:
    case ALIGN_TOOL_ADD_LAYER:
        tool_cursor = GIMP_TOOL_CURSOR_HAND;
        break;

    case ALIGN_TOOL_PICK_GUIDE:
    case ALIGN_TOOL_ADD_GUIDE:
        tool_cursor = GIMP_TOOL_CURSOR_MOVE;
        break;

    case ALIGN_TOOL_PICK_PATH:
    case ALIGN_TOOL_ADD_PATH:
        tool_cursor = GIMP_TOOL_CURSOR_PATHS;
        break;

    case ALIGN_TOOL_DRAG_BOX:
        break;
    }

    gimp_tool_control_set_cursor          (tool->control, GIMP_CURSOR_MOUSE);
    gimp_tool_control_set_tool_cursor     (tool->control, tool_cursor);
    gimp_tool_control_set_cursor_modifier (tool->control, modifier);

    GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 11
0
static void
gimp_warp_tool_cursor_update (GimpTool         *tool,
                              const GimpCoords *coords,
                              GdkModifierType   state,
                              GimpDisplay      *display)
{
  GimpWarpOptions    *options  = GIMP_WARP_TOOL_GET_OPTIONS (tool);
  GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_PLUS;

  if (display == tool->display)
    {
      /* FIXME have better cursors  */

      switch (options->behavior)
        {
        case GIMP_WARP_BEHAVIOR_MOVE:
        case GEGL_WARP_BEHAVIOR_GROW:
        case GEGL_WARP_BEHAVIOR_SHRINK:
        case GEGL_WARP_BEHAVIOR_SWIRL_CW:
        case GEGL_WARP_BEHAVIOR_SWIRL_CCW:
        case GEGL_WARP_BEHAVIOR_ERASE:
        case GEGL_WARP_BEHAVIOR_SMOOTH:
          modifier = GIMP_CURSOR_MODIFIER_MOVE;
          break;
        }
    }
  else
    {
      GimpImage    *image    = gimp_display_get_image (display);
      GimpDrawable *drawable = gimp_image_get_active_drawable (image);

      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
          gimp_item_is_content_locked (GIMP_ITEM (drawable))    ||
          ! gimp_item_is_visible (GIMP_ITEM (drawable)))
        {
          modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 12
0
static void
gimp_blend_tool_cursor_update (GimpTool         *tool,
                               const GimpCoords *coords,
                               GdkModifierType   state,
                               GimpDisplay      *display)
{
    GimpImage          *image    = gimp_display_get_image (display);
    GimpDrawable       *drawable = gimp_image_get_active_drawable (image);
    GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_NONE;

    if (gimp_drawable_is_indexed (drawable)                   ||
            gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) ||
            gimp_item_is_content_locked (GIMP_ITEM (drawable)))
    {
        modifier = GIMP_CURSOR_MODIFIER_BAD;
    }

    gimp_tool_control_set_cursor_modifier (tool->control, modifier);

    GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 13
0
static void
gimp_bucket_fill_tool_cursor_update (GimpTool         *tool,
                                     const GimpCoords *coords,
                                     GdkModifierType   state,
                                     GimpDisplay      *display)
{
  GimpBucketFillOptions *options  = GIMP_BUCKET_FILL_TOOL_GET_OPTIONS (tool);
  GimpCursorModifier     modifier = GIMP_CURSOR_MODIFIER_BAD;
  GimpImage             *image    = gimp_display_get_image (display);

  if (gimp_image_coords_in_active_pickable (image, coords,
                                            options->sample_merged, TRUE))
    {
      GimpDrawable *drawable = gimp_image_get_active_drawable (image);

      if (! gimp_viewable_get_children (GIMP_VIEWABLE (drawable)) &&
          ! gimp_item_is_content_locked (GIMP_ITEM (drawable))    &&
          gimp_item_is_visible (GIMP_ITEM (drawable)))
        {
          switch (options->fill_mode)
            {
            case GIMP_BUCKET_FILL_FG:
              modifier = GIMP_CURSOR_MODIFIER_FOREGROUND;
              break;

            case GIMP_BUCKET_FILL_BG:
              modifier = GIMP_CURSOR_MODIFIER_BACKGROUND;
              break;

            case GIMP_BUCKET_FILL_PATTERN:
              modifier = GIMP_CURSOR_MODIFIER_PATTERN;
              break;
            }
        }
    }

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
static void
gimp_n_point_deformation_tool_cursor_update (GimpTool         *tool,
                                             const GimpCoords *coords,
                                             GdkModifierType   state,
                                             GimpDisplay      *display)
{
  GimpNPointDeformationTool *npd_tool = GIMP_N_POINT_DEFORMATION_TOOL (tool);
  GimpCursorModifier         modifier = GIMP_CURSOR_MODIFIER_PLUS;

  if (! npd_tool->active)
    {
      modifier = GIMP_CURSOR_MODIFIER_NONE;
    }
  else if (npd_tool->hovering_cp)
    {
      modifier = GIMP_CURSOR_MODIFIER_MOVE;
    }

  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 15
0
static void
gimp_flip_tool_cursor_update (GimpTool        *tool,
                              GimpCoords      *coords,
                              GdkModifierType  state,
                              GimpDisplay     *display)
{
  GimpFlipOptions    *options  = GIMP_FLIP_TOOL_GET_OPTIONS (tool);
  GimpCursorModifier  modifier = GIMP_CURSOR_MODIFIER_BAD;

  if (gimp_image_coords_in_active_pickable (display->image, coords,
                                            FALSE, TRUE))
    {
      modifier = GIMP_CURSOR_MODIFIER_NONE;
    }

  gimp_tool_control_set_cursor_modifier        (tool->control, modifier);
  gimp_tool_control_set_toggle_cursor_modifier (tool->control, modifier);

  gimp_tool_control_set_toggled (tool->control,
                                 options->flip_type ==
                                 GIMP_ORIENTATION_VERTICAL);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
Ejemplo n.º 16
0
static void
gimp_move_tool_cursor_update (GimpTool         *tool,
                              const GimpCoords *coords,
                              GdkModifierType   state,
                              GimpDisplay      *display)
{
  GimpMoveOptions    *options     = GIMP_MOVE_TOOL_GET_OPTIONS (tool);
  GimpDisplayShell   *shell       = gimp_display_get_shell (display);
  GimpImage          *image       = gimp_display_get_image (display);
  GimpCursorType      cursor      = GIMP_CURSOR_MOUSE;
  GimpToolCursorType  tool_cursor = GIMP_TOOL_CURSOR_MOVE;
  GimpCursorModifier  modifier    = GIMP_CURSOR_MODIFIER_NONE;

  if (options->move_type == GIMP_TRANSFORM_TYPE_PATH)
    {
      tool_cursor = GIMP_TOOL_CURSOR_PATHS;
      modifier    = GIMP_CURSOR_MODIFIER_MOVE;

      if (options->move_current)
        {
          if (! gimp_image_get_active_vectors (image))
            modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
      else
        {
          if (gimp_draw_tool_on_vectors (GIMP_DRAW_TOOL (tool), display,
                                         coords, 7, 7,
                                         NULL, NULL, NULL, NULL, NULL, NULL))
            {
              tool_cursor = GIMP_TOOL_CURSOR_HAND;
            }
          else
            {
              modifier = GIMP_CURSOR_MODIFIER_BAD;
            }
        }
    }
  else if (options->move_type == GIMP_TRANSFORM_TYPE_SELECTION)
    {
      tool_cursor = GIMP_TOOL_CURSOR_RECT_SELECT;
      modifier    = GIMP_CURSOR_MODIFIER_MOVE;

      if (gimp_channel_is_empty (gimp_image_get_mask (image)))
        modifier = GIMP_CURSOR_MODIFIER_BAD;
    }
  else if (options->move_current)
    {
      if (! gimp_image_get_active_drawable (image))
        modifier = GIMP_CURSOR_MODIFIER_BAD;
    }
  else
    {
      GimpGuide  *guide;
      GimpLayer  *layer;
      const gint  snap_distance = display->config->snap_distance;

      if (gimp_display_shell_get_show_guides (shell) &&
          (guide = gimp_image_find_guide (image, coords->x, coords->y,
                                          FUNSCALEX (shell, snap_distance),
                                          FUNSCALEY (shell, snap_distance))))
        {
          tool_cursor = GIMP_TOOL_CURSOR_HAND;
          modifier    = GIMP_CURSOR_MODIFIER_MOVE;
        }
      else if ((layer = gimp_image_pick_layer (image,
                                               coords->x, coords->y)))
        {
          /*  if there is a floating selection, and this aint it...  */
          if (gimp_image_get_floating_selection (image) &&
              ! gimp_layer_is_floating_sel (layer))
            {
              tool_cursor = GIMP_TOOL_CURSOR_MOVE;
              modifier    = GIMP_CURSOR_MODIFIER_ANCHOR;
            }
          else if (layer != gimp_image_get_active_layer (image))
            {
              tool_cursor = GIMP_TOOL_CURSOR_HAND;
              modifier    = GIMP_CURSOR_MODIFIER_MOVE;
            }
        }
      else
        {
          modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor          (tool->control, cursor);
  gimp_tool_control_set_tool_cursor     (tool->control, tool_cursor);
  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
static void
gimp_perspective_clone_tool_cursor_update (GimpTool         *tool,
                                           const GimpCoords *coords,
                                           GdkModifierType   state,
                                           GimpDisplay      *display)
{
  GimpPerspectiveCloneTool    *clone_tool = GIMP_PERSPECTIVE_CLONE_TOOL (tool);
  GimpPerspectiveCloneOptions *options;
  GimpImage                   *image;
  GimpToolClass               *tool_class;
  GimpCursorType               cursor     = GIMP_CURSOR_MOUSE;
  GimpCursorModifier           modifier   = GIMP_CURSOR_MODIFIER_NONE;

  options = GIMP_PERSPECTIVE_CLONE_TOOL_GET_OPTIONS (tool);

  image = gimp_display_get_image (display);

  if (gimp_image_coords_in_active_pickable (image, coords,
                                            FALSE, TRUE))
    {
      cursor = GIMP_CURSOR_MOUSE;
    }

  if (options->clone_mode == GIMP_PERSPECTIVE_CLONE_MODE_ADJUST)
    {
      /* perspective cursors */
      cursor = gimp_tool_control_get_cursor (tool->control);

      switch (clone_tool->function)
        {
        case TRANSFORM_HANDLE_NW:
          cursor = GIMP_CURSOR_CORNER_TOP_LEFT;
          break;

        case TRANSFORM_HANDLE_NE:
          cursor = GIMP_CURSOR_CORNER_TOP_RIGHT;
          break;

        case TRANSFORM_HANDLE_SW:
          cursor = GIMP_CURSOR_CORNER_BOTTOM_LEFT;
          break;

        case TRANSFORM_HANDLE_SE:
          cursor = GIMP_CURSOR_CORNER_BOTTOM_RIGHT;
          break;

        default:
          cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
          break;
        }
    }
  else
    {
      GdkModifierType extend_mask = gimp_get_extend_selection_mask ();
      GdkModifierType toggle_mask = gimp_get_toggle_behavior_mask ();

      if ((state & (toggle_mask | extend_mask)) == toggle_mask)
        {
          cursor = GIMP_CURSOR_CROSSHAIR_SMALL;
        }
      else if (! GIMP_SOURCE_CORE (GIMP_PAINT_TOOL (tool)->core)->src_drawable)
        {
          modifier = GIMP_CURSOR_MODIFIER_BAD;
        }
    }

  gimp_tool_control_set_cursor          (tool->control, cursor);
  gimp_tool_control_set_cursor_modifier (tool->control, modifier);

  /*  If we are in adjust mode, skip the GimpBrushClass when chaining up.
   *  This ensures that the cursor will be set regardless of
   *  GimpBrushTool::show_cursor (see bug #354933).
   */
  if (options->clone_mode == GIMP_PERSPECTIVE_CLONE_MODE_ADJUST)
    tool_class = GIMP_TOOL_CLASS (g_type_class_peek_parent (parent_class));
  else
    tool_class = GIMP_TOOL_CLASS (parent_class);

  tool_class->cursor_update (tool, coords, state, display);
}