home *** CD-ROM | disk | FTP | other *** search
- /* The GIMP -- an image manipulation program
- * Copyright (C) 1995-1997 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 <string.h>
-
- #include "fileops.h"
- #include "gimage.h"
- #include "gimpcontextpreview.h"
- #include "gimpdnd.h"
- #include "gimpbrushlist.h"
- #include "gimprc.h"
- #include "gradient_header.h"
- #include "tools.h"
-
- #include "libgimp/gimplimits.h"
-
- #define DRAG_PREVIEW_SIZE 32
-
- #define DRAG_ICON_OFFSET -8
-
- typedef enum
- {
- GIMP_DND_DATA_COLOR = 1,
- GIMP_DND_DATA_BRUSH,
- GIMP_DND_DATA_PATTERN,
- GIMP_DND_DATA_GRADIENT,
- GIMP_DND_DATA_PALETTE,
- GIMP_DND_DATA_TOOL,
- GIMP_DND_DATA_LAST = GIMP_DND_DATA_TOOL
- } GimpDndDataType;
-
- typedef GtkWidget * (* GimpDndGetIconFunc) (GtkWidget *widget,
- GtkSignalFunc get_data_func,
- gpointer get_data_data);
- typedef guchar * (* GimpDndDragDataFunc) (GtkWidget *widget,
- GtkSignalFunc get_data_func,
- gpointer get_data_data,
- gint *format,
- gint *length);
- typedef void (* GimpDndDropDataFunc) (GtkWidget *widget,
- GtkSignalFunc set_data_func,
- gpointer set_data_data,
- guchar *vals,
- gint format,
- gint length);
-
- typedef struct _GimpDndDataDef GimpDndDataDef;
-
- struct _GimpDndDataDef
- {
- GtkTargetEntry target_entry;
-
- gchar *set_data_func_name;
- gchar *set_data_data_name;
-
- GimpDndGetIconFunc get_icon_func;
- GimpDndDragDataFunc get_data_func;
- GimpDndDropDataFunc set_data_func;
- };
-
- static GtkWidget * gimp_dnd_get_color_icon (GtkWidget *widget,
- GtkSignalFunc get_color_func,
- gpointer get_color_data);
- static GtkWidget * gimp_dnd_get_brush_icon (GtkWidget *widget,
- GtkSignalFunc get_brush_func,
- gpointer get_brush_data);
- static GtkWidget * gimp_dnd_get_pattern_icon (GtkWidget *widget,
- GtkSignalFunc get_pattern_func,
- gpointer get_pattern_data);
- static GtkWidget * gimp_dnd_get_gradient_icon (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data);
- static GtkWidget * gimp_dnd_get_palette_icon (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data);
- static GtkWidget * gimp_dnd_get_tool_icon (GtkWidget *widget,
- GtkSignalFunc get_tool_func,
- gpointer get_tool_data);
-
- static guchar * gimp_dnd_get_color_data (GtkWidget *widget,
- GtkSignalFunc get_color_func,
- gpointer get_color_data,
- gint *format,
- gint *length);
- static guchar * gimp_dnd_get_brush_data (GtkWidget *widget,
- GtkSignalFunc get_brush_func,
- gpointer get_brush_data,
- gint *format,
- gint *length);
- static guchar * gimp_dnd_get_pattern_data (GtkWidget *widget,
- GtkSignalFunc get_pattern_func,
- gpointer get_pattern_data,
- gint *format,
- gint *length);
- static guchar * gimp_dnd_get_gradient_data (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data,
- gint *format,
- gint *length);
- static guchar * gimp_dnd_get_palette_data (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data,
- gint *format,
- gint *length);
- static guchar * gimp_dnd_get_tool_data (GtkWidget *widget,
- GtkSignalFunc get_tool_func,
- gpointer get_tool_data,
- gint *format,
- gint *length);
-
- static void gimp_dnd_set_color_data (GtkWidget *widget,
- GtkSignalFunc set_color_func,
- gpointer set_color_data,
- guchar *vals,
- gint format,
- gint length);
- static void gimp_dnd_set_brush_data (GtkWidget *widget,
- GtkSignalFunc set_brush_func,
- gpointer set_brush_data,
- guchar *vals,
- gint format,
- gint length);
- static void gimp_dnd_set_pattern_data (GtkWidget *widget,
- GtkSignalFunc set_pattern_func,
- gpointer set_pattern_data,
- guchar *vals,
- gint format,
- gint length);
- static void gimp_dnd_set_gradient_data (GtkWidget *widget,
- GtkSignalFunc set_gradient_func,
- gpointer set_gradient_data,
- guchar *vals,
- gint format,
- gint length);
- static void gimp_dnd_set_palette_data (GtkWidget *widget,
- GtkSignalFunc set_gradient_func,
- gpointer set_gradient_data,
- guchar *vals,
- gint format,
- gint length);
- static void gimp_dnd_set_tool_data (GtkWidget *widget,
- GtkSignalFunc set_tool_func,
- gpointer set_tool_data,
- guchar *vals,
- gint format,
- gint length);
-
- static GimpDndDataDef dnd_data_defs[] =
- {
- {
- { NULL, 0, -1 },
-
- NULL,
- NULL,
-
- NULL,
- NULL,
- NULL
- },
-
- {
- GIMP_TARGET_COLOR,
-
- "gimp_dnd_set_color_func",
- "gimp_dnd_set_color_data",
-
- gimp_dnd_get_color_icon,
- gimp_dnd_get_color_data,
- gimp_dnd_set_color_data
- },
-
- {
- GIMP_TARGET_BRUSH,
-
- "gimp_dnd_set_brush_func",
- "gimp_dnd_set_brush_data",
-
- gimp_dnd_get_brush_icon,
- gimp_dnd_get_brush_data,
- gimp_dnd_set_brush_data
- },
-
- {
- GIMP_TARGET_PATTERN,
-
- "gimp_dnd_set_pattern_func",
- "gimp_dnd_set_pattern_data",
-
- gimp_dnd_get_pattern_icon,
- gimp_dnd_get_pattern_data,
- gimp_dnd_set_pattern_data
- },
-
- {
- GIMP_TARGET_GRADIENT,
-
- "gimp_dnd_set_gradient_func",
- "gimp_dnd_set_gradient_data",
-
- gimp_dnd_get_gradient_icon,
- gimp_dnd_get_gradient_data,
- gimp_dnd_set_gradient_data
- },
-
- {
- GIMP_TARGET_PALETTE,
-
- "gimp_dnd_set_palette_func",
- "gimp_dnd_set_palette_data",
-
- gimp_dnd_get_palette_icon,
- gimp_dnd_get_palette_data,
- gimp_dnd_set_palette_data
- },
-
- {
- GIMP_TARGET_TOOL,
-
- "gimp_dnd_set_tool_func",
- "gimp_dnd_set_tool_data",
-
- gimp_dnd_get_tool_icon,
- gimp_dnd_get_tool_data,
- gimp_dnd_set_tool_data
- }
- };
-
- /********************************/
- /* general data dnd functions */
- /********************************/
-
- static void
- gimp_dnd_data_drag_begin (GtkWidget *widget,
- GdkDragContext *context,
- gpointer data)
- {
- GimpDndDataType data_type;
- GtkSignalFunc get_data_func;
- gpointer get_data_data;
- GtkWidget *icon_widget;
-
- data_type =
- (GimpDndDataType) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_get_data_type");
-
- if (! data_type)
- return;
-
- get_data_func =
- (GtkSignalFunc) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_get_data_func");
- get_data_data =
- (gpointer) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_get_data_data");
-
- if (! get_data_func)
- return;
-
- icon_widget = (* dnd_data_defs[data_type].get_icon_func) (widget,
- get_data_func,
- get_data_data);
-
- if (icon_widget)
- {
- GtkWidget *frame;
- GtkWidget *window;
-
- window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_widget_realize (window);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
- gtk_container_add (GTK_CONTAINER (window), frame);
- gtk_widget_show (frame);
-
- gtk_container_add (GTK_CONTAINER (frame), icon_widget);
- gtk_widget_show (icon_widget);
-
- gtk_object_set_data_full (GTK_OBJECT (widget),
- "gimp-dnd-data-widget",
- window,
- (GtkDestroyNotify) gtk_widget_destroy);
-
- gtk_drag_set_icon_widget (context, window,
- DRAG_ICON_OFFSET, DRAG_ICON_OFFSET);
- }
- }
-
- static void
- gimp_dnd_data_drag_end (GtkWidget *widget,
- GdkDragContext *context)
- {
- gtk_object_set_data (GTK_OBJECT (widget),
- "gimp-dnd-data-widget", NULL);
- }
-
- static void
- gimp_dnd_data_drag_handle (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer data)
- {
- GimpDndDataType data_type;
- GtkSignalFunc get_data_func;
- gpointer get_data_data;
- gint format;
- guchar *vals;
- gint length;
-
- data_type =
- (GimpDndDataType) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_get_data_type");
-
- if (! data_type)
- return;
-
- get_data_func =
- (GtkSignalFunc) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_get_data_func");
- get_data_data =
- (gpointer) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_get_data_data");
-
- if (! get_data_func)
- return;
-
- vals = (* dnd_data_defs[data_type].get_data_func) (widget,
- get_data_func,
- get_data_data,
- &format,
- &length);
-
- if (vals)
- {
- gtk_selection_data_set
- (selection_data,
- gdk_atom_intern (dnd_data_defs[data_type].target_entry.target, FALSE),
- format, vals, length);
-
- g_free (vals);
- }
- }
-
- static void
- gimp_dnd_data_drop_handle (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer data)
- {
- GtkSignalFunc set_data_func;
- gpointer set_data_data;
- GimpDndDataType data_type;
-
- if (selection_data->length < 0)
- return;
-
- for (data_type = GIMP_DND_DATA_COLOR;
- data_type <= GIMP_DND_DATA_LAST;
- data_type++)
- {
- if (dnd_data_defs[data_type].target_entry.info == info)
- {
- set_data_func = (GtkSignalFunc)
- gtk_object_get_data (GTK_OBJECT (widget),
- dnd_data_defs[data_type].set_data_func_name);
- set_data_data = (gpointer)
- gtk_object_get_data (GTK_OBJECT (widget),
- dnd_data_defs[data_type].set_data_data_name);
-
- if (! set_data_func)
- return;
-
- (* dnd_data_defs[data_type].set_data_func) (widget,
- set_data_func,
- set_data_data,
- selection_data->data,
- selection_data->format,
- selection_data->length);
-
- return;
- }
- }
- }
-
- static void
- gimp_dnd_data_source_set (GimpDndDataType data_type,
- GtkWidget *widget,
- GtkSignalFunc get_data_func,
- gpointer get_data_data)
- {
- gboolean drag_connected;
-
- drag_connected =
- (gboolean) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_drag_connected");
-
- if (! drag_connected)
- {
- gtk_signal_connect (GTK_OBJECT (widget), "drag_begin",
- GTK_SIGNAL_FUNC (gimp_dnd_data_drag_begin),
- NULL);
- gtk_signal_connect (GTK_OBJECT (widget), "drag_end",
- GTK_SIGNAL_FUNC (gimp_dnd_data_drag_end),
- NULL);
- gtk_signal_connect (GTK_OBJECT (widget), "drag_data_get",
- GTK_SIGNAL_FUNC (gimp_dnd_data_drag_handle),
- NULL);
-
- gtk_object_set_data (GTK_OBJECT (widget), "gimp_dnd_drag_connected",
- (gpointer) TRUE);
- }
-
- gtk_object_set_data (GTK_OBJECT (widget), "gimp_dnd_get_data_type",
- (gpointer) data_type);
- gtk_object_set_data (GTK_OBJECT (widget), "gimp_dnd_get_data_func",
- get_data_func);
- gtk_object_set_data (GTK_OBJECT (widget), "gimp_dnd_get_data_data",
- get_data_data);
- }
-
- static void
- gimp_dnd_data_dest_set (GimpDndDataType data_type,
- GtkWidget *widget,
- gpointer set_data_func,
- gpointer set_data_data)
- {
- gboolean drop_connected;
-
- drop_connected =
- (gboolean) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_drop_connected");
-
- if (! drop_connected)
- {
- gtk_signal_connect (GTK_OBJECT (widget), "drag_data_received",
- GTK_SIGNAL_FUNC (gimp_dnd_data_drop_handle),
- NULL);
-
- gtk_object_set_data (GTK_OBJECT (widget), "gimp_dnd_drop_connected",
- (gpointer) TRUE);
- }
-
- gtk_object_set_data (GTK_OBJECT (widget),
- dnd_data_defs[data_type].set_data_func_name,
- set_data_func);
- gtk_object_set_data (GTK_OBJECT (widget),
- dnd_data_defs[data_type].set_data_data_name,
- set_data_data);
- }
-
- /*************************/
- /* color dnd functions */
- /*************************/
-
- static GtkWidget *
- gimp_dnd_get_color_icon (GtkWidget *widget,
- GtkSignalFunc get_color_func,
- gpointer get_color_data)
- {
- GtkWidget *preview;
- guchar r, g, b;
- guchar row[DRAG_PREVIEW_SIZE * 3];
- gint i;
-
- (* (GimpDndDragColorFunc) get_color_func) (widget, &r, &g, &b,
- get_color_data);
-
- for (i = 0; i < DRAG_PREVIEW_SIZE; i++)
- {
- row[i * 3] = r;
- row[i * 3 + 1] = g;
- row[i * 3 + 2] = b;
- }
-
- preview = gtk_preview_new (GTK_PREVIEW_COLOR);
- gtk_preview_size (GTK_PREVIEW (preview),
- DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE);
-
- for (i = 0; i < DRAG_PREVIEW_SIZE; i++)
- {
- gtk_preview_draw_row (GTK_PREVIEW (preview), row,
- 0, i, DRAG_PREVIEW_SIZE);
- }
-
- return preview;
- }
-
- static guchar *
- gimp_dnd_get_color_data (GtkWidget *widget,
- GtkSignalFunc get_color_func,
- gpointer get_color_data,
- gint *format,
- gint *length)
- {
- guint16 *vals;
- guchar r, g, b;
-
- (* (GimpDndDragColorFunc) get_color_func) (widget, &r, &g, &b,
- get_color_data);
-
- vals = g_new (guint16, 4);
-
- vals[0] = r + (r << 8);
- vals[1] = g + (g << 8);
- vals[2] = b + (b << 8);
- vals[3] = 0xffff;
-
- *format = 16;
- *length = 8;
-
- return (guchar *) vals;
- }
-
- static void
- gimp_dnd_set_color_data (GtkWidget *widget,
- GtkSignalFunc set_color_func,
- gpointer set_color_data,
- guchar *vals,
- gint format,
- gint length)
- {
- guint16 *color_vals;
- guchar r, g, b;
-
- if ((format != 16) || (length != 8))
- {
- g_warning ("Received invalid color data\n");
- return;
- }
-
- color_vals = (guint16 *) vals;
-
- r = color_vals[0] >> 8;
- g = color_vals[1] >> 8;
- b = color_vals[2] >> 8;
-
- (* (GimpDndDropColorFunc) set_color_func) (widget, r, g, b,
- set_color_data);
- }
-
- void
- gimp_dnd_color_source_set (GtkWidget *widget,
- GimpDndDragColorFunc get_color_func,
- gpointer data)
- {
- gimp_dnd_data_source_set (GIMP_DND_DATA_COLOR, widget,
- GTK_SIGNAL_FUNC (get_color_func),
- data);
- }
-
- void
- gimp_dnd_color_dest_set (GtkWidget *widget,
- GimpDndDropColorFunc set_color_func,
- gpointer data)
- {
- gimp_dnd_data_dest_set (GIMP_DND_DATA_COLOR, widget,
- GTK_SIGNAL_FUNC (set_color_func),
- data);
- }
-
- /*************************/
- /* brush dnd functions */
- /*************************/
-
- static GtkWidget *
- gimp_dnd_get_brush_icon (GtkWidget *widget,
- GtkSignalFunc get_brush_func,
- gpointer get_brush_data)
- {
- GtkWidget *preview;
- GimpBrush *brush;
-
- brush = (* (GimpDndDragBrushFunc) get_brush_func) (widget, get_brush_data);
-
- if (! brush)
- return NULL;
-
- preview = gtk_preview_new (GTK_PREVIEW_COLOR);
- gtk_preview_size (GTK_PREVIEW (preview),
- DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE);
-
- draw_brush (GTK_PREVIEW (preview), brush,
- DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE, FALSE);
-
- return preview;
- }
-
- static guchar *
- gimp_dnd_get_brush_data (GtkWidget *widget,
- GtkSignalFunc get_brush_func,
- gpointer get_brush_data,
- gint *format,
- gint *length)
- {
- GimpBrush *brush;
- gchar *name;
-
- brush = (* (GimpDndDragBrushFunc) get_brush_func) (widget, get_brush_data);
-
- if (! brush)
- return NULL;
-
- name = g_strdup (gimp_brush_get_name (brush));
-
- if (! name)
- return NULL;
-
- *format = 8;
- *length = strlen (name) + 1;
-
- return (guchar *) name;
- }
-
- static void
- gimp_dnd_set_brush_data (GtkWidget *widget,
- GtkSignalFunc set_brush_func,
- gpointer set_brush_data,
- guchar *vals,
- gint format,
- gint length)
- {
- GimpBrush *brush;
- gchar *name;
-
- if ((format != 8) || (length < 1))
- {
- g_warning ("Received invalid brush data\n");
- return;
- }
-
- name = (gchar *) vals;
-
- if (strcmp (name, "Standard") == 0)
- brush = brushes_get_standard_brush ();
- else
- brush = gimp_brush_list_get_brush (brush_list, name);
-
- if (brush)
- (* (GimpDndDropBrushFunc) set_brush_func) (widget, brush, set_brush_data);
- }
-
- void
- gimp_dnd_brush_source_set (GtkWidget *widget,
- GimpDndDragBrushFunc get_brush_func,
- gpointer data)
- {
- gimp_dnd_data_source_set (GIMP_DND_DATA_BRUSH, widget,
- GTK_SIGNAL_FUNC (get_brush_func),
- data);
- }
-
- void
- gimp_dnd_brush_dest_set (GtkWidget *widget,
- GimpDndDropBrushFunc set_brush_func,
- gpointer data)
- {
- gimp_dnd_data_dest_set (GIMP_DND_DATA_BRUSH, widget,
- GTK_SIGNAL_FUNC (set_brush_func),
- data);
- }
-
- /***************************/
- /* pattern dnd functions */
- /***************************/
-
- static GtkWidget *
- gimp_dnd_get_pattern_icon (GtkWidget *widget,
- GtkSignalFunc get_pattern_func,
- gpointer get_pattern_data)
- {
- GtkWidget *preview;
- GPattern *pattern;
-
- pattern = (* (GimpDndDragPatternFunc) get_pattern_func) (widget,
- get_pattern_data);
-
- if (! pattern)
- return NULL;
-
- preview = gtk_preview_new (GTK_PREVIEW_COLOR);
- gtk_preview_size (GTK_PREVIEW (preview),
- DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE);
-
- draw_pattern (GTK_PREVIEW (preview), pattern,
- DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE);
-
- return preview;
- }
-
- static guchar *
- gimp_dnd_get_pattern_data (GtkWidget *widget,
- GtkSignalFunc get_pattern_func,
- gpointer get_pattern_data,
- gint *format,
- gint *length)
- {
- GPattern *pattern;
- gchar *name;
-
- pattern = (* (GimpDndDragPatternFunc) get_pattern_func) (widget,
- get_pattern_data);
-
- if (! pattern)
- return NULL;
-
- name = g_strdup (pattern->name);
-
- *format = 8;
- *length = strlen (name) + 1;
-
- return (guchar *) name;
- }
-
- static void
- gimp_dnd_set_pattern_data (GtkWidget *widget,
- GtkSignalFunc set_pattern_func,
- gpointer set_pattern_data,
- guchar *vals,
- gint format,
- gint length)
- {
- GPattern *pattern;
- gchar *name;
-
- if ((format != 8) || (length < 1))
- {
- g_warning ("Received invalid pattern data\n");
- return;
- }
-
- name = (gchar *) vals;
-
- if (strcmp (name, "Standard") == 0)
- pattern = patterns_get_standard_pattern ();
- else
- pattern = pattern_list_get_pattern (pattern_list, name);
-
- if (pattern)
- (* (GimpDndDropPatternFunc) set_pattern_func) (widget, pattern,
- set_pattern_data);
- }
-
- void
- gimp_dnd_pattern_source_set (GtkWidget *widget,
- GimpDndDragPatternFunc get_pattern_func,
- gpointer data)
- {
- gimp_dnd_data_source_set (GIMP_DND_DATA_PATTERN, widget,
- GTK_SIGNAL_FUNC (get_pattern_func),
- data);
- }
-
- void
- gimp_dnd_pattern_dest_set (GtkWidget *widget,
- GimpDndDropPatternFunc set_pattern_func,
- gpointer data)
- {
- gimp_dnd_data_dest_set (GIMP_DND_DATA_PATTERN, widget,
- GTK_SIGNAL_FUNC (set_pattern_func),
- data);
- }
-
- /****************************/
- /* gradient dnd functions */
- /****************************/
-
- static GtkWidget *
- gimp_dnd_get_gradient_icon (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data)
- {
- GtkWidget *preview;
- gradient_t *gradient;
-
- gradient =
- (* (GimpDndDragGradientFunc) get_gradient_func) (widget, get_gradient_data);
-
- if (! gradient)
- return NULL;
-
- preview = gtk_preview_new (GTK_PREVIEW_COLOR);
- gtk_preview_size (GTK_PREVIEW (preview),
- DRAG_PREVIEW_SIZE * 2, DRAG_PREVIEW_SIZE / 2);
-
- draw_gradient (GTK_PREVIEW (preview), gradient,
- DRAG_PREVIEW_SIZE * 2, DRAG_PREVIEW_SIZE / 2);
-
- return preview;
- }
-
- static guchar *
- gimp_dnd_get_gradient_data (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data,
- gint *format,
- gint *length)
- {
- gradient_t *gradient;
- gchar *name;
-
- gradient =
- (* (GimpDndDragGradientFunc) get_gradient_func) (widget, get_gradient_data);
-
- if (! gradient)
- return NULL;
-
- name = g_strdup (gradient->name);
-
- *format = 8;
- *length = strlen (name) + 1;
-
- return (guchar *) name;
- }
-
- static void
- gimp_dnd_set_gradient_data (GtkWidget *widget,
- GtkSignalFunc set_gradient_func,
- gpointer set_gradient_data,
- guchar *vals,
- gint format,
- gint length)
- {
- gradient_t *gradient;
- gchar *name;
-
- if ((format != 8) || (length < 1))
- {
- g_warning ("Received invalid gradient data\n");
- return;
- }
-
- name = (gchar *) vals;
-
- if (strcmp (name, "Standard") == 0)
- gradient = gradients_get_standard_gradient ();
- else
- gradient = gradient_list_get_gradient (gradients_list, name);
-
- if (gradient)
- (* (GimpDndDropGradientFunc) set_gradient_func) (widget, gradient,
- set_gradient_data);
- }
-
- void
- gimp_dnd_gradient_source_set (GtkWidget *widget,
- GimpDndDragGradientFunc get_gradient_func,
- gpointer data)
- {
- gimp_dnd_data_source_set (GIMP_DND_DATA_GRADIENT, widget,
- GTK_SIGNAL_FUNC (get_gradient_func),
- data);
- }
-
- void
- gimp_dnd_gradient_dest_set (GtkWidget *widget,
- GimpDndDropGradientFunc set_gradient_func,
- gpointer data)
- {
- gimp_dnd_data_dest_set (GIMP_DND_DATA_GRADIENT, widget,
- GTK_SIGNAL_FUNC (set_gradient_func),
- data);
- }
-
- /***************************/
- /* palette dnd functions */
- /***************************/
-
- static GtkWidget *
- gimp_dnd_get_palette_icon (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data)
- {
- return NULL;
- }
-
- static guchar *
- gimp_dnd_get_palette_data (GtkWidget *widget,
- GtkSignalFunc get_gradient_func,
- gpointer get_gradient_data,
- gint *format,
- gint *length)
- {
- return NULL;
- }
-
- static void
- gimp_dnd_set_palette_data (GtkWidget *widget,
- GtkSignalFunc set_gradient_func,
- gpointer set_gradient_data,
- guchar *vals,
- gint format,
- gint length)
- {
- }
-
- void
- gimp_dnd_palette_source_set (GtkWidget *widget,
- GimpDndDragPaletteFunc get_palette_func,
- gpointer data)
- {
- gimp_dnd_data_source_set (GIMP_DND_DATA_PALETTE, widget,
- GTK_SIGNAL_FUNC (get_palette_func),
- data);
- }
-
- void
- gimp_dnd_palette_dest_set (GtkWidget *widget,
- GimpDndDropPaletteFunc set_palette_func,
- gpointer data)
- {
- gimp_dnd_data_dest_set (GIMP_DND_DATA_PALETTE, widget,
- GTK_SIGNAL_FUNC (set_palette_func),
- data);
- }
-
- /************************/
- /* tool dnd functions */
- /************************/
-
- static GtkWidget *
- gimp_dnd_get_tool_icon (GtkWidget *widget,
- GtkSignalFunc get_tool_func,
- gpointer get_tool_data)
- {
- GtkWidget *tool_icon;
- ToolType tool_type;
-
- tool_type =
- (* (GimpDndDragToolFunc) get_tool_func) (widget, get_tool_data);
-
- if (((gint) tool_type < 0) || ((gint) tool_type >= num_tools))
- return NULL;
-
- tool_icon = gtk_pixmap_new (tool_get_pixmap (tool_type),
- tool_get_mask (tool_type));
-
- return tool_icon;
- }
-
- static guchar *
- gimp_dnd_get_tool_data (GtkWidget *widget,
- GtkSignalFunc get_tool_func,
- gpointer get_tool_data,
- gint *format,
- gint *length)
- {
- ToolType tool_type;
- guint16 *val;
-
- tool_type =
- (* (GimpDndDragToolFunc) get_tool_func) (widget, get_tool_data);
-
- if (((gint) tool_type < 0) || ((gint) tool_type >= num_tools))
- return NULL;
-
- val = g_new (guint16, 1);
-
- val[0] = (guint16) tool_type;
-
- *format = 16;
- *length = 2;
-
- return (guchar *) val;
- }
-
- static void
- gimp_dnd_set_tool_data (GtkWidget *widget,
- GtkSignalFunc set_tool_func,
- gpointer set_tool_data,
- guchar *vals,
- gint format,
- gint length)
- {
- ToolType tool_type;
- guint16 val;
-
- if ((format != 16) || (length != 2))
- {
- g_warning ("Received invalid tool data\n");
- return;
- }
-
- val = *((guint16 *) vals);
-
- tool_type = (ToolType) val;
-
- if (((gint) tool_type < 0) || ((gint) tool_type >= num_tools))
- return;
-
- (* (GimpDndDropToolFunc) set_tool_func) (widget, tool_type, set_tool_data);
- }
-
- void
- gimp_dnd_tool_source_set (GtkWidget *widget,
- GimpDndDragToolFunc get_tool_func,
- gpointer data)
- {
- gimp_dnd_data_source_set (GIMP_DND_DATA_TOOL, widget,
- GTK_SIGNAL_FUNC (get_tool_func),
- data);
- }
-
- void
- gimp_dnd_tool_dest_set (GtkWidget *widget,
- GimpDndDropToolFunc set_tool_func,
- gpointer data)
- {
- gimp_dnd_data_dest_set (GIMP_DND_DATA_TOOL, widget,
- GTK_SIGNAL_FUNC (set_tool_func),
- data);
- }
-
- /****************************/
- /* drawable dnd functions */
- /****************************/
-
- void
- gimp_dnd_set_drawable_preview_icon (GtkWidget *widget,
- GdkDragContext *context,
- GimpDrawable *drawable)
- {
- GtkWidget *window;
- GtkWidget *frame;
- GtkWidget *preview;
-
- gboolean drag_connected;
-
- TempBuf *tmpbuf;
- gint bpp;
- gint x, y;
- guchar *src;
- gdouble r, g, b, a;
- gdouble c0, c1;
- guchar *p0, *p1, *even, *odd;
- gint width;
- gint height;
- gdouble ratio;
-
- if (! preview_size)
- return;
-
- if (gimp_drawable_width (drawable) > gimp_drawable_height (drawable))
- ratio = (gdouble) DRAG_PREVIEW_SIZE /
- (gdouble) (gimp_drawable_width (drawable));
- else
- ratio = (gdouble) DRAG_PREVIEW_SIZE /
- (gdouble) (gimp_drawable_height (drawable));
-
- width = (gint) (ratio * gimp_drawable_width (drawable));
- height = (gint) (ratio * gimp_drawable_height (drawable));
-
- if (width < 1)
- width = 1;
- if (height < 1)
- height = 1;
-
- preview = gtk_preview_new (GTK_PREVIEW_COLOR);
- gtk_preview_size (GTK_PREVIEW (preview), width, height);
-
- if (GIMP_IS_LAYER (drawable))
- {
- tmpbuf = layer_preview (GIMP_LAYER (drawable), width, height);
- }
- else if (GIMP_IS_LAYER_MASK (drawable))
- {
- tmpbuf =
- layer_mask_preview (layer_mask_get_layer (GIMP_LAYER_MASK (drawable)),
- width, height);
- }
- else if (GIMP_IS_CHANNEL (drawable))
- {
- tmpbuf = channel_preview (GIMP_CHANNEL (drawable), width, height);
- }
- else
- {
- gtk_widget_destroy (preview);
- return;
- }
-
- bpp = tmpbuf->bytes;
-
- /* Draw the thumbnail with checks */
- src = temp_buf_data (tmpbuf);
-
- even = g_new (guchar, width * 3);
- odd = g_new (guchar, width * 3);
-
- for (y = 0; y < height; y++)
- {
- p0 = even;
- p1 = odd;
-
- for (x = 0; x < width; x++)
- {
- if (bpp == 4)
- {
- r = ((gdouble) src[x*4+0]) / 255.0;
- g = ((gdouble) src[x*4+1]) / 255.0;
- b = ((gdouble) src[x*4+2]) / 255.0;
- a = ((gdouble) src[x*4+3]) / 255.0;
- }
- else if (bpp == 3)
- {
- r = ((gdouble) src[x*3+0]) / 255.0;
- g = ((gdouble) src[x*3+1]) / 255.0;
- b = ((gdouble) src[x*3+2]) / 255.0;
- a = 1.0;
- }
- else
- {
- r = ((gdouble) src[x*bpp+0]) / 255.0;
- g = b = r;
- if (bpp == 2)
- a = ((gdouble) src[x*bpp+1]) / 255.0;
- else
- a = 1.0;
- }
-
- if ((x / GIMP_CHECK_SIZE_SM) & 1)
- {
- c0 = GIMP_CHECK_LIGHT;
- c1 = GIMP_CHECK_DARK;
- }
- else
- {
- c0 = GIMP_CHECK_DARK;
- c1 = GIMP_CHECK_LIGHT;
- }
-
- *p0++ = (c0 + (r - c0) * a) * 255.0;
- *p0++ = (c0 + (g - c0) * a) * 255.0;
- *p0++ = (c0 + (b - c0) * a) * 255.0;
-
- *p1++ = (c1 + (r - c1) * a) * 255.0;
- *p1++ = (c1 + (g - c1) * a) * 255.0;
- *p1++ = (c1 + (b - c1) * a) * 255.0;
-
- }
-
- if ((y / GIMP_CHECK_SIZE_SM) & 1)
- {
- gtk_preview_draw_row (GTK_PREVIEW (preview), odd,
- 0, y, width);
- }
- else
- {
- gtk_preview_draw_row (GTK_PREVIEW (preview), even,
- 0, y, width);
- }
- src += width * bpp;
- }
-
- g_free (even);
- g_free (odd);
-
- window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_widget_realize (window);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
- gtk_container_add (GTK_CONTAINER (window), frame);
- gtk_widget_show (frame);
-
- gtk_container_add (GTK_CONTAINER (frame), preview);
- gtk_widget_show (preview);
-
- drag_connected =
- (gboolean) gtk_object_get_data (GTK_OBJECT (widget),
- "gimp_dnd_drag_connected");
-
- if (! drag_connected)
- {
- gtk_signal_connect (GTK_OBJECT (widget), "drag_end",
- GTK_SIGNAL_FUNC (gimp_dnd_data_drag_end),
- NULL);
-
- gtk_object_set_data (GTK_OBJECT (widget), "gimp_dnd_drag_connected",
- (gpointer) TRUE);
- }
-
- gtk_object_set_data_full (GTK_OBJECT (widget),
- "gimp-dnd-data-widget",
- window,
- (GtkDestroyNotify) gtk_widget_destroy);
-
- gtk_drag_set_icon_widget (context, window,
- DRAG_ICON_OFFSET, DRAG_ICON_OFFSET);
- }
-
- /******************************/
- /* file / url dnd functions */
- /******************************/
-
- static void
- gimp_dnd_file_open_files (gchar *buffer)
- {
- gchar name_buffer[1024];
- const gchar *data_type = "file:";
- const gint sig_len = strlen (data_type);
-
- while (*buffer)
- {
- gchar *name = name_buffer;
- gint len = 0;
-
- while ((*buffer != 0) && (*buffer != '\n') && len < 1024)
- {
- *name++ = *buffer++;
- len++;
- }
- if (len == 0)
- break;
-
- if (*(name - 1) == 0xd) /* gmc uses RETURN+NEWLINE as delimiter */
- *(name - 1) = '\0';
- else
- *name = '\0';
- name = name_buffer;
- if ((sig_len < len) && (! strncmp (name, data_type, sig_len)))
- name += sig_len;
-
- if (name && strlen (name) > 2)
- file_open (name, name);
-
- if (*buffer)
- buffer++;
- }
- }
-
- static void
- gimp_dnd_file_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *data,
- guint info,
- guint time)
- {
- switch (context->action)
- {
- case GDK_ACTION_DEFAULT:
- case GDK_ACTION_COPY:
- case GDK_ACTION_MOVE:
- case GDK_ACTION_LINK:
- case GDK_ACTION_ASK:
- default:
- gimp_dnd_file_open_files ((gchar *) data->data);
- gtk_drag_finish (context, TRUE, FALSE, time);
- break;
- }
- return;
- }
-
- void
- gimp_dnd_file_dest_set (GtkWidget *widget)
- {
- gtk_signal_connect (GTK_OBJECT (widget), "drag_data_received",
- GTK_SIGNAL_FUNC (gimp_dnd_file_drag_data_received),
- widget);
- }
-
-