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