]> Pileus Git - ~andy/gtk/blob - gtk/gtkclipboard-wayland.c
Remove some more CUPS 1.2 ifdefs.
[~andy/gtk] / gtk / gtkclipboard-wayland.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2000 Red Hat, Inc.
3  * Copyright (C) 2004 Nokia Corporation
4  * Copyright (C) 2006-2008 Imendio AB
5  * Copyright (C) 2011-2012 Intel Corporation
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include "config.h"
23 #include <string.h>
24
25 #include "gtkclipboard.h"
26 #include "gtkinvisible.h"
27 #include "gtkmain.h"
28 #include "gtkmarshalers.h"
29 #include "gtkintl.h"
30 #include "gtktextbuffer.h"
31 #include "gtkselectionprivate.h"
32
33 #include "../gdk/gdk.h"
34 #include "../gdk/wayland/gdkwayland.h"
35
36 enum {
37     OWNER_CHANGE,
38     LAST_SIGNAL
39 };
40
41 typedef struct _GtkClipboardClass GtkClipboardClass;
42
43 typedef struct _SetContentClosure SetContentClosure;
44 struct _GtkClipboard
45 {
46   GObject parent_instance;
47
48   GObject *owner;
49   GdkDisplay *display;
50
51   SetContentClosure *last_closure;
52 };
53
54 struct _GtkClipboardClass
55 {
56   GObjectClass parent_class;
57
58   void (*owner_change) (GtkClipboard        *clipboard,
59                         GdkEventOwnerChange *event);
60 };
61
62 static void gtk_clipboard_class_init   (GtkClipboardClass   *class);
63 static void gtk_clipboard_finalize     (GObject             *object);
64 static void gtk_clipboard_owner_change (GtkClipboard        *clipboard,
65                                         GdkEventOwnerChange *event);
66
67 static GObjectClass *parent_class;
68 static guint         clipboard_signals[LAST_SIGNAL] = { 0 };
69
70 GType
71 gtk_clipboard_get_type (void)
72 {
73   static GType clipboard_type = 0;
74
75   if (!clipboard_type)
76     {
77       const GTypeInfo clipboard_info =
78         {
79           sizeof (GtkClipboardClass),
80           NULL,           /* base_init */
81           NULL,           /* base_finalize */
82           (GClassInitFunc) gtk_clipboard_class_init,
83           NULL,           /* class_finalize */
84           NULL,           /* class_data */
85           sizeof (GtkClipboard),
86           0,              /* n_preallocs */
87           (GInstanceInitFunc) NULL,
88         };
89
90       clipboard_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkClipboard"),
91                                                &clipboard_info, 0);
92     }
93
94   return clipboard_type;
95 }
96
97 static void
98 gtk_clipboard_class_init (GtkClipboardClass *class)
99 {
100   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
101
102   parent_class = g_type_class_peek_parent (class);
103
104   gobject_class->finalize = gtk_clipboard_finalize;
105
106   class->owner_change = gtk_clipboard_owner_change;
107
108   clipboard_signals[OWNER_CHANGE] =
109     g_signal_new (I_("owner-change"),
110                   G_TYPE_FROM_CLASS (gobject_class),
111                   G_SIGNAL_RUN_FIRST,
112                   G_STRUCT_OFFSET (GtkClipboardClass, owner_change),
113                   NULL, NULL,
114                   _gtk_marshal_VOID__BOXED,
115                   G_TYPE_NONE, 1,
116                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
117 }
118
119 static void
120 gtk_clipboard_finalize (GObject *object)
121 {
122   G_OBJECT_CLASS (parent_class)->finalize (object);
123 }
124
125 GtkClipboard *
126 gtk_clipboard_get_for_display (GdkDisplay *display,
127                                GdkAtom     selection)
128 {
129   GtkClipboard *clipboard;
130
131   if (selection == GDK_NONE)
132     selection = GDK_SELECTION_CLIPBOARD;
133
134   if (selection != GDK_SELECTION_CLIPBOARD)
135     {
136       g_warning (G_STRLOC ": Only able to create clipboard for CLIPBOARD");
137     }
138
139   selection = GDK_SELECTION_CLIPBOARD;
140
141   clipboard = g_object_get_data (G_OBJECT (display), "gtk-clipboard");
142
143   if (clipboard)
144     return clipboard;
145
146   clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
147   clipboard->display = display;
148
149   g_object_set_data (G_OBJECT (display), "gtk-clipboard", clipboard);
150
151   /* TODO: Need to connect to display closed to free this */
152   return clipboard;
153 }
154
155 GtkClipboard *
156 gtk_clipboard_get (GdkAtom selection)
157 {
158   return gtk_clipboard_get_for_display (gdk_display_get_default (), selection);
159 }
160
161
162 struct _SetContentClosure {
163     GtkClipboard *clipboard;
164     GtkClipboardGetFunc get_func;
165     GtkClipboardClearFunc clear_func;
166     guint info;
167     gpointer userdata;
168     GtkTargetPair *targets;
169     gint n_targets;
170 };
171
172 static gchar *
173 _offer_cb (GdkDevice   *device,
174            const gchar *mime_type,
175            gssize      *len,
176            gpointer     userdata)
177 {
178   SetContentClosure *closure = (SetContentClosure *)userdata;
179   GtkSelectionData selection_data = { 0, };
180   guint info = 0;
181   gint i;
182
183   selection_data.target = gdk_atom_intern (mime_type, FALSE);
184
185   for (i = 0; i < closure->n_targets; i++)
186     {
187       if (closure->targets[i].target == selection_data.target)
188         {
189           info = closure->targets[i].info;
190           break;
191         }
192     }
193
194   closure->get_func (closure->clipboard,
195                      &selection_data,
196                      info,
197                      closure->userdata);
198
199   *len = gtk_selection_data_get_length (&selection_data);
200
201   /* The caller of this callback will free this data - the GtkClipboardGetFunc
202    * uses gtk_selection_data_set which copies*/
203   return (gchar *)selection_data.data;
204 }
205
206 static gboolean
207 gtk_clipboard_set_contents (GtkClipboard         *clipboard,
208                             const GtkTargetEntry *targets,
209                             guint                 n_targets,
210                             GtkClipboardGetFunc   get_func,
211                             GtkClipboardClearFunc clear_func,
212                             gpointer              user_data,
213                             gboolean              have_owner)
214 {
215   GdkDeviceManager *device_manager;
216   GdkDevice *device;
217   gint i;
218   gchar **mimetypes;
219   SetContentClosure *closure;
220
221   gtk_clipboard_clear (clipboard);
222
223   device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
224   device = gdk_device_manager_get_client_pointer (device_manager);
225
226   closure = g_new0 (SetContentClosure, 1);
227   closure->clipboard = clipboard;
228   closure->get_func = get_func;
229   closure->clear_func = clear_func;
230   closure->userdata = user_data;
231   closure->targets = g_new0 (GtkTargetPair, n_targets);
232   closure->n_targets = n_targets;
233
234   mimetypes = g_new (gchar *, n_targets);
235
236   for (i = 0; i < n_targets; i++)
237     {
238       mimetypes[i] = targets[i].target;
239       closure->targets[i].target = gdk_atom_intern (targets[i].target, FALSE);
240       closure->targets[i].flags = targets[i].flags;
241       closure->targets[i].info = targets[i].info;
242     }
243
244   gdk_wayland_device_offer_selection_content (device,
245                                               (const gchar **)mimetypes,
246                                               n_targets,
247                                               _offer_cb,
248                                               closure);
249   clipboard->last_closure = closure;
250
251   g_free (mimetypes);
252   return TRUE;
253 }
254
255 gboolean
256 gtk_clipboard_set_with_data (GtkClipboard          *clipboard,
257                              const GtkTargetEntry  *targets,
258                              guint                  n_targets,
259                              GtkClipboardGetFunc    get_func,
260                              GtkClipboardClearFunc  clear_func,
261                              gpointer               user_data)
262 {
263   g_return_val_if_fail (clipboard != NULL, FALSE);
264   g_return_val_if_fail (targets != NULL, FALSE);
265   g_return_val_if_fail (get_func != NULL, FALSE);
266
267   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
268                                      get_func, clear_func, user_data,
269                                      FALSE);
270 }
271
272 gboolean
273 gtk_clipboard_set_with_owner (GtkClipboard          *clipboard,
274                               const GtkTargetEntry  *targets,
275                               guint                  n_targets,
276                               GtkClipboardGetFunc    get_func,
277                               GtkClipboardClearFunc  clear_func,
278                               GObject               *owner)
279 {
280   g_return_val_if_fail (clipboard != NULL, FALSE);
281   g_return_val_if_fail (targets != NULL, FALSE);
282   g_return_val_if_fail (get_func != NULL, FALSE);
283   g_return_val_if_fail (G_IS_OBJECT (owner), FALSE);
284
285   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
286                                      get_func, clear_func, owner,
287                                      TRUE);
288 }
289
290 GObject *
291 gtk_clipboard_get_owner (GtkClipboard *clipboard)
292 {
293   g_return_val_if_fail (clipboard != NULL, NULL);
294
295   if (clipboard->owner)
296     return clipboard->owner;
297   else
298     return NULL;
299 }
300
301 void
302 gtk_clipboard_clear (GtkClipboard *clipboard)
303 {
304   GdkDeviceManager *device_manager;
305   GdkDevice *device;
306
307   if (!clipboard->last_closure)
308     return;
309
310   device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
311   device = gdk_device_manager_get_client_pointer (device_manager);
312
313   gdk_wayland_device_clear_selection_content (device);
314
315   if (clipboard->last_closure->clear_func)
316     {
317       clipboard->last_closure->clear_func (clipboard,
318                                            clipboard->last_closure->userdata);
319     }
320
321   /* TODO: Free last closure */
322   clipboard->last_closure = NULL;
323 }
324
325 static void 
326 text_get_func (GtkClipboard     *clipboard,
327                GtkSelectionData *selection_data,
328                guint             info,
329                gpointer          data)
330 {
331   gtk_selection_data_set_text (selection_data, data, -1);
332 }
333
334 static void 
335 text_clear_func (GtkClipboard *clipboard,
336                  gpointer      data)
337 {
338   g_free (data);
339 }
340
341 void
342 gtk_clipboard_set_text (GtkClipboard *clipboard,
343                         const gchar  *text,
344                         gint          len)
345 {
346   GtkTargetEntry target = { "text/plain;charset=utf-8", 0, 0 };
347
348   g_return_if_fail (clipboard != NULL);
349   g_return_if_fail (text != NULL);
350
351   if (len < 0)
352     len = strlen (text);
353
354   gtk_clipboard_set_with_data (clipboard, 
355                                &target, 1,
356                                text_get_func, text_clear_func,
357                                g_strndup (text, len));
358   gtk_clipboard_set_can_store (clipboard, NULL, 0);
359 }
360
361
362 static void
363 pixbuf_get_func (GtkClipboard     *clipboard,
364                  GtkSelectionData *selection_data,
365                  guint             info,
366                  gpointer          data)
367 {
368   gtk_selection_data_set_pixbuf (selection_data, data);
369 }
370
371 static void 
372 pixbuf_clear_func (GtkClipboard *clipboard,
373                    gpointer      data)
374 {
375   g_object_unref (data);
376 }
377
378 void
379 gtk_clipboard_set_image (GtkClipboard *clipboard,
380                          GdkPixbuf    *pixbuf)
381 {
382   GtkTargetList *list;
383   GList *l;
384   GtkTargetEntry *targets;
385   gint n_targets, i;
386
387   g_return_if_fail (clipboard != NULL);
388   g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
389
390   list = gtk_target_list_new (NULL, 0);
391   gtk_target_list_add_image_targets (list, 0, TRUE);
392
393   n_targets = g_list_length (list->list);
394   targets = g_new0 (GtkTargetEntry, n_targets);
395   for (l = list->list, i = 0; l; l = l->next, i++)
396     {
397       GtkTargetPair *pair = (GtkTargetPair *)l->data;
398       targets[i].target = gdk_atom_name (pair->target);
399     }
400
401   gtk_clipboard_set_with_data (clipboard, 
402                                targets, n_targets,
403                                pixbuf_get_func, pixbuf_clear_func,
404                                g_object_ref (pixbuf));
405   gtk_clipboard_set_can_store (clipboard, NULL, 0);
406
407   for (i = 0; i < n_targets; i++)
408     g_free (targets[i].target);
409   g_free (targets);
410   gtk_target_list_unref (list);
411 }
412
413 typedef struct {
414     GtkClipboard *clipboard;
415     GCallback cb;
416     gpointer userdata;
417     GdkAtom target;
418 } ClipboardRequestClosure;
419
420 static void
421 _request_generic_cb (GdkDevice   *device,
422                      const gchar *data,
423                      gsize        len,
424                      gpointer     userdata)
425 {
426   ClipboardRequestClosure *closure = (ClipboardRequestClosure *)userdata;
427   GtkClipboardReceivedFunc cb = (GtkClipboardReceivedFunc)closure->cb;
428   GtkSelectionData selection_data;
429
430   selection_data.selection = GDK_SELECTION_CLIPBOARD;
431   selection_data.target = closure->target;
432   selection_data.length = len;
433   selection_data.data = (guchar *)data;
434
435   cb (closure->clipboard, &selection_data, closure->userdata);
436
437   g_free (closure);
438 }
439
440 void
441 gtk_clipboard_request_contents (GtkClipboard            *clipboard,
442                                 GdkAtom                  target,
443                                 GtkClipboardReceivedFunc callback,
444                                 gpointer                 user_data)
445 {
446   GdkDeviceManager *device_manager;
447   GdkDevice *device;
448   ClipboardRequestClosure *closure;
449
450   device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
451   device = gdk_device_manager_get_client_pointer (device_manager);
452
453   closure = g_new0 (ClipboardRequestClosure, 1);
454   closure->clipboard = clipboard;
455   closure->cb = (GCallback)callback;
456   closure->userdata = user_data;
457   closure->target = target;
458
459   /* TODO: Do we need to check that target is valid ? */
460   gdk_wayland_device_request_selection_content (device,
461                                                 gdk_atom_name (target),
462                                                 _request_generic_cb,
463                                                 closure);
464 }
465
466 static void
467 _request_text_cb (GdkDevice   *device,
468                   const gchar *data,
469                   gsize        len,
470                   gpointer     userdata)
471 {
472   ClipboardRequestClosure *closure = (ClipboardRequestClosure *)userdata;
473   GtkClipboardTextReceivedFunc cb = (GtkClipboardTextReceivedFunc)closure->cb;
474
475   cb (closure->clipboard, data, closure->userdata);
476
477   g_free (closure);
478 }
479
480 void
481 gtk_clipboard_request_text (GtkClipboard                *clipboard,
482                             GtkClipboardTextReceivedFunc callback,
483                             gpointer                     user_data)
484 {
485   GdkDeviceManager *device_manager;
486   GdkDevice *device;
487
488   ClipboardRequestClosure *closure;
489
490   device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
491   device = gdk_device_manager_get_client_pointer (device_manager);
492
493   closure = g_new0 (ClipboardRequestClosure, 1);
494   closure->clipboard = clipboard;
495   closure->cb = (GCallback)callback;
496   closure->userdata = user_data;
497   gdk_wayland_device_request_selection_content (device,
498                                                 "text/plain;charset=utf-8",
499                                                 _request_text_cb,
500                                                 closure);
501 }
502
503 void
504 gtk_clipboard_request_rich_text (GtkClipboard                    *clipboard,
505                                  GtkTextBuffer                   *buffer,
506                                  GtkClipboardRichTextReceivedFunc callback,
507                                  gpointer                         user_data)
508 {
509   /* FIXME: Implement */
510 }
511
512 void
513 gtk_clipboard_request_image (GtkClipboard                  *clipboard,
514                              GtkClipboardImageReceivedFunc  callback,
515                              gpointer                       user_data)
516 {
517   /* FIXME: Implement */
518 }
519
520 void
521 gtk_clipboard_request_uris (GtkClipboard                *clipboard,
522                             GtkClipboardURIReceivedFunc  callback,
523                             gpointer                     user_data)
524 {
525   /* FIXME: Implement */
526 }
527
528 void
529 gtk_clipboard_request_targets (GtkClipboard                    *clipboard,
530                                GtkClipboardTargetsReceivedFunc  callback,
531                                gpointer                         user_data)
532 {
533   GdkAtom *targets;
534   gint n_targets;
535
536   gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets);
537
538   callback (clipboard, targets, n_targets, user_data);
539
540   g_free (targets);
541 }
542
543 typedef struct {
544     GMainLoop *loop;
545     GtkSelectionData *selection_data;
546 } WaitClosure;
547
548 static void
549 _wait_for_contents_cb (GtkClipboard     *clipboard,
550                        GtkSelectionData *selection_data,
551                        gpointer          userdata)
552 {
553   WaitClosure *closure = (WaitClosure *)userdata;
554
555   if (gtk_selection_data_get_length (selection_data) != -1)
556     closure->selection_data = gtk_selection_data_copy (selection_data);
557
558   g_main_loop_quit (closure->loop);
559 }
560
561 GtkSelectionData *
562 gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
563                                  GdkAtom       target)
564 {
565   GdkDeviceManager *device_manager;
566   GdkDevice *device;
567   WaitClosure *closure;
568   GtkSelectionData *selection_data = NULL;
569
570   g_return_val_if_fail (clipboard != NULL, NULL);
571   g_return_val_if_fail (target != GDK_NONE, NULL);
572
573   device_manager = gdk_display_get_device_manager (clipboard->display);
574   device = gdk_device_manager_get_client_pointer (device_manager);
575
576   if (target == gdk_atom_intern_static_string ("TARGETS")) 
577     {
578       GdkAtom *atoms;
579       gint nr_atoms;
580
581       selection_data = g_slice_new0 (GtkSelectionData);
582       selection_data->selection = GDK_SELECTION_CLIPBOARD;
583       selection_data->target = target;
584
585       nr_atoms = gdk_wayland_device_get_selection_type_atoms (device, &atoms);
586       gtk_selection_data_set (selection_data,
587                               GDK_SELECTION_TYPE_ATOM, 32,
588                               (guchar *)atoms,
589                               32 * nr_atoms);
590
591       g_free (atoms);
592
593       return selection_data;
594     }
595
596   closure = g_new0 (WaitClosure, 1);
597   closure->selection_data = NULL;
598   closure->loop = g_main_loop_new (NULL, TRUE);
599
600   gtk_clipboard_request_contents (clipboard,
601                                   target,
602                                   _wait_for_contents_cb,
603                                   closure);
604
605   if (g_main_loop_is_running (closure->loop))
606     {
607       GDK_THREADS_LEAVE ();
608       g_main_loop_run (closure->loop);
609       GDK_THREADS_ENTER ();
610     }
611
612   g_main_loop_unref (closure->loop);
613
614   selection_data = closure->selection_data;
615
616   g_free (closure);
617
618   return selection_data;
619 }
620
621 gchar *
622 gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
623 {
624   GtkSelectionData *data;
625   gchar *result;
626
627   data =
628     gtk_clipboard_wait_for_contents (clipboard,
629                                      gdk_atom_intern_static_string ("text/plain;charset=utf-8"));
630
631   result = (gchar *)gtk_selection_data_get_text (data);
632
633   gtk_selection_data_free (data);
634
635   return result;
636 }
637
638 GdkPixbuf *
639 gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
640 {
641   const gchar *priority[] = { "image/png",
642       "image/tiff",
643       "image/jpeg",
644       "image/gif",
645       "image/bmp" };
646   int i;
647   GtkSelectionData *data;
648
649   for (i = 0; i < G_N_ELEMENTS (priority); i++) 
650     {
651       data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string (priority[i]));
652
653       if (data)
654         {
655           GdkPixbuf *pixbuf = gtk_selection_data_get_pixbuf (data);
656
657           gtk_selection_data_free (data);
658
659           return pixbuf;
660         }
661     }
662
663   return NULL;
664 }
665
666 guint8 *
667 gtk_clipboard_wait_for_rich_text (GtkClipboard  *clipboard,
668                                   GtkTextBuffer *buffer,
669                                   GdkAtom       *format,
670                                   gsize         *length)
671 {
672   /* FIXME: Implement */
673   return NULL;
674 }
675
676 gchar **
677 gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
678 {
679   GtkSelectionData *data;
680
681   data =
682     gtk_clipboard_wait_for_contents (clipboard,
683                                      gdk_atom_intern_static_string ("text/uri-list"));
684   if (data)
685     {
686       gchar **uris;
687
688       uris = gtk_selection_data_get_uris (data);
689       gtk_selection_data_free (data);
690
691       return uris;
692     }  
693
694   return NULL;
695 }
696
697 GdkDisplay *
698 gtk_clipboard_get_display (GtkClipboard *clipboard)
699 {
700   g_return_val_if_fail (clipboard != NULL, NULL);
701
702   return clipboard->display;
703 }
704
705 gboolean
706 gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
707 {
708   GtkSelectionData *data;
709   gboolean result = FALSE;
710
711   data =
712     gtk_clipboard_wait_for_contents (clipboard,
713                                      gdk_atom_intern_static_string ("TARGETS"));
714   if (data)
715     {
716       result = gtk_selection_data_targets_include_text (data);
717       gtk_selection_data_free (data);
718     }
719
720   return result;
721 }
722
723 gboolean
724 gtk_clipboard_wait_is_rich_text_available (GtkClipboard  *clipboard,
725                                            GtkTextBuffer *buffer)
726 {
727   GtkSelectionData *data;
728   gboolean result = FALSE;
729
730   g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
731   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
732
733   data =
734     gtk_clipboard_wait_for_contents (clipboard,
735                                      gdk_atom_intern_static_string ("TARGETS"));
736   if (data)
737     {
738       result = gtk_selection_data_targets_include_rich_text (data, buffer);
739       gtk_selection_data_free (data);
740     }
741
742   return result;
743 }
744
745 gboolean
746 gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
747 {
748   GtkSelectionData *data;
749   gboolean result = FALSE;
750
751   data =
752     gtk_clipboard_wait_for_contents (clipboard, 
753                                      gdk_atom_intern_static_string ("TARGETS"));
754   if (data)
755     {
756       result = gtk_selection_data_targets_include_image (data, FALSE);
757       gtk_selection_data_free (data);
758     }
759
760   return result;
761 }
762
763 gboolean
764 gtk_clipboard_wait_is_uris_available (GtkClipboard *clipboard)
765 {
766   GtkSelectionData *data;
767   gboolean result = FALSE;
768
769   data =
770     gtk_clipboard_wait_for_contents (clipboard, 
771                                      gdk_atom_intern_static_string ("TARGETS"));
772   if (data)
773     {
774       result = gtk_selection_data_targets_include_uri (data);
775       gtk_selection_data_free (data);
776     }
777
778   return result;
779 }
780
781 gboolean
782 gtk_clipboard_wait_for_targets (GtkClipboard  *clipboard,
783                                 GdkAtom      **targets,
784                                 gint          *n_targets)
785 {
786   GtkSelectionData *data;
787   gboolean result = FALSE;
788
789   g_return_val_if_fail (clipboard != NULL, FALSE);
790
791   data =
792     gtk_clipboard_wait_for_contents (clipboard,
793                                      gdk_atom_intern_static_string ("TARGETS"));
794
795   if (data)
796     {
797       GdkAtom *tmp_targets;
798       gint tmp_n_targets;
799
800       result = gtk_selection_data_get_targets (data,
801                                                &tmp_targets,
802                                                &tmp_n_targets);
803
804       if (n_targets)
805         *n_targets = tmp_n_targets;
806
807       if (targets)
808         *targets = tmp_targets;
809       else
810         g_free (tmp_targets);
811
812       gtk_selection_data_free (data);
813     }
814
815   return result;
816 }
817
818 static void
819 gtk_clipboard_owner_change (GtkClipboard        *clipboard,
820                             GdkEventOwnerChange *event)
821 {
822
823 }
824
825 gboolean
826 gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
827                                         GdkAtom       target)
828 {
829   GdkAtom *targets;
830   gint i, n_targets;
831   gboolean retval = FALSE;
832
833   g_return_val_if_fail (clipboard != NULL, FALSE);
834
835   if (!gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets))
836     return FALSE;
837
838   for (i = 0; i < n_targets; i++)
839     {
840       if (targets[i] == target)
841         {
842           retval = TRUE;
843           break;
844         }
845     }
846
847   g_free (targets);
848
849   return retval;
850 }
851
852 void
853 _gtk_clipboard_handle_event (GdkEventOwnerChange *event)
854 {
855 }
856
857 void
858 gtk_clipboard_set_can_store (GtkClipboard         *clipboard,
859                              const GtkTargetEntry *targets,
860                              gint                  n_targets)
861 {
862   /* FIXME: Implement */
863 }
864
865 void
866 gtk_clipboard_store (GtkClipboard *clipboard)
867 {
868   /* FIXME: Implement */
869 }
870
871 void
872 _gtk_clipboard_store_all (void)
873 {
874   /* FIXME: Implement */
875 }