mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-21 12:02:32 +00:00
17335326d5
2001-02-24 Michael Natterer <mitch@gimp.org> * TODO.xml: updated. * app/appenums.h * app/apptypes.h: prefixed the cursor stuff with "Gimp", added the new stock tool cursor enum. Removed the old ToolType enum. * app/cursorutil.[ch] * app/gdisplay.[ch]: removed the old ToolType enum and prefixed the functions with "gimp_". Also stripped all "toggle cursor" stuff from the cursor code, so the new API is easier and not depending on the tool system. All existing tool cursors can be used via the new stock tool cursor enum, so no tool has to fiddle around with bitmap cursors. There will be an cursorutil function for registering stock tool cursor types on the fly. * app/disp_callbacks.c * app/scroll.[ch]: moved the display scrollbar callbacks from scroll.[ch] to disp_callbacks.c. Removed some crap from scroll.h * app/tools/tool.[ch]: removed the BitmapCursor pointers from the tool class struct and add cursor and toggle cursor IDs to the GimpTool struct. Work in progress. * app/dialog_handler.c * app/tools/bezier_select.c * app/tools/blend.c * app/tools/bucket_fill.c * app/tools/by_color_select.c * app/tools/clone.c * app/tools/color_picker.c * app/tools/convolve.c * app/tools/crop.c * app/tools/dodgeburn.c * app/tools/edit_selection.c * app/tools/ellipse_select.c * app/tools/flip_tool.c * app/tools/free_select.c * app/tools/fuzzy_select.c * app/tools/ink.c * app/tools/iscissors.c * app/tools/magnify.c * app/tools/measure.c * app/tools/move.c * app/tools/paint_core.[ch] * app/tools/perspective_tool.c * app/tools/rect_select.c * app/tools/rotate_tool.c * app/tools/scale_tool.c * app/tools/shear_tool.c * app/tools/text_tool.c * app/tools/transform_core.[ch]: changed accordingly. Did this "blind" for most tools because they don't compile. The changes are minimal, so there should be no conflicts.
756 lines
20 KiB
C
756 lines
20 KiB
C
/* The GIMP -- an image manipulation program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "apptypes.h"
|
|
|
|
#include "appenv.h"
|
|
#include "cursorutil.h"
|
|
#include "dialog_handler.h"
|
|
#include "gdisplay.h" /* for gdisplay_*_override_cursor() */
|
|
|
|
/* standard gimp cursors */
|
|
#include "cursors/mouse.xbm"
|
|
#include "cursors/mouse_mask.xbm"
|
|
#include "cursors/crosshair.xbm"
|
|
#include "cursors/crosshair_mask.xbm"
|
|
#include "cursors/crosshair_small.xbm"
|
|
#include "cursors/crosshair_small_mask.xbm"
|
|
#include "cursors/bad.xbm"
|
|
#include "cursors/bad_mask.xbm"
|
|
#include "cursors/zoom.xbm"
|
|
#include "cursors/zoom_mask.xbm"
|
|
#include "cursors/dropper.xbm"
|
|
#include "cursors/dropper_mask.xbm"
|
|
|
|
/* stock tool cursors */
|
|
#include "cursors/rect_select_small.xbm"
|
|
#include "cursors/rect_select_small_mask.xbm"
|
|
#include "cursors/ellipse_select_small.xbm"
|
|
#include "cursors/ellipse_select_small_mask.xbm"
|
|
#include "cursors/free_select_small.xbm"
|
|
#include "cursors/free_select_small_mask.xbm"
|
|
#include "cursors/fuzzy_select_small.xbm"
|
|
#include "cursors/fuzzy_select_small_mask.xbm"
|
|
#include "cursors/bezier_select_small.xbm"
|
|
#include "cursors/bezier_select_small_mask.xbm"
|
|
#include "cursors/scissors_small.xbm"
|
|
#include "cursors/scissors_small_mask.xbm"
|
|
#include "cursors/move_small.xbm"
|
|
#include "cursors/move_small_mask.xbm"
|
|
#include "cursors/zoom_small.xbm"
|
|
#include "cursors/zoom_small_mask.xbm"
|
|
#include "cursors/crop_small.xbm"
|
|
#include "cursors/crop_small_mask.xbm"
|
|
#include "cursors/resize_small.xbm"
|
|
#include "cursors/resize_small_mask.xbm"
|
|
#include "cursors/rotate_small.xbm"
|
|
#include "cursors/rotate_small_mask.xbm"
|
|
#include "cursors/shear_small.xbm"
|
|
#include "cursors/shear_small_mask.xbm"
|
|
#include "cursors/perspective_small.xbm"
|
|
#include "cursors/perspective_small_mask.xbm"
|
|
#include "cursors/flip_horizontal_small.xbm"
|
|
#include "cursors/flip_horizontal_small_mask.xbm"
|
|
#include "cursors/flip_vertical_small.xbm"
|
|
#include "cursors/flip_vertical_small_mask.xbm"
|
|
#include "cursors/text_small.xbm"
|
|
#include "cursors/text_small_mask.xbm"
|
|
#include "cursors/dropper_small.xbm"
|
|
#include "cursors/dropper_small_mask.xbm"
|
|
#include "cursors/bucket_fill_small.xbm"
|
|
#include "cursors/bucket_fill_small_mask.xbm"
|
|
#include "cursors/blend_small.xbm"
|
|
#include "cursors/blend_small_mask.xbm"
|
|
#include "cursors/pencil_small.xbm"
|
|
#include "cursors/pencil_small_mask.xbm"
|
|
#include "cursors/paintbrush_small.xbm"
|
|
#include "cursors/paintbrush_small_mask.xbm"
|
|
#include "cursors/eraser_small.xbm"
|
|
#include "cursors/eraser_small_mask.xbm"
|
|
#include "cursors/airbrush_small.xbm"
|
|
#include "cursors/airbrush_small_mask.xbm"
|
|
#include "cursors/clone_small.xbm"
|
|
#include "cursors/clone_small_mask.xbm"
|
|
#include "cursors/blur_small.xbm"
|
|
#include "cursors/blur_small_mask.xbm"
|
|
#include "cursors/ink_small.xbm"
|
|
#include "cursors/ink_small_mask.xbm"
|
|
#include "cursors/dodge_small.xbm"
|
|
#include "cursors/dodge_small_mask.xbm"
|
|
#include "cursors/burn_small.xbm"
|
|
#include "cursors/burn_small_mask.xbm"
|
|
#include "cursors/smudge_small.xbm"
|
|
#include "cursors/smudge_small_mask.xbm"
|
|
#include "cursors/measure_small.xbm"
|
|
#include "cursors/measure_small_mask.xbm"
|
|
|
|
/* modifiers */
|
|
#include "cursors/plus.xbm"
|
|
#include "cursors/plus_mask.xbm"
|
|
#include "cursors/minus.xbm"
|
|
#include "cursors/minus_mask.xbm"
|
|
#include "cursors/intersect.xbm"
|
|
#include "cursors/intersect_mask.xbm"
|
|
#include "cursors/move.xbm"
|
|
#include "cursors/move_mask.xbm"
|
|
#include "cursors/resize.xbm"
|
|
#include "cursors/resize_mask.xbm"
|
|
#include "cursors/control.xbm"
|
|
#include "cursors/control_mask.xbm"
|
|
#include "cursors/anchor.xbm"
|
|
#include "cursors/anchor_mask.xbm"
|
|
#include "cursors/foreground.xbm"
|
|
#include "cursors/foreground_mask.xbm"
|
|
#include "cursors/background.xbm"
|
|
#include "cursors/background_mask.xbm"
|
|
#include "cursors/pattern.xbm"
|
|
#include "cursors/pattern_mask.xbm"
|
|
#include "cursors/hand.xbm"
|
|
#include "cursors/hand_mask.xbm"
|
|
|
|
|
|
/* FIXME: gimp_busy HACK */
|
|
gboolean gimp_busy = FALSE;
|
|
|
|
|
|
static GimpBitmapCursor gimp_cursors[] =
|
|
/* these have to match up with the enum in cursorutil.h */
|
|
{
|
|
{
|
|
mouse_bits, mouse_mask_bits,
|
|
mouse_width, mouse_height,
|
|
mouse_x_hot, mouse_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
crosshair_bits, crosshair_mask_bits,
|
|
crosshair_width, crosshair_height,
|
|
crosshair_x_hot, crosshair_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
crosshair_small_bits, crosshair_small_mask_bits,
|
|
crosshair_small_width, crosshair_small_height,
|
|
crosshair_small_x_hot, crosshair_small_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
bad_bits, bad_mask_bits,
|
|
bad_width, bad_height,
|
|
bad_x_hot, bad_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
zoom_bits, zoom_mask_bits,
|
|
zoom_width, zoom_height,
|
|
zoom_x_hot, zoom_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
dropper_bits, dropper_mask_bits,
|
|
dropper_width, dropper_height,
|
|
dropper_x_hot, dropper_y_hot, NULL, NULL, NULL
|
|
}
|
|
};
|
|
|
|
static GimpBitmapCursor gimp_stock_tool_cursors[] =
|
|
/* these have to match up with the enum in appenums.h */
|
|
{
|
|
{
|
|
NULL, NULL,
|
|
0, 0,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
rect_select_small_bits, rect_select_small_mask_bits,
|
|
rect_select_small_width, rect_select_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
ellipse_select_small_bits, ellipse_select_small_mask_bits,
|
|
ellipse_select_small_width, ellipse_select_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
free_select_small_bits, free_select_small_mask_bits,
|
|
free_select_small_width, free_select_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
fuzzy_select_small_bits, fuzzy_select_small_mask_bits,
|
|
fuzzy_select_small_width, fuzzy_select_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
bezier_select_small_bits, bezier_select_small_mask_bits,
|
|
bezier_select_small_width, bezier_select_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
scissors_small_bits, scissors_small_mask_bits,
|
|
scissors_small_width, scissors_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
move_small_bits, move_small_mask_bits,
|
|
move_small_width, move_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
zoom_small_bits, zoom_small_mask_bits,
|
|
zoom_small_width, zoom_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
crop_small_bits, crop_small_mask_bits,
|
|
crop_small_width, crop_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
resize_small_bits, resize_small_mask_bits,
|
|
resize_small_width, resize_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
rotate_small_bits, rotate_small_mask_bits,
|
|
rotate_small_width, rotate_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
shear_small_bits, shear_small_mask_bits,
|
|
shear_small_width, shear_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
perspective_small_bits, perspective_small_mask_bits,
|
|
perspective_small_width, perspective_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
flip_horizontal_small_bits, flip_horizontal_small_mask_bits,
|
|
flip_horizontal_small_width, flip_horizontal_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
flip_vertical_small_bits, flip_vertical_small_mask_bits,
|
|
flip_vertical_small_width, flip_vertical_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
text_small_bits, text_small_mask_bits,
|
|
text_small_width, text_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
dropper_small_bits, dropper_small_mask_bits,
|
|
dropper_small_width, dropper_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
bucket_fill_small_bits, bucket_fill_small_mask_bits,
|
|
bucket_fill_small_width, bucket_fill_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
blend_small_bits, blend_small_mask_bits,
|
|
blend_small_width, blend_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
pencil_small_bits, pencil_small_mask_bits,
|
|
pencil_small_width, pencil_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
paintbrush_small_bits, paintbrush_small_mask_bits,
|
|
paintbrush_small_width, paintbrush_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
airbrush_small_bits, airbrush_small_mask_bits,
|
|
airbrush_small_width, airbrush_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
ink_small_bits, ink_small_mask_bits,
|
|
ink_small_width, ink_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
clone_small_bits, clone_small_mask_bits,
|
|
clone_small_width, clone_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
eraser_small_bits, eraser_small_mask_bits,
|
|
eraser_small_width, eraser_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
smudge_small_bits, smudge_small_mask_bits,
|
|
smudge_small_width, smudge_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
blur_small_bits, blur_small_mask_bits,
|
|
blur_small_width, blur_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
dodge_small_bits, dodge_small_mask_bits,
|
|
dodge_small_width, dodge_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
burn_small_bits, burn_small_mask_bits,
|
|
burn_small_width, burn_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
measure_small_bits, measure_small_mask_bits,
|
|
measure_small_width, measure_small_height,
|
|
0, 0, NULL, NULL, NULL
|
|
}
|
|
};
|
|
|
|
static GimpBitmapCursor gimp_modifier_cursors[] =
|
|
/* these have to match up with the enum in appenums.h */
|
|
{
|
|
{
|
|
NULL, NULL,
|
|
0, 0,
|
|
0, 0, NULL, NULL, NULL
|
|
},
|
|
{
|
|
plus_bits, plus_mask_bits,
|
|
plus_width, plus_height,
|
|
plus_x_hot, plus_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
minus_bits, minus_mask_bits,
|
|
minus_width, minus_height,
|
|
minus_x_hot, minus_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
intersect_bits, intersect_mask_bits,
|
|
intersect_width, intersect_height,
|
|
intersect_x_hot, intersect_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
move_bits, move_mask_bits,
|
|
move_width, move_height,
|
|
move_x_hot, move_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
resize_bits, resize_mask_bits,
|
|
resize_width, resize_height,
|
|
resize_x_hot, resize_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
control_bits, control_mask_bits,
|
|
control_width, control_height,
|
|
control_x_hot, control_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
anchor_bits, anchor_mask_bits,
|
|
anchor_width, anchor_height,
|
|
anchor_x_hot, anchor_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
foreground_bits, foreground_mask_bits,
|
|
foreground_width, foreground_height,
|
|
foreground_x_hot, foreground_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
background_bits, background_mask_bits,
|
|
background_width, background_height,
|
|
background_x_hot, background_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
pattern_bits, pattern_mask_bits,
|
|
pattern_width, pattern_height,
|
|
pattern_x_hot, pattern_y_hot, NULL, NULL, NULL
|
|
},
|
|
{
|
|
hand_bits, hand_mask_bits,
|
|
hand_width, hand_height,
|
|
hand_x_hot, hand_y_hot, NULL, NULL, NULL
|
|
}
|
|
};
|
|
|
|
|
|
extern GSList *display_list; /* It's in gdisplay.c, FYI */
|
|
static gboolean pending_removebusy = FALSE;
|
|
|
|
|
|
static void
|
|
create_cursor_bitmaps (GimpBitmapCursor *bmcursor)
|
|
{
|
|
if (bmcursor->bitmap == NULL)
|
|
bmcursor->bitmap = gdk_bitmap_create_from_data (NULL, bmcursor->bits,
|
|
bmcursor->width,
|
|
bmcursor->height);
|
|
g_return_if_fail (bmcursor->bitmap != NULL);
|
|
|
|
if (bmcursor->mask == NULL)
|
|
bmcursor->mask = gdk_bitmap_create_from_data (NULL, bmcursor->mask_bits,
|
|
bmcursor->width,
|
|
bmcursor->height);
|
|
g_return_if_fail (bmcursor->mask != NULL);
|
|
}
|
|
|
|
static void
|
|
create_cursor (GimpBitmapCursor *bmcursor)
|
|
{
|
|
if (bmcursor->bitmap == NULL ||
|
|
bmcursor->mask == NULL)
|
|
create_cursor_bitmaps (bmcursor);
|
|
|
|
if (bmcursor->cursor == NULL)
|
|
{
|
|
GdkColor fg, bg;
|
|
|
|
/* should have a way to configure the mouse colors */
|
|
gdk_color_parse ("#FFFFFF", &bg);
|
|
gdk_color_parse ("#000000", &fg);
|
|
|
|
bmcursor->cursor = gdk_cursor_new_from_pixmap (bmcursor->bitmap,
|
|
bmcursor->mask,
|
|
&fg, &bg,
|
|
bmcursor->x_hot,
|
|
bmcursor->y_hot);
|
|
}
|
|
|
|
g_return_if_fail (bmcursor->cursor != NULL);
|
|
}
|
|
|
|
static void
|
|
gimp_change_win_cursor_internal (GdkWindow *window,
|
|
GimpCursorType cursor_type,
|
|
GimpToolCursorType tool_cursor,
|
|
GimpCursorModifier modifier)
|
|
{
|
|
GdkCursor *cursor;
|
|
|
|
GdkBitmap *bitmap;
|
|
GdkBitmap *mask;
|
|
|
|
GdkColor color;
|
|
GdkColor fg, bg;
|
|
|
|
static GdkGC *gc = NULL;
|
|
|
|
gint width;
|
|
gint height;
|
|
|
|
GimpBitmapCursor *bmcursor = NULL;
|
|
GimpBitmapCursor *bmmodifier = NULL;
|
|
GimpBitmapCursor *bmtool = NULL;
|
|
|
|
g_return_if_fail (window != NULL);
|
|
g_return_if_fail (cursor_type < GIMP_LAST_CURSOR_ENTRY);
|
|
|
|
/* allow the small tool cursor only with the standard mouse,
|
|
* the small crosshair and the bad cursor
|
|
*/
|
|
if (cursor_type != GIMP_MOUSE_CURSOR &&
|
|
cursor_type != GIMP_CROSSHAIR_SMALL_CURSOR &&
|
|
cursor_type != GIMP_BAD_CURSOR)
|
|
{
|
|
tool_cursor = GIMP_TOOL_CURSOR_NONE;
|
|
}
|
|
|
|
cursor_type -= GIMP_MOUSE_CURSOR;
|
|
bmcursor = &gimp_cursors[(gint) cursor_type];
|
|
|
|
/* if there are no modifiers, we can show the cursor immediately
|
|
*/
|
|
if (modifier == GIMP_CURSOR_MODIFIER_NONE &&
|
|
tool_cursor == GIMP_TOOL_CURSOR_NONE)
|
|
{
|
|
if (bmcursor->cursor == NULL)
|
|
create_cursor (bmcursor);
|
|
|
|
gdk_window_set_cursor (window, bmcursor->cursor);
|
|
|
|
return;
|
|
}
|
|
else if (bmcursor->bitmap == NULL ||
|
|
bmcursor->mask == NULL)
|
|
{
|
|
create_cursor_bitmaps (bmcursor);
|
|
}
|
|
|
|
/* prepare the tool cursor */
|
|
|
|
if (tool_cursor < GIMP_TOOL_CURSOR_NONE ||
|
|
tool_cursor >= GIMP_LAST_STOCK_TOOL_CURSOR_ENTRY)
|
|
{
|
|
tool_cursor = GIMP_TOOL_CURSOR_NONE;
|
|
}
|
|
|
|
if (tool_cursor != GIMP_TOOL_CURSOR_NONE)
|
|
{
|
|
bmtool = &gimp_stock_tool_cursors[(gint) tool_cursor];
|
|
|
|
if (bmtool->bitmap == NULL ||
|
|
bmtool->mask == NULL)
|
|
{
|
|
create_cursor_bitmaps (bmtool);
|
|
}
|
|
}
|
|
|
|
/* prepare the cursor modifier */
|
|
|
|
if (modifier < GIMP_CURSOR_MODIFIER_NONE ||
|
|
modifier >= GIMP_LAST_CURSOR_MODIFIER_ENTRY)
|
|
{
|
|
modifier = GIMP_CURSOR_MODIFIER_NONE;
|
|
}
|
|
|
|
if (modifier != GIMP_CURSOR_MODIFIER_NONE)
|
|
{
|
|
bmmodifier = &gimp_modifier_cursors[(gint) modifier];
|
|
|
|
if (bmmodifier->bitmap == NULL ||
|
|
bmmodifier->mask == NULL)
|
|
{
|
|
create_cursor_bitmaps (bmmodifier);
|
|
}
|
|
}
|
|
|
|
if (gc == NULL)
|
|
gc = gdk_gc_new (bmcursor->bitmap);
|
|
|
|
gdk_window_get_size (bmcursor->bitmap, &width, &height);
|
|
|
|
/* new bitmap and mask for on-the-fly cursor creation */
|
|
|
|
bitmap = gdk_pixmap_new (NULL, width, height, 1);
|
|
mask = gdk_pixmap_new (NULL, width, height, 1);
|
|
|
|
color.pixel = 1;
|
|
gdk_gc_set_foreground (gc, &color);
|
|
|
|
/* first draw the bitmap completely ... */
|
|
|
|
gdk_draw_pixmap (bitmap, gc, bmcursor->bitmap,
|
|
0, 0, 0, 0, width, height);
|
|
|
|
if (bmmodifier)
|
|
{
|
|
gdk_gc_set_clip_mask (gc, bmmodifier->bitmap);
|
|
gdk_draw_pixmap (bitmap, gc, bmmodifier->bitmap,
|
|
0, 0, 0, 0, width, height);
|
|
gdk_gc_set_clip_mask (gc, NULL);
|
|
}
|
|
|
|
if (bmtool)
|
|
{
|
|
gdk_gc_set_clip_mask (gc, bmtool->bitmap);
|
|
gdk_draw_pixmap (bitmap, gc, bmtool->bitmap,
|
|
0, 0, 0, 0, width, height);
|
|
gdk_gc_set_clip_mask (gc, NULL);
|
|
}
|
|
|
|
/* ... then the mask */
|
|
|
|
gdk_draw_pixmap (mask, gc, bmcursor->mask,
|
|
0, 0, 0, 0, width, height);
|
|
|
|
if (bmmodifier)
|
|
{
|
|
gdk_gc_set_clip_mask (gc, bmmodifier->mask);
|
|
gdk_draw_pixmap (mask, gc, bmmodifier->mask,
|
|
0, 0, 0, 0, width, height);
|
|
gdk_gc_set_clip_mask (gc, NULL);
|
|
}
|
|
|
|
if (bmtool)
|
|
{
|
|
gdk_gc_set_clip_mask (gc, bmtool->mask);
|
|
gdk_draw_pixmap (mask, gc, bmtool->mask,
|
|
0, 0, 0, 0, width, height);
|
|
gdk_gc_set_clip_mask (gc, NULL);
|
|
}
|
|
|
|
/* should have a way to configure the mouse colors */
|
|
gdk_color_parse ("#FFFFFF", &bg);
|
|
gdk_color_parse ("#000000", &fg);
|
|
|
|
cursor = gdk_cursor_new_from_pixmap (bitmap, mask,
|
|
&fg, &bg,
|
|
bmcursor->x_hot,
|
|
bmcursor->y_hot);
|
|
|
|
gdk_window_set_cursor (window, cursor);
|
|
|
|
gdk_cursor_destroy (cursor);
|
|
gdk_bitmap_unref (bitmap);
|
|
gdk_bitmap_unref (mask);
|
|
}
|
|
|
|
void
|
|
gimp_change_win_cursor (GdkWindow *win,
|
|
GdkCursorType cursor_type,
|
|
GimpToolCursorType tool_cursor,
|
|
GimpCursorModifier modifier)
|
|
{
|
|
GdkCursor *cursor;
|
|
|
|
if (cursor_type > GDK_LAST_CURSOR)
|
|
{
|
|
gimp_change_win_cursor_internal (win,
|
|
(GimpCursorType) cursor_type,
|
|
tool_cursor,
|
|
modifier);
|
|
return;
|
|
}
|
|
|
|
cursor = gdk_cursor_new (cursor_type);
|
|
gdk_window_set_cursor (win, cursor);
|
|
gdk_cursor_destroy (cursor);
|
|
}
|
|
|
|
void
|
|
gimp_unset_win_cursor (GdkWindow *win)
|
|
{
|
|
gdk_window_set_cursor (win, NULL);
|
|
}
|
|
|
|
void
|
|
gimp_add_busy_cursors_until_idle (void)
|
|
{
|
|
if (!pending_removebusy)
|
|
{
|
|
gimp_add_busy_cursors ();
|
|
gtk_idle_add_priority (GTK_PRIORITY_HIGH,
|
|
gimp_remove_busy_cursors, NULL);
|
|
pending_removebusy = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
gimp_add_busy_cursors (void)
|
|
{
|
|
GDisplay *gdisp;
|
|
GSList *list;
|
|
|
|
/* FIXME: gimp_busy HACK */
|
|
gimp_busy = TRUE;
|
|
|
|
/* Canvases */
|
|
for (list = display_list; list; list = g_slist_next (list))
|
|
{
|
|
gdisp = (GDisplay *) list->data;
|
|
gdisplay_install_override_cursor (gdisp, GDK_WATCH);
|
|
}
|
|
|
|
/* Dialogs */
|
|
dialog_idle_all ();
|
|
|
|
gdk_flush ();
|
|
}
|
|
|
|
gint
|
|
gimp_remove_busy_cursors (gpointer data)
|
|
{
|
|
GDisplay *gdisp;
|
|
GSList *list;
|
|
|
|
/* Canvases */
|
|
for (list = display_list; list; list = g_slist_next (list))
|
|
{
|
|
gdisp = (GDisplay *) list->data;
|
|
gdisplay_remove_override_cursor (gdisp);
|
|
}
|
|
|
|
/* Dialogs */
|
|
dialog_unidle_all ();
|
|
|
|
pending_removebusy = FALSE;
|
|
|
|
/* FIXME: gimp_busy HACK */
|
|
gimp_busy = FALSE;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***************************************************************/
|
|
/* gtkutil_compress_motion:
|
|
|
|
This function walks the whole GDK event queue seeking motion events
|
|
corresponding to the widget 'widget'. If it finds any it will
|
|
remove them from the queue, write the most recent motion offset
|
|
to 'lastmotion_x' and 'lastmotion_y', then return TRUE. Otherwise
|
|
it will return FALSE and 'lastmotion_x' / 'lastmotion_y' will be
|
|
untouched.
|
|
*/
|
|
/* The gtkutil_compress_motion function source may be re-used under
|
|
the XFree86-style license. <adam@gimp.org> */
|
|
gboolean
|
|
gtkutil_compress_motion (GtkWidget *widget,
|
|
gdouble *lastmotion_x,
|
|
gdouble *lastmotion_y)
|
|
{
|
|
GdkEvent *event;
|
|
GList *requeued_events = NULL;
|
|
GList *list;
|
|
gboolean success = FALSE;
|
|
|
|
/* Move the entire GDK event queue to a private list, filtering
|
|
out any motion events for the desired widget. */
|
|
while (gdk_events_pending ())
|
|
{
|
|
event = gdk_event_get ();
|
|
|
|
if (!event)
|
|
{
|
|
/* Do nothing */
|
|
}
|
|
else if ((gtk_get_event_widget (event) == widget) &&
|
|
(event->any.type == GDK_MOTION_NOTIFY))
|
|
{
|
|
*lastmotion_x = event->motion.x;
|
|
*lastmotion_y = event->motion.y;
|
|
|
|
gdk_event_free (event);
|
|
success = TRUE;
|
|
}
|
|
else
|
|
{
|
|
requeued_events = g_list_prepend (requeued_events, event);
|
|
}
|
|
}
|
|
|
|
/* Replay the remains of our private event list back into the
|
|
event queue in order. */
|
|
|
|
requeued_events = g_list_reverse (requeued_events);
|
|
|
|
for (list = requeued_events; list; list = g_list_next (list))
|
|
{
|
|
gdk_event_put ((GdkEvent*) list->data);
|
|
gdk_event_free ((GdkEvent*) list->data);
|
|
}
|
|
|
|
g_list_free (requeued_events);
|
|
|
|
return success;
|
|
}
|