new global variable "gimp_busy" which gets set/unset whenever busy cursors

2000-03-25  Michael Natterer  <mitch@gimp.org>

	* app/cursorutil.[ch]: new global variable "gimp_busy" which gets
	set/unset whenever busy cursors are added/removed.

	* app/info_dialog.c: register the info dialogs with the dialog
	handler.

	* app/fuzzy_select.[ch]: cleanups.

	Here starts the ugly workaround which simulates something like
	locking. If it works, it will close lots of bugs, if not, it's
	easy to remove again.

	So far, I didn't find strange side effects but Gimp is told to be
	a complex program :-) Please test this.

	* app/context_manager.c: don't allow tool changes if gimp_busy
	is TRUE.

	* app/disp_callbacks.c: don't allow mouse and key events in the
	display_canvas if gimp_busy is TRUE.
	(except if the current tool is FUZZY_SELECT and it is ACTIVE,
	 which is very ugly)
	Also block other stuff like dropping colors/patterns etc.

	* app/gdisplay_ops.c: don't close any display while Gimp is
	busy. This is not really what we want but at least it prevents
	crashes.
This commit is contained in:
Michael Natterer
2000-03-25 18:17:01 +00:00
committed by Michael Natterer
parent cb4ddb964b
commit 3e64ff6a1b
22 changed files with 947 additions and 661 deletions

View File

@ -1,3 +1,33 @@
2000-03-25 Michael Natterer <mitch@gimp.org>
* app/cursorutil.[ch]: new global variable "gimp_busy" which gets
set/unset whenever busy cursors are added/removed.
* app/info_dialog.c: register the info dialogs with the dialog
handler.
* app/fuzzy_select.[ch]: cleanups.
Here starts the ugly workaround which simulates something like
locking. If it works, it will close lots of bugs, if not, it's
easy to remove again.
So far, I didn't find strange side effects but Gimp is told to be
a complex program :-) Please test this.
* app/context_manager.c: don't allow tool changes if gimp_busy
is TRUE.
* app/disp_callbacks.c: don't allow mouse and key events in the
display_canvas if gimp_busy is TRUE.
(except if the current tool is FUZZY_SELECT and it is ACTIVE,
which is very ugly)
Also block other stuff like dropping colors/patterns etc.
* app/gdisplay_ops.c: don't close any display while Gimp is
busy. This is not really what we want but at least it prevents
crashes.
2000-03-25 Sven Neumann <sven@gimp.org>
* plug-ins/script-fu/script-fu-console.c: only call gtk_main_quit()

View File

@ -17,6 +17,7 @@
*/
#include "appenv.h"
#include "colormaps.h"
#include "cursorutil.h"
#include "context_manager.h"
#include "gdisplay.h"
#include "gimprc.h"
@ -37,29 +38,57 @@ context_manager_display_changed (GimpContext *context,
}
static void
context_manager_tool_changed (GimpContext *context,
context_manager_tool_changed (GimpContext *user_context,
ToolType tool_type,
gpointer data)
{
GimpContext* tool_context;
if (! global_paint_options)
/* FIXME: gimp_busy HACK */
if (gimp_busy)
{
if (active_tool &&
(tool_context = tool_info[active_tool->type].tool_context))
/* there may be contexts waiting for the user_context's "tool_changed"
* signal, so stop emitting it.
*/
gtk_signal_emit_stop_by_name (GTK_OBJECT (user_context), "tool_changed");
if (active_tool->type != tool_type)
{
gimp_context_unset_parent (tool_context);
gtk_signal_handler_block_by_func (GTK_OBJECT (user_context),
context_manager_tool_changed,
NULL);
/* explicitly set the current tool */
gimp_context_set_tool (user_context, active_tool->type);
gtk_signal_handler_unblock_by_func (GTK_OBJECT (user_context),
context_manager_tool_changed,
NULL);
}
if ((tool_context = tool_info[tool_type].tool_context))
{
gimp_context_copy_args (tool_context, gimp_context_get_user (),
PAINT_OPTIONS_MASK);
gimp_context_set_parent (tool_context, gimp_context_get_user ());
}
/* take care that the correct toolbox button gets re-activated */
tool_type = active_tool->type;
}
else
{
GimpContext* tool_context;
tools_select (tool_type);
if (! global_paint_options)
{
if (active_tool &&
(tool_context = tool_info[active_tool->type].tool_context))
{
gimp_context_unset_parent (tool_context);
}
if ((tool_context = tool_info[tool_type].tool_context))
{
gimp_context_copy_args (tool_context, user_context,
PAINT_OPTIONS_MASK);
gimp_context_set_parent (tool_context, user_context);
}
}
tools_select (tool_type);
}
if (tool_type == SCALE ||
tool_type == SHEAR ||

View File

@ -61,7 +61,10 @@ typedef struct
gint x_hot, y_hot;
GdkCursor *cursor;
} BM_Cursor;
/* FIXME: gimp_busy HACK */
gboolean gimp_busy = FALSE;
static BM_Cursor gimp_cursors[] =
/* these have to match up with the enum in cursorutil.h */
{
@ -232,6 +235,9 @@ 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))
{
@ -263,6 +269,9 @@ gimp_remove_busy_cursors (gpointer data)
pending_removebusy = FALSE;
/* FIXME: gimp_busy HACK */
gimp_busy = FALSE;
return 0;
}

View File

@ -28,6 +28,9 @@
#include <gtk/gtk.h>
/* FIXME: gimp_busy HACK */
extern gboolean gimp_busy;
typedef enum
{
GIMP_MOUSE_CURSOR = (GDK_LAST_CURSOR + 2),

View File

@ -162,6 +162,8 @@ info_dialog_new_extended (gchar *title,
gtk_window_set_title (GTK_WINDOW (shell), title);
session_set_window_geometry (shell, &info_dialog_session_info, FALSE );
dialog_register (shell);
gtk_signal_connect (GTK_OBJECT (shell), "delete_event",
GTK_SIGNAL_FUNC (info_dialog_delete_callback),
idialog);
@ -236,6 +238,8 @@ info_dialog_free (InfoDialog *idialog)
/* Free the actual field linked list */
g_slist_free (idialog->field_list);
dialog_unregister (idialog->shell);
session_get_window_info (idialog->shell, &info_dialog_session_info);
/* Destroy the associated widgets */

View File

@ -49,12 +49,12 @@ static void gdisplay_check_device_cursor (GDisplay *gdisp);
static void
redraw (GDisplay *gdisp,
int x,
int y,
int w,
int h)
gint x,
gint y,
gint w,
gint h)
{
long x1, y1, x2, y2; /* coordinate of rectangle corners */
glong x1, y1, x2, y2; /* coordinate of rectangle corners */
x1 = x;
y1 = y;
@ -76,9 +76,9 @@ gdisplay_check_device_cursor (GDisplay *gdisp)
{
GList *list;
/* gdk_input_list_devices returns an internal list, so we shouldn't
free it afterwards */
/* gdk_input_list_devices returns an internal list, so we shouldn't
* free it afterwards
*/
for (list = gdk_input_list_devices(); list; list = g_list_next (list))
{
GdkDeviceInfo *info = (GdkDeviceInfo *) list->data;
@ -92,15 +92,18 @@ gdisplay_check_device_cursor (GDisplay *gdisp)
}
static int
key_to_state (int key)
key_to_state (gint key)
{
switch (key)
{
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Alt_L:
case GDK_Alt_R:
return GDK_MOD1_MASK;
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Shift_L:
case GDK_Shift_R:
return GDK_SHIFT_MASK;
case GDK_Control_L: case GDK_Control_R:
case GDK_Control_L:
case GDK_Control_R:
return GDK_CONTROL_MASK;
default:
return 0;
@ -130,19 +133,18 @@ gint
gdisplay_canvas_events (GtkWidget *canvas,
GdkEvent *event)
{
GDisplay *gdisp;
GdkEventExpose *eevent;
GdkEventMotion *mevent;
GdkEventButton *bevent;
GdkEventKey *kevent;
gdouble tx, ty;
guint state = 0;
gint return_val = FALSE;
static gboolean scrolled = FALSE;
static guint key_signal_id = 0;
int update_cursor = FALSE;
tx = ty = 0;
GDisplay *gdisp;
GdkEventExpose *eevent;
GdkEventMotion *mevent;
GdkEventButton *bevent;
GdkEventKey *kevent;
gdouble tx = 0;
gdouble ty = 0;
guint state = 0;
gint return_val = FALSE;
static gboolean scrolled = FALSE;
static guint key_signal_id = 0;
gboolean update_cursor = FALSE;
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
@ -177,7 +179,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
}
/* Find out what device the event occurred upon */
if (devices_check_change (event))
if (!gimp_busy && devices_check_change (event))
gdisplay_check_device_cursor (gdisp);
switch (event->type)
@ -222,6 +224,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
bevent = (GdkEventButton *) event;
state = bevent->state;
/* ignore new mouse events */
if (gimp_busy)
return TRUE;
switch (bevent->button)
{
case 1:
@ -337,11 +343,23 @@ gdisplay_canvas_events (GtkWidget *canvas,
bevent = (GdkEventButton *) event;
state = bevent->state;
/* ugly side consition: all operations which set busy cursors are
* invoked on BUTTON_RELEASE, thus no new BUTTON_PRESS events are
* accepted while Gimp is busy, thus it should be safe to block
* BUTTON_RELEASE. --Mitch
*
* ugly: fuzzy_select sets busy cursors while ACTIVE.
*/
if (gimp_busy &&
!(active_tool->type == FUZZY_SELECT &&
active_tool->state == ACTIVE))
return TRUE;
switch (bevent->button)
{
case 1:
state &= ~GDK_BUTTON1_MASK;
/* Lame hack. See above */
if (key_signal_id)
{
@ -401,17 +419,29 @@ gdisplay_canvas_events (GtkWidget *canvas,
mevent = (GdkEventMotion *) event;
state = mevent->state;
/* for the same reason we block BUTTON_RELEASE,
* we block MOTION_NOTIFY. --Mitch
*
* ugly: fuzzy_select sets busy cursors while ACTIVE.
*/
if (gimp_busy &&
!(active_tool->type == FUZZY_SELECT &&
active_tool->state == ACTIVE))
return TRUE;
/* Ask for the pointer position, but ignore it except for cursor
* handling, so motion events sync with the button press/release events */
if (mevent->is_hint)
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
{
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
#ifdef GTK_HAVE_SIX_VALUATORS
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL, NULL
#else /* !GTK_HAVE_SIX_VALUATORS */
NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
#endif /* GTK_HAVE_SIX_VALUATORS */
);
);
}
else
{
tx = mevent->x;
@ -424,7 +454,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
gdisp->proximity = TRUE;
gdisplay_check_device_cursor (gdisp);
}
if (active_tool && ((active_tool->type == MOVE) ||
!gimage_is_empty (gdisp->gimage)) &&
(mevent->state & GDK_BUTTON1_MASK))
@ -434,7 +464,8 @@ gdisplay_canvas_events (GtkWidget *canvas,
/* if the first mouse button is down, check for automatic
* scrolling...
*/
if ((mevent->state & GDK_BUTTON1_MASK) && !active_tool->scroll_lock)
if ((mevent->state & GDK_BUTTON1_MASK) &&
!active_tool->scroll_lock)
{
if (mevent->x < 0 || mevent->y < 0 ||
mevent->x > gdisp->disp_width ||
@ -460,13 +491,11 @@ gdisplay_canvas_events (GtkWidget *canvas,
/* Operator update support: Bug #XXXX */
if (
/* Should we have a tool... */
active_tool &&
/* and this event is NOT driving */
/* button press handlers ... */
!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))
)
if (/* Should we have a tool... */
active_tool &&
/* and this event is NOT driving */
/* button press handlers ... */
!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
{
/* ...then preconditions to modify a tool */
/* operator state have been met. */
@ -479,6 +508,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event;
state = kevent->state;
/* ignore any key presses */
if (gimp_busy)
return TRUE;
switch (kevent->keyval)
{
case GDK_Left: case GDK_Right:
@ -491,7 +524,9 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_Tab:
if (kevent->state & GDK_MOD1_MASK && !gimage_is_empty (gdisp->gimage))
layer_select_init (gdisp->gimage, 1, kevent->time);
if (kevent->state & GDK_CONTROL_MASK && !gimage_is_empty (gdisp->gimage))
if (kevent->state & GDK_CONTROL_MASK &&
!gimage_is_empty (gdisp->gimage))
layer_select_init (gdisp->gimage, -1, kevent->time);
/* Hide or show all dialogs */
@ -505,7 +540,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Control_L: case GDK_Control_R:
state |= key_to_state(kevent->keyval);
state |= key_to_state (kevent->keyval);
/* For all modifier keys: call the tools modifier_key_func */
if (active_tool && !gimage_is_empty (gdisp->gimage))
{
@ -527,12 +562,16 @@ gdisplay_canvas_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event;
state = kevent->state;
/* ignore any key releases */
if (gimp_busy)
return TRUE;
switch (kevent->keyval)
{
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Control_L: case GDK_Control_R:
state &= ~key_to_state(kevent->keyval);
state &= ~key_to_state (kevent->keyval);
/* For all modifier keys: call the tools modifier_key_func */
if (active_tool && !gimage_is_empty (gdisp->gimage))
{
@ -556,6 +595,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
break;
}
/* if re reached this point in gimp_busy mode, return now */
if (gimp_busy)
return TRUE;
/* Cursor update support */
/* no_cursor_updating is TRUE (=1) when */
/* <Toolbox>/File/Preferences.../Interface/... */
@ -590,6 +633,9 @@ gdisplay_hruler_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (gimp_busy)
return TRUE;
if (event->button == 1)
{
gdisp = data;
@ -609,6 +655,9 @@ gdisplay_vruler_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (gimp_busy)
return TRUE;
if (event->button == 1)
{
gdisp = data;
@ -628,15 +677,16 @@ gdisplay_origin_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (event->button == 1)
if (!gimp_busy && event->button == 1)
{
gdisp = data;
gtk_menu_popup (GTK_MENU (gdisp->popup),
NULL, NULL, NULL, NULL, 1, event->time);
}
/* Stop the signal emission so the button doesn't grab the
* pointer away from us */
/* Stop the signal emission so the button doesn't grab the
* pointer away from us
*/
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "button_press_event");
return FALSE;
@ -656,7 +706,7 @@ gdisplay_drag_drop (GtkWidget *widget,
gdisp = (GDisplay *) data;
if ((src_widget = gtk_drag_get_source_widget (context)))
if (!gimp_busy && (src_widget = gtk_drag_get_source_widget (context)))
{
GimpDrawable *drawable = NULL;
Layer *layer = NULL;
@ -812,6 +862,9 @@ gdisplay_bucket_fill (GtkWidget *widget,
TempBuf *pat_buf = NULL;
gboolean new_buf = FALSE;
if (gimp_busy)
return;
gimage = ((GDisplay *) data)->gimage;
drawable = gimage_active_drawable (gimage);
if (!drawable)

View File

@ -49,12 +49,12 @@ static void gdisplay_check_device_cursor (GDisplay *gdisp);
static void
redraw (GDisplay *gdisp,
int x,
int y,
int w,
int h)
gint x,
gint y,
gint w,
gint h)
{
long x1, y1, x2, y2; /* coordinate of rectangle corners */
glong x1, y1, x2, y2; /* coordinate of rectangle corners */
x1 = x;
y1 = y;
@ -76,9 +76,9 @@ gdisplay_check_device_cursor (GDisplay *gdisp)
{
GList *list;
/* gdk_input_list_devices returns an internal list, so we shouldn't
free it afterwards */
/* gdk_input_list_devices returns an internal list, so we shouldn't
* free it afterwards
*/
for (list = gdk_input_list_devices(); list; list = g_list_next (list))
{
GdkDeviceInfo *info = (GdkDeviceInfo *) list->data;
@ -92,15 +92,18 @@ gdisplay_check_device_cursor (GDisplay *gdisp)
}
static int
key_to_state (int key)
key_to_state (gint key)
{
switch (key)
{
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Alt_L:
case GDK_Alt_R:
return GDK_MOD1_MASK;
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Shift_L:
case GDK_Shift_R:
return GDK_SHIFT_MASK;
case GDK_Control_L: case GDK_Control_R:
case GDK_Control_L:
case GDK_Control_R:
return GDK_CONTROL_MASK;
default:
return 0;
@ -130,19 +133,18 @@ gint
gdisplay_canvas_events (GtkWidget *canvas,
GdkEvent *event)
{
GDisplay *gdisp;
GdkEventExpose *eevent;
GdkEventMotion *mevent;
GdkEventButton *bevent;
GdkEventKey *kevent;
gdouble tx, ty;
guint state = 0;
gint return_val = FALSE;
static gboolean scrolled = FALSE;
static guint key_signal_id = 0;
int update_cursor = FALSE;
tx = ty = 0;
GDisplay *gdisp;
GdkEventExpose *eevent;
GdkEventMotion *mevent;
GdkEventButton *bevent;
GdkEventKey *kevent;
gdouble tx = 0;
gdouble ty = 0;
guint state = 0;
gint return_val = FALSE;
static gboolean scrolled = FALSE;
static guint key_signal_id = 0;
gboolean update_cursor = FALSE;
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
@ -177,7 +179,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
}
/* Find out what device the event occurred upon */
if (devices_check_change (event))
if (!gimp_busy && devices_check_change (event))
gdisplay_check_device_cursor (gdisp);
switch (event->type)
@ -222,6 +224,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
bevent = (GdkEventButton *) event;
state = bevent->state;
/* ignore new mouse events */
if (gimp_busy)
return TRUE;
switch (bevent->button)
{
case 1:
@ -337,11 +343,23 @@ gdisplay_canvas_events (GtkWidget *canvas,
bevent = (GdkEventButton *) event;
state = bevent->state;
/* ugly side consition: all operations which set busy cursors are
* invoked on BUTTON_RELEASE, thus no new BUTTON_PRESS events are
* accepted while Gimp is busy, thus it should be safe to block
* BUTTON_RELEASE. --Mitch
*
* ugly: fuzzy_select sets busy cursors while ACTIVE.
*/
if (gimp_busy &&
!(active_tool->type == FUZZY_SELECT &&
active_tool->state == ACTIVE))
return TRUE;
switch (bevent->button)
{
case 1:
state &= ~GDK_BUTTON1_MASK;
/* Lame hack. See above */
if (key_signal_id)
{
@ -401,17 +419,29 @@ gdisplay_canvas_events (GtkWidget *canvas,
mevent = (GdkEventMotion *) event;
state = mevent->state;
/* for the same reason we block BUTTON_RELEASE,
* we block MOTION_NOTIFY. --Mitch
*
* ugly: fuzzy_select sets busy cursors while ACTIVE.
*/
if (gimp_busy &&
!(active_tool->type == FUZZY_SELECT &&
active_tool->state == ACTIVE))
return TRUE;
/* Ask for the pointer position, but ignore it except for cursor
* handling, so motion events sync with the button press/release events */
if (mevent->is_hint)
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
{
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
#ifdef GTK_HAVE_SIX_VALUATORS
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL, NULL
#else /* !GTK_HAVE_SIX_VALUATORS */
NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
#endif /* GTK_HAVE_SIX_VALUATORS */
);
);
}
else
{
tx = mevent->x;
@ -424,7 +454,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
gdisp->proximity = TRUE;
gdisplay_check_device_cursor (gdisp);
}
if (active_tool && ((active_tool->type == MOVE) ||
!gimage_is_empty (gdisp->gimage)) &&
(mevent->state & GDK_BUTTON1_MASK))
@ -434,7 +464,8 @@ gdisplay_canvas_events (GtkWidget *canvas,
/* if the first mouse button is down, check for automatic
* scrolling...
*/
if ((mevent->state & GDK_BUTTON1_MASK) && !active_tool->scroll_lock)
if ((mevent->state & GDK_BUTTON1_MASK) &&
!active_tool->scroll_lock)
{
if (mevent->x < 0 || mevent->y < 0 ||
mevent->x > gdisp->disp_width ||
@ -460,13 +491,11 @@ gdisplay_canvas_events (GtkWidget *canvas,
/* Operator update support: Bug #XXXX */
if (
/* Should we have a tool... */
active_tool &&
/* and this event is NOT driving */
/* button press handlers ... */
!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))
)
if (/* Should we have a tool... */
active_tool &&
/* and this event is NOT driving */
/* button press handlers ... */
!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
{
/* ...then preconditions to modify a tool */
/* operator state have been met. */
@ -479,6 +508,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event;
state = kevent->state;
/* ignore any key presses */
if (gimp_busy)
return TRUE;
switch (kevent->keyval)
{
case GDK_Left: case GDK_Right:
@ -491,7 +524,9 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_Tab:
if (kevent->state & GDK_MOD1_MASK && !gimage_is_empty (gdisp->gimage))
layer_select_init (gdisp->gimage, 1, kevent->time);
if (kevent->state & GDK_CONTROL_MASK && !gimage_is_empty (gdisp->gimage))
if (kevent->state & GDK_CONTROL_MASK &&
!gimage_is_empty (gdisp->gimage))
layer_select_init (gdisp->gimage, -1, kevent->time);
/* Hide or show all dialogs */
@ -505,7 +540,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Control_L: case GDK_Control_R:
state |= key_to_state(kevent->keyval);
state |= key_to_state (kevent->keyval);
/* For all modifier keys: call the tools modifier_key_func */
if (active_tool && !gimage_is_empty (gdisp->gimage))
{
@ -527,12 +562,16 @@ gdisplay_canvas_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event;
state = kevent->state;
/* ignore any key releases */
if (gimp_busy)
return TRUE;
switch (kevent->keyval)
{
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Control_L: case GDK_Control_R:
state &= ~key_to_state(kevent->keyval);
state &= ~key_to_state (kevent->keyval);
/* For all modifier keys: call the tools modifier_key_func */
if (active_tool && !gimage_is_empty (gdisp->gimage))
{
@ -556,6 +595,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
break;
}
/* if re reached this point in gimp_busy mode, return now */
if (gimp_busy)
return TRUE;
/* Cursor update support */
/* no_cursor_updating is TRUE (=1) when */
/* <Toolbox>/File/Preferences.../Interface/... */
@ -590,6 +633,9 @@ gdisplay_hruler_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (gimp_busy)
return TRUE;
if (event->button == 1)
{
gdisp = data;
@ -609,6 +655,9 @@ gdisplay_vruler_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (gimp_busy)
return TRUE;
if (event->button == 1)
{
gdisp = data;
@ -628,15 +677,16 @@ gdisplay_origin_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (event->button == 1)
if (!gimp_busy && event->button == 1)
{
gdisp = data;
gtk_menu_popup (GTK_MENU (gdisp->popup),
NULL, NULL, NULL, NULL, 1, event->time);
}
/* Stop the signal emission so the button doesn't grab the
* pointer away from us */
/* Stop the signal emission so the button doesn't grab the
* pointer away from us
*/
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "button_press_event");
return FALSE;
@ -656,7 +706,7 @@ gdisplay_drag_drop (GtkWidget *widget,
gdisp = (GDisplay *) data;
if ((src_widget = gtk_drag_get_source_widget (context)))
if (!gimp_busy && (src_widget = gtk_drag_get_source_widget (context)))
{
GimpDrawable *drawable = NULL;
Layer *layer = NULL;
@ -812,6 +862,9 @@ gdisplay_bucket_fill (GtkWidget *widget,
TempBuf *pat_buf = NULL;
gboolean new_buf = FALSE;
if (gimp_busy)
return;
gimage = ((GDisplay *) data)->gimage;
drawable = gimage_active_drawable (gimage);
if (!drawable)

View File

@ -116,6 +116,12 @@ void
gdisplay_close_window (GDisplay *gdisp,
gboolean kill_it)
{
/* FIXME: gimp_busy HACK not really appropriate here because we only
* want to prevent the busy image and display to be closed. --Mitch
*/
if (gimp_busy)
return;
/* If the image has been modified, give the user a chance to save
* it before nuking it--this only applies if its the last view
* to an image canvas. (a gimage with disp_count = 1)

View File

@ -49,12 +49,12 @@ static void gdisplay_check_device_cursor (GDisplay *gdisp);
static void
redraw (GDisplay *gdisp,
int x,
int y,
int w,
int h)
gint x,
gint y,
gint w,
gint h)
{
long x1, y1, x2, y2; /* coordinate of rectangle corners */
glong x1, y1, x2, y2; /* coordinate of rectangle corners */
x1 = x;
y1 = y;
@ -76,9 +76,9 @@ gdisplay_check_device_cursor (GDisplay *gdisp)
{
GList *list;
/* gdk_input_list_devices returns an internal list, so we shouldn't
free it afterwards */
/* gdk_input_list_devices returns an internal list, so we shouldn't
* free it afterwards
*/
for (list = gdk_input_list_devices(); list; list = g_list_next (list))
{
GdkDeviceInfo *info = (GdkDeviceInfo *) list->data;
@ -92,15 +92,18 @@ gdisplay_check_device_cursor (GDisplay *gdisp)
}
static int
key_to_state (int key)
key_to_state (gint key)
{
switch (key)
{
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Alt_L:
case GDK_Alt_R:
return GDK_MOD1_MASK;
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Shift_L:
case GDK_Shift_R:
return GDK_SHIFT_MASK;
case GDK_Control_L: case GDK_Control_R:
case GDK_Control_L:
case GDK_Control_R:
return GDK_CONTROL_MASK;
default:
return 0;
@ -130,19 +133,18 @@ gint
gdisplay_canvas_events (GtkWidget *canvas,
GdkEvent *event)
{
GDisplay *gdisp;
GdkEventExpose *eevent;
GdkEventMotion *mevent;
GdkEventButton *bevent;
GdkEventKey *kevent;
gdouble tx, ty;
guint state = 0;
gint return_val = FALSE;
static gboolean scrolled = FALSE;
static guint key_signal_id = 0;
int update_cursor = FALSE;
tx = ty = 0;
GDisplay *gdisp;
GdkEventExpose *eevent;
GdkEventMotion *mevent;
GdkEventButton *bevent;
GdkEventKey *kevent;
gdouble tx = 0;
gdouble ty = 0;
guint state = 0;
gint return_val = FALSE;
static gboolean scrolled = FALSE;
static guint key_signal_id = 0;
gboolean update_cursor = FALSE;
gdisp = (GDisplay *) gtk_object_get_user_data (GTK_OBJECT (canvas));
@ -177,7 +179,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
}
/* Find out what device the event occurred upon */
if (devices_check_change (event))
if (!gimp_busy && devices_check_change (event))
gdisplay_check_device_cursor (gdisp);
switch (event->type)
@ -222,6 +224,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
bevent = (GdkEventButton *) event;
state = bevent->state;
/* ignore new mouse events */
if (gimp_busy)
return TRUE;
switch (bevent->button)
{
case 1:
@ -337,11 +343,23 @@ gdisplay_canvas_events (GtkWidget *canvas,
bevent = (GdkEventButton *) event;
state = bevent->state;
/* ugly side consition: all operations which set busy cursors are
* invoked on BUTTON_RELEASE, thus no new BUTTON_PRESS events are
* accepted while Gimp is busy, thus it should be safe to block
* BUTTON_RELEASE. --Mitch
*
* ugly: fuzzy_select sets busy cursors while ACTIVE.
*/
if (gimp_busy &&
!(active_tool->type == FUZZY_SELECT &&
active_tool->state == ACTIVE))
return TRUE;
switch (bevent->button)
{
case 1:
state &= ~GDK_BUTTON1_MASK;
/* Lame hack. See above */
if (key_signal_id)
{
@ -401,17 +419,29 @@ gdisplay_canvas_events (GtkWidget *canvas,
mevent = (GdkEventMotion *) event;
state = mevent->state;
/* for the same reason we block BUTTON_RELEASE,
* we block MOTION_NOTIFY. --Mitch
*
* ugly: fuzzy_select sets busy cursors while ACTIVE.
*/
if (gimp_busy &&
!(active_tool->type == FUZZY_SELECT &&
active_tool->state == ACTIVE))
return TRUE;
/* Ask for the pointer position, but ignore it except for cursor
* handling, so motion events sync with the button press/release events */
if (mevent->is_hint)
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
{
gdk_input_window_get_pointer (canvas->window, current_device, &tx, &ty,
#ifdef GTK_HAVE_SIX_VALUATORS
NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL, NULL
#else /* !GTK_HAVE_SIX_VALUATORS */
NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL
#endif /* GTK_HAVE_SIX_VALUATORS */
);
);
}
else
{
tx = mevent->x;
@ -424,7 +454,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
gdisp->proximity = TRUE;
gdisplay_check_device_cursor (gdisp);
}
if (active_tool && ((active_tool->type == MOVE) ||
!gimage_is_empty (gdisp->gimage)) &&
(mevent->state & GDK_BUTTON1_MASK))
@ -434,7 +464,8 @@ gdisplay_canvas_events (GtkWidget *canvas,
/* if the first mouse button is down, check for automatic
* scrolling...
*/
if ((mevent->state & GDK_BUTTON1_MASK) && !active_tool->scroll_lock)
if ((mevent->state & GDK_BUTTON1_MASK) &&
!active_tool->scroll_lock)
{
if (mevent->x < 0 || mevent->y < 0 ||
mevent->x > gdisp->disp_width ||
@ -460,13 +491,11 @@ gdisplay_canvas_events (GtkWidget *canvas,
/* Operator update support: Bug #XXXX */
if (
/* Should we have a tool... */
active_tool &&
/* and this event is NOT driving */
/* button press handlers ... */
!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK))
)
if (/* Should we have a tool... */
active_tool &&
/* and this event is NOT driving */
/* button press handlers ... */
!(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
{
/* ...then preconditions to modify a tool */
/* operator state have been met. */
@ -479,6 +508,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event;
state = kevent->state;
/* ignore any key presses */
if (gimp_busy)
return TRUE;
switch (kevent->keyval)
{
case GDK_Left: case GDK_Right:
@ -491,7 +524,9 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_Tab:
if (kevent->state & GDK_MOD1_MASK && !gimage_is_empty (gdisp->gimage))
layer_select_init (gdisp->gimage, 1, kevent->time);
if (kevent->state & GDK_CONTROL_MASK && !gimage_is_empty (gdisp->gimage))
if (kevent->state & GDK_CONTROL_MASK &&
!gimage_is_empty (gdisp->gimage))
layer_select_init (gdisp->gimage, -1, kevent->time);
/* Hide or show all dialogs */
@ -505,7 +540,7 @@ gdisplay_canvas_events (GtkWidget *canvas,
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Control_L: case GDK_Control_R:
state |= key_to_state(kevent->keyval);
state |= key_to_state (kevent->keyval);
/* For all modifier keys: call the tools modifier_key_func */
if (active_tool && !gimage_is_empty (gdisp->gimage))
{
@ -527,12 +562,16 @@ gdisplay_canvas_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event;
state = kevent->state;
/* ignore any key releases */
if (gimp_busy)
return TRUE;
switch (kevent->keyval)
{
case GDK_Alt_L: case GDK_Alt_R:
case GDK_Shift_L: case GDK_Shift_R:
case GDK_Control_L: case GDK_Control_R:
state &= ~key_to_state(kevent->keyval);
state &= ~key_to_state (kevent->keyval);
/* For all modifier keys: call the tools modifier_key_func */
if (active_tool && !gimage_is_empty (gdisp->gimage))
{
@ -556,6 +595,10 @@ gdisplay_canvas_events (GtkWidget *canvas,
break;
}
/* if re reached this point in gimp_busy mode, return now */
if (gimp_busy)
return TRUE;
/* Cursor update support */
/* no_cursor_updating is TRUE (=1) when */
/* <Toolbox>/File/Preferences.../Interface/... */
@ -590,6 +633,9 @@ gdisplay_hruler_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (gimp_busy)
return TRUE;
if (event->button == 1)
{
gdisp = data;
@ -609,6 +655,9 @@ gdisplay_vruler_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (gimp_busy)
return TRUE;
if (event->button == 1)
{
gdisp = data;
@ -628,15 +677,16 @@ gdisplay_origin_button_press (GtkWidget *widget,
{
GDisplay *gdisp;
if (event->button == 1)
if (!gimp_busy && event->button == 1)
{
gdisp = data;
gtk_menu_popup (GTK_MENU (gdisp->popup),
NULL, NULL, NULL, NULL, 1, event->time);
}
/* Stop the signal emission so the button doesn't grab the
* pointer away from us */
/* Stop the signal emission so the button doesn't grab the
* pointer away from us
*/
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "button_press_event");
return FALSE;
@ -656,7 +706,7 @@ gdisplay_drag_drop (GtkWidget *widget,
gdisp = (GDisplay *) data;
if ((src_widget = gtk_drag_get_source_widget (context)))
if (!gimp_busy && (src_widget = gtk_drag_get_source_widget (context)))
{
GimpDrawable *drawable = NULL;
Layer *layer = NULL;
@ -812,6 +862,9 @@ gdisplay_bucket_fill (GtkWidget *widget,
TempBuf *pat_buf = NULL;
gboolean new_buf = FALSE;
if (gimp_busy)
return;
gimage = ((GDisplay *) data)->gimage;
drawable = gimage_active_drawable (gimage);
if (!drawable)

View File

@ -16,8 +16,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
#include <math.h>
#include "appenv.h"
#include "boundary.h"
#include "cursorutil.h"
@ -27,12 +28,14 @@
#include "fuzzy_select.h"
#include "gimage_mask.h"
#include "gimprc.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "rect_select.h"
#include "selection_options.h"
#include "tile.h" /* ick. */
#include "libgimp/gimpmath.h"
#include "libgimp/gimpintl.h"
/* the fuzzy selection structures */
@ -58,18 +61,18 @@ struct _FuzzySelect
typedef struct _FuzzySelectOptions FuzzySelectOptions;
struct _FuzzySelectOptions
{
SelectionOptions selection_options;
double threshold;
double threshold_d;
GtkObject *threshold_w;
SelectionOptions selection_options;
gdouble threshold;
gdouble threshold_d;
GtkObject *threshold_w;
};
/* the fuzzy selection tool options */
static FuzzySelectOptions *fuzzy_options = NULL;
/* XSegments which make up the fuzzy selection boundary */
static GdkSegment * segs = NULL;
static int num_segs = 0;
static GdkSegment *segs = NULL;
static gint num_segs = 0;
Channel * fuzzy_mask = NULL;
@ -89,18 +92,18 @@ static GdkSegment * fuzzy_select_calculate (Tool *, void *, int *);
/*************************************/
/* Fuzzy selection apparatus */
static int
is_pixel_sufficiently_different (unsigned char *col1,
unsigned char *col2,
int antialias,
int threshold,
int bytes,
int has_alpha)
static gint
is_pixel_sufficiently_different (guchar *col1,
guchar *col2,
gboolean antialias,
gint threshold,
gint bytes,
gboolean has_alpha)
{
int diff;
int max;
int b;
int alpha;
gint diff;
gint max;
gint b;
gint alpha;
max = 0;
alpha = (has_alpha) ? bytes - 1 : bytes;
@ -139,14 +142,14 @@ is_pixel_sufficiently_different (unsigned char *col1,
}
static void
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
int x,
int y,
unsigned char **s,
unsigned char **m)
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
gint x,
gint y,
guchar **s,
guchar **m)
{
if (*s_tile != NULL)
tile_release (*s_tile, FALSE);
@ -161,22 +164,23 @@ ref_tiles (TileManager *src,
}
static int
find_contiguous_segment (unsigned char *col,
PixelRegion *src,
PixelRegion *mask,
int width,
int bytes,
int has_alpha,
int antialias,
int threshold,
int initial,
int *start,
int *end)
find_contiguous_segment (guchar *col,
PixelRegion *src,
PixelRegion *mask,
gint width,
gint bytes,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gint initial,
gint *start,
gint *end)
{
unsigned char *s, *m;
unsigned char diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
guchar *s;
guchar *m;
guchar diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
ref_tiles (src->tiles, mask->tiles, &s_tile, &m_tile, src->x, src->y, &s, &m);
@ -232,19 +236,19 @@ find_contiguous_segment (unsigned char *col,
}
static void
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
int has_alpha,
int antialias,
int threshold,
int indexed,
int x,
int y,
unsigned char *col)
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gboolean indexed,
gint x,
gint y,
guchar *col)
{
int start, end, i;
int val;
int bytes;
gint start, end, i;
gint val;
gint bytes;
Tile *tile;
@ -253,8 +257,8 @@ find_contiguous_region_helper (PixelRegion *mask,
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, TRUE, FALSE);
val = *(unsigned char *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
val = *(guchar *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
tile_release (tile, FALSE);
if (val != 0)
return;
@ -267,11 +271,10 @@ find_contiguous_region_helper (PixelRegion *mask,
{
bytes = has_alpha ? 4 : 3;
}
if ( ! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
if (! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
return;
for (i = start + 1; i < end; i++)
@ -286,20 +289,20 @@ find_contiguous_region_helper (PixelRegion *mask,
Channel *
find_contiguous_region (GImage *gimage,
GimpDrawable *drawable,
int antialias,
int threshold,
int x,
int y,
int sample_merged)
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged)
{
PixelRegion srcPR, maskPR;
Channel *mask;
unsigned char *start;
int has_alpha;
int indexed;
int type;
int bytes;
Tile *tile;
Channel *mask;
guchar *start;
gboolean has_alpha;
gboolean indexed;
gint type;
gint bytes;
Tile *tile;
if (sample_merged)
{
@ -313,13 +316,14 @@ find_contiguous_region (GImage *gimage,
else
{
pixel_region_init (&srcPR, drawable_data (drawable), 0, 0,
drawable_width (drawable), drawable_height (drawable), FALSE);
drawable_width (drawable), drawable_height (drawable),
FALSE);
has_alpha = drawable_has_alpha (drawable);
}
indexed = drawable_indexed (drawable);
bytes = drawable_bytes (drawable);
if(indexed)
if (indexed)
{
bytes = has_alpha ? 4 : 3;
}
@ -343,21 +347,14 @@ find_contiguous_region (GImage *gimage,
return mask;
}
static void
fuzzy_select_scale_update (GtkAdjustment *adjustment,
double *scale_val)
{
*scale_val = adjustment->value;
}
void
fuzzy_select (GImage *gimage,
GimpDrawable *drawable,
int op,
int feather,
double feather_radius)
gint op,
gboolean feather,
gdouble feather_radius)
{
int off_x, off_y;
gint off_x, off_y;
/* if applicable, replace the current selection */
if (op == REPLACE)
@ -391,7 +388,7 @@ fuzzy_select_button_press (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
GDisplay *gdisp;
GDisplay *gdisp;
FuzzySelect *fuzzy_sel;
gdisp = (GDisplay *) gdisp_ptr;
@ -436,8 +433,8 @@ fuzzy_select_button_release (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GDisplay * gdisp;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
GimpDrawable *drawable;
gdisp = (GDisplay *) gdisp_ptr;
@ -472,11 +469,11 @@ fuzzy_select_motion (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GdkSegment * new_segs;
int num_new_segs;
int diff_x, diff_y;
double diff;
FuzzySelect *fuzzy_sel;
GdkSegment *new_segs;
gint num_new_segs;
gint diff_x, diff_y;
gdouble diff;
static guint last_time = 0;
@ -523,25 +520,27 @@ fuzzy_select_motion (Tool *tool,
static GdkSegment *
fuzzy_select_calculate (Tool *tool,
void *gdisp_ptr,
int *nsegs)
gint *nsegs)
{
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
int i, x, y;
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
GimpDrawable *drawable;
int use_offsets;
gimp_add_busy_cursors();
gint i;
gint x, y;
gboolean use_offsets;
fuzzy_sel = (FuzzySelect *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
drawable = gimage_active_drawable (gdisp->gimage);
use_offsets = (((SelectionOptions *)fuzzy_options)->sample_merged) ? FALSE : TRUE;
gimp_add_busy_cursors ();
use_offsets =
(((SelectionOptions *) fuzzy_options)->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, fuzzy_sel->x,
fuzzy_sel->y, &x, &y, FALSE, use_offsets);
@ -567,7 +566,7 @@ fuzzy_select_calculate (Tool *tool,
drawable_width (GIMP_DRAWABLE(fuzzy_mask)),
drawable_height (GIMP_DRAWABLE(fuzzy_mask)));
segs = (GdkSegment *) g_malloc (sizeof (GdkSegment) * *nsegs);
segs = g_new (GdkSegment, *nsegs);
for (i = 0; i < *nsegs; i++)
{
@ -588,7 +587,7 @@ fuzzy_select_calculate (Tool *tool,
static void
fuzzy_select_draw (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -601,7 +600,7 @@ fuzzy_select_control (Tool *tool,
ToolAction action,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -645,7 +644,7 @@ fuzzy_select_options_new (void)
GtkWidget *label;
GtkWidget *scale;
options = (FuzzySelectOptions *) g_malloc (sizeof (FuzzySelectOptions));
options = g_new (FuzzySelectOptions, 1);
selection_options_init ((SelectionOptions *) options,
FUZZY_SELECT,
fuzzy_select_options_reset);
@ -670,7 +669,7 @@ fuzzy_select_options_new (void)
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (options->threshold_w), "value_changed",
(GtkSignalFunc) fuzzy_select_scale_update,
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
&options->threshold);
gtk_widget_show (scale);
@ -680,10 +679,10 @@ fuzzy_select_options_new (void)
}
Tool *
tools_new_fuzzy_select ()
tools_new_fuzzy_select (void)
{
Tool * tool;
FuzzySelect * private;
Tool *tool;
FuzzySelect *private;
/* The tool options */
if (! fuzzy_options)
@ -715,7 +714,7 @@ tools_new_fuzzy_select ()
void
tools_free_fuzzy_select (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
draw_core_free (fuzzy_sel->core);

View File

@ -21,18 +21,24 @@
#include "gimage.h"
#include "tools.h"
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *);
/* functions */
Channel * find_contiguous_region (GimpImage *, GimpDrawable *, int, int,
int, int, int);
void fuzzy_select (GimpImage *, GimpDrawable *, int, int,
double);
extern Channel *fuzzy_mask;
#endif /* __FUZZY_SELECT_H__ */
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *tool);
/* functions */
Channel * find_contiguous_region (GimpImage *gimage,
GimpDrawable *drawable,
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged);
void fuzzy_select (GimpImage *gimage,
GimpDrawable *drawable,
gint op,
gboolean feather,
gdouble feather_radius);
#endif /* __FUZZY_SELECT_H__ */

View File

@ -116,6 +116,12 @@ void
gdisplay_close_window (GDisplay *gdisp,
gboolean kill_it)
{
/* FIXME: gimp_busy HACK not really appropriate here because we only
* want to prevent the busy image and display to be closed. --Mitch
*/
if (gimp_busy)
return;
/* If the image has been modified, give the user a chance to save
* it before nuking it--this only applies if its the last view
* to an image canvas. (a gimage with disp_count = 1)

View File

@ -162,6 +162,8 @@ info_dialog_new_extended (gchar *title,
gtk_window_set_title (GTK_WINDOW (shell), title);
session_set_window_geometry (shell, &info_dialog_session_info, FALSE );
dialog_register (shell);
gtk_signal_connect (GTK_OBJECT (shell), "delete_event",
GTK_SIGNAL_FUNC (info_dialog_delete_callback),
idialog);
@ -236,6 +238,8 @@ info_dialog_free (InfoDialog *idialog)
/* Free the actual field linked list */
g_slist_free (idialog->field_list);
dialog_unregister (idialog->shell);
session_get_window_info (idialog->shell, &info_dialog_session_info);
/* Destroy the associated widgets */

View File

@ -162,6 +162,8 @@ info_dialog_new_extended (gchar *title,
gtk_window_set_title (GTK_WINDOW (shell), title);
session_set_window_geometry (shell, &info_dialog_session_info, FALSE );
dialog_register (shell);
gtk_signal_connect (GTK_OBJECT (shell), "delete_event",
GTK_SIGNAL_FUNC (info_dialog_delete_callback),
idialog);
@ -236,6 +238,8 @@ info_dialog_free (InfoDialog *idialog)
/* Free the actual field linked list */
g_slist_free (idialog->field_list);
dialog_unregister (idialog->shell);
session_get_window_info (idialog->shell, &info_dialog_session_info);
/* Destroy the associated widgets */

View File

@ -16,8 +16,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
#include <math.h>
#include "appenv.h"
#include "boundary.h"
#include "cursorutil.h"
@ -27,12 +28,14 @@
#include "fuzzy_select.h"
#include "gimage_mask.h"
#include "gimprc.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "rect_select.h"
#include "selection_options.h"
#include "tile.h" /* ick. */
#include "libgimp/gimpmath.h"
#include "libgimp/gimpintl.h"
/* the fuzzy selection structures */
@ -58,18 +61,18 @@ struct _FuzzySelect
typedef struct _FuzzySelectOptions FuzzySelectOptions;
struct _FuzzySelectOptions
{
SelectionOptions selection_options;
double threshold;
double threshold_d;
GtkObject *threshold_w;
SelectionOptions selection_options;
gdouble threshold;
gdouble threshold_d;
GtkObject *threshold_w;
};
/* the fuzzy selection tool options */
static FuzzySelectOptions *fuzzy_options = NULL;
/* XSegments which make up the fuzzy selection boundary */
static GdkSegment * segs = NULL;
static int num_segs = 0;
static GdkSegment *segs = NULL;
static gint num_segs = 0;
Channel * fuzzy_mask = NULL;
@ -89,18 +92,18 @@ static GdkSegment * fuzzy_select_calculate (Tool *, void *, int *);
/*************************************/
/* Fuzzy selection apparatus */
static int
is_pixel_sufficiently_different (unsigned char *col1,
unsigned char *col2,
int antialias,
int threshold,
int bytes,
int has_alpha)
static gint
is_pixel_sufficiently_different (guchar *col1,
guchar *col2,
gboolean antialias,
gint threshold,
gint bytes,
gboolean has_alpha)
{
int diff;
int max;
int b;
int alpha;
gint diff;
gint max;
gint b;
gint alpha;
max = 0;
alpha = (has_alpha) ? bytes - 1 : bytes;
@ -139,14 +142,14 @@ is_pixel_sufficiently_different (unsigned char *col1,
}
static void
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
int x,
int y,
unsigned char **s,
unsigned char **m)
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
gint x,
gint y,
guchar **s,
guchar **m)
{
if (*s_tile != NULL)
tile_release (*s_tile, FALSE);
@ -161,22 +164,23 @@ ref_tiles (TileManager *src,
}
static int
find_contiguous_segment (unsigned char *col,
PixelRegion *src,
PixelRegion *mask,
int width,
int bytes,
int has_alpha,
int antialias,
int threshold,
int initial,
int *start,
int *end)
find_contiguous_segment (guchar *col,
PixelRegion *src,
PixelRegion *mask,
gint width,
gint bytes,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gint initial,
gint *start,
gint *end)
{
unsigned char *s, *m;
unsigned char diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
guchar *s;
guchar *m;
guchar diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
ref_tiles (src->tiles, mask->tiles, &s_tile, &m_tile, src->x, src->y, &s, &m);
@ -232,19 +236,19 @@ find_contiguous_segment (unsigned char *col,
}
static void
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
int has_alpha,
int antialias,
int threshold,
int indexed,
int x,
int y,
unsigned char *col)
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gboolean indexed,
gint x,
gint y,
guchar *col)
{
int start, end, i;
int val;
int bytes;
gint start, end, i;
gint val;
gint bytes;
Tile *tile;
@ -253,8 +257,8 @@ find_contiguous_region_helper (PixelRegion *mask,
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, TRUE, FALSE);
val = *(unsigned char *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
val = *(guchar *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
tile_release (tile, FALSE);
if (val != 0)
return;
@ -267,11 +271,10 @@ find_contiguous_region_helper (PixelRegion *mask,
{
bytes = has_alpha ? 4 : 3;
}
if ( ! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
if (! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
return;
for (i = start + 1; i < end; i++)
@ -286,20 +289,20 @@ find_contiguous_region_helper (PixelRegion *mask,
Channel *
find_contiguous_region (GImage *gimage,
GimpDrawable *drawable,
int antialias,
int threshold,
int x,
int y,
int sample_merged)
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged)
{
PixelRegion srcPR, maskPR;
Channel *mask;
unsigned char *start;
int has_alpha;
int indexed;
int type;
int bytes;
Tile *tile;
Channel *mask;
guchar *start;
gboolean has_alpha;
gboolean indexed;
gint type;
gint bytes;
Tile *tile;
if (sample_merged)
{
@ -313,13 +316,14 @@ find_contiguous_region (GImage *gimage,
else
{
pixel_region_init (&srcPR, drawable_data (drawable), 0, 0,
drawable_width (drawable), drawable_height (drawable), FALSE);
drawable_width (drawable), drawable_height (drawable),
FALSE);
has_alpha = drawable_has_alpha (drawable);
}
indexed = drawable_indexed (drawable);
bytes = drawable_bytes (drawable);
if(indexed)
if (indexed)
{
bytes = has_alpha ? 4 : 3;
}
@ -343,21 +347,14 @@ find_contiguous_region (GImage *gimage,
return mask;
}
static void
fuzzy_select_scale_update (GtkAdjustment *adjustment,
double *scale_val)
{
*scale_val = adjustment->value;
}
void
fuzzy_select (GImage *gimage,
GimpDrawable *drawable,
int op,
int feather,
double feather_radius)
gint op,
gboolean feather,
gdouble feather_radius)
{
int off_x, off_y;
gint off_x, off_y;
/* if applicable, replace the current selection */
if (op == REPLACE)
@ -391,7 +388,7 @@ fuzzy_select_button_press (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
GDisplay *gdisp;
GDisplay *gdisp;
FuzzySelect *fuzzy_sel;
gdisp = (GDisplay *) gdisp_ptr;
@ -436,8 +433,8 @@ fuzzy_select_button_release (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GDisplay * gdisp;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
GimpDrawable *drawable;
gdisp = (GDisplay *) gdisp_ptr;
@ -472,11 +469,11 @@ fuzzy_select_motion (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GdkSegment * new_segs;
int num_new_segs;
int diff_x, diff_y;
double diff;
FuzzySelect *fuzzy_sel;
GdkSegment *new_segs;
gint num_new_segs;
gint diff_x, diff_y;
gdouble diff;
static guint last_time = 0;
@ -523,25 +520,27 @@ fuzzy_select_motion (Tool *tool,
static GdkSegment *
fuzzy_select_calculate (Tool *tool,
void *gdisp_ptr,
int *nsegs)
gint *nsegs)
{
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
int i, x, y;
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
GimpDrawable *drawable;
int use_offsets;
gimp_add_busy_cursors();
gint i;
gint x, y;
gboolean use_offsets;
fuzzy_sel = (FuzzySelect *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
drawable = gimage_active_drawable (gdisp->gimage);
use_offsets = (((SelectionOptions *)fuzzy_options)->sample_merged) ? FALSE : TRUE;
gimp_add_busy_cursors ();
use_offsets =
(((SelectionOptions *) fuzzy_options)->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, fuzzy_sel->x,
fuzzy_sel->y, &x, &y, FALSE, use_offsets);
@ -567,7 +566,7 @@ fuzzy_select_calculate (Tool *tool,
drawable_width (GIMP_DRAWABLE(fuzzy_mask)),
drawable_height (GIMP_DRAWABLE(fuzzy_mask)));
segs = (GdkSegment *) g_malloc (sizeof (GdkSegment) * *nsegs);
segs = g_new (GdkSegment, *nsegs);
for (i = 0; i < *nsegs; i++)
{
@ -588,7 +587,7 @@ fuzzy_select_calculate (Tool *tool,
static void
fuzzy_select_draw (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -601,7 +600,7 @@ fuzzy_select_control (Tool *tool,
ToolAction action,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -645,7 +644,7 @@ fuzzy_select_options_new (void)
GtkWidget *label;
GtkWidget *scale;
options = (FuzzySelectOptions *) g_malloc (sizeof (FuzzySelectOptions));
options = g_new (FuzzySelectOptions, 1);
selection_options_init ((SelectionOptions *) options,
FUZZY_SELECT,
fuzzy_select_options_reset);
@ -670,7 +669,7 @@ fuzzy_select_options_new (void)
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (options->threshold_w), "value_changed",
(GtkSignalFunc) fuzzy_select_scale_update,
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
&options->threshold);
gtk_widget_show (scale);
@ -680,10 +679,10 @@ fuzzy_select_options_new (void)
}
Tool *
tools_new_fuzzy_select ()
tools_new_fuzzy_select (void)
{
Tool * tool;
FuzzySelect * private;
Tool *tool;
FuzzySelect *private;
/* The tool options */
if (! fuzzy_options)
@ -715,7 +714,7 @@ tools_new_fuzzy_select ()
void
tools_free_fuzzy_select (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
draw_core_free (fuzzy_sel->core);

View File

@ -21,18 +21,24 @@
#include "gimage.h"
#include "tools.h"
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *);
/* functions */
Channel * find_contiguous_region (GimpImage *, GimpDrawable *, int, int,
int, int, int);
void fuzzy_select (GimpImage *, GimpDrawable *, int, int,
double);
extern Channel *fuzzy_mask;
#endif /* __FUZZY_SELECT_H__ */
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *tool);
/* functions */
Channel * find_contiguous_region (GimpImage *gimage,
GimpDrawable *drawable,
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged);
void fuzzy_select (GimpImage *gimage,
GimpDrawable *drawable,
gint op,
gboolean feather,
gdouble feather_radius);
#endif /* __FUZZY_SELECT_H__ */

View File

@ -16,8 +16,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
#include <math.h>
#include "appenv.h"
#include "boundary.h"
#include "cursorutil.h"
@ -27,12 +28,14 @@
#include "fuzzy_select.h"
#include "gimage_mask.h"
#include "gimprc.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "rect_select.h"
#include "selection_options.h"
#include "tile.h" /* ick. */
#include "libgimp/gimpmath.h"
#include "libgimp/gimpintl.h"
/* the fuzzy selection structures */
@ -58,18 +61,18 @@ struct _FuzzySelect
typedef struct _FuzzySelectOptions FuzzySelectOptions;
struct _FuzzySelectOptions
{
SelectionOptions selection_options;
double threshold;
double threshold_d;
GtkObject *threshold_w;
SelectionOptions selection_options;
gdouble threshold;
gdouble threshold_d;
GtkObject *threshold_w;
};
/* the fuzzy selection tool options */
static FuzzySelectOptions *fuzzy_options = NULL;
/* XSegments which make up the fuzzy selection boundary */
static GdkSegment * segs = NULL;
static int num_segs = 0;
static GdkSegment *segs = NULL;
static gint num_segs = 0;
Channel * fuzzy_mask = NULL;
@ -89,18 +92,18 @@ static GdkSegment * fuzzy_select_calculate (Tool *, void *, int *);
/*************************************/
/* Fuzzy selection apparatus */
static int
is_pixel_sufficiently_different (unsigned char *col1,
unsigned char *col2,
int antialias,
int threshold,
int bytes,
int has_alpha)
static gint
is_pixel_sufficiently_different (guchar *col1,
guchar *col2,
gboolean antialias,
gint threshold,
gint bytes,
gboolean has_alpha)
{
int diff;
int max;
int b;
int alpha;
gint diff;
gint max;
gint b;
gint alpha;
max = 0;
alpha = (has_alpha) ? bytes - 1 : bytes;
@ -139,14 +142,14 @@ is_pixel_sufficiently_different (unsigned char *col1,
}
static void
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
int x,
int y,
unsigned char **s,
unsigned char **m)
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
gint x,
gint y,
guchar **s,
guchar **m)
{
if (*s_tile != NULL)
tile_release (*s_tile, FALSE);
@ -161,22 +164,23 @@ ref_tiles (TileManager *src,
}
static int
find_contiguous_segment (unsigned char *col,
PixelRegion *src,
PixelRegion *mask,
int width,
int bytes,
int has_alpha,
int antialias,
int threshold,
int initial,
int *start,
int *end)
find_contiguous_segment (guchar *col,
PixelRegion *src,
PixelRegion *mask,
gint width,
gint bytes,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gint initial,
gint *start,
gint *end)
{
unsigned char *s, *m;
unsigned char diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
guchar *s;
guchar *m;
guchar diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
ref_tiles (src->tiles, mask->tiles, &s_tile, &m_tile, src->x, src->y, &s, &m);
@ -232,19 +236,19 @@ find_contiguous_segment (unsigned char *col,
}
static void
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
int has_alpha,
int antialias,
int threshold,
int indexed,
int x,
int y,
unsigned char *col)
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gboolean indexed,
gint x,
gint y,
guchar *col)
{
int start, end, i;
int val;
int bytes;
gint start, end, i;
gint val;
gint bytes;
Tile *tile;
@ -253,8 +257,8 @@ find_contiguous_region_helper (PixelRegion *mask,
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, TRUE, FALSE);
val = *(unsigned char *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
val = *(guchar *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
tile_release (tile, FALSE);
if (val != 0)
return;
@ -267,11 +271,10 @@ find_contiguous_region_helper (PixelRegion *mask,
{
bytes = has_alpha ? 4 : 3;
}
if ( ! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
if (! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
return;
for (i = start + 1; i < end; i++)
@ -286,20 +289,20 @@ find_contiguous_region_helper (PixelRegion *mask,
Channel *
find_contiguous_region (GImage *gimage,
GimpDrawable *drawable,
int antialias,
int threshold,
int x,
int y,
int sample_merged)
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged)
{
PixelRegion srcPR, maskPR;
Channel *mask;
unsigned char *start;
int has_alpha;
int indexed;
int type;
int bytes;
Tile *tile;
Channel *mask;
guchar *start;
gboolean has_alpha;
gboolean indexed;
gint type;
gint bytes;
Tile *tile;
if (sample_merged)
{
@ -313,13 +316,14 @@ find_contiguous_region (GImage *gimage,
else
{
pixel_region_init (&srcPR, drawable_data (drawable), 0, 0,
drawable_width (drawable), drawable_height (drawable), FALSE);
drawable_width (drawable), drawable_height (drawable),
FALSE);
has_alpha = drawable_has_alpha (drawable);
}
indexed = drawable_indexed (drawable);
bytes = drawable_bytes (drawable);
if(indexed)
if (indexed)
{
bytes = has_alpha ? 4 : 3;
}
@ -343,21 +347,14 @@ find_contiguous_region (GImage *gimage,
return mask;
}
static void
fuzzy_select_scale_update (GtkAdjustment *adjustment,
double *scale_val)
{
*scale_val = adjustment->value;
}
void
fuzzy_select (GImage *gimage,
GimpDrawable *drawable,
int op,
int feather,
double feather_radius)
gint op,
gboolean feather,
gdouble feather_radius)
{
int off_x, off_y;
gint off_x, off_y;
/* if applicable, replace the current selection */
if (op == REPLACE)
@ -391,7 +388,7 @@ fuzzy_select_button_press (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
GDisplay *gdisp;
GDisplay *gdisp;
FuzzySelect *fuzzy_sel;
gdisp = (GDisplay *) gdisp_ptr;
@ -436,8 +433,8 @@ fuzzy_select_button_release (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GDisplay * gdisp;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
GimpDrawable *drawable;
gdisp = (GDisplay *) gdisp_ptr;
@ -472,11 +469,11 @@ fuzzy_select_motion (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GdkSegment * new_segs;
int num_new_segs;
int diff_x, diff_y;
double diff;
FuzzySelect *fuzzy_sel;
GdkSegment *new_segs;
gint num_new_segs;
gint diff_x, diff_y;
gdouble diff;
static guint last_time = 0;
@ -523,25 +520,27 @@ fuzzy_select_motion (Tool *tool,
static GdkSegment *
fuzzy_select_calculate (Tool *tool,
void *gdisp_ptr,
int *nsegs)
gint *nsegs)
{
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
int i, x, y;
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
GimpDrawable *drawable;
int use_offsets;
gimp_add_busy_cursors();
gint i;
gint x, y;
gboolean use_offsets;
fuzzy_sel = (FuzzySelect *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
drawable = gimage_active_drawable (gdisp->gimage);
use_offsets = (((SelectionOptions *)fuzzy_options)->sample_merged) ? FALSE : TRUE;
gimp_add_busy_cursors ();
use_offsets =
(((SelectionOptions *) fuzzy_options)->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, fuzzy_sel->x,
fuzzy_sel->y, &x, &y, FALSE, use_offsets);
@ -567,7 +566,7 @@ fuzzy_select_calculate (Tool *tool,
drawable_width (GIMP_DRAWABLE(fuzzy_mask)),
drawable_height (GIMP_DRAWABLE(fuzzy_mask)));
segs = (GdkSegment *) g_malloc (sizeof (GdkSegment) * *nsegs);
segs = g_new (GdkSegment, *nsegs);
for (i = 0; i < *nsegs; i++)
{
@ -588,7 +587,7 @@ fuzzy_select_calculate (Tool *tool,
static void
fuzzy_select_draw (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -601,7 +600,7 @@ fuzzy_select_control (Tool *tool,
ToolAction action,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -645,7 +644,7 @@ fuzzy_select_options_new (void)
GtkWidget *label;
GtkWidget *scale;
options = (FuzzySelectOptions *) g_malloc (sizeof (FuzzySelectOptions));
options = g_new (FuzzySelectOptions, 1);
selection_options_init ((SelectionOptions *) options,
FUZZY_SELECT,
fuzzy_select_options_reset);
@ -670,7 +669,7 @@ fuzzy_select_options_new (void)
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (options->threshold_w), "value_changed",
(GtkSignalFunc) fuzzy_select_scale_update,
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
&options->threshold);
gtk_widget_show (scale);
@ -680,10 +679,10 @@ fuzzy_select_options_new (void)
}
Tool *
tools_new_fuzzy_select ()
tools_new_fuzzy_select (void)
{
Tool * tool;
FuzzySelect * private;
Tool *tool;
FuzzySelect *private;
/* The tool options */
if (! fuzzy_options)
@ -715,7 +714,7 @@ tools_new_fuzzy_select ()
void
tools_free_fuzzy_select (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
draw_core_free (fuzzy_sel->core);

View File

@ -21,18 +21,24 @@
#include "gimage.h"
#include "tools.h"
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *);
/* functions */
Channel * find_contiguous_region (GimpImage *, GimpDrawable *, int, int,
int, int, int);
void fuzzy_select (GimpImage *, GimpDrawable *, int, int,
double);
extern Channel *fuzzy_mask;
#endif /* __FUZZY_SELECT_H__ */
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *tool);
/* functions */
Channel * find_contiguous_region (GimpImage *gimage,
GimpDrawable *drawable,
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged);
void fuzzy_select (GimpImage *gimage,
GimpDrawable *drawable,
gint op,
gboolean feather,
gdouble feather_radius);
#endif /* __FUZZY_SELECT_H__ */

View File

@ -16,8 +16,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdlib.h>
#include <math.h>
#include "appenv.h"
#include "boundary.h"
#include "cursorutil.h"
@ -27,12 +28,14 @@
#include "fuzzy_select.h"
#include "gimage_mask.h"
#include "gimprc.h"
#include "gimpui.h"
#include "gdisplay.h"
#include "rect_select.h"
#include "selection_options.h"
#include "tile.h" /* ick. */
#include "libgimp/gimpmath.h"
#include "libgimp/gimpintl.h"
/* the fuzzy selection structures */
@ -58,18 +61,18 @@ struct _FuzzySelect
typedef struct _FuzzySelectOptions FuzzySelectOptions;
struct _FuzzySelectOptions
{
SelectionOptions selection_options;
double threshold;
double threshold_d;
GtkObject *threshold_w;
SelectionOptions selection_options;
gdouble threshold;
gdouble threshold_d;
GtkObject *threshold_w;
};
/* the fuzzy selection tool options */
static FuzzySelectOptions *fuzzy_options = NULL;
/* XSegments which make up the fuzzy selection boundary */
static GdkSegment * segs = NULL;
static int num_segs = 0;
static GdkSegment *segs = NULL;
static gint num_segs = 0;
Channel * fuzzy_mask = NULL;
@ -89,18 +92,18 @@ static GdkSegment * fuzzy_select_calculate (Tool *, void *, int *);
/*************************************/
/* Fuzzy selection apparatus */
static int
is_pixel_sufficiently_different (unsigned char *col1,
unsigned char *col2,
int antialias,
int threshold,
int bytes,
int has_alpha)
static gint
is_pixel_sufficiently_different (guchar *col1,
guchar *col2,
gboolean antialias,
gint threshold,
gint bytes,
gboolean has_alpha)
{
int diff;
int max;
int b;
int alpha;
gint diff;
gint max;
gint b;
gint alpha;
max = 0;
alpha = (has_alpha) ? bytes - 1 : bytes;
@ -139,14 +142,14 @@ is_pixel_sufficiently_different (unsigned char *col1,
}
static void
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
int x,
int y,
unsigned char **s,
unsigned char **m)
ref_tiles (TileManager *src,
TileManager *mask,
Tile **s_tile,
Tile **m_tile,
gint x,
gint y,
guchar **s,
guchar **m)
{
if (*s_tile != NULL)
tile_release (*s_tile, FALSE);
@ -161,22 +164,23 @@ ref_tiles (TileManager *src,
}
static int
find_contiguous_segment (unsigned char *col,
PixelRegion *src,
PixelRegion *mask,
int width,
int bytes,
int has_alpha,
int antialias,
int threshold,
int initial,
int *start,
int *end)
find_contiguous_segment (guchar *col,
PixelRegion *src,
PixelRegion *mask,
gint width,
gint bytes,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gint initial,
gint *start,
gint *end)
{
unsigned char *s, *m;
unsigned char diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
guchar *s;
guchar *m;
guchar diff;
Tile *s_tile = NULL;
Tile *m_tile = NULL;
ref_tiles (src->tiles, mask->tiles, &s_tile, &m_tile, src->x, src->y, &s, &m);
@ -232,19 +236,19 @@ find_contiguous_segment (unsigned char *col,
}
static void
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
int has_alpha,
int antialias,
int threshold,
int indexed,
int x,
int y,
unsigned char *col)
find_contiguous_region_helper (PixelRegion *mask,
PixelRegion *src,
gboolean has_alpha,
gboolean antialias,
gint threshold,
gboolean indexed,
gint x,
gint y,
guchar *col)
{
int start, end, i;
int val;
int bytes;
gint start, end, i;
gint val;
gint bytes;
Tile *tile;
@ -253,8 +257,8 @@ find_contiguous_region_helper (PixelRegion *mask,
if (y < 0 || y >= src->h) return;
tile = tile_manager_get_tile (mask->tiles, x, y, TRUE, FALSE);
val = *(unsigned char *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
val = *(guchar *)(tile_data_pointer (tile,
x % TILE_WIDTH, y % TILE_HEIGHT));
tile_release (tile, FALSE);
if (val != 0)
return;
@ -267,11 +271,10 @@ find_contiguous_region_helper (PixelRegion *mask,
{
bytes = has_alpha ? 4 : 3;
}
if ( ! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
if (! find_contiguous_segment (col, src, mask, src->w,
src->bytes, has_alpha,
antialias, threshold, x, &start, &end))
return;
for (i = start + 1; i < end; i++)
@ -286,20 +289,20 @@ find_contiguous_region_helper (PixelRegion *mask,
Channel *
find_contiguous_region (GImage *gimage,
GimpDrawable *drawable,
int antialias,
int threshold,
int x,
int y,
int sample_merged)
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged)
{
PixelRegion srcPR, maskPR;
Channel *mask;
unsigned char *start;
int has_alpha;
int indexed;
int type;
int bytes;
Tile *tile;
Channel *mask;
guchar *start;
gboolean has_alpha;
gboolean indexed;
gint type;
gint bytes;
Tile *tile;
if (sample_merged)
{
@ -313,13 +316,14 @@ find_contiguous_region (GImage *gimage,
else
{
pixel_region_init (&srcPR, drawable_data (drawable), 0, 0,
drawable_width (drawable), drawable_height (drawable), FALSE);
drawable_width (drawable), drawable_height (drawable),
FALSE);
has_alpha = drawable_has_alpha (drawable);
}
indexed = drawable_indexed (drawable);
bytes = drawable_bytes (drawable);
if(indexed)
if (indexed)
{
bytes = has_alpha ? 4 : 3;
}
@ -343,21 +347,14 @@ find_contiguous_region (GImage *gimage,
return mask;
}
static void
fuzzy_select_scale_update (GtkAdjustment *adjustment,
double *scale_val)
{
*scale_val = adjustment->value;
}
void
fuzzy_select (GImage *gimage,
GimpDrawable *drawable,
int op,
int feather,
double feather_radius)
gint op,
gboolean feather,
gdouble feather_radius)
{
int off_x, off_y;
gint off_x, off_y;
/* if applicable, replace the current selection */
if (op == REPLACE)
@ -391,7 +388,7 @@ fuzzy_select_button_press (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
GDisplay *gdisp;
GDisplay *gdisp;
FuzzySelect *fuzzy_sel;
gdisp = (GDisplay *) gdisp_ptr;
@ -436,8 +433,8 @@ fuzzy_select_button_release (Tool *tool,
GdkEventButton *bevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GDisplay * gdisp;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
GimpDrawable *drawable;
gdisp = (GDisplay *) gdisp_ptr;
@ -472,11 +469,11 @@ fuzzy_select_motion (Tool *tool,
GdkEventMotion *mevent,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
GdkSegment * new_segs;
int num_new_segs;
int diff_x, diff_y;
double diff;
FuzzySelect *fuzzy_sel;
GdkSegment *new_segs;
gint num_new_segs;
gint diff_x, diff_y;
gdouble diff;
static guint last_time = 0;
@ -523,25 +520,27 @@ fuzzy_select_motion (Tool *tool,
static GdkSegment *
fuzzy_select_calculate (Tool *tool,
void *gdisp_ptr,
int *nsegs)
gint *nsegs)
{
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
int i, x, y;
PixelRegion maskPR;
FuzzySelect *fuzzy_sel;
GDisplay *gdisp;
Channel *new;
GdkSegment *segs;
BoundSeg *bsegs;
GimpDrawable *drawable;
int use_offsets;
gimp_add_busy_cursors();
gint i;
gint x, y;
gboolean use_offsets;
fuzzy_sel = (FuzzySelect *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
drawable = gimage_active_drawable (gdisp->gimage);
use_offsets = (((SelectionOptions *)fuzzy_options)->sample_merged) ? FALSE : TRUE;
gimp_add_busy_cursors ();
use_offsets =
(((SelectionOptions *) fuzzy_options)->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, fuzzy_sel->x,
fuzzy_sel->y, &x, &y, FALSE, use_offsets);
@ -567,7 +566,7 @@ fuzzy_select_calculate (Tool *tool,
drawable_width (GIMP_DRAWABLE(fuzzy_mask)),
drawable_height (GIMP_DRAWABLE(fuzzy_mask)));
segs = (GdkSegment *) g_malloc (sizeof (GdkSegment) * *nsegs);
segs = g_new (GdkSegment, *nsegs);
for (i = 0; i < *nsegs; i++)
{
@ -588,7 +587,7 @@ fuzzy_select_calculate (Tool *tool,
static void
fuzzy_select_draw (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -601,7 +600,7 @@ fuzzy_select_control (Tool *tool,
ToolAction action,
gpointer gdisp_ptr)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -645,7 +644,7 @@ fuzzy_select_options_new (void)
GtkWidget *label;
GtkWidget *scale;
options = (FuzzySelectOptions *) g_malloc (sizeof (FuzzySelectOptions));
options = g_new (FuzzySelectOptions, 1);
selection_options_init ((SelectionOptions *) options,
FUZZY_SELECT,
fuzzy_select_options_reset);
@ -670,7 +669,7 @@ fuzzy_select_options_new (void)
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (options->threshold_w), "value_changed",
(GtkSignalFunc) fuzzy_select_scale_update,
GTK_SIGNAL_FUNC (gimp_double_adjustment_update),
&options->threshold);
gtk_widget_show (scale);
@ -680,10 +679,10 @@ fuzzy_select_options_new (void)
}
Tool *
tools_new_fuzzy_select ()
tools_new_fuzzy_select (void)
{
Tool * tool;
FuzzySelect * private;
Tool *tool;
FuzzySelect *private;
/* The tool options */
if (! fuzzy_options)
@ -715,7 +714,7 @@ tools_new_fuzzy_select ()
void
tools_free_fuzzy_select (Tool *tool)
{
FuzzySelect * fuzzy_sel;
FuzzySelect *fuzzy_sel;
fuzzy_sel = (FuzzySelect *) tool->private;
draw_core_free (fuzzy_sel->core);

View File

@ -21,18 +21,24 @@
#include "gimage.h"
#include "tools.h"
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *);
/* functions */
Channel * find_contiguous_region (GimpImage *, GimpDrawable *, int, int,
int, int, int);
void fuzzy_select (GimpImage *, GimpDrawable *, int, int,
double);
extern Channel *fuzzy_mask;
#endif /* __FUZZY_SELECT_H__ */
/* fuzzy select functions */
Tool * tools_new_fuzzy_select (void);
void tools_free_fuzzy_select (Tool *tool);
/* functions */
Channel * find_contiguous_region (GimpImage *gimage,
GimpDrawable *drawable,
gboolean antialias,
gint threshold,
gint x,
gint y,
gboolean sample_merged);
void fuzzy_select (GimpImage *gimage,
GimpDrawable *drawable,
gint op,
gboolean feather,
gdouble feather_radius);
#endif /* __FUZZY_SELECT_H__ */

View File

@ -61,7 +61,10 @@ typedef struct
gint x_hot, y_hot;
GdkCursor *cursor;
} BM_Cursor;
/* FIXME: gimp_busy HACK */
gboolean gimp_busy = FALSE;
static BM_Cursor gimp_cursors[] =
/* these have to match up with the enum in cursorutil.h */
{
@ -232,6 +235,9 @@ 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))
{
@ -263,6 +269,9 @@ gimp_remove_busy_cursors (gpointer data)
pending_removebusy = FALSE;
/* FIXME: gimp_busy HACK */
gimp_busy = FALSE;
return 0;
}

View File

@ -28,6 +28,9 @@
#include <gtk/gtk.h>
/* FIXME: gimp_busy HACK */
extern gboolean gimp_busy;
typedef enum
{
GIMP_MOUSE_CURSOR = (GDK_LAST_CURSOR + 2),