Commit c1c876a9 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

Some DND fixes / cleanup:

2005-07-25  Michael Natterer  <mitch@gimp.org>

	Some DND fixes / cleanup:

	* app/widgets/widgets-enums.h: renamed GIMP_DND_TYPE_TOOL to
	GIMP_DND_TYPE_TOOL_INFO.

	* app/widgets/gimpselectiondata.[ch]: s/tool/tool_info/g. Moved
	private functions to the end of the file. Include GIMP's PID in
	all GtkSelectionData strings which are used to pass around stuff
	by reference. For things which are referenced by name, also encode
	the object's address in the GtkSelectionData so having a brush
	called "Standard" or a named buffer called "Global Buffer" will
	work together with DND.

	* app/widgets/gimpdnd.[ch]: s/tool/tool_info/g. Renamed
	gimp_dnd_get_data_data() to gimp_dnd_get_object_data() since it's
	not limited to GimpData objects. Follow above selection data API
	changes. Cleanup.

	* libgimp/gimpbrushmenu.c
	* libgimp/gimpdrawablecombobox.c
	* libgimp/gimpfontselectbutton.c
	* libgimp/gimpgradientmenu.c
	* libgimp/gimpimagecombobox.c
	* libgimp/gimppalettemenu.c
	* libgimp/gimppatternmenu.c: follow GtkSelectionData format change
	and check the dropped things' PID against the return value of
	gimp_getpid().
parent 1999d56e
2005-07-25 Michael Natterer <mitch@gimp.org>
Some DND fixes / cleanup:
* app/widgets/widgets-enums.h: renamed GIMP_DND_TYPE_TOOL to
GIMP_DND_TYPE_TOOL_INFO.
* app/widgets/gimpselectiondata.[ch]: s/tool/tool_info/g. Moved
private functions to the end of the file. Include GIMP's PID in
all GtkSelectionData strings which are used to pass around stuff
by reference. For things which are referenced by name, also encode
the object's address in the GtkSelectionData so having a brush
called "Standard" or a named buffer called "Global Buffer" will
work together with DND.
* app/widgets/gimpdnd.[ch]: s/tool/tool_info/g. Renamed
gimp_dnd_get_data_data() to gimp_dnd_get_object_data() since it's
not limited to GimpData objects. Follow above selection data API
changes. Cleanup.
* libgimp/gimpbrushmenu.c
* libgimp/gimpdrawablecombobox.c
* libgimp/gimpfontselectbutton.c
* libgimp/gimpgradientmenu.c
* libgimp/gimpimagecombobox.c
* libgimp/gimppalettemenu.c
* libgimp/gimppatternmenu.c: follow GtkSelectionData format change
and check the dropped things' PID against the return value of
gimp_getpid().
2005-07-25 Sven Neumann <sven@gimp.org>
* tools/pdbgen/pdb/misc.pdb: on Win32, include <process.h> for
......
......@@ -201,10 +201,10 @@ static gboolean gimp_dnd_set_item_data (GtkWidget *widget,
gpointer set_item_data,
GtkSelectionData *selection);
static void gimp_dnd_get_data_data (GtkWidget *widget,
static void gimp_dnd_get_object_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_data_func,
gpointer get_data_data,
GCallback get_object_func,
gpointer get_object_data,
GtkSelectionData *selection);
static gboolean gimp_dnd_set_brush_data (GtkWidget *widget,
......@@ -255,11 +255,11 @@ static gboolean gimp_dnd_set_template_data (GtkWidget *widget,
GCallback set_template_func,
gpointer set_template_data,
GtkSelectionData *selection);
static gboolean gimp_dnd_set_tool_data (GtkWidget *widget,
static gboolean gimp_dnd_set_tool_info_data (GtkWidget *widget,
gint x,
gint y,
GCallback set_tool_func,
gpointer set_tool_data,
GCallback set_tool_info_func,
gpointer set_tool_info_data,
GtkSelectionData *selection);
......@@ -483,7 +483,7 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-brush-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_brush_data
},
......@@ -497,7 +497,7 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-pattern-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_pattern_data
},
......@@ -511,7 +511,7 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-gradient-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_gradient_data
},
......@@ -525,7 +525,7 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-palette-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_palette_data
},
......@@ -539,7 +539,7 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-font-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_font_data
},
......@@ -553,7 +553,7 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-buffer-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_buffer_data
},
......@@ -567,7 +567,7 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-imagefile-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_imagefile_data
},
......@@ -581,22 +581,22 @@ static const GimpDndDataDef dnd_data_defs[] =
"gimp-dnd-set-template-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_get_object_data,
gimp_dnd_set_template_data
},
{
GIMP_TARGET_TOOL,
GIMP_TARGET_TOOL_INFO,
"gimp-dnd-get-tool-func",
"gimp-dnd-get-tool-data",
"gimp-dnd-get-tool-info-func",
"gimp-dnd-get-tool-info-data",
"gimp-dnd-set-tool-func",
"gimp-dnd-set-tool-data",
"gimp-dnd-set-tool-info-func",
"gimp-dnd-set-tool-info-data",
gimp_dnd_get_viewable_icon,
gimp_dnd_get_data_data,
gimp_dnd_set_tool_data
gimp_dnd_get_object_data,
gimp_dnd_set_tool_info_data
},
{
......@@ -1803,7 +1803,7 @@ gimp_dnd_data_type_get_by_g_type (GType type)
}
else if (g_type_is_a (type, GIMP_TYPE_TOOL_INFO))
{
dnd_type = GIMP_DND_TYPE_TOOL;
dnd_type = GIMP_DND_TYPE_TOOL_INFO;
}
return dnd_type;
......@@ -1968,9 +1968,9 @@ gimp_dnd_get_drag_data (GtkWidget *widget)
}
/*************************/
/* image dnd functions */
/*************************/
/*****************************/
/* GimpImage dnd functions */
/*****************************/
static void
gimp_dnd_get_image_data (GtkWidget *widget,
......@@ -2009,9 +2009,9 @@ gimp_dnd_set_image_data (GtkWidget *widget,
}
/************************/
/* item dnd functions */
/************************/
/****************************/
/* GimpItem dnd functions */
/****************************/
static void
gimp_dnd_get_item_data (GtkWidget *widget,
......@@ -2050,30 +2050,30 @@ gimp_dnd_set_item_data (GtkWidget *widget,
}
/****************************/
/* GimpData dnd functions */
/****************************/
/******************************/
/* GimpObject dnd functions */
/******************************/
static void
gimp_dnd_get_data_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_data_func,
gpointer get_data_data,
GtkSelectionData *selection)
gimp_dnd_get_object_data (GtkWidget *widget,
GdkDragContext *context,
GCallback get_object_func,
gpointer get_object_data,
GtkSelectionData *selection)
{
GimpData *data;
GimpObject *object;
data = (GimpData *)
(* (GimpDndDragViewableFunc) get_data_func) (widget, get_data_data);
object = (GimpObject *)
(* (GimpDndDragViewableFunc) get_object_func) (widget, get_object_data);
if (data)
gimp_selection_data_set_viewable (selection, GIMP_VIEWABLE (data));
if (GIMP_IS_OBJECT (object))
gimp_selection_data_set_object (selection, object);
}
/*************************/
/* brush dnd functions */
/*************************/
/*****************************/
/* GimpBrush dnd functions */
/*****************************/
static gboolean
gimp_dnd_set_brush_data (GtkWidget *widget,
......@@ -2096,9 +2096,9 @@ gimp_dnd_set_brush_data (GtkWidget *widget,
}
/***************************/
/* pattern dnd functions */
/***************************/
/*******************************/
/* GimpPattern dnd functions */
/*******************************/
static gboolean
gimp_dnd_set_pattern_data (GtkWidget *widget,
......@@ -2122,9 +2122,9 @@ gimp_dnd_set_pattern_data (GtkWidget *widget,
}
/****************************/
/* gradient dnd functions */
/****************************/
/********************************/
/* GimpGradient dnd functions */
/********************************/
static gboolean
gimp_dnd_set_gradient_data (GtkWidget *widget,
......@@ -2148,9 +2148,9 @@ gimp_dnd_set_gradient_data (GtkWidget *widget,
}
/***************************/
/* palette dnd functions */
/***************************/
/*******************************/
/* GimpPalette dnd functions */
/*******************************/
static gboolean
gimp_dnd_set_palette_data (GtkWidget *widget,
......@@ -2174,9 +2174,9 @@ gimp_dnd_set_palette_data (GtkWidget *widget,
}
/************************/
/* font dnd functions */
/************************/
/****************************/
/* GimpFont dnd functions */
/****************************/
static gboolean
gimp_dnd_set_font_data (GtkWidget *widget,
......@@ -2199,9 +2199,9 @@ gimp_dnd_set_font_data (GtkWidget *widget,
}
/**************************/
/* buffer dnd functions */
/**************************/
/******************************/
/* GimpBuffer dnd functions */
/******************************/
static gboolean
gimp_dnd_set_buffer_data (GtkWidget *widget,
......@@ -2224,9 +2224,9 @@ gimp_dnd_set_buffer_data (GtkWidget *widget,
}
/*****************************/
/* imagefile dnd functions */
/*****************************/
/*********************************/
/* GimpImagefile dnd functions */
/*********************************/
static gboolean
gimp_dnd_set_imagefile_data (GtkWidget *widget,
......@@ -2250,9 +2250,9 @@ gimp_dnd_set_imagefile_data (GtkWidget *widget,
}
/*****************************/
/* template dnd functions */
/*****************************/
/********************************/
/* GimpTemplate dnd functions */
/********************************/
static gboolean
gimp_dnd_set_template_data (GtkWidget *widget,
......@@ -2276,27 +2276,27 @@ gimp_dnd_set_template_data (GtkWidget *widget,
}
/************************/
/* tool dnd functions */
/************************/
/********************************/
/* GimpToolInfo dnd functions */
/********************************/
static gboolean
gimp_dnd_set_tool_data (GtkWidget *widget,
gint x,
gint y,
GCallback set_tool_func,
gpointer set_tool_data,
GtkSelectionData *selection)
gimp_dnd_set_tool_info_data (GtkWidget *widget,
gint x,
gint y,
GCallback set_tool_info_func,
gpointer set_tool_info_data,
GtkSelectionData *selection)
{
GimpToolInfo *tool_info = gimp_selection_data_get_tool (selection,
the_dnd_gimp);
GimpToolInfo *tool_info = gimp_selection_data_get_tool_info (selection,
the_dnd_gimp);
if (! tool_info)
return FALSE;
(* (GimpDndDropViewableFunc) set_tool_func) (widget, x, y,
GIMP_VIEWABLE (tool_info),
set_tool_data);
(* (GimpDndDropViewableFunc) set_tool_info_func) (widget, x, y,
GIMP_VIEWABLE (tool_info),
set_tool_info_data);
return TRUE;
}
......@@ -89,8 +89,8 @@
#define GIMP_TARGET_TEMPLATE \
{ "application/x-gimp-template-name", GTK_TARGET_SAME_APP, GIMP_DND_TYPE_TEMPLATE }
#define GIMP_TARGET_TOOL \
{ "application/x-gimp-tool-name", GTK_TARGET_SAME_APP, GIMP_DND_TYPE_TOOL }
#define GIMP_TARGET_TOOL_INFO \
{ "application/x-gimp-tool-info-name", GTK_TARGET_SAME_APP, GIMP_DND_TYPE_TOOL_INFO }
#define GIMP_TARGET_DIALOG \
{ "application/x-gimp-dialog", GTK_TARGET_SAME_APP, GIMP_DND_TYPE_DIALOG }
......
......@@ -21,6 +21,12 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef G_OS_WIN32
#include <process.h> /* getpid() */
#endif
#include <gtk/gtk.h>
......@@ -56,6 +62,20 @@
#endif
/* local function prototypes */
static gchar * gimp_selection_data_get_name (GtkSelectionData *selection);
static GimpObject * gimp_selection_data_get_object (GtkSelectionData *selection,
GimpContainer *container,
GimpObject *additional);
static gchar * gimp_unescape_uri_string (const char *escaped,
int len,
const char *illegal_escaped_characters,
gboolean ascii_must_not_be_escaped);
/* public functions */
void
gimp_selection_data_set_uri_list (GtkSelectionData *selection,
GList *uri_list)
......@@ -91,88 +111,6 @@ gimp_selection_data_set_uri_list (GtkSelectionData *selection,
g_free (vals);
}
/* the next two functions are straight cut'n'paste from glib/glib/gconvert.c,
* except that gimp_unescape_uri_string() does not try to UTF-8 validate
* the unescaped result.
*/
static int
unescape_character (const char *scanner)
{
int first_digit;
int second_digit;
first_digit = g_ascii_xdigit_value (scanner[0]);
if (first_digit < 0)
return -1;
second_digit = g_ascii_xdigit_value (scanner[1]);
if (second_digit < 0)
return -1;
return (first_digit << 4) | second_digit;
}
static gchar *
gimp_unescape_uri_string (const char *escaped,
int len,
const char *illegal_escaped_characters,
gboolean ascii_must_not_be_escaped)
{
const gchar *in, *in_end;
gchar *out, *result;
int c;
if (escaped == NULL)
return NULL;
if (len < 0)
len = strlen (escaped);
result = g_malloc (len + 1);
out = result;
for (in = escaped, in_end = escaped + len; in < in_end; in++)
{
c = *in;
if (c == '%')
{
/* catch partial escape sequences past the end of the substring */
if (in + 3 > in_end)
break;
c = unescape_character (in + 1);
/* catch bad escape sequences and NUL characters */
if (c <= 0)
break;
/* catch escaped ASCII */
if (ascii_must_not_be_escaped && c <= 0x7F)
break;
/* catch other illegal escaped characters */
if (strchr (illegal_escaped_characters, c) != NULL)
break;
in += 2;
}
*out++ = c;
}
g_assert (out - result <= len);
*out = '\0';
if (in != in_end)
{
g_free (result);
return NULL;
}
return result;
}
GList *
gimp_selection_data_get_uri_list (GtkSelectionData *selection)
{
......@@ -433,43 +371,44 @@ void
gimp_selection_data_set_image (GtkSelectionData *selection,
GimpImage *gimage)
{
gchar *id;
gchar *str;
g_return_if_fail (selection != NULL);
g_return_if_fail (GIMP_IS_IMAGE (gimage));
id = g_strdup_printf ("%d", gimp_image_get_ID (gimage));
str = g_strdup_printf ("%d:%d", getpid (), gimp_image_get_ID (gimage));
gtk_selection_data_set (selection, selection->target,
8, (guchar *) id, strlen (id) + 1);
8, (guchar *) str, strlen (str) + 1);
g_free (id);
g_free (str);
}
GimpImage *
gimp_selection_data_get_image (GtkSelectionData *selection,
Gimp *gimp)
{
gchar *id;
gint ID;
GimpImage *image = NULL;
gchar *str;
gint pid;
gint ID;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (selection != NULL, NULL);
if ((selection->format != 8) || (selection->length < 1))
str = gimp_selection_data_get_name (selection);
if (! str)
return NULL;
if (sscanf (str, "%i:%i", &pid, &ID) == 2 &&
pid == getpid ())
{
g_warning ("Received invalid image ID data!");
return NULL;
image = gimp_image_get_by_ID (gimp, ID);
}
id = g_strndup (selection->data, selection->length);
ID = atoi (id);
g_free (id);
if (! ID)
return NULL;
g_free (str);
return gimp_image_get_by_ID (gimp, ID);
return image;
}
void
......@@ -477,17 +416,18 @@ gimp_selection_data_set_component (GtkSelectionData *selection,
GimpImage *gimage,
GimpChannelType channel)
{
gchar *id;
gchar *str;
g_return_if_fail (selection != NULL);
g_return_if_fail (GIMP_IS_IMAGE (gimage));
id = g_strdup_printf ("%d:%d", gimp_image_get_ID (gimage), (gint) channel);
str = g_strdup_printf ("%d:%d:%d", getpid (), gimp_image_get_ID (gimage),
(gint) channel);
gtk_selection_data_set (selection, selection->target,
8, (guchar *) id, strlen (id) + 1);
8, (guchar *) str, strlen (str) + 1);
g_free (id);
g_free (str);
}
GimpImage *
......@@ -495,382 +435,379 @@ gimp_selection_data_get_component (GtkSelectionData *selection,
Gimp *gimp,
GimpChannelType *channel)
{
gchar *id;
gint ID;
gint ch;
GimpImage *image = NULL;
gchar *str;
gint pid;
gint ID;
gint ch;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (selection != NULL, NULL);
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid image ID data!");
return NULL;
}
if (channel)
*channel = 0;
id = g_strndup (selection->data, selection->length);
str = gimp_selection_data_get_name (selection);
if (! str)
return NULL;
if (sscanf (id, "%i:%i", &ID, &ch) != 2)
if (sscanf (str, "%i:%i:%i", &pid, &ID, &ch) == 3 &&
pid == getpid ())
{
g_free (id);
return NULL;
}
g_free (id);
image = gimp_image_get_by_ID (gimp, ID);
if (! ID)
return NULL;
if (image && channel)
*channel = ch;
}
if (channel)
*channel = ch;
g_free (str);
return gimp_image_get_by_ID (gimp, ID);
return image;
}
void
gimp_selection_data_set_item (GtkSelectionData *selection,
GimpItem *item)
{
gchar *id;
gchar *str;
g_return_if_fail (selection != NULL);
g_return_if_fail (GIMP_IS_ITEM (item));
id = g_strdup_printf ("%d", gimp_item_get_ID (item));
str = g_strdup_printf ("%d:%d", getpid (), gimp_item_get_ID (item));
gtk_selection_data_set (selection, selection->target,
8, (guchar *) id, strlen (id) + 1);
8, (guchar *) str, strlen (str) + 1);
g_free (id);
g_free (str);
}
GimpItem *
gimp_selection_data_get_item (GtkSelectionData *selection,
Gimp *gimp)
{
gchar *id;
gint ID;
GimpItem *item = NULL;
gchar *str;
gint pid;
gint ID;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (selection != NULL, NULL);
if ((selection->format != 8) || (selection->length < 1))
str = gimp_selection_data_get_name (selection);
if (! str)
return NULL;
if (sscanf (str, "%i:%i", &pid, &ID) == 2 &&
pid == getpid ())
{
g_warning ("Received invalid item ID data!");
return NULL;
item = gimp_item_get_by_ID (gimp, ID);
}
id = g_strndup (selection->data, selection->length);
ID = atoi (id);
g_free (id);
if (! ID)
return NULL;
g_free (str);
return gimp_item_get_by_ID (gimp, ID);
return item;
}
void
gimp_selection_data_set_viewable (GtkSelectionData *selection,
GimpViewable *viewable)
gimp_selection_data_set_object (GtkSelectionData *selection,
GimpObject *object)
{
const gchar *name;
g_return_if_fail (selection != NULL);
g_return_if_fail (GIMP_IS_VIEWABLE (viewable));
g_return_if_fail (GIMP_IS_OBJECT (object));
name = gimp_object_get_name (GIMP_OBJECT (viewable));
name = gimp_object_get_name (object);
if (name)
gtk_selection_data_set (selection, selection->target,
8, (const guchar *) name, strlen (name) + 1);
}
static gchar *
gimp_selection_data_get_name (GtkSelectionData *selection)
{
gchar *name = g_strndup (selection->data, selection->length);
if (! g_utf8_validate (name, -1, NULL))
{
g_warning ("Received invalid selection data "
"(doesn't validate as UTF-8)!");
g_free (name);
return NULL;
}
gchar *str;
return name;
str = g_strdup_printf ("%d:%p:%s", getpid (), object, name);
gtk_selection_data_set (selection, selection->target,
8, (guchar *) str, strlen (str) + 1);
g_free (str);
}
}
GimpBrush *
gimp_selection_data_get_brush (GtkSelectionData *selection,
Gimp *gimp)
{
GimpBrush *brush;
gchar *name;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (selection != NULL, NULL);
if ((selection->format != 8) || (selection->length < 1))
{
g_warning ("Received invalid brush data!");