1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <string.h>
21
22 #include <gegl.h>
23 #include <gtk/gtk.h>
24
25 #include "libgimpcolor/gimpcolor.h"
26 #include "libgimpconfig/gimpconfig.h"
27
28 #include "widgets-types.h"
29
30 #include "core/gimp.h"
31 #include "core/gimp-utils.h"
32 #include "core/gimpbrush.h"
33 #include "core/gimpcontainer.h"
34 #include "core/gimpcurve.h"
35 #include "core/gimpdatafactory.h"
36 #include "core/gimpgradient.h"
37 #include "core/gimpimage.h"
38 #include "core/gimpimagefile.h"
39 #include "core/gimpitem.h"
40 #include "core/gimppalette.h"
41 #include "core/gimppattern.h"
42 #include "core/gimptoolinfo.h"
43
44 #include "text/gimpfont.h"
45
46 #include "xcf/xcf.h"
47
48 #include "gimpselectiondata.h"
49
50 #include "gimp-log.h"
51 #include "gimp-intl.h"
52
53
54 /* local function prototypes */
55
56 static const gchar * gimp_selection_data_get_name (GtkSelectionData *selection,
57 const gchar *strfunc);
58 static GimpObject * gimp_selection_data_get_object (GtkSelectionData *selection,
59 GimpContainer *container,
60 GimpObject *additional);
61 static gchar * gimp_unescape_uri_string (const char *escaped,
62 int len,
63 const char *illegal_escaped_characters,
64 gboolean ascii_must_not_be_escaped);
65
66
67 /* public functions */
68
69 void
gimp_selection_data_set_uri_list(GtkSelectionData * selection,GList * uri_list)70 gimp_selection_data_set_uri_list (GtkSelectionData *selection,
71 GList *uri_list)
72 {
73 GList *list;
74 gchar *vals = NULL;
75
76 g_return_if_fail (selection != NULL);
77 g_return_if_fail (uri_list != NULL);
78
79 for (list = uri_list; list; list = g_list_next (list))
80 {
81 if (vals)
82 {
83 gchar *tmp = g_strconcat (vals,
84 list->data,
85 list->next ? "\n" : NULL,
86 NULL);
87 g_free (vals);
88 vals = tmp;
89 }
90 else
91 {
92 vals = g_strconcat (list->data,
93 list->next ? "\n" : NULL,
94 NULL);
95 }
96 }
97
98 gtk_selection_data_set (selection,
99 gtk_selection_data_get_target (selection),
100 8, (guchar *) vals, strlen (vals));
101
102 g_free (vals);
103 }
104
105 GList *
gimp_selection_data_get_uri_list(GtkSelectionData * selection)106 gimp_selection_data_get_uri_list (GtkSelectionData *selection)
107 {
108 GList *crap_list = NULL;
109 GList *uri_list = NULL;
110 GList *list;
111 gint length;
112 const gchar *data;
113 const gchar *buffer;
114
115 g_return_val_if_fail (selection != NULL, NULL);
116
117 length = gtk_selection_data_get_length (selection);
118
119 if (gtk_selection_data_get_format (selection) != 8 || length < 1)
120 {
121 g_warning ("Received invalid file data!");
122 return NULL;
123 }
124
125 data = buffer = (const gchar *) gtk_selection_data_get_data (selection);
126
127 GIMP_LOG (DND, "raw buffer >>%s<<", buffer);
128
129 {
130 gchar name_buffer[1024];
131
132 while (*buffer && (buffer - data < length))
133 {
134 gchar *name = name_buffer;
135 gint len = 0;
136
137 while (len < sizeof (name_buffer) && *buffer && *buffer != '\n')
138 {
139 *name++ = *buffer++;
140 len++;
141 }
142 if (len == 0)
143 break;
144
145 if (*(name - 1) == 0xd) /* gmc uses RETURN+NEWLINE as delimiter */
146 len--;
147
148 if (len > 2)
149 crap_list = g_list_prepend (crap_list, g_strndup (name_buffer, len));
150
151 if (*buffer)
152 buffer++;
153 }
154 }
155
156 if (! crap_list)
157 return NULL;
158
159 /* do various checks because file drag sources send all kinds of
160 * arbitrary crap...
161 */
162 for (list = crap_list; list; list = g_list_next (list))
163 {
164 const gchar *dnd_crap = list->data;
165 gchar *filename;
166 gchar *hostname;
167 gchar *uri = NULL;
168 GError *error = NULL;
169
170 GIMP_LOG (DND, "trying to convert \"%s\" to an uri", dnd_crap);
171
172 filename = g_filename_from_uri (dnd_crap, &hostname, NULL);
173
174 if (filename)
175 {
176 /* if we got a correctly encoded "file:" uri...
177 *
178 * (for GLib < 2.4.4, this is escaped UTF-8,
179 * for GLib > 2.4.4, this is escaped local filename encoding)
180 */
181
182 uri = g_filename_to_uri (filename, hostname, NULL);
183
184 g_free (hostname);
185 g_free (filename);
186 }
187 else if (g_file_test (dnd_crap, G_FILE_TEST_EXISTS))
188 {
189 /* ...else if we got a valid local filename... */
190
191 uri = g_filename_to_uri (dnd_crap, NULL, NULL);
192 }
193 else
194 {
195 /* ...otherwise do evil things... */
196
197 const gchar *start = dnd_crap;
198
199 if (g_str_has_prefix (dnd_crap, "file://"))
200 {
201 start += strlen ("file://");
202 }
203 else if (g_str_has_prefix (dnd_crap, "file:"))
204 {
205 start += strlen ("file:");
206 }
207
208 if (start != dnd_crap)
209 {
210 /* try if we got a "file:" uri in the wrong encoding...
211 *
212 * (for GLib < 2.4.4, this is escaped local filename encoding,
213 * for GLib > 2.4.4, this is escaped UTF-8)
214 */
215 gchar *unescaped_filename;
216
217 if (strstr (dnd_crap, "%"))
218 {
219 gchar *local_filename;
220
221 unescaped_filename = gimp_unescape_uri_string (start, -1,
222 "/", FALSE);
223
224 /* check if we got a drop from an application that
225 * encodes file: URIs as UTF-8 (apps linked against
226 * GLib < 2.4.4)
227 */
228 local_filename = g_filename_from_utf8 (unescaped_filename,
229 -1, NULL, NULL,
230 NULL);
231
232 if (local_filename)
233 {
234 g_free (unescaped_filename);
235 unescaped_filename = local_filename;
236 }
237 }
238 else
239 {
240 unescaped_filename = g_strdup (start);
241 }
242
243 uri = g_filename_to_uri (unescaped_filename, NULL, &error);
244
245 if (! uri)
246 {
247 gchar *escaped_filename = g_strescape (unescaped_filename,
248 NULL);
249
250 g_message (_("The filename '%s' couldn't be converted to a "
251 "valid URI:\n\n%s"),
252 escaped_filename,
253 error->message ?
254 error->message : _("Invalid UTF-8"));
255 g_free (escaped_filename);
256 g_clear_error (&error);
257
258 g_free (unescaped_filename);
259 continue;
260 }
261
262 g_free (unescaped_filename);
263 }
264 else
265 {
266 /* otherwise try the crap passed anyway, in case it's
267 * a "http:" or whatever uri a plug-in might handle
268 */
269 uri = g_strdup (dnd_crap);
270 }
271 }
272
273 uri_list = g_list_prepend (uri_list, uri);
274 }
275
276 g_list_free_full (crap_list, (GDestroyNotify) g_free);
277
278 return uri_list;
279 }
280
281 void
gimp_selection_data_set_color(GtkSelectionData * selection,const GimpRGB * color)282 gimp_selection_data_set_color (GtkSelectionData *selection,
283 const GimpRGB *color)
284 {
285 guint16 vals[4];
286 guchar r, g, b, a;
287
288 g_return_if_fail (selection != NULL);
289 g_return_if_fail (color != NULL);
290
291 gimp_rgba_get_uchar (color, &r, &g, &b, &a);
292
293 vals[0] = r + (r << 8);
294 vals[1] = g + (g << 8);
295 vals[2] = b + (b << 8);
296 vals[3] = a + (a << 8);
297
298 gtk_selection_data_set (selection,
299 gtk_selection_data_get_target (selection),
300 16, (const guchar *) vals, 8);
301 }
302
303 gboolean
gimp_selection_data_get_color(GtkSelectionData * selection,GimpRGB * color)304 gimp_selection_data_get_color (GtkSelectionData *selection,
305 GimpRGB *color)
306 {
307 const guint16 *color_vals;
308
309 g_return_val_if_fail (selection != NULL, FALSE);
310 g_return_val_if_fail (color != NULL, FALSE);
311
312 if (gtk_selection_data_get_format (selection) != 16 ||
313 gtk_selection_data_get_length (selection) != 8)
314 {
315 g_warning ("Received invalid color data!");
316 return FALSE;
317 }
318
319 color_vals = (const guint16 *) gtk_selection_data_get_data (selection);
320
321 gimp_rgba_set_uchar (color,
322 (guchar) (color_vals[0] >> 8),
323 (guchar) (color_vals[1] >> 8),
324 (guchar) (color_vals[2] >> 8),
325 (guchar) (color_vals[3] >> 8));
326
327 return TRUE;
328 }
329
330 void
gimp_selection_data_set_xcf(GtkSelectionData * selection,GimpImage * image)331 gimp_selection_data_set_xcf (GtkSelectionData *selection,
332 GimpImage *image)
333 {
334 GMemoryOutputStream *output;
335
336 g_return_if_fail (selection != NULL);
337 g_return_if_fail (GIMP_IS_IMAGE (image));
338
339 output = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
340
341 xcf_save_stream (image->gimp, image, G_OUTPUT_STREAM (output), NULL,
342 NULL, NULL);
343
344 gtk_selection_data_set (selection,
345 gtk_selection_data_get_target (selection),
346 8,
347 g_memory_output_stream_get_data (output),
348 g_memory_output_stream_get_data_size (output));
349
350 g_object_unref (output);
351 }
352
353 GimpImage *
gimp_selection_data_get_xcf(GtkSelectionData * selection,Gimp * gimp)354 gimp_selection_data_get_xcf (GtkSelectionData *selection,
355 Gimp *gimp)
356 {
357 GInputStream *input;
358 GimpImage *image;
359 gsize length;
360 const guchar *data;
361 GError *error = NULL;
362
363 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
364 g_return_val_if_fail (selection != NULL, NULL);
365
366 length = gtk_selection_data_get_length (selection);
367
368 if (gtk_selection_data_get_format (selection) != 8 || length < 1)
369 {
370 g_warning ("Received invalid data stream!");
371 return NULL;
372 }
373
374 data = gtk_selection_data_get_data (selection);
375
376 input = g_memory_input_stream_new_from_data (data, length, NULL);
377
378 image = xcf_load_stream (gimp, input, NULL, NULL, &error);
379
380 if (image)
381 {
382 /* don't keep clipboard images in the image list */
383 gimp_container_remove (gimp->images, GIMP_OBJECT (image));
384 }
385 else
386 {
387 g_warning ("Received invalid XCF data: %s", error->message);
388 g_clear_error (&error);
389 }
390
391 g_object_unref (input);
392
393 return image;
394 }
395
396 void
gimp_selection_data_set_stream(GtkSelectionData * selection,const guchar * stream,gsize stream_length)397 gimp_selection_data_set_stream (GtkSelectionData *selection,
398 const guchar *stream,
399 gsize stream_length)
400 {
401 g_return_if_fail (selection != NULL);
402 g_return_if_fail (stream != NULL);
403 g_return_if_fail (stream_length > 0);
404
405 gtk_selection_data_set (selection,
406 gtk_selection_data_get_target (selection),
407 8, (guchar *) stream, stream_length);
408 }
409
410 const guchar *
gimp_selection_data_get_stream(GtkSelectionData * selection,gsize * stream_length)411 gimp_selection_data_get_stream (GtkSelectionData *selection,
412 gsize *stream_length)
413 {
414 gint length;
415
416 g_return_val_if_fail (selection != NULL, NULL);
417 g_return_val_if_fail (stream_length != NULL, NULL);
418
419 length = gtk_selection_data_get_length (selection);
420
421 if (gtk_selection_data_get_format (selection) != 8 || length < 1)
422 {
423 g_warning ("Received invalid data stream!");
424 return NULL;
425 }
426
427 *stream_length = length;
428
429 return (const guchar *) gtk_selection_data_get_data (selection);
430 }
431
432 void
gimp_selection_data_set_curve(GtkSelectionData * selection,GimpCurve * curve)433 gimp_selection_data_set_curve (GtkSelectionData *selection,
434 GimpCurve *curve)
435 {
436 gchar *str;
437
438 g_return_if_fail (selection != NULL);
439 g_return_if_fail (GIMP_IS_CURVE (curve));
440
441 str = gimp_config_serialize_to_string (GIMP_CONFIG (curve), NULL);
442
443 gtk_selection_data_set (selection,
444 gtk_selection_data_get_target (selection),
445 8, (guchar *) str, strlen (str));
446
447 g_free (str);
448 }
449
450 GimpCurve *
gimp_selection_data_get_curve(GtkSelectionData * selection)451 gimp_selection_data_get_curve (GtkSelectionData *selection)
452 {
453 GimpCurve *curve;
454 gint length;
455 GError *error = NULL;
456
457 g_return_val_if_fail (selection != NULL, NULL);
458
459 length = gtk_selection_data_get_length (selection);
460
461 if (gtk_selection_data_get_format (selection) != 8 || length < 1)
462 {
463 g_warning ("Received invalid curve data!");
464 return NULL;
465 }
466
467 curve = GIMP_CURVE (gimp_curve_new ("pasted curve"));
468
469 if (! gimp_config_deserialize_string (GIMP_CONFIG (curve),
470 (const gchar *)
471 gtk_selection_data_get_data (selection),
472 length,
473 NULL,
474 &error))
475 {
476 g_warning ("Received invalid curve data: %s", error->message);
477 g_clear_error (&error);
478 g_object_unref (curve);
479 return NULL;
480 }
481
482 return curve;
483 }
484
485 void
gimp_selection_data_set_image(GtkSelectionData * selection,GimpImage * image)486 gimp_selection_data_set_image (GtkSelectionData *selection,
487 GimpImage *image)
488 {
489 gchar *str;
490
491 g_return_if_fail (selection != NULL);
492 g_return_if_fail (GIMP_IS_IMAGE (image));
493
494 str = g_strdup_printf ("%d:%d", gimp_get_pid (), gimp_image_get_ID (image));
495
496 gtk_selection_data_set (selection,
497 gtk_selection_data_get_target (selection),
498 8, (guchar *) str, strlen (str));
499
500 g_free (str);
501 }
502
503 GimpImage *
gimp_selection_data_get_image(GtkSelectionData * selection,Gimp * gimp)504 gimp_selection_data_get_image (GtkSelectionData *selection,
505 Gimp *gimp)
506 {
507 const gchar *str;
508
509 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
510 g_return_val_if_fail (selection != NULL, NULL);
511
512 str = gimp_selection_data_get_name (selection, G_STRFUNC);
513
514 if (str)
515 {
516 gint pid;
517 gint ID;
518
519 if (sscanf (str, "%i:%i", &pid, &ID) == 2 &&
520 pid == gimp_get_pid ())
521 {
522 return gimp_image_get_by_ID (gimp, ID);
523 }
524 }
525
526 return NULL;
527 }
528
529 void
gimp_selection_data_set_component(GtkSelectionData * selection,GimpImage * image,GimpChannelType channel)530 gimp_selection_data_set_component (GtkSelectionData *selection,
531 GimpImage *image,
532 GimpChannelType channel)
533 {
534 gchar *str;
535
536 g_return_if_fail (selection != NULL);
537 g_return_if_fail (GIMP_IS_IMAGE (image));
538
539 str = g_strdup_printf ("%d:%d:%d", gimp_get_pid (), gimp_image_get_ID (image),
540 (gint) channel);
541
542 gtk_selection_data_set (selection,
543 gtk_selection_data_get_target (selection),
544 8, (guchar *) str, strlen (str));
545
546 g_free (str);
547 }
548
549 GimpImage *
gimp_selection_data_get_component(GtkSelectionData * selection,Gimp * gimp,GimpChannelType * channel)550 gimp_selection_data_get_component (GtkSelectionData *selection,
551 Gimp *gimp,
552 GimpChannelType *channel)
553 {
554 const gchar *str;
555
556 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
557 g_return_val_if_fail (selection != NULL, NULL);
558
559 if (channel)
560 *channel = 0;
561
562 str = gimp_selection_data_get_name (selection, G_STRFUNC);
563
564 if (str)
565 {
566 gint pid;
567 gint ID;
568 gint ch;
569
570 if (sscanf (str, "%i:%i:%i", &pid, &ID, &ch) == 3 &&
571 pid == gimp_get_pid ())
572 {
573 GimpImage *image = gimp_image_get_by_ID (gimp, ID);
574
575 if (image && channel)
576 *channel = ch;
577
578 return image;
579 }
580 }
581
582 return NULL;
583 }
584
585 void
gimp_selection_data_set_item(GtkSelectionData * selection,GimpItem * item)586 gimp_selection_data_set_item (GtkSelectionData *selection,
587 GimpItem *item)
588 {
589 gchar *str;
590
591 g_return_if_fail (selection != NULL);
592 g_return_if_fail (GIMP_IS_ITEM (item));
593
594 str = g_strdup_printf ("%d:%d", gimp_get_pid (), gimp_item_get_ID (item));
595
596 gtk_selection_data_set (selection,
597 gtk_selection_data_get_target (selection),
598 8, (guchar *) str, strlen (str));
599
600 g_free (str);
601 }
602
603 GimpItem *
gimp_selection_data_get_item(GtkSelectionData * selection,Gimp * gimp)604 gimp_selection_data_get_item (GtkSelectionData *selection,
605 Gimp *gimp)
606 {
607 const gchar *str;
608
609 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
610 g_return_val_if_fail (selection != NULL, NULL);
611
612 str = gimp_selection_data_get_name (selection, G_STRFUNC);
613
614 if (str)
615 {
616 gint pid;
617 gint ID;
618
619 if (sscanf (str, "%i:%i", &pid, &ID) == 2 &&
620 pid == gimp_get_pid ())
621 {
622 return gimp_item_get_by_ID (gimp, ID);
623 }
624 }
625
626 return NULL;
627 }
628
629 void
gimp_selection_data_set_object(GtkSelectionData * selection,GimpObject * object)630 gimp_selection_data_set_object (GtkSelectionData *selection,
631 GimpObject *object)
632 {
633 const gchar *name;
634
635 g_return_if_fail (selection != NULL);
636 g_return_if_fail (GIMP_IS_OBJECT (object));
637
638 name = gimp_object_get_name (object);
639
640 if (name)
641 {
642 gchar *str;
643
644 str = g_strdup_printf ("%d:%p:%s", gimp_get_pid (), object, name);
645
646 gtk_selection_data_set (selection,
647 gtk_selection_data_get_target (selection),
648 8, (guchar *) str, strlen (str));
649
650 g_free (str);
651 }
652 }
653
654 GimpBrush *
gimp_selection_data_get_brush(GtkSelectionData * selection,Gimp * gimp)655 gimp_selection_data_get_brush (GtkSelectionData *selection,
656 Gimp *gimp)
657 {
658 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
659 g_return_val_if_fail (selection != NULL, NULL);
660
661 return (GimpBrush *)
662 gimp_selection_data_get_object (selection,
663 gimp_data_factory_get_container (gimp->brush_factory),
664 GIMP_OBJECT (gimp_brush_get_standard (gimp_get_user_context (gimp))));
665 }
666
667 GimpPattern *
gimp_selection_data_get_pattern(GtkSelectionData * selection,Gimp * gimp)668 gimp_selection_data_get_pattern (GtkSelectionData *selection,
669 Gimp *gimp)
670 {
671 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
672 g_return_val_if_fail (selection != NULL, NULL);
673
674 return (GimpPattern *)
675 gimp_selection_data_get_object (selection,
676 gimp_data_factory_get_container (gimp->pattern_factory),
677 GIMP_OBJECT (gimp_pattern_get_standard (gimp_get_user_context (gimp))));
678 }
679
680 GimpGradient *
gimp_selection_data_get_gradient(GtkSelectionData * selection,Gimp * gimp)681 gimp_selection_data_get_gradient (GtkSelectionData *selection,
682 Gimp *gimp)
683 {
684 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
685 g_return_val_if_fail (selection != NULL, NULL);
686
687 return (GimpGradient *)
688 gimp_selection_data_get_object (selection,
689 gimp_data_factory_get_container (gimp->gradient_factory),
690 GIMP_OBJECT (gimp_gradient_get_standard (gimp_get_user_context (gimp))));
691 }
692
693 GimpPalette *
gimp_selection_data_get_palette(GtkSelectionData * selection,Gimp * gimp)694 gimp_selection_data_get_palette (GtkSelectionData *selection,
695 Gimp *gimp)
696 {
697 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
698 g_return_val_if_fail (selection != NULL, NULL);
699
700 return (GimpPalette *)
701 gimp_selection_data_get_object (selection,
702 gimp_data_factory_get_container (gimp->palette_factory),
703 GIMP_OBJECT (gimp_palette_get_standard (gimp_get_user_context (gimp))));
704 }
705
706 GimpFont *
gimp_selection_data_get_font(GtkSelectionData * selection,Gimp * gimp)707 gimp_selection_data_get_font (GtkSelectionData *selection,
708 Gimp *gimp)
709 {
710 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
711 g_return_val_if_fail (selection != NULL, NULL);
712
713 return (GimpFont *)
714 gimp_selection_data_get_object (selection,
715 gimp_data_factory_get_container (gimp->font_factory),
716 GIMP_OBJECT (gimp_font_get_standard ()));
717 }
718
719 GimpBuffer *
gimp_selection_data_get_buffer(GtkSelectionData * selection,Gimp * gimp)720 gimp_selection_data_get_buffer (GtkSelectionData *selection,
721 Gimp *gimp)
722 {
723 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
724 g_return_val_if_fail (selection != NULL, NULL);
725
726 return (GimpBuffer *)
727 gimp_selection_data_get_object (selection,
728 gimp->named_buffers,
729 GIMP_OBJECT (gimp_get_clipboard_buffer (gimp)));
730 }
731
732 GimpImagefile *
gimp_selection_data_get_imagefile(GtkSelectionData * selection,Gimp * gimp)733 gimp_selection_data_get_imagefile (GtkSelectionData *selection,
734 Gimp *gimp)
735 {
736 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
737 g_return_val_if_fail (selection != NULL, NULL);
738
739 return (GimpImagefile *) gimp_selection_data_get_object (selection,
740 gimp->documents,
741 NULL);
742 }
743
744 GimpTemplate *
gimp_selection_data_get_template(GtkSelectionData * selection,Gimp * gimp)745 gimp_selection_data_get_template (GtkSelectionData *selection,
746 Gimp *gimp)
747 {
748 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
749 g_return_val_if_fail (selection != NULL, NULL);
750
751 return (GimpTemplate *) gimp_selection_data_get_object (selection,
752 gimp->templates,
753 NULL);
754 }
755
756 GimpToolItem *
gimp_selection_data_get_tool_item(GtkSelectionData * selection,Gimp * gimp)757 gimp_selection_data_get_tool_item (GtkSelectionData *selection,
758 Gimp *gimp)
759 {
760 GimpToolItem *tool_item;
761
762 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
763 g_return_val_if_fail (selection != NULL, NULL);
764
765 tool_item = (GimpToolItem *)
766 gimp_selection_data_get_object (selection,
767 gimp->tool_info_list,
768 GIMP_OBJECT (gimp_tool_info_get_standard (gimp)));
769
770 if (! tool_item)
771 {
772 tool_item = (GimpToolItem *)
773 gimp_selection_data_get_object (selection,
774 gimp->tool_item_list,
775 NULL);
776 }
777
778 return tool_item;
779 }
780
781
782 /* private functions */
783
784 static const gchar *
gimp_selection_data_get_name(GtkSelectionData * selection,const gchar * strfunc)785 gimp_selection_data_get_name (GtkSelectionData *selection,
786 const gchar *strfunc)
787 {
788 const gchar *name;
789
790 if (gtk_selection_data_get_format (selection) != 8 ||
791 gtk_selection_data_get_length (selection) < 1)
792 {
793 g_warning ("%s: received invalid selection data", strfunc);
794 return NULL;
795 }
796
797 name = (const gchar *) gtk_selection_data_get_data (selection);
798
799 if (! g_utf8_validate (name, -1, NULL))
800 {
801 g_warning ("%s: received invalid selection data "
802 "(doesn't validate as UTF-8)", strfunc);
803 return NULL;
804 }
805
806 GIMP_LOG (DND, "name = '%s'", name);
807
808 return name;
809 }
810
811 static GimpObject *
gimp_selection_data_get_object(GtkSelectionData * selection,GimpContainer * container,GimpObject * additional)812 gimp_selection_data_get_object (GtkSelectionData *selection,
813 GimpContainer *container,
814 GimpObject *additional)
815 {
816 const gchar *str;
817
818 str = gimp_selection_data_get_name (selection, G_STRFUNC);
819
820 if (str)
821 {
822 gint pid;
823 gpointer object_addr;
824 gint name_offset = 0;
825
826 if (sscanf (str, "%i:%p:%n", &pid, &object_addr, &name_offset) >= 2 &&
827 pid == gimp_get_pid () && name_offset > 0)
828 {
829 const gchar *name = str + name_offset;
830
831 GIMP_LOG (DND, "pid = %d, addr = %p, name = '%s'",
832 pid, object_addr, name);
833
834 if (additional &&
835 strcmp (name, gimp_object_get_name (additional)) == 0 &&
836 object_addr == (gpointer) additional)
837 {
838 return additional;
839 }
840 else
841 {
842 GimpObject *object;
843
844 object = gimp_container_get_child_by_name (container, name);
845
846 if (object_addr == (gpointer) object)
847 return object;
848 }
849 }
850 }
851
852 return NULL;
853 }
854
855 /* the next two functions are straight cut'n'paste from glib/glib/gconvert.c,
856 * except that gimp_unescape_uri_string() does not try to UTF-8 validate
857 * the unescaped result.
858 */
859 static int
unescape_character(const char * scanner)860 unescape_character (const char *scanner)
861 {
862 int first_digit;
863 int second_digit;
864
865 first_digit = g_ascii_xdigit_value (scanner[0]);
866 if (first_digit < 0)
867 return -1;
868
869 second_digit = g_ascii_xdigit_value (scanner[1]);
870 if (second_digit < 0)
871 return -1;
872
873 return (first_digit << 4) | second_digit;
874 }
875
876 static gchar *
gimp_unescape_uri_string(const char * escaped,int len,const char * illegal_escaped_characters,gboolean ascii_must_not_be_escaped)877 gimp_unescape_uri_string (const char *escaped,
878 int len,
879 const char *illegal_escaped_characters,
880 gboolean ascii_must_not_be_escaped)
881 {
882 const gchar *inp, *in_end;
883 gchar *out, *result;
884 int c;
885
886 if (escaped == NULL)
887 return NULL;
888
889 if (len < 0)
890 len = strlen (escaped);
891
892 result = g_malloc (len + 1);
893
894 out = result;
895 for (inp = escaped, in_end = escaped + len; inp < in_end; inp++)
896 {
897 c = *inp;
898
899 if (c == '%')
900 {
901 /* catch partial escape sequences past the end of the substring */
902 if (inp + 3 > in_end)
903 break;
904
905 c = unescape_character (inp + 1);
906
907 /* catch bad escape sequences and NUL characters */
908 if (c <= 0)
909 break;
910
911 /* catch escaped ASCII */
912 if (ascii_must_not_be_escaped && c <= 0x7F)
913 break;
914
915 /* catch other illegal escaped characters */
916 if (strchr (illegal_escaped_characters, c) != NULL)
917 break;
918
919 inp += 2;
920 }
921
922 *out++ = c;
923 }
924
925 gimp_assert (out - result <= len);
926 *out = '\0';
927
928 if (inp != in_end)
929 {
930 g_free (result);
931 return NULL;
932 }
933
934 return result;
935 }
936