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