]> Pileus Git - ~andy/gtk/blob - gtk/gtkclipboard.c
Merge branch 'windows_list'
[~andy/gtk] / gtk / gtkclipboard.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2000 Red Hat, Inc.
3  * Copyright (C) 2004 Nokia Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Global clipboard abstraction. 
21  */
22
23 #include "config.h"
24 #include <string.h>
25
26 #include "gtkclipboard.h"
27 #include "gtkinvisible.h"
28 #include "gtkmain.h"
29 #include "gtkmarshalers.h"
30 #include "gtktextbufferrichtext.h"
31 #include "gtkintl.h"
32
33 #ifdef GDK_WINDOWING_X11
34 #include "x11/gdkx.h"
35 #endif
36
37 #ifdef GDK_WINDOWING_WIN32
38 #include "win32/gdkwin32.h"
39 #endif
40
41 enum {
42   OWNER_CHANGE,
43   LAST_SIGNAL
44 };
45
46 typedef struct _GtkClipboardClass GtkClipboardClass;
47
48 typedef struct _RequestContentsInfo RequestContentsInfo;
49 typedef struct _RequestTextInfo RequestTextInfo;
50 typedef struct _RequestRichTextInfo RequestRichTextInfo;
51 typedef struct _RequestImageInfo RequestImageInfo;
52 typedef struct _RequestURIInfo RequestURIInfo;
53 typedef struct _RequestTargetsInfo RequestTargetsInfo;
54
55 struct _GtkClipboard 
56 {
57   GObject parent_instance;
58
59   GdkAtom selection;
60
61   GtkClipboardGetFunc get_func;
62   GtkClipboardClearFunc clear_func;
63   gpointer user_data;
64   gboolean have_owner;
65
66   guint32 timestamp;
67
68   gboolean have_selection;
69   GdkDisplay *display;
70
71   GdkAtom *cached_targets;
72   gint     n_cached_targets;
73
74   guint      notify_signal_id;
75   gboolean   storing_selection;
76   GMainLoop *store_loop;
77   guint      store_timeout;
78   gint       n_storable_targets;
79   GdkAtom   *storable_targets;
80 };
81
82 struct _GtkClipboardClass
83 {
84   GObjectClass parent_class;
85
86   void (*owner_change) (GtkClipboard        *clipboard,
87                         GdkEventOwnerChange *event);
88 };
89
90 struct _RequestContentsInfo
91 {
92   GtkClipboardReceivedFunc callback;
93   gpointer user_data;
94 };
95
96 struct _RequestTextInfo
97 {
98   GtkClipboardTextReceivedFunc callback;
99   gpointer user_data;
100 };
101
102 struct _RequestRichTextInfo
103 {
104   GtkClipboardRichTextReceivedFunc callback;
105   GdkAtom *atoms;
106   gint     n_atoms;
107   gint     current_atom;
108   gpointer user_data;
109 };
110
111 struct _RequestImageInfo
112 {
113   GtkClipboardImageReceivedFunc callback;
114   gpointer user_data;
115 };
116
117 struct _RequestURIInfo
118 {
119   GtkClipboardURIReceivedFunc callback;
120   gpointer user_data;
121 };
122
123 struct _RequestTargetsInfo
124 {
125   GtkClipboardTargetsReceivedFunc callback;
126   gpointer user_data;
127 };
128
129 static void gtk_clipboard_class_init   (GtkClipboardClass   *class);
130 static void gtk_clipboard_finalize     (GObject             *object);
131 static void gtk_clipboard_owner_change (GtkClipboard        *clipboard,
132                                         GdkEventOwnerChange *event);
133
134 static void          clipboard_unset      (GtkClipboard     *clipboard);
135 static void          selection_received   (GtkWidget        *widget,
136                                            GtkSelectionData *selection_data,
137                                            guint             time);
138 static GtkClipboard *clipboard_peek       (GdkDisplay       *display,
139                                            GdkAtom           selection,
140                                            gboolean          only_if_exists);
141 static GtkWidget *   get_clipboard_widget (GdkDisplay       *display);
142
143
144 enum {
145   TARGET_STRING,
146   TARGET_TEXT,
147   TARGET_COMPOUND_TEXT,
148   TARGET_UTF8_STRING,
149   TARGET_SAVE_TARGETS
150 };
151
152 static const gchar request_contents_key[] = "gtk-request-contents";
153 static GQuark request_contents_key_id = 0;
154
155 static const gchar clipboards_owned_key[] = "gtk-clipboards-owned";
156 static GQuark clipboards_owned_key_id = 0;
157
158 static guint         clipboard_signals[LAST_SIGNAL] = { 0 };
159
160 G_DEFINE_TYPE (GtkClipboard, gtk_clipboard, G_TYPE_OBJECT)
161
162 static void
163 gtk_clipboard_init (GtkClipboard *object)
164 {
165 }
166
167 static void
168 gtk_clipboard_class_init (GtkClipboardClass *class)
169 {
170   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
171
172   gobject_class->finalize = gtk_clipboard_finalize;
173
174   class->owner_change = gtk_clipboard_owner_change;
175
176   /**
177    * GtkClipboard::owner-change:
178    * @clipboard: the #GtkClipboard on which the signal is emitted
179    * @event: the @GdkEventOwnerChange event 
180    *
181    * The ::owner-change signal is emitted when GTK+ receives an
182    * event that indicates that the ownership of the selection 
183    * associated with @clipboard has changed.
184    *
185    * Since: 2.6
186    */ 
187   clipboard_signals[OWNER_CHANGE] =
188     g_signal_new (I_("owner-change"),
189                   G_TYPE_FROM_CLASS (gobject_class),
190                   G_SIGNAL_RUN_FIRST,
191                   G_STRUCT_OFFSET (GtkClipboardClass, owner_change),
192                   NULL, NULL,
193                   _gtk_marshal_VOID__BOXED,
194                   G_TYPE_NONE, 1,
195                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
196 }
197
198 static void
199 gtk_clipboard_finalize (GObject *object)
200 {
201   GtkClipboard *clipboard;
202   GtkWidget *clipboard_widget = NULL;
203   GSList *clipboards = NULL;
204
205   clipboard = GTK_CLIPBOARD (object);
206
207   if (clipboard->display)
208     {
209       clipboards = g_object_get_data (G_OBJECT (clipboard->display), "gtk-clipboard-list");
210
211       if (g_slist_index (clipboards, clipboard) >= 0)
212         g_warning ("GtkClipboard prematurely finalized");
213
214       clipboards = g_slist_remove (clipboards, clipboard);
215
216       g_object_set_data (G_OBJECT (clipboard->display), "gtk-clipboard-list", 
217                          clipboards);
218
219       /* don't use get_clipboard_widget() here because it would create the
220        * widget if it doesn't exist.
221        */
222       clipboard_widget = g_object_get_data (G_OBJECT (clipboard->display),
223                                             "gtk-clipboard-widget");
224     }
225
226   clipboard_unset (clipboard);
227
228   if (clipboard->store_loop && g_main_loop_is_running (clipboard->store_loop))
229     g_main_loop_quit (clipboard->store_loop);
230
231   if (clipboard->store_timeout != 0)
232     g_source_remove (clipboard->store_timeout);
233
234   if (clipboard->notify_signal_id != 0)
235     g_signal_handler_disconnect (clipboard_widget, clipboard->notify_signal_id);
236   
237   g_free (clipboard->storable_targets);
238   g_free (clipboard->cached_targets);
239
240   G_OBJECT_CLASS (gtk_clipboard_parent_class)->finalize (object);
241 }
242
243 static void
244 clipboard_display_closed (GdkDisplay   *display,
245                           gboolean      is_error,
246                           GtkClipboard *clipboard)
247 {
248   GSList *clipboards;
249
250   clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
251   g_object_run_dispose (G_OBJECT (clipboard));
252   clipboards = g_slist_remove (clipboards, clipboard);
253   g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
254   g_object_unref (clipboard);
255 }
256
257 /**
258  * gtk_clipboard_get_for_display:
259  * @display: the display for which the clipboard is to be retrieved or created
260  * @selection: a #GdkAtom which identifies the clipboard
261  *             to use.
262  * 
263  * Returns the clipboard object for the given selection.
264  * Cut/copy/paste menu items and keyboard shortcuts should use
265  * the default clipboard, returned by passing %GDK_SELECTION_CLIPBOARD for @selection.
266  * (%GDK_NONE is supported as a synonym for GDK_SELECTION_CLIPBOARD
267  * for backwards compatibility reasons.)
268  * The currently-selected object or text should be provided on the clipboard
269  * identified by #GDK_SELECTION_PRIMARY. Cut/copy/paste menu items
270  * conceptually copy the contents of the #GDK_SELECTION_PRIMARY clipboard
271  * to the default clipboard, i.e. they copy the selection to what the
272  * user sees as the clipboard.
273  *
274  * (Passing #GDK_NONE is the same as using <literal>gdk_atom_intern
275  * ("CLIPBOARD", FALSE)</literal>. See <ulink
276  * url="http://www.freedesktop.org/Standards/clipboards-spec">
277  * http://www.freedesktop.org/Standards/clipboards-spec</ulink>
278  * for a detailed discussion of the "CLIPBOARD" vs. "PRIMARY"
279  * selections under the X window system. On Win32 the
280  * #GDK_SELECTION_PRIMARY clipboard is essentially ignored.)
281  *
282  * It's possible to have arbitrary named clipboards; if you do invent
283  * new clipboards, you should prefix the selection name with an
284  * underscore (because the ICCCM requires that nonstandard atoms are
285  * underscore-prefixed), and namespace it as well. For example,
286  * if your application called "Foo" has a special-purpose
287  * clipboard, you might call it "_FOO_SPECIAL_CLIPBOARD".
288  * 
289  * Return value: (transfer none): the appropriate clipboard object. If no
290  *             clipboard already exists, a new one will
291  *             be created. Once a clipboard object has
292  *             been created, it is persistent and, since
293  *             it is owned by GTK+, must not be freed or
294  *             unrefd.
295  *
296  * Since: 2.2
297  **/
298 GtkClipboard *
299 gtk_clipboard_get_for_display (GdkDisplay *display, 
300                                GdkAtom     selection)
301 {
302   g_return_val_if_fail (display != NULL, NULL); /* See bgo#463773; this is needed because Flash Player sucks */
303   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
304   g_return_val_if_fail (!display->closed, NULL);
305
306   return clipboard_peek (display, selection, FALSE);
307 }
308
309
310 /**
311  * gtk_clipboard_get:
312  * @selection: a #GdkAtom which identifies the clipboard to use
313  *
314  * Returns the clipboard object for the given selection.
315  * See gtk_clipboard_get_for_display() for complete details.
316  *
317  * Return value: (transfer none): the appropriate clipboard object. If no clipboard
318  *     already exists, a new one will be created. Once a clipboard
319  *     object has been created, it is persistent and, since it is
320  *     owned by GTK+, must not be freed or unreffed.
321  */
322 GtkClipboard *
323 gtk_clipboard_get (GdkAtom selection)
324 {
325   return gtk_clipboard_get_for_display (gdk_display_get_default (), selection);
326 }
327
328 static void 
329 selection_get_cb (GtkWidget          *widget,
330                   GtkSelectionData   *selection_data,
331                   guint               info,
332                   guint               time)
333 {
334   GtkClipboard *clipboard = gtk_widget_get_clipboard (widget, selection_data->selection);
335
336   if (clipboard && clipboard->get_func)
337     clipboard->get_func (clipboard, selection_data, info, clipboard->user_data);
338 }
339
340 static gboolean
341 selection_clear_event_cb (GtkWidget         *widget,
342                           GdkEventSelection *event)
343 {
344   GtkClipboard *clipboard = gtk_widget_get_clipboard (widget, event->selection);
345
346   if (clipboard)
347     {
348       clipboard_unset (clipboard);
349
350       return TRUE;
351     }
352
353   return FALSE;
354 }
355
356 static GtkWidget *
357 make_clipboard_widget (GdkDisplay *display, 
358                        gboolean    provider)
359 {
360   GtkWidget *widget = gtk_invisible_new_for_screen (gdk_display_get_default_screen (display));
361
362   g_signal_connect (widget, "selection-received",
363                     G_CALLBACK (selection_received), NULL);
364
365   if (provider)
366     {
367       /* We need this for gdk_x11_get_server_time() */
368       gtk_widget_add_events (widget, GDK_PROPERTY_CHANGE_MASK);
369       
370       g_signal_connect (widget, "selection-get",
371                         G_CALLBACK (selection_get_cb), NULL);
372       g_signal_connect (widget, "selection-clear-event",
373                         G_CALLBACK (selection_clear_event_cb), NULL);
374     }
375
376   return widget;
377 }
378
379 static GtkWidget *
380 get_clipboard_widget (GdkDisplay *display)
381 {
382   GtkWidget *clip_widget = g_object_get_data (G_OBJECT (display), "gtk-clipboard-widget");
383   if (!clip_widget)
384     {
385       clip_widget = make_clipboard_widget (display, TRUE);
386       g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-widget"), clip_widget);
387     }
388
389   return clip_widget;
390 }
391
392 /* This function makes a very good guess at what the correct
393  * timestamp for a selection request should be. If there is
394  * a currently processed event, it uses the timestamp for that
395  * event, otherwise it uses the current server time. However,
396  * if the time resulting from that is older than the time used
397  * last time, it uses the time used last time instead.
398  *
399  * In order implement this correctly, we never use CurrentTime,
400  * but actually retrieve the actual timestamp from the server.
401  * This is a little slower but allows us to make the guarantee
402  * that the times used by this application will always ascend
403  * and we won't get selections being rejected just because
404  * we are using a correct timestamp from an event, but used
405  * CurrentTime previously.
406  */
407 static guint32
408 clipboard_get_timestamp (GtkClipboard *clipboard)
409 {
410   GtkWidget *clipboard_widget = get_clipboard_widget (clipboard->display);
411   guint32 timestamp = gtk_get_current_event_time ();
412
413   if (timestamp == GDK_CURRENT_TIME)
414     {
415 #ifdef GDK_WINDOWING_X11
416       timestamp = gdk_x11_get_server_time (clipboard_widget->window);
417 #elif defined GDK_WINDOWING_WIN32
418       timestamp = GetMessageTime ();
419 #endif
420     }
421   else
422     {
423       if (clipboard->timestamp != GDK_CURRENT_TIME)
424         {
425           /* Check to see if clipboard->timestamp is newer than
426            * timestamp, accounting for wraparound.
427            */
428
429           guint32 max = timestamp + 0x80000000;
430
431           if ((max > timestamp &&
432                (clipboard->timestamp > timestamp &&
433                 clipboard->timestamp <= max)) ||
434               (max <= timestamp &&
435                (clipboard->timestamp > timestamp ||
436                 clipboard->timestamp <= max)))
437             {
438               timestamp = clipboard->timestamp;
439             }
440         }
441     }
442
443   clipboard->timestamp = timestamp;
444
445   return timestamp;
446 }
447
448 static void
449 clipboard_owner_destroyed (gpointer data)
450 {
451   GSList *clipboards = data;
452   GSList *tmp_list;
453
454   tmp_list = clipboards;
455   while (tmp_list)
456     {
457       GtkClipboard *clipboard = tmp_list->data;
458
459       clipboard->get_func = NULL;
460       clipboard->clear_func = NULL;
461       clipboard->user_data = NULL;
462       clipboard->have_owner = FALSE;
463
464       gtk_clipboard_clear (clipboard);
465
466       tmp_list = tmp_list->next;
467     }
468   
469   g_slist_free (clipboards);
470 }
471
472 static void
473 clipboard_add_owner_notify (GtkClipboard *clipboard)
474 {
475   if (!clipboards_owned_key_id)
476     clipboards_owned_key_id = g_quark_from_static_string (clipboards_owned_key);
477   
478   if (clipboard->have_owner)
479     g_object_set_qdata_full (clipboard->user_data, clipboards_owned_key_id,
480                              g_slist_prepend (g_object_steal_qdata (clipboard->user_data,
481                                                                     clipboards_owned_key_id),
482                                               clipboard),
483                              clipboard_owner_destroyed);
484 }
485
486 static void
487 clipboard_remove_owner_notify (GtkClipboard *clipboard)
488 {
489   if (clipboard->have_owner)
490      g_object_set_qdata_full (clipboard->user_data, clipboards_owned_key_id,
491                               g_slist_remove (g_object_steal_qdata (clipboard->user_data,
492                                                                     clipboards_owned_key_id),
493                                               clipboard),
494                               clipboard_owner_destroyed);
495 }
496           
497 static gboolean
498 gtk_clipboard_set_contents (GtkClipboard         *clipboard,
499                             const GtkTargetEntry *targets,
500                             guint                 n_targets,
501                             GtkClipboardGetFunc   get_func,
502                             GtkClipboardClearFunc clear_func,
503                             gpointer              user_data,
504                             gboolean              have_owner)
505 {
506   GtkWidget *clipboard_widget = get_clipboard_widget (clipboard->display);
507
508   if (gtk_selection_owner_set_for_display (clipboard->display,
509                                            clipboard_widget,
510                                            clipboard->selection,
511                                            clipboard_get_timestamp (clipboard)))
512     {
513       clipboard->have_selection = TRUE;
514
515       if (clipboard->n_cached_targets != -1)
516         {
517           g_free (clipboard->cached_targets);
518           clipboard->cached_targets = NULL;
519           clipboard->n_cached_targets = -1;
520         }
521
522       if (!(clipboard->have_owner && have_owner) ||
523           clipboard->user_data != user_data)
524         {
525           clipboard_unset (clipboard);
526
527           if (clipboard->get_func)
528             {
529               /* Calling unset() caused the clipboard contents to be reset!
530                * Avoid leaking and return 
531                */
532               if (!(clipboard->have_owner && have_owner) ||
533                   clipboard->user_data != user_data)
534                 {
535                   (*clear_func) (clipboard, user_data);
536                   return FALSE;
537                 }
538               else
539                 return TRUE;
540             }
541           else
542             {
543               clipboard->user_data = user_data;
544               clipboard->have_owner = have_owner;
545               if (have_owner)
546                 clipboard_add_owner_notify (clipboard);
547             }
548           
549         }
550
551       clipboard->get_func = get_func;
552       clipboard->clear_func = clear_func;
553
554       gtk_selection_clear_targets (clipboard_widget, clipboard->selection);
555       gtk_selection_add_targets (clipboard_widget, clipboard->selection,
556                                  targets, n_targets);
557
558       return TRUE;
559     }
560   else
561     return FALSE;
562 }
563
564 /**
565  * gtk_clipboard_set_with_data:
566  * @clipboard:  a #GtkClipboard
567  * @targets:    array containing information about the available forms for the
568  *              clipboard data
569  * @n_targets:  number of elements in @targets
570  * @get_func:   function to call to get the actual clipboard data
571  * @clear_func: when the clipboard contents are set again, this function will
572  *              be called, and @get_func will not be subsequently called.
573  * @user_data:  user data to pass to @get_func and @clear_func.
574  * 
575  * Virtually sets the contents of the specified clipboard by providing
576  * a list of supported formats for the clipboard data and a function
577  * to call to get the actual data when it is requested.
578  * 
579  * Return value: %TRUE if setting the clipboard data succeeded. If setting
580  *               the clipboard data failed the provided callback functions
581  *               will be ignored.
582  **/
583 gboolean
584 gtk_clipboard_set_with_data (GtkClipboard          *clipboard,
585                              const GtkTargetEntry  *targets,
586                              guint                  n_targets,
587                              GtkClipboardGetFunc    get_func,
588                              GtkClipboardClearFunc  clear_func,
589                              gpointer               user_data)
590 {
591   g_return_val_if_fail (clipboard != NULL, FALSE);
592   g_return_val_if_fail (targets != NULL, FALSE);
593   g_return_val_if_fail (get_func != NULL, FALSE);
594
595   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
596                                      get_func, clear_func, user_data,
597                                      FALSE);
598 }
599
600 /**
601  * gtk_clipboard_set_with_owner:
602  * @clipboard:  a #GtkClipboard
603  * @targets:    array containing information about the available forms for the
604  *              clipboard data
605  * @n_targets:  number of elements in @targets
606  * @get_func:   function to call to get the actual clipboard data
607  * @clear_func: when the clipboard contents are set again, this function will
608  *              be called, and @get_func will not be subsequently called.
609  * @owner:      an object that "owns" the data. This object will be passed
610  *              to the callbacks when called. 
611  * 
612  * Virtually sets the contents of the specified clipboard by providing
613  * a list of supported formats for the clipboard data and a function
614  * to call to get the actual data when it is requested.
615  *
616  * The difference between this function and gtk_clipboard_set_with_data()
617  * is that instead of an generic @user_data pointer, a #GObject is passed
618  * in. 
619  * 
620  * Return value: %TRUE if setting the clipboard data succeeded. If setting
621  *               the clipboard data failed the provided callback functions
622  *               will be ignored.
623  **/
624 gboolean
625 gtk_clipboard_set_with_owner (GtkClipboard          *clipboard,
626                               const GtkTargetEntry  *targets,
627                               guint                  n_targets,
628                               GtkClipboardGetFunc    get_func,
629                               GtkClipboardClearFunc  clear_func,
630                               GObject               *owner)
631 {
632   g_return_val_if_fail (clipboard != NULL, FALSE);
633   g_return_val_if_fail (targets != NULL, FALSE);
634   g_return_val_if_fail (get_func != NULL, FALSE);
635   g_return_val_if_fail (G_IS_OBJECT (owner), FALSE);
636
637   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
638                                      get_func, clear_func, owner,
639                                      TRUE);
640 }
641
642 /**
643  * gtk_clipboard_get_owner:
644  * @clipboard: a #GtkClipboard
645  * 
646  * If the clipboard contents callbacks were set with 
647  * gtk_clipboard_set_with_owner(), and the gtk_clipboard_set_with_data() or 
648  * gtk_clipboard_clear() has not subsequently called, returns the owner set 
649  * by gtk_clipboard_set_with_owner().
650  * 
651  * Return value: the owner of the clipboard, if any; otherwise %NULL.
652  **/
653 GObject *
654 gtk_clipboard_get_owner (GtkClipboard *clipboard)
655 {
656   g_return_val_if_fail (clipboard != NULL, NULL);
657
658   if (clipboard->have_owner)
659     return clipboard->user_data;
660   else
661     return NULL;
662 }
663
664 static void
665 clipboard_unset (GtkClipboard *clipboard)
666 {
667   GtkClipboardClearFunc old_clear_func;
668   gpointer old_data;
669   gboolean old_have_owner;
670   gint old_n_storable_targets;
671   
672   old_clear_func = clipboard->clear_func;
673   old_data = clipboard->user_data;
674   old_have_owner = clipboard->have_owner;
675   old_n_storable_targets = clipboard->n_storable_targets;
676   
677   if (old_have_owner)
678     {
679       clipboard_remove_owner_notify (clipboard);
680       clipboard->have_owner = FALSE;
681     }
682
683   clipboard->n_storable_targets = -1;
684   g_free (clipboard->storable_targets);
685   clipboard->storable_targets = NULL;
686       
687   clipboard->get_func = NULL;
688   clipboard->clear_func = NULL;
689   clipboard->user_data = NULL;
690   
691   if (old_clear_func)
692     old_clear_func (clipboard, old_data);
693
694   /* If we've transferred the clipboard data to the manager,
695    * unref the owner
696    */
697   if (old_have_owner &&
698       old_n_storable_targets != -1)
699     g_object_unref (old_data);
700 }
701
702 /**
703  * gtk_clipboard_clear:
704  * @clipboard:  a #GtkClipboard
705  * 
706  * Clears the contents of the clipboard. Generally this should only
707  * be called between the time you call gtk_clipboard_set_with_owner()
708  * or gtk_clipboard_set_with_data(),
709  * and when the @clear_func you supplied is called. Otherwise, the
710  * clipboard may be owned by someone else.
711  **/
712 void
713 gtk_clipboard_clear (GtkClipboard *clipboard)
714 {
715   g_return_if_fail (clipboard != NULL);
716
717   if (clipboard->have_selection)
718     gtk_selection_owner_set_for_display (clipboard->display, 
719                                          NULL,
720                                          clipboard->selection,
721                                          clipboard_get_timestamp (clipboard));
722 }
723
724 static void 
725 text_get_func (GtkClipboard     *clipboard,
726                GtkSelectionData *selection_data,
727                guint             info,
728                gpointer          data)
729 {
730   gtk_selection_data_set_text (selection_data, data, -1);
731 }
732
733 static void 
734 text_clear_func (GtkClipboard *clipboard,
735                  gpointer      data)
736 {
737   g_free (data);
738 }
739
740
741 /**
742  * gtk_clipboard_set_text:
743  * @clipboard: a #GtkClipboard object
744  * @text:      a UTF-8 string.
745  * @len:       length of @text, in bytes, or -1, in which case
746  *             the length will be determined with <function>strlen()</function>.
747  * 
748  * Sets the contents of the clipboard to the given UTF-8 string. GTK+ will
749  * make a copy of the text and take responsibility for responding
750  * for requests for the text, and for converting the text into
751  * the requested format.
752  **/
753 void 
754 gtk_clipboard_set_text (GtkClipboard *clipboard,
755                         const gchar  *text,
756                         gint          len)
757 {
758   GtkTargetList *list;
759   GtkTargetEntry *targets;
760   gint n_targets;
761
762   g_return_if_fail (clipboard != NULL);
763   g_return_if_fail (text != NULL);
764
765   list = gtk_target_list_new (NULL, 0);
766   gtk_target_list_add_text_targets (list, 0);
767
768   targets = gtk_target_table_new_from_list (list, &n_targets);
769   
770   if (len < 0)
771     len = strlen (text);
772   
773   gtk_clipboard_set_with_data (clipboard, 
774                                targets, n_targets,
775                                text_get_func, text_clear_func,
776                                g_strndup (text, len));
777   gtk_clipboard_set_can_store (clipboard, NULL, 0);
778
779   gtk_target_table_free (targets, n_targets);
780   gtk_target_list_unref (list);
781 }
782
783 static void 
784 pixbuf_get_func (GtkClipboard     *clipboard,
785                  GtkSelectionData *selection_data,
786                  guint             info,
787                  gpointer          data)
788 {
789   gtk_selection_data_set_pixbuf (selection_data, data);
790 }
791
792 static void 
793 pixbuf_clear_func (GtkClipboard *clipboard,
794                    gpointer      data)
795 {
796   g_object_unref (data);
797 }
798
799 /**
800  * gtk_clipboard_set_image:
801  * @clipboard: a #GtkClipboard object
802  * @pixbuf:    a #GdkPixbuf 
803  * 
804  * Sets the contents of the clipboard to the given #GdkPixbuf. 
805  * GTK+ will take responsibility for responding for requests 
806  * for the image, and for converting the image into the 
807  * requested format.
808  * 
809  * Since: 2.6
810  **/
811 void
812 gtk_clipboard_set_image (GtkClipboard *clipboard,
813                           GdkPixbuf    *pixbuf)
814 {
815   GtkTargetList *list;
816   GtkTargetEntry *targets;
817   gint n_targets;
818
819   g_return_if_fail (clipboard != NULL);
820   g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
821
822   list = gtk_target_list_new (NULL, 0);
823   gtk_target_list_add_image_targets (list, 0, TRUE);
824
825   targets = gtk_target_table_new_from_list (list, &n_targets);
826
827   gtk_clipboard_set_with_data (clipboard, 
828                                targets, n_targets,
829                                pixbuf_get_func, pixbuf_clear_func,
830                                g_object_ref (pixbuf));
831   gtk_clipboard_set_can_store (clipboard, NULL, 0);
832
833   gtk_target_table_free (targets, n_targets);
834   gtk_target_list_unref (list);
835 }
836
837 static void
838 set_request_contents_info (GtkWidget           *widget,
839                            RequestContentsInfo *info)
840 {
841   if (!request_contents_key_id)
842     request_contents_key_id = g_quark_from_static_string (request_contents_key);
843
844   g_object_set_qdata (G_OBJECT (widget), request_contents_key_id, info);
845 }
846
847 static RequestContentsInfo *
848 get_request_contents_info (GtkWidget *widget)
849 {
850   if (!request_contents_key_id)
851     return NULL;
852   else
853     return g_object_get_qdata (G_OBJECT (widget), request_contents_key_id);
854 }
855
856 static void 
857 selection_received (GtkWidget            *widget,
858                     GtkSelectionData     *selection_data,
859                     guint                 time)
860 {
861   RequestContentsInfo *request_info = get_request_contents_info (widget);
862   set_request_contents_info (widget, NULL);
863   
864   request_info->callback (gtk_widget_get_clipboard (widget, selection_data->selection), 
865                           selection_data,
866                           request_info->user_data);
867
868   g_free (request_info);
869
870   if (widget != get_clipboard_widget (gtk_widget_get_display (widget)))
871     gtk_widget_destroy (widget);
872 }
873
874 /**
875  * gtk_clipboard_request_contents:
876  * @clipboard: a #GtkClipboard
877  * @target:    an atom representing the form into which the clipboard
878  *             owner should convert the selection.
879  * @callback:  A function to call when the results are received
880  *             (or the retrieval fails). If the retrieval fails
881  *             the length field of @selection_data will be
882  *             negative.
883  * @user_data: user data to pass to @callback
884  * 
885  * Requests the contents of clipboard as the given target.
886  * When the results of the result are later received the supplied callback
887  * will be called.
888  **/
889 void 
890 gtk_clipboard_request_contents (GtkClipboard            *clipboard,
891                                 GdkAtom                  target,
892                                 GtkClipboardReceivedFunc callback,
893                                 gpointer                 user_data)
894 {
895   RequestContentsInfo *info;
896   GtkWidget *widget;
897   GtkWidget *clipboard_widget;
898
899   g_return_if_fail (clipboard != NULL);
900   g_return_if_fail (target != GDK_NONE);
901   g_return_if_fail (callback != NULL);
902   
903   clipboard_widget = get_clipboard_widget (clipboard->display);
904
905   if (get_request_contents_info (clipboard_widget))
906     widget = make_clipboard_widget (clipboard->display, FALSE);
907   else
908     widget = clipboard_widget;
909
910   info = g_new (RequestContentsInfo, 1);
911   info->callback = callback;
912   info->user_data = user_data;
913
914   set_request_contents_info (widget, info);
915
916   gtk_selection_convert (widget, clipboard->selection, target,
917                          clipboard_get_timestamp (clipboard));
918 }
919
920 static void 
921 request_text_received_func (GtkClipboard     *clipboard,
922                             GtkSelectionData *selection_data,
923                             gpointer          data)
924 {
925   RequestTextInfo *info = data;
926   gchar *result = NULL;
927
928   result = (gchar *) gtk_selection_data_get_text (selection_data);
929
930   if (!result)
931     {
932       /* If we asked for UTF8 and didn't get it, try compound_text;
933        * if we asked for compound_text and didn't get it, try string;
934        * If we asked for anything else and didn't get it, give up.
935        */
936       if (selection_data->target == gdk_atom_intern_static_string ("UTF8_STRING"))
937         {
938           gtk_clipboard_request_contents (clipboard,
939                                           gdk_atom_intern_static_string ("COMPOUND_TEXT"), 
940                                           request_text_received_func, info);
941           return;
942         }
943       else if (selection_data->target == gdk_atom_intern_static_string ("COMPOUND_TEXT"))
944         {
945           gtk_clipboard_request_contents (clipboard,
946                                           GDK_TARGET_STRING, 
947                                           request_text_received_func, info);
948           return;
949         }
950     }
951
952   info->callback (clipboard, result, info->user_data);
953   g_free (info);
954   g_free (result);
955 }
956
957 /**
958  * gtk_clipboard_request_text:
959  * @clipboard: a #GtkClipboard
960  * @callback:  a function to call when the text is received,
961  *             or the retrieval fails. (It will always be called
962  *             one way or the other.)
963  * @user_data: user data to pass to @callback.
964  * 
965  * Requests the contents of the clipboard as text. When the text is
966  * later received, it will be converted to UTF-8 if necessary, and
967  * @callback will be called. 
968  *
969  * The @text parameter to @callback will contain the resulting text if
970  * the request succeeded, or %NULL if it failed. This could happen for
971  * various reasons, in particular if the clipboard was empty or if the
972  * contents of the clipboard could not be converted into text form.
973  **/
974 void 
975 gtk_clipboard_request_text (GtkClipboard                *clipboard,
976                             GtkClipboardTextReceivedFunc callback,
977                             gpointer                     user_data)
978 {
979   RequestTextInfo *info;
980   
981   g_return_if_fail (clipboard != NULL);
982   g_return_if_fail (callback != NULL);
983   
984   info = g_new (RequestTextInfo, 1);
985   info->callback = callback;
986   info->user_data = user_data;
987
988   gtk_clipboard_request_contents (clipboard, gdk_atom_intern_static_string ("UTF8_STRING"),
989                                   request_text_received_func,
990                                   info);
991 }
992
993 static void
994 request_rich_text_received_func (GtkClipboard     *clipboard,
995                                  GtkSelectionData *selection_data,
996                                  gpointer          data)
997 {
998   RequestRichTextInfo *info = data;
999   guint8 *result = NULL;
1000   gsize length = 0;
1001
1002   result = selection_data->data;
1003   length = selection_data->length;
1004
1005   info->current_atom++;
1006
1007   if ((!result || length < 1) && (info->current_atom < info->n_atoms))
1008     {
1009       gtk_clipboard_request_contents (clipboard, info->atoms[info->current_atom],
1010                                       request_rich_text_received_func,
1011                                       info);
1012       return;
1013     }
1014
1015   info->callback (clipboard, selection_data->target, result, length,
1016                   info->user_data);
1017   g_free (info->atoms);
1018   g_free (info);
1019 }
1020
1021 /**
1022  * gtk_clipboard_request_rich_text:
1023  * @clipboard: a #GtkClipboard
1024  * @buffer:    a #GtkTextBuffer
1025  * @callback:  a function to call when the text is received,
1026  *             or the retrieval fails. (It will always be called
1027  *             one way or the other.)
1028  * @user_data: user data to pass to @callback.
1029  *
1030  * Requests the contents of the clipboard as rich text. When the rich
1031  * text is later received, @callback will be called.
1032  *
1033  * The @text parameter to @callback will contain the resulting rich
1034  * text if the request succeeded, or %NULL if it failed. The @length
1035  * parameter will contain @text's length. This function can fail for
1036  * various reasons, in particular if the clipboard was empty or if the
1037  * contents of the clipboard could not be converted into rich text form.
1038  *
1039  * Since: 2.10
1040  **/
1041 void
1042 gtk_clipboard_request_rich_text (GtkClipboard                    *clipboard,
1043                                  GtkTextBuffer                   *buffer,
1044                                  GtkClipboardRichTextReceivedFunc callback,
1045                                  gpointer                         user_data)
1046 {
1047   RequestRichTextInfo *info;
1048
1049   g_return_if_fail (clipboard != NULL);
1050   g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1051   g_return_if_fail (callback != NULL);
1052
1053   info = g_new (RequestRichTextInfo, 1);
1054   info->callback = callback;
1055   info->atoms = NULL;
1056   info->n_atoms = 0;
1057   info->current_atom = 0;
1058   info->user_data = user_data;
1059
1060   info->atoms = gtk_text_buffer_get_deserialize_formats (buffer, &info->n_atoms);
1061
1062   gtk_clipboard_request_contents (clipboard, info->atoms[info->current_atom],
1063                                   request_rich_text_received_func,
1064                                   info);
1065 }
1066
1067 static void 
1068 request_image_received_func (GtkClipboard     *clipboard,
1069                              GtkSelectionData *selection_data,
1070                              gpointer          data)
1071 {
1072   RequestImageInfo *info = data;
1073   GdkPixbuf *result = NULL;
1074
1075   result = gtk_selection_data_get_pixbuf (selection_data);
1076
1077   if (!result)
1078     {
1079       /* If we asked for image/png and didn't get it, try image/jpeg;
1080        * if we asked for image/jpeg and didn't get it, try image/gif;
1081        * if we asked for image/gif and didn't get it, try image/bmp;
1082        * If we asked for anything else and didn't get it, give up.
1083        */
1084       if (selection_data->target == gdk_atom_intern_static_string ("image/png"))
1085         {
1086           gtk_clipboard_request_contents (clipboard,
1087                                           gdk_atom_intern_static_string ("image/jpeg"), 
1088                                           request_image_received_func, info);
1089           return;
1090         }
1091       else if (selection_data->target == gdk_atom_intern_static_string ("image/jpeg"))
1092         {
1093           gtk_clipboard_request_contents (clipboard,
1094                                           gdk_atom_intern_static_string ("image/gif"), 
1095                                           request_image_received_func, info);
1096           return;
1097         }
1098       else if (selection_data->target == gdk_atom_intern_static_string ("image/gif"))
1099         {
1100           gtk_clipboard_request_contents (clipboard,
1101                                           gdk_atom_intern_static_string ("image/bmp"), 
1102                                           request_image_received_func, info);
1103           return;
1104         }
1105     }
1106
1107   info->callback (clipboard, result, info->user_data);
1108   g_free (info);
1109
1110   if (result)
1111     g_object_unref (result);
1112 }
1113
1114 /**
1115  * gtk_clipboard_request_image:
1116  * @clipboard: a #GtkClipboard
1117  * @callback:  a function to call when the image is received,
1118  *             or the retrieval fails. (It will always be called
1119  *             one way or the other.)
1120  * @user_data: user data to pass to @callback.
1121  * 
1122  * Requests the contents of the clipboard as image. When the image is
1123  * later received, it will be converted to a #GdkPixbuf, and
1124  * @callback will be called. 
1125  *
1126  * The @pixbuf parameter to @callback will contain the resulting 
1127  * #GdkPixbuf if the request succeeded, or %NULL if it failed. This 
1128  * could happen for various reasons, in particular if the clipboard 
1129  * was empty or if the contents of the clipboard could not be 
1130  * converted into an image.
1131  *
1132  * Since: 2.6
1133  **/
1134 void 
1135 gtk_clipboard_request_image (GtkClipboard                  *clipboard,
1136                              GtkClipboardImageReceivedFunc  callback,
1137                              gpointer                       user_data)
1138 {
1139   RequestImageInfo *info;
1140   
1141   g_return_if_fail (clipboard != NULL);
1142   g_return_if_fail (callback != NULL);
1143   
1144   info = g_new (RequestImageInfo, 1);
1145   info->callback = callback;
1146   info->user_data = user_data;
1147
1148   gtk_clipboard_request_contents (clipboard, 
1149                                   gdk_atom_intern_static_string ("image/png"),
1150                                   request_image_received_func,
1151                                   info);
1152 }
1153
1154 static void 
1155 request_uris_received_func (GtkClipboard     *clipboard,
1156                             GtkSelectionData *selection_data,
1157                             gpointer          data)
1158 {
1159   RequestURIInfo *info = data;
1160   gchar **uris;
1161
1162   uris = gtk_selection_data_get_uris (selection_data);
1163   info->callback (clipboard, uris, info->user_data);
1164   g_strfreev (uris);
1165
1166   g_slice_free (RequestURIInfo, info);
1167 }
1168
1169 /**
1170  * gtk_clipboard_request_uris:
1171  * @clipboard: a #GtkClipboard
1172  * @callback:  a function to call when the URIs are received,
1173  *             or the retrieval fails. (It will always be called
1174  *             one way or the other.)
1175  * @user_data: user data to pass to @callback.
1176  * 
1177  * Requests the contents of the clipboard as URIs. When the URIs are
1178  * later received @callback will be called.
1179  *
1180  * The @uris parameter to @callback will contain the resulting array of
1181  * URIs if the request succeeded, or %NULL if it failed. This could happen
1182  * for various reasons, in particular if the clipboard was empty or if the
1183  * contents of the clipboard could not be converted into URI form.
1184  *
1185  * Since: 2.14
1186  **/
1187 void 
1188 gtk_clipboard_request_uris (GtkClipboard                *clipboard,
1189                             GtkClipboardURIReceivedFunc  callback,
1190                             gpointer                     user_data)
1191 {
1192   RequestURIInfo *info;
1193   
1194   g_return_if_fail (clipboard != NULL);
1195   g_return_if_fail (callback != NULL);
1196   
1197   info = g_slice_new (RequestURIInfo);
1198   info->callback = callback;
1199   info->user_data = user_data;
1200
1201   gtk_clipboard_request_contents (clipboard, gdk_atom_intern_static_string ("text/uri-list"),
1202                                   request_uris_received_func,
1203                                   info);
1204 }
1205
1206 static void 
1207 request_targets_received_func (GtkClipboard     *clipboard,
1208                                GtkSelectionData *selection_data,
1209                                gpointer          data)
1210 {
1211   RequestTargetsInfo *info = data;
1212   GdkAtom *targets = NULL;
1213   gint n_targets = 0;
1214
1215   gtk_selection_data_get_targets (selection_data, &targets, &n_targets);
1216
1217   info->callback (clipboard, targets, n_targets, info->user_data);
1218
1219   g_free (info);
1220   g_free (targets);
1221 }
1222
1223 /**
1224  * gtk_clipboard_request_targets:
1225  * @clipboard: a #GtkClipboard
1226  * @callback:  a function to call when the targets are received,
1227  *             or the retrieval fails. (It will always be called
1228  *             one way or the other.)
1229  * @user_data: user data to pass to @callback.
1230  * 
1231  * Requests the contents of the clipboard as list of supported targets. 
1232  * When the list is later received, @callback will be called. 
1233  *
1234  * The @targets parameter to @callback will contain the resulting targets if
1235  * the request succeeded, or %NULL if it failed.
1236  *
1237  * Since: 2.4
1238  **/
1239 void 
1240 gtk_clipboard_request_targets (GtkClipboard                *clipboard,
1241                                GtkClipboardTargetsReceivedFunc callback,
1242                                gpointer                     user_data)
1243 {
1244   RequestTargetsInfo *info;
1245   
1246   g_return_if_fail (clipboard != NULL);
1247   g_return_if_fail (callback != NULL);
1248
1249   /* If the display supports change notification we cache targets */
1250   if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)) &&
1251       clipboard->n_cached_targets != -1)
1252     {
1253       (* callback) (clipboard, clipboard->cached_targets, clipboard->n_cached_targets, user_data);
1254       return;
1255     }
1256   
1257   info = g_new (RequestTargetsInfo, 1);
1258   info->callback = callback;
1259   info->user_data = user_data;
1260
1261   gtk_clipboard_request_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"),
1262                                   request_targets_received_func,
1263                                   info);
1264 }
1265
1266 typedef struct
1267 {
1268   GMainLoop *loop;
1269   gpointer data;
1270   GdkAtom format; /* used by rich text */
1271   gsize length; /* used by rich text */
1272 } WaitResults;
1273
1274 static void 
1275 clipboard_received_func (GtkClipboard     *clipboard,
1276                          GtkSelectionData *selection_data,
1277                          gpointer          data)
1278 {
1279   WaitResults *results = data;
1280
1281   if (selection_data->length >= 0)
1282     results->data = gtk_selection_data_copy (selection_data);
1283   
1284   g_main_loop_quit (results->loop);
1285 }
1286
1287 /**
1288  * gtk_clipboard_wait_for_contents:
1289  * @clipboard: a #GtkClipboard
1290  * @target: an atom representing the form into which the clipboard
1291  *          owner should convert the selection.
1292  * 
1293  * Requests the contents of the clipboard using the given target.
1294  * This function waits for the data to be received using the main 
1295  * loop, so events, timeouts, etc, may be dispatched during the wait.
1296  * 
1297  * Return value: a newly-allocated #GtkSelectionData object or %NULL
1298  *               if retrieving the given target failed. If non-%NULL,
1299  *               this value must be freed with gtk_selection_data_free() 
1300  *               when you are finished with it.
1301  **/
1302 GtkSelectionData *
1303 gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
1304                                  GdkAtom       target)
1305 {
1306   WaitResults results;
1307
1308   g_return_val_if_fail (clipboard != NULL, NULL);
1309   g_return_val_if_fail (target != GDK_NONE, NULL);
1310   
1311   results.data = NULL;
1312   results.loop = g_main_loop_new (NULL, TRUE);
1313
1314   gtk_clipboard_request_contents (clipboard, target, 
1315                                   clipboard_received_func,
1316                                   &results);
1317
1318   if (g_main_loop_is_running (results.loop))
1319     {
1320       GDK_THREADS_LEAVE ();
1321       g_main_loop_run (results.loop);
1322       GDK_THREADS_ENTER ();
1323     }
1324
1325   g_main_loop_unref (results.loop);
1326
1327   return results.data;
1328 }
1329
1330 static void 
1331 clipboard_text_received_func (GtkClipboard *clipboard,
1332                               const gchar  *text,
1333                               gpointer      data)
1334 {
1335   WaitResults *results = data;
1336
1337   results->data = g_strdup (text);
1338   g_main_loop_quit (results->loop);
1339 }
1340
1341 /**
1342  * gtk_clipboard_wait_for_text:
1343  * @clipboard: a #GtkClipboard
1344  * 
1345  * Requests the contents of the clipboard as text and converts
1346  * the result to UTF-8 if necessary. This function waits for
1347  * the data to be received using the main loop, so events,
1348  * timeouts, etc, may be dispatched during the wait.
1349  * 
1350  * Return value: a newly-allocated UTF-8 string which must
1351  *               be freed with g_free(), or %NULL if retrieving
1352  *               the selection data failed. (This could happen
1353  *               for various reasons, in particular if the
1354  *               clipboard was empty or if the contents of the
1355  *               clipboard could not be converted into text form.)
1356  **/
1357 gchar *
1358 gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
1359 {
1360   WaitResults results;
1361
1362   g_return_val_if_fail (clipboard != NULL, NULL);
1363   
1364   results.data = NULL;
1365   results.loop = g_main_loop_new (NULL, TRUE);
1366
1367   gtk_clipboard_request_text (clipboard,
1368                               clipboard_text_received_func,
1369                               &results);
1370
1371   if (g_main_loop_is_running (results.loop))
1372     {
1373       GDK_THREADS_LEAVE ();
1374       g_main_loop_run (results.loop);
1375       GDK_THREADS_ENTER ();
1376     }
1377
1378   g_main_loop_unref (results.loop);
1379
1380   return results.data;
1381 }
1382
1383 static void
1384 clipboard_rich_text_received_func (GtkClipboard *clipboard,
1385                                    GdkAtom       format,
1386                                    const guint8 *text,
1387                                    gsize         length,
1388                                    gpointer      data)
1389 {
1390   WaitResults *results = data;
1391
1392   results->data = g_memdup (text, length);
1393   results->format = format;
1394   results->length = length;
1395   g_main_loop_quit (results->loop);
1396 }
1397
1398 /**
1399  * gtk_clipboard_wait_for_rich_text:
1400  * @clipboard: a #GtkClipboard
1401  * @buffer: a #GtkTextBuffer
1402  * @format: return location for the format of the returned data
1403  * @length: return location for the length of the returned data
1404  *
1405  * Requests the contents of the clipboard as rich text.  This function
1406  * waits for the data to be received using the main loop, so events,
1407  * timeouts, etc, may be dispatched during the wait.
1408  *
1409  * Return value: a newly-allocated binary block of data which must
1410  *               be freed with g_free(), or %NULL if retrieving
1411  *               the selection data failed. (This could happen
1412  *               for various reasons, in particular if the
1413  *               clipboard was empty or if the contents of the
1414  *               clipboard could not be converted into text form.)
1415  *
1416  * Since: 2.10
1417  **/
1418 guint8 *
1419 gtk_clipboard_wait_for_rich_text (GtkClipboard  *clipboard,
1420                                   GtkTextBuffer *buffer,
1421                                   GdkAtom       *format,
1422                                   gsize         *length)
1423 {
1424   WaitResults results;
1425
1426   g_return_val_if_fail (clipboard != NULL, NULL);
1427   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1428   g_return_val_if_fail (format != NULL, NULL);
1429   g_return_val_if_fail (length != NULL, NULL);
1430
1431   results.data = NULL;
1432   results.loop = g_main_loop_new (NULL, TRUE);
1433
1434   gtk_clipboard_request_rich_text (clipboard, buffer,
1435                                    clipboard_rich_text_received_func,
1436                                    &results);
1437
1438   if (g_main_loop_is_running (results.loop))
1439     {
1440       GDK_THREADS_LEAVE ();
1441       g_main_loop_run (results.loop);
1442       GDK_THREADS_ENTER ();
1443     }
1444
1445   g_main_loop_unref (results.loop);
1446
1447   *format = results.format;
1448   *length = results.length;
1449
1450   return results.data;
1451 }
1452
1453 static void 
1454 clipboard_image_received_func (GtkClipboard *clipboard,
1455                                GdkPixbuf    *pixbuf,
1456                                gpointer      data)
1457 {
1458   WaitResults *results = data;
1459
1460   if (pixbuf)
1461     results->data = g_object_ref (pixbuf);
1462
1463   g_main_loop_quit (results->loop);
1464 }
1465
1466 /**
1467  * gtk_clipboard_wait_for_image:
1468  * @clipboard: a #GtkClipboard
1469  * 
1470  * Requests the contents of the clipboard as image and converts
1471  * the result to a #GdkPixbuf. This function waits for
1472  * the data to be received using the main loop, so events,
1473  * timeouts, etc, may be dispatched during the wait.
1474  * 
1475  * Return value: a newly-allocated #GdkPixbuf object which must
1476  *               be disposed with g_object_unref(), or %NULL if 
1477  *               retrieving the selection data failed. (This 
1478  *               could happen for various reasons, in particular 
1479  *               if the clipboard was empty or if the contents of 
1480  *               the clipboard could not be converted into an image.)
1481  *
1482  * Since: 2.6
1483  **/
1484 GdkPixbuf *
1485 gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
1486 {
1487   WaitResults results;
1488
1489   g_return_val_if_fail (clipboard != NULL, NULL);
1490   
1491   results.data = NULL;
1492   results.loop = g_main_loop_new (NULL, TRUE);
1493
1494   gtk_clipboard_request_image (clipboard,
1495                                clipboard_image_received_func,
1496                                &results);
1497
1498   if (g_main_loop_is_running (results.loop))
1499     {
1500       GDK_THREADS_LEAVE ();
1501       g_main_loop_run (results.loop);
1502       GDK_THREADS_ENTER ();
1503     }
1504
1505   g_main_loop_unref (results.loop);
1506
1507   return results.data;
1508 }
1509
1510 static void 
1511 clipboard_uris_received_func (GtkClipboard *clipboard,
1512                               gchar       **uris,
1513                               gpointer      data)
1514 {
1515   WaitResults *results = data;
1516
1517   results->data = g_strdupv (uris);
1518   g_main_loop_quit (results->loop);
1519 }
1520
1521 /**
1522  * gtk_clipboard_wait_for_uris:
1523  * @clipboard: a #GtkClipboard
1524  * 
1525  * Requests the contents of the clipboard as URIs. This function waits
1526  * for the data to be received using the main loop, so events,
1527  * timeouts, etc, may be dispatched during the wait.
1528  *
1529  * Return value: (array zero-terminated=1) (element-type utf8) (transfer full): a newly-allocated
1530  *               %NULL-terminated array of strings which must
1531  *               be freed with g_strfreev(), or %NULL if
1532  *               retrieving the selection data failed. (This
1533  *               could happen for various reasons, in particular
1534  *               if the clipboard was empty or if the contents of
1535  *               the clipboard could not be converted into URI form.)
1536  *
1537  * Since: 2.14
1538  **/
1539 gchar **
1540 gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
1541 {
1542   WaitResults results;
1543
1544   g_return_val_if_fail (clipboard != NULL, NULL);
1545   
1546   results.data = NULL;
1547   results.loop = g_main_loop_new (NULL, TRUE);
1548
1549   gtk_clipboard_request_uris (clipboard,
1550                               clipboard_uris_received_func,
1551                               &results);
1552
1553   if (g_main_loop_is_running (results.loop))
1554     {
1555       GDK_THREADS_LEAVE ();
1556       g_main_loop_run (results.loop);
1557       GDK_THREADS_ENTER ();
1558     }
1559
1560   g_main_loop_unref (results.loop);
1561
1562   return results.data;
1563 }
1564
1565 /**
1566  * gtk_clipboard_get_display:
1567  * @clipboard: a #GtkClipboard
1568  *
1569  * Gets the #GdkDisplay associated with @clipboard
1570  *
1571  * Return value: the #GdkDisplay associated with @clipboard
1572  *
1573  * Since: 2.2
1574  **/
1575 GdkDisplay *
1576 gtk_clipboard_get_display (GtkClipboard *clipboard)
1577 {
1578   g_return_val_if_fail (clipboard != NULL, NULL);
1579
1580   return clipboard->display;
1581 }
1582
1583 /**
1584  * gtk_clipboard_wait_is_text_available:
1585  * @clipboard: a #GtkClipboard
1586  * 
1587  * Test to see if there is text available to be pasted
1588  * This is done by requesting the TARGETS atom and checking
1589  * if it contains any of the supported text targets. This function 
1590  * waits for the data to be received using the main loop, so events, 
1591  * timeouts, etc, may be dispatched during the wait.
1592  *
1593  * This function is a little faster than calling
1594  * gtk_clipboard_wait_for_text() since it doesn't need to retrieve
1595  * the actual text.
1596  * 
1597  * Return value: %TRUE is there is text available, %FALSE otherwise.
1598  **/
1599 gboolean
1600 gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
1601 {
1602   GtkSelectionData *data;
1603   gboolean result = FALSE;
1604
1605   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1606   if (data)
1607     {
1608       result = gtk_selection_data_targets_include_text (data);
1609       gtk_selection_data_free (data);
1610     }
1611
1612   return result;
1613 }
1614
1615 /**
1616  * gtk_clipboard_wait_is_rich_text_available:
1617  * @clipboard: a #GtkClipboard
1618  * @buffer: a #GtkTextBuffer
1619  *
1620  * Test to see if there is rich text available to be pasted
1621  * This is done by requesting the TARGETS atom and checking
1622  * if it contains any of the supported rich text targets. This function
1623  * waits for the data to be received using the main loop, so events,
1624  * timeouts, etc, may be dispatched during the wait.
1625  *
1626  * This function is a little faster than calling
1627  * gtk_clipboard_wait_for_rich_text() since it doesn't need to retrieve
1628  * the actual text.
1629  *
1630  * Return value: %TRUE is there is rich text available, %FALSE otherwise.
1631  *
1632  * Since: 2.10
1633  **/
1634 gboolean
1635 gtk_clipboard_wait_is_rich_text_available (GtkClipboard  *clipboard,
1636                                            GtkTextBuffer *buffer)
1637 {
1638   GtkSelectionData *data;
1639   gboolean result = FALSE;
1640
1641   g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
1642   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1643
1644   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1645   if (data)
1646     {
1647       result = gtk_selection_data_targets_include_rich_text (data, buffer);
1648       gtk_selection_data_free (data);
1649     }
1650
1651   return result;
1652 }
1653
1654 /**
1655  * gtk_clipboard_wait_is_image_available:
1656  * @clipboard: a #GtkClipboard
1657  * 
1658  * Test to see if there is an image available to be pasted
1659  * This is done by requesting the TARGETS atom and checking
1660  * if it contains any of the supported image targets. This function 
1661  * waits for the data to be received using the main loop, so events, 
1662  * timeouts, etc, may be dispatched during the wait.
1663  *
1664  * This function is a little faster than calling
1665  * gtk_clipboard_wait_for_image() since it doesn't need to retrieve
1666  * the actual image data.
1667  * 
1668  * Return value: %TRUE is there is an image available, %FALSE otherwise.
1669  *
1670  * Since: 2.6
1671  **/
1672 gboolean
1673 gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
1674 {
1675   GtkSelectionData *data;
1676   gboolean result = FALSE;
1677
1678   data = gtk_clipboard_wait_for_contents (clipboard, 
1679                                           gdk_atom_intern_static_string ("TARGETS"));
1680   if (data)
1681     {
1682       result = gtk_selection_data_targets_include_image (data, FALSE);
1683       gtk_selection_data_free (data);
1684     }
1685
1686   return result;
1687 }
1688
1689 /**
1690  * gtk_clipboard_wait_is_uris_available:
1691  * @clipboard: a #GtkClipboard
1692  * 
1693  * Test to see if there is a list of URIs available to be pasted
1694  * This is done by requesting the TARGETS atom and checking
1695  * if it contains the URI targets. This function
1696  * waits for the data to be received using the main loop, so events, 
1697  * timeouts, etc, may be dispatched during the wait.
1698  *
1699  * This function is a little faster than calling
1700  * gtk_clipboard_wait_for_uris() since it doesn't need to retrieve
1701  * the actual URI data.
1702  * 
1703  * Return value: %TRUE is there is an URI list available, %FALSE otherwise.
1704  *
1705  * Since: 2.14
1706  **/
1707 gboolean
1708 gtk_clipboard_wait_is_uris_available (GtkClipboard *clipboard)
1709 {
1710   GtkSelectionData *data;
1711   gboolean result = FALSE;
1712
1713   data = gtk_clipboard_wait_for_contents (clipboard, 
1714                                           gdk_atom_intern_static_string ("TARGETS"));
1715   if (data)
1716     {
1717       result = gtk_selection_data_targets_include_uri (data);
1718       gtk_selection_data_free (data);
1719     }
1720
1721   return result;
1722 }
1723
1724 /**
1725  * gtk_clipboard_wait_for_targets
1726  * @clipboard: a #GtkClipboard
1727  * @targets: location to store an array of targets. The result
1728  *           stored here must be freed with g_free().
1729  * @n_targets: location to store number of items in @targets.
1730  *
1731  * Returns a list of targets that are present on the clipboard, or %NULL
1732  * if there aren't any targets available. The returned list must be 
1733  * freed with g_free().
1734  * This function waits for the data to be received using the main 
1735  * loop, so events, timeouts, etc, may be dispatched during the wait.
1736  *
1737  * Return value: %TRUE if any targets are present on the clipboard,
1738  *               otherwise %FALSE.
1739  *
1740  * Since: 2.4
1741  */
1742 gboolean
1743 gtk_clipboard_wait_for_targets (GtkClipboard  *clipboard, 
1744                                 GdkAtom      **targets,
1745                                 gint          *n_targets)
1746 {
1747   GtkSelectionData *data;
1748   gboolean result = FALSE;
1749   
1750   g_return_val_if_fail (clipboard != NULL, FALSE);
1751
1752   /* If the display supports change notification we cache targets */
1753   if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)) &&
1754       clipboard->n_cached_targets != -1)
1755     {
1756       if (n_targets)
1757         *n_targets = clipboard->n_cached_targets;
1758  
1759       if (targets)
1760         *targets = g_memdup (clipboard->cached_targets,
1761                              clipboard->n_cached_targets * sizeof (GdkAtom));
1762
1763        return TRUE;
1764     }
1765   
1766   if (n_targets)
1767     *n_targets = 0;
1768       
1769   if (targets)
1770     *targets = NULL;      
1771
1772   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1773
1774   if (data)
1775     {
1776       GdkAtom *tmp_targets;
1777       gint tmp_n_targets;
1778        
1779       result = gtk_selection_data_get_targets (data, &tmp_targets, &tmp_n_targets);
1780  
1781       if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)))
1782         {
1783           clipboard->n_cached_targets = tmp_n_targets;
1784           clipboard->cached_targets = g_memdup (tmp_targets,
1785                                                 tmp_n_targets * sizeof (GdkAtom));
1786         }
1787  
1788       if (n_targets)
1789         *n_targets = tmp_n_targets;
1790  
1791       if (targets)
1792         *targets = tmp_targets;
1793       else
1794         g_free (tmp_targets);
1795       
1796       gtk_selection_data_free (data);
1797     }
1798
1799   return result;
1800 }
1801
1802 static GtkClipboard *
1803 clipboard_peek (GdkDisplay *display, 
1804                 GdkAtom     selection,
1805                 gboolean    only_if_exists)
1806 {
1807   GtkClipboard *clipboard = NULL;
1808   GSList *clipboards;
1809   GSList *tmp_list;
1810
1811   if (selection == GDK_NONE)
1812     selection = GDK_SELECTION_CLIPBOARD;
1813
1814   clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
1815
1816   tmp_list = clipboards;
1817   while (tmp_list)
1818     {
1819       clipboard = tmp_list->data;
1820       if (clipboard->selection == selection)
1821         break;
1822
1823       tmp_list = tmp_list->next;
1824     }
1825
1826   if (!tmp_list && !only_if_exists)
1827     {
1828       clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
1829       clipboard->selection = selection;
1830       clipboard->display = display;
1831       clipboard->n_cached_targets = -1;
1832       clipboard->n_storable_targets = -1;
1833       clipboards = g_slist_prepend (clipboards, clipboard);
1834       g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
1835       g_signal_connect (display, "closed",
1836                         G_CALLBACK (clipboard_display_closed), clipboard);
1837       gdk_display_request_selection_notification (display, selection);
1838     }
1839   
1840   return clipboard;
1841 }
1842
1843 static void
1844 gtk_clipboard_owner_change (GtkClipboard        *clipboard,
1845                             GdkEventOwnerChange *event)
1846 {
1847   if (clipboard->n_cached_targets != -1)
1848     {
1849       g_free (clipboard->cached_targets);
1850       clipboard->cached_targets = NULL;
1851       clipboard->n_cached_targets = -1;
1852     }
1853 }
1854
1855 /**
1856  * gtk_clipboard_wait_is_target_available:
1857  * @clipboard: a #GtkClipboard
1858  * @target:    A #GdkAtom indicating which target to look for.
1859  *
1860  * Checks if a clipboard supports pasting data of a given type. This
1861  * function can be used to determine if a "Paste" menu item should be
1862  * insensitive or not.
1863  *
1864  * If you want to see if there's text available on the clipboard, use
1865  * gtk_clipboard_wait_is_text_available () instead.
1866  *
1867  * Return value: %TRUE if the target is available, %FALSE otherwise.
1868  *
1869  * Since: 2.6
1870  */
1871 gboolean
1872 gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
1873                                         GdkAtom       target)
1874 {
1875   GdkAtom *targets;
1876   gint i, n_targets;
1877   gboolean retval = FALSE;
1878     
1879   if (!gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets))
1880     return FALSE;
1881
1882   for (i = 0; i < n_targets; i++)
1883     {
1884       if (targets[i] == target)
1885         {
1886           retval = TRUE;
1887           break;
1888         }
1889     }
1890
1891   g_free (targets);
1892   
1893   return retval;
1894 }
1895
1896 /**
1897  * _gtk_clipboard_handle_event:
1898  * @event: a owner change event
1899  * 
1900  * Emits the #GtkClipboard::owner-change signal on the appropriate @clipboard.
1901  *
1902  * Since: 2.6
1903  **/
1904 void 
1905 _gtk_clipboard_handle_event (GdkEventOwnerChange *event)
1906 {
1907   GdkDisplay *display;
1908   GtkClipboard *clipboard;
1909   
1910   display = gdk_drawable_get_display (event->window);
1911   clipboard = clipboard_peek (display, event->selection, TRUE);
1912       
1913   if (clipboard)
1914     g_signal_emit (clipboard, 
1915                    clipboard_signals[OWNER_CHANGE], 0, event, NULL);
1916 }
1917
1918 static gboolean
1919 gtk_clipboard_store_timeout (GtkClipboard *clipboard)
1920 {
1921   g_main_loop_quit (clipboard->store_loop);
1922   
1923   return FALSE;
1924 }
1925
1926 /**
1927  * gtk_clipboard_set_can_store:
1928  * @clipboard: a #GtkClipboard
1929  * @targets: (allow-none): array containing information about which forms 
1930  *           should be stored or %NULL to indicate that all forms should 
1931  *           be stored.
1932  * @n_targets: number of elements in @targets
1933  *
1934  * Hints that the clipboard data should be stored somewhere when the
1935  * application exits or when gtk_clipboard_store () is called.
1936  *
1937  * This value is reset when the clipboard owner changes.
1938  * Where the clipboard data is stored is platform dependent,
1939  * see gdk_display_store_clipboard () for more information.
1940  * 
1941  * Since: 2.6
1942  */
1943 void
1944 gtk_clipboard_set_can_store (GtkClipboard         *clipboard,
1945                              const GtkTargetEntry *targets,
1946                              gint                  n_targets)
1947 {
1948   GtkWidget *clipboard_widget;
1949   int i;
1950   static const GtkTargetEntry save_targets[] = {
1951     { "SAVE_TARGETS", 0, TARGET_SAVE_TARGETS }
1952   };
1953   
1954   g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
1955   g_return_if_fail (n_targets >= 0);
1956
1957   if (clipboard->selection != GDK_SELECTION_CLIPBOARD)
1958     return;
1959   
1960   g_free (clipboard->storable_targets);
1961   
1962   clipboard_widget = get_clipboard_widget (clipboard->display);
1963
1964   /* n_storable_targets being -1 means that
1965    * gtk_clipboard_set_can_store hasn't been called since the
1966    * clipboard owner changed. We only want to add SAVE_TARGETS and 
1967    * ref the owner once , so we do that here
1968    */  
1969   if (clipboard->n_storable_targets == -1)
1970     {
1971       gtk_selection_add_targets (clipboard_widget, clipboard->selection,
1972                                  save_targets, 1);
1973
1974       /* Ref the owner so it won't go away */
1975       if (clipboard->have_owner)
1976         g_object_ref (clipboard->user_data);
1977     }
1978   
1979   clipboard->n_storable_targets = n_targets;
1980   clipboard->storable_targets = g_new (GdkAtom, n_targets);
1981   for (i = 0; i < n_targets; i++)
1982     clipboard->storable_targets[i] = gdk_atom_intern (targets[i].target, FALSE);
1983 }
1984
1985 static gboolean
1986 gtk_clipboard_selection_notify (GtkWidget         *widget,
1987                                 GdkEventSelection *event,
1988                                 GtkClipboard      *clipboard)
1989 {
1990   if (event->selection == gdk_atom_intern_static_string ("CLIPBOARD_MANAGER") &&
1991       clipboard->storing_selection)
1992     g_main_loop_quit (clipboard->store_loop);
1993
1994   return FALSE;
1995 }
1996
1997 /**
1998  * gtk_clipboard_store:
1999  * @clipboard: a #GtkClipboard
2000  *
2001  * Stores the current clipboard data somewhere so that it will stay
2002  * around after the application has quit.
2003  *
2004  * Since: 2.6
2005  */
2006 void
2007 gtk_clipboard_store (GtkClipboard *clipboard)
2008 {
2009   GtkWidget *clipboard_widget;
2010
2011   g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
2012
2013   if (clipboard->n_storable_targets < 0)
2014     return;
2015   
2016   if (!gdk_display_supports_clipboard_persistence (clipboard->display))
2017     return;
2018
2019   g_object_ref (clipboard);
2020
2021   clipboard_widget = get_clipboard_widget (clipboard->display);
2022   clipboard->notify_signal_id = g_signal_connect (clipboard_widget,
2023                                                   "selection-notify-event",
2024                                                   G_CALLBACK (gtk_clipboard_selection_notify),
2025                                                   clipboard);
2026
2027   gdk_display_store_clipboard (clipboard->display,
2028                                clipboard_widget->window,
2029                                clipboard_get_timestamp (clipboard),
2030                                clipboard->storable_targets,
2031                                clipboard->n_storable_targets);
2032
2033   clipboard->storing_selection = TRUE;
2034
2035   clipboard->store_loop = g_main_loop_new (NULL, TRUE);
2036   clipboard->store_timeout = g_timeout_add_seconds (10, (GSourceFunc) gtk_clipboard_store_timeout, clipboard);
2037
2038   if (g_main_loop_is_running (clipboard->store_loop))
2039     {
2040       GDK_THREADS_LEAVE ();
2041       g_main_loop_run (clipboard->store_loop);
2042       GDK_THREADS_ENTER ();
2043     }
2044   
2045   g_main_loop_unref (clipboard->store_loop);
2046   clipboard->store_loop = NULL;
2047   
2048   g_source_remove (clipboard->store_timeout);
2049   clipboard->store_timeout = 0;
2050   g_signal_handler_disconnect (clipboard_widget, clipboard->notify_signal_id);
2051   clipboard->notify_signal_id = 0;
2052   
2053   clipboard->storing_selection = FALSE;
2054
2055   g_object_unref (clipboard);
2056 }
2057
2058 /* Stores all clipboard selections on all displays, called from
2059  * gtk_main_quit ().
2060  */
2061 void
2062 _gtk_clipboard_store_all (void)
2063 {
2064   GtkClipboard *clipboard;
2065   GSList *displays, *list;
2066   
2067   displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
2068
2069   list = displays;
2070   while (list)
2071     {
2072       GdkDisplay *display = list->data;
2073
2074       clipboard = clipboard_peek (display, GDK_SELECTION_CLIPBOARD, TRUE);
2075
2076       if (clipboard)
2077         gtk_clipboard_store (clipboard);
2078       
2079       list = list->next;
2080     }
2081   g_slist_free (displays);
2082   
2083 }