]> Pileus Git - ~andy/gtk/blob - gtk/gtkclipboard-quartz.c
24563f24074f951af408618db67cd9c6ddbbc5a1
[~andy/gtk] / gtk / gtkclipboard-quartz.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2000 Red Hat, Inc.
3  * Copyright (C) 2004 Nokia Corporation
4  * Copyright (C) 2006 Imendio AB
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22
23 #include <config.h>
24 #include <string.h>
25
26 #import <Cocoa/Cocoa.h>
27
28 #include "gtkclipboard.h"
29 #include "gtkinvisible.h"
30 #include "gtkmain.h"
31 #include "gtkmarshalers.h"
32 #include "gtkintl.h"
33 #include "gtktextbuffer.h"
34 #include "gtkquartz.h"
35 #include "gtkalias.h"
36
37 enum {
38   OWNER_CHANGE,
39   LAST_SIGNAL
40 };
41
42 typedef struct _GtkClipboardClass GtkClipboardClass;
43
44 struct _GtkClipboard 
45 {
46   GObject parent_instance;
47
48   NSPasteboard *pasteboard;
49
50   GdkAtom selection;
51
52   GtkClipboardGetFunc get_func;
53   GtkClipboardClearFunc clear_func;
54   gpointer user_data;
55   gboolean have_owner;
56   GtkTargetList *target_list;
57
58   gboolean have_selection;
59   GdkDisplay *display;
60
61   GdkAtom *cached_targets;
62   gint     n_cached_targets;
63
64   guint      notify_signal_id;
65   gboolean   storing_selection;
66   GMainLoop *store_loop;
67   guint      store_timeout;
68   gint       n_storable_targets;
69   GdkAtom   *storable_targets;
70 };
71
72 struct _GtkClipboardClass
73 {
74   GObjectClass parent_class;
75
76   void (*owner_change) (GtkClipboard        *clipboard,
77                         GdkEventOwnerChange *event);
78 };
79
80 @interface GtkClipboardOwner : NSObject {
81   GtkClipboard *clipboard;
82
83   GtkClipboardGetFunc get_func;
84   GtkClipboardClearFunc clear_func;
85   gpointer user_data;
86   
87 }
88
89 @end
90
91 @implementation GtkClipboardOwner
92 -(void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
93 {
94   GtkSelectionData selection_data;
95   guint info;
96
97   selection_data.selection = clipboard->selection;
98   selection_data.data = NULL;
99   selection_data.target = _gtk_quartz_pasteboard_type_to_atom (type);
100
101   if (clipboard->target_list &&
102       gtk_target_list_find (clipboard->target_list, selection_data.target, &info))
103     {
104       clipboard->get_func (clipboard, &selection_data,
105                            info,
106                            clipboard->user_data);
107     }
108   else
109     {
110       selection_data.length = -1;
111     }
112
113   _gtk_quartz_set_selection_data_for_pasteboard (clipboard->pasteboard,
114                                                  &selection_data);
115
116   g_free (selection_data.data);
117 }
118
119 - (void)pasteboardChangedOwner:(NSPasteboard *)sender
120 {
121   if (clear_func)
122     clear_func (clipboard, user_data);
123
124   [self release];
125 }
126
127 - (id)initWithClipboard:(GtkClipboard *)aClipboard
128 {
129   self = [super init];
130
131   if (self) 
132     {
133       clipboard = aClipboard;
134     }
135
136   return self;
137 }
138
139 @end
140
141 static void gtk_clipboard_class_init   (GtkClipboardClass   *class);
142 static void gtk_clipboard_finalize     (GObject             *object);
143 static void gtk_clipboard_owner_change (GtkClipboard        *clipboard,
144                                         GdkEventOwnerChange *event);
145
146 static void          clipboard_unset      (GtkClipboard     *clipboard);
147 static GtkClipboard *clipboard_peek       (GdkDisplay       *display,
148                                            GdkAtom           selection,
149                                            gboolean          only_if_exists);
150
151 static const gchar clipboards_owned_key[] = "gtk-clipboards-owned";
152 static GQuark clipboards_owned_key_id = 0;
153
154 static GObjectClass *parent_class;
155 static guint         clipboard_signals[LAST_SIGNAL] = { 0 };
156
157 GType
158 gtk_clipboard_get_type (void)
159 {
160   static GType clipboard_type = 0;
161   
162   if (!clipboard_type)
163     {
164       const GTypeInfo clipboard_info =
165       {
166         sizeof (GtkClipboardClass),
167         NULL,           /* base_init */
168         NULL,           /* base_finalize */
169         (GClassInitFunc) gtk_clipboard_class_init,
170         NULL,           /* class_finalize */
171         NULL,           /* class_data */
172         sizeof (GtkClipboard),
173         0,              /* n_preallocs */
174         (GInstanceInitFunc) NULL,
175       };
176       
177       clipboard_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkClipboard"),
178                                                &clipboard_info, 0);
179     }
180   
181   return clipboard_type;
182 }
183
184 static void
185 gtk_clipboard_class_init (GtkClipboardClass *class)
186 {
187   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
188
189   parent_class = g_type_class_peek_parent (class);
190   
191   gobject_class->finalize = gtk_clipboard_finalize;
192
193   class->owner_change = gtk_clipboard_owner_change;
194
195   clipboard_signals[OWNER_CHANGE] =
196     g_signal_new (I_("owner_change"),
197                   G_TYPE_FROM_CLASS (gobject_class),
198                   G_SIGNAL_RUN_FIRST,
199                   G_STRUCT_OFFSET (GtkClipboardClass, owner_change),
200                   NULL, NULL,
201                   _gtk_marshal_VOID__BOXED,
202                   G_TYPE_NONE, 1,
203                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
204 }
205
206 static void
207 gtk_clipboard_finalize (GObject *object)
208 {
209   GtkClipboard *clipboard;
210   GSList *clipboards;
211
212   clipboard = GTK_CLIPBOARD (object);
213
214   clipboards = g_object_get_data (G_OBJECT (clipboard->display), "gtk-clipboard-list");
215   if (g_slist_index (clipboards, clipboard) >= 0)
216     g_warning ("GtkClipboard prematurely finalized");
217
218   clipboard_unset (clipboard);
219   
220   clipboards = g_object_get_data (G_OBJECT (clipboard->display), "gtk-clipboard-list");
221   clipboards = g_slist_remove (clipboards, clipboard);
222   g_object_set_data (G_OBJECT (clipboard->display), I_("gtk-clipboard-list"), clipboards);
223
224   if (clipboard->store_loop && g_main_loop_is_running (clipboard->store_loop))
225     g_main_loop_quit (clipboard->store_loop);
226
227   if (clipboard->store_timeout != 0)
228     g_source_remove (clipboard->store_timeout);
229
230   g_free (clipboard->storable_targets);
231
232   G_OBJECT_CLASS (parent_class)->finalize (object);
233 }
234
235 static void
236 clipboard_display_closed (GdkDisplay   *display,
237                           gboolean      is_error,
238                           GtkClipboard *clipboard)
239 {
240   GSList *clipboards;
241
242   clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
243   g_object_run_dispose (G_OBJECT (clipboard));
244   clipboards = g_slist_remove (clipboards, clipboard);
245   g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
246   g_object_unref (clipboard);
247 }
248
249 /**
250  * gtk_clipboard_get_for_display:
251  * @display: the display for which the clipboard is to be retrieved or created
252  * @selection: a #GdkAtom which identifies the clipboard
253  *             to use.
254  * 
255  * Returns the clipboard object for the given selection.
256  * Cut/copy/paste menu items and keyboard shortcuts should use
257  * the default clipboard, returned by passing %GDK_SELECTION_CLIPBOARD for @selection.
258  * (%GDK_NONE is supported as a synonym for GDK_SELECTION_CLIPBOARD
259  * for backwards compatibility reasons.)
260  * The currently-selected object or text should be provided on the clipboard
261  * identified by #GDK_SELECTION_PRIMARY. Cut/copy/paste menu items
262  * conceptually copy the contents of the #GDK_SELECTION_PRIMARY clipboard
263  * to the default clipboard, i.e. they copy the selection to what the
264  * user sees as the clipboard.
265  *
266  * (Passing #GDK_NONE is the same as using <literal>gdk_atom_intern
267  * ("CLIPBOARD", FALSE)</literal>. See <ulink
268  * url="http://www.freedesktop.org/Standards/clipboards-spec">
269  * http://www.freedesktop.org/Standards/clipboards-spec</ulink>
270  * for a detailed discussion of the "CLIPBOARD" vs. "PRIMARY"
271  * selections under the X window system. On Win32 the
272  * #GDK_SELECTION_PRIMARY clipboard is essentially ignored.)
273  *
274  * It's possible to have arbitrary named clipboards; if you do invent
275  * new clipboards, you should prefix the selection name with an
276  * underscore (because the ICCCM requires that nonstandard atoms are
277  * underscore-prefixed), and namespace it as well. For example,
278  * if your application called "Foo" has a special-purpose
279  * clipboard, you might call it "_FOO_SPECIAL_CLIPBOARD".
280  * 
281  * Return value: the appropriate clipboard object. If no
282  *             clipboard already exists, a new one will
283  *             be created. Once a clipboard object has
284  *             been created, it is persistent and, since
285  *             it is owned by GTK+, must not be freed or
286  *             unrefd.
287  *
288  * Since: 2.2
289  **/
290 GtkClipboard *
291 gtk_clipboard_get_for_display (GdkDisplay *display, 
292                                GdkAtom     selection)
293 {
294   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
295   g_return_val_if_fail (!display->closed, NULL);
296
297   return clipboard_peek (display, selection, FALSE);
298 }
299
300
301 /**
302  * gtk_clipboard_get():
303  * @selection: a #GdkAtom which identifies the clipboard
304  *             to use.
305  * 
306  * Returns the clipboard object for the given selection.
307  * See gtk_clipboard_get_for_display() for complete details.
308  * 
309  * Return value: the appropriate clipboard object. If no
310  *             clipboard already exists, a new one will
311  *             be created. Once a clipboard object has
312  *             been created, it is persistent and, since
313  *             it is owned by GTK+, must not be freed or
314  *             unrefd.
315  **/
316 GtkClipboard *
317 gtk_clipboard_get (GdkAtom selection)
318 {
319   return gtk_clipboard_get_for_display (gdk_display_get_default (), selection);
320 }
321
322 static void
323 clipboard_owner_destroyed (gpointer data)
324 {
325   GSList *clipboards = data;
326   GSList *tmp_list;
327
328   tmp_list = clipboards;
329   while (tmp_list)
330     {
331       GtkClipboard *clipboard = tmp_list->data;
332
333       clipboard->get_func = NULL;
334       clipboard->clear_func = NULL;
335       clipboard->user_data = NULL;
336       clipboard->have_owner = FALSE;
337
338       if (clipboard->target_list)
339         {
340           gtk_target_list_unref (clipboard->target_list);
341           clipboard->target_list = NULL;
342         }
343
344       gtk_clipboard_clear (clipboard);
345
346       tmp_list = tmp_list->next;
347     }
348   
349   g_slist_free (clipboards);
350 }
351
352 static void
353 clipboard_add_owner_notify (GtkClipboard *clipboard)
354 {
355   if (!clipboards_owned_key_id)
356     clipboards_owned_key_id = g_quark_from_static_string (clipboards_owned_key);
357   
358   if (clipboard->have_owner)
359     g_object_set_qdata_full (clipboard->user_data, clipboards_owned_key_id,
360                              g_slist_prepend (g_object_steal_qdata (clipboard->user_data,
361                                                                     clipboards_owned_key_id),
362                                               clipboard),
363                              clipboard_owner_destroyed);
364 }
365
366 static void
367 clipboard_remove_owner_notify (GtkClipboard *clipboard)
368 {
369   if (clipboard->have_owner)
370      g_object_set_qdata_full (clipboard->user_data, clipboards_owned_key_id,
371                               g_slist_remove (g_object_steal_qdata (clipboard->user_data,
372                                                                     clipboards_owned_key_id),
373                                               clipboard),
374                               clipboard_owner_destroyed);
375 }
376
377 static gboolean
378 gtk_clipboard_set_contents (GtkClipboard         *clipboard,
379                             const GtkTargetEntry *targets,
380                             guint                 n_targets,
381                             GtkClipboardGetFunc   get_func,
382                             GtkClipboardClearFunc clear_func,
383                             gpointer              user_data,
384                             gboolean              have_owner)
385 {
386   GtkClipboardOwner *owner;
387   NSArray *types;
388   NSAutoreleasePool *pool;
389
390   pool = [[NSAutoreleasePool alloc] init];
391
392   owner = [[GtkClipboardOwner alloc] initWithClipboard:clipboard];
393
394   types = _gtk_quartz_target_entries_to_pasteboard_types (targets, n_targets);
395
396   clipboard->user_data = user_data;
397   clipboard->have_owner = have_owner;
398   if (have_owner)
399     clipboard_add_owner_notify (clipboard);
400   clipboard->get_func = get_func;
401   clipboard->clear_func = clear_func;
402
403   if (clipboard->target_list)
404     gtk_target_list_unref (clipboard->target_list);
405   clipboard->target_list = gtk_target_list_new (targets, n_targets);
406
407   [clipboard->pasteboard declareTypes:types owner:owner];
408
409   [pool release];
410
411   return TRUE;
412 }
413
414 /**
415  * gtk_clipboard_set_with_data:
416  * @clipboard:  a #GtkClipboard
417  * @targets:    array containing information about the available forms for the
418  *              clipboard data
419  * @n_targets:  number of elements in @targets
420  * @get_func:   function to call to get the actual clipboard data
421  * @clear_func: when the clipboard contents are set again, this function will
422  *              be called, and @get_func will not be subsequently called.
423  * @user_data:  user data to pass to @get_func and @clear_func.
424  * 
425  * Virtually sets the contents of the specified clipboard by providing
426  * a list of supported formats for the clipboard data and a function
427  * to call to get the actual data when it is requested.
428  * 
429  * Return value: %TRUE if setting the clipboard data succeeded. If setting
430  *               the clipboard data failed the provided callback functions
431  *               will be ignored.
432  **/
433 gboolean
434 gtk_clipboard_set_with_data (GtkClipboard          *clipboard,
435                              const GtkTargetEntry  *targets,
436                              guint                  n_targets,
437                              GtkClipboardGetFunc    get_func,
438                              GtkClipboardClearFunc  clear_func,
439                              gpointer               user_data)
440 {
441   g_return_val_if_fail (clipboard != NULL, FALSE);
442   g_return_val_if_fail (targets != NULL, FALSE);
443   g_return_val_if_fail (get_func != NULL, FALSE);
444
445   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
446                                      get_func, clear_func, user_data,
447                                      FALSE);
448 }
449
450 /**
451  * gtk_clipboard_set_with_owner:
452  * @clipboard:  a #GtkClipboard
453  * @targets:    array containing information about the available forms for the
454  *              clipboard data
455  * @n_targets:  number of elements in @targets
456  * @get_func:   function to call to get the actual clipboard data
457  * @clear_func: when the clipboard contents are set again, this function will
458  *              be called, and @get_func will not be subsequently called.
459  * @owner:      an object that "owns" the data. This object will be passed
460  *              to the callbacks when called. 
461  * 
462  * Virtually sets the contents of the specified clipboard by providing
463  * a list of supported formats for the clipboard data and a function
464  * to call to get the actual data when it is requested.
465  *
466  * The difference between this function and gtk_clipboard_set_with_data()
467  * is that instead of an generic @user_data pointer, a #GObject is passed
468  * in. 
469  * 
470  * Return value: %TRUE if setting the clipboard data succeeded. If setting
471  *               the clipboard data failed the provided callback functions
472  *               will be ignored.
473  **/
474 gboolean
475 gtk_clipboard_set_with_owner (GtkClipboard          *clipboard,
476                               const GtkTargetEntry  *targets,
477                               guint                  n_targets,
478                               GtkClipboardGetFunc    get_func,
479                               GtkClipboardClearFunc  clear_func,
480                               GObject               *owner)
481 {
482   g_return_val_if_fail (clipboard != NULL, FALSE);
483   g_return_val_if_fail (targets != NULL, FALSE);
484   g_return_val_if_fail (get_func != NULL, FALSE);
485   g_return_val_if_fail (G_IS_OBJECT (owner), FALSE);
486
487   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
488                                      get_func, clear_func, owner,
489                                      TRUE);
490 }
491
492 /**
493  * gtk_clipboard_get_owner:
494  * @clipboard: a #GtkClipboard
495  * 
496  * If the clipboard contents callbacks were set with 
497  * gtk_clipboard_set_with_owner(), and the gtk_clipboard_set_with_data() or 
498  * gtk_clipboard_clear() has not subsequently called, returns the owner set 
499  * by gtk_clipboard_set_with_owner().
500  * 
501  * Return value: the owner of the clipboard, if any; otherwise %NULL.
502  **/
503 GObject *
504 gtk_clipboard_get_owner (GtkClipboard *clipboard)
505 {
506   g_return_val_if_fail (clipboard != NULL, NULL);
507
508   if (clipboard->have_owner)
509     return clipboard->user_data;
510   else
511     return NULL;
512 }
513
514 static void
515 clipboard_unset (GtkClipboard *clipboard)
516 {
517   GtkClipboardClearFunc old_clear_func;
518   gpointer old_data;
519   gboolean old_have_owner;
520   gint old_n_storable_targets;
521   
522   old_clear_func = clipboard->clear_func;
523   old_data = clipboard->user_data;
524   old_have_owner = clipboard->have_owner;
525   old_n_storable_targets = clipboard->n_storable_targets;
526   
527   if (old_have_owner)
528     {
529       clipboard->have_owner = FALSE;
530     }
531
532   clipboard->n_storable_targets = -1;
533   g_free (clipboard->storable_targets);
534   clipboard->storable_targets = NULL;
535       
536   clipboard->get_func = NULL;
537   clipboard->clear_func = NULL;
538   clipboard->user_data = NULL;
539   
540   if (old_clear_func)
541     old_clear_func (clipboard, old_data);
542
543   if (clipboard->target_list)
544     {
545       gtk_target_list_unref (clipboard->target_list);
546       clipboard->target_list = NULL;
547     }
548
549   /* If we've transferred the clipboard data to the manager,
550    * unref the owner
551    */
552   if (old_have_owner &&
553       old_n_storable_targets != -1)
554     g_object_unref (old_data);
555 }
556
557 /**
558  * gtk_clipboard_clear:
559  * @clipboard:  a #GtkClipboard
560  * 
561  * Clears the contents of the clipboard. Generally this should only
562  * be called between the time you call gtk_clipboard_set_with_owner()
563  * or gtk_clipboard_set_with_data(),
564  * and when the @clear_func you supplied is called. Otherwise, the
565  * clipboard may be owned by someone else.
566  **/
567 void
568 gtk_clipboard_clear (GtkClipboard *clipboard)
569 {
570   [clipboard->pasteboard declareTypes:nil owner:nil];
571 }
572
573 static void 
574 text_get_func (GtkClipboard     *clipboard,
575                GtkSelectionData *selection_data,
576                guint             info,
577                gpointer          data)
578 {
579   gtk_selection_data_set_text (selection_data, data, -1);
580 }
581
582 static void 
583 text_clear_func (GtkClipboard *clipboard,
584                  gpointer      data)
585 {
586   g_free (data);
587 }
588
589 /**
590  * gtk_clipboard_set_text:
591  * @clipboard: a #GtkClipboard object
592  * @text:      a UTF-8 string.
593  * @len:       length of @text, in bytes, or -1, in which case
594  *             the length will be determined with <function>strlen()</function>.
595  * 
596  * Sets the contents of the clipboard to the given UTF-8 string. GTK+ will
597  * make a copy of the text and take responsibility for responding
598  * for requests for the text, and for converting the text into
599  * the requested format.
600  **/
601 void 
602 gtk_clipboard_set_text (GtkClipboard *clipboard,
603                         const gchar  *text,
604                         gint          len)
605 {
606   GtkTargetEntry target = { "UTF8_STRING", 0, 0 };
607
608   g_return_if_fail (clipboard != NULL);
609   g_return_if_fail (text != NULL);
610   
611   if (len < 0)
612     len = strlen (text);
613   
614   gtk_clipboard_set_with_data (clipboard, 
615                                &target, 1,
616                                text_get_func, text_clear_func,
617                                g_strndup (text, len));
618   gtk_clipboard_set_can_store (clipboard, NULL, 0);
619 }
620
621
622 static void 
623 pixbuf_get_func (GtkClipboard     *clipboard,
624                  GtkSelectionData *selection_data,
625                  guint             info,
626                  gpointer          data)
627 {
628   gtk_selection_data_set_pixbuf (selection_data, data);
629 }
630
631 static void 
632 pixbuf_clear_func (GtkClipboard *clipboard,
633                    gpointer      data)
634 {
635   g_object_unref (data);
636 }
637
638 /**
639  * gtk_clipboard_set_image:
640  * @clipboard: a #GtkClipboard object
641  * @pixbuf:    a #GdkPixbuf 
642  * 
643  * Sets the contents of the clipboard to the given #GdkPixbuf. 
644  * GTK+ will take responsibility for responding for requests 
645  * for the image, and for converting the image into the 
646  * requested format.
647  * 
648  * Since: 2.6
649  **/
650 void
651 gtk_clipboard_set_image (GtkClipboard *clipboard,
652                          GdkPixbuf    *pixbuf)
653 {
654   GtkTargetList *list;
655   GList *l;
656   GtkTargetEntry *targets;
657   gint n_targets, i;
658
659   g_return_if_fail (clipboard != NULL);
660   g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
661
662   list = gtk_target_list_new (NULL, 0);
663   gtk_target_list_add_image_targets (list, 0, TRUE);
664
665   n_targets = g_list_length (list->list);
666   targets = g_new0 (GtkTargetEntry, n_targets);
667   for (l = list->list, i = 0; l; l = l->next, i++)
668     {
669       GtkTargetPair *pair = (GtkTargetPair *)l->data;
670       targets[i].target = gdk_atom_name (pair->target);
671     }
672
673   gtk_clipboard_set_with_data (clipboard, 
674                                targets, n_targets,
675                                pixbuf_get_func, pixbuf_clear_func,
676                                g_object_ref (pixbuf));
677   gtk_clipboard_set_can_store (clipboard, NULL, 0);
678
679   for (i = 0; i < n_targets; i++)
680     g_free (targets[i].target);
681   g_free (targets);
682   gtk_target_list_unref (list);
683 }
684
685 /**
686  * gtk_clipboard_request_contents:
687  * @clipboard: a #GtkClipboard
688  * @target:    an atom representing the form into which the clipboard
689  *             owner should convert the selection.
690  * @callback:  A function to call when the results are received
691  *             (or the retrieval fails). If the retrieval fails
692  *             the length field of @selection_data will be
693  *             negative.
694  * @user_data: user data to pass to @callback
695  * 
696  * Requests the contents of clipboard as the given target.
697  * When the results of the result are later received the supplied callback
698  * will be called.
699  **/
700 void 
701 gtk_clipboard_request_contents (GtkClipboard            *clipboard,
702                                 GdkAtom                  target,
703                                 GtkClipboardReceivedFunc callback,
704                                 gpointer                 user_data)
705 {
706   GtkSelectionData *data;
707
708   data = gtk_clipboard_wait_for_contents (clipboard, target);
709
710   callback (clipboard, data, user_data);
711
712   gtk_selection_data_free (data);
713 }
714
715 /**
716  * gtk_clipboard_request_text:
717  * @clipboard: a #GtkClipboard
718  * @callback:  a function to call when the text is received,
719  *             or the retrieval fails. (It will always be called
720  *             one way or the other.)
721  * @user_data: user data to pass to @callback.
722  * 
723  * Requests the contents of the clipboard as text. When the text is
724  * later received, it will be converted to UTF-8 if necessary, and
725  * @callback will be called. 
726  *
727  * The @text parameter to @callback will contain the resulting text if
728  * the request succeeded, or %NULL if it failed. This could happen for
729  * various reasons, in particular if the clipboard was empty or if the
730  * contents of the clipboard could not be converted into text form.
731  **/
732 void 
733 gtk_clipboard_request_text (GtkClipboard                *clipboard,
734                             GtkClipboardTextReceivedFunc callback,
735                             gpointer                     user_data)
736 {
737   gchar *data = gtk_clipboard_wait_for_text (clipboard);
738
739   callback (clipboard, data, user_data);
740
741   g_free (data);
742 }
743
744 void
745 gtk_clipboard_request_rich_text (GtkClipboard                    *clipboard,
746                                  GtkTextBuffer                   *buffer,
747                                  GtkClipboardRichTextReceivedFunc callback,
748                                  gpointer                         user_data)
749 {
750   /* FIXME: Implement */
751 }
752
753
754 guint8 *
755 gtk_clipboard_wait_for_rich_text (GtkClipboard  *clipboard,
756                                   GtkTextBuffer *buffer,
757                                   GdkAtom       *format,
758                                   gsize         *length)
759 {
760   /* FIXME: Implement */
761   return NULL;
762 }
763
764 /**
765  * gtk_clipboard_request_image:
766  * @clipboard: a #GtkClipboard
767  * @callback:  a function to call when the image is received,
768  *             or the retrieval fails. (It will always be called
769  *             one way or the other.)
770  * @user_data: user data to pass to @callback.
771  * 
772  * Requests the contents of the clipboard as image. When the image is
773  * later received, it will be converted to a #GdkPixbuf, and
774  * @callback will be called. 
775  *
776  * The @pixbuf parameter to @callback will contain the resulting 
777  * #GdkPixbuf if the request succeeded, or %NULL if it failed. This 
778  * could happen for various reasons, in particular if the clipboard 
779  * was empty or if the contents of the clipboard could not be 
780  * converted into an image.
781  *
782  * Since: 2.6
783  **/
784 void 
785 gtk_clipboard_request_image (GtkClipboard                  *clipboard,
786                              GtkClipboardImageReceivedFunc  callback,
787                              gpointer                       user_data)
788 {
789   GdkPixbuf *pixbuf = gtk_clipboard_wait_for_image (clipboard);
790
791   callback (clipboard, pixbuf, user_data);
792
793   if (pixbuf)
794     g_object_unref (pixbuf);
795 }
796
797 /**
798  * gtk_clipboard_request_targets:
799  * @clipboard: a #GtkClipboard
800  * @callback:  a function to call when the targets are received,
801  *             or the retrieval fails. (It will always be called
802  *             one way or the other.)
803  * @user_data: user data to pass to @callback.
804  * 
805  * Requests the contents of the clipboard as list of supported targets. 
806  * When the list is later received, @callback will be called. 
807  *
808  * The @targets parameter to @callback will contain the resulting targets if
809  * the request succeeded, or %NULL if it failed.
810  *
811  * Since: 2.4
812  **/
813 void 
814 gtk_clipboard_request_targets (GtkClipboard                *clipboard,
815                                GtkClipboardTargetsReceivedFunc callback,
816                                gpointer                     user_data)
817 {
818   GdkAtom *targets;
819   gint n_targets;
820
821   gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets);
822
823   callback (clipboard, targets, n_targets, user_data);
824 }
825
826
827 /**
828  * gtk_clipboard_wait_for_contents:
829  * @clipboard: a #GtkClipboard
830  * @target: an atom representing the form into which the clipboard
831  *          owner should convert the selection.
832  * 
833  * Requests the contents of the clipboard using the given target.
834  * This function waits for the data to be received using the main 
835  * loop, so events, timeouts, etc, may be dispatched during the wait.
836  * 
837  * Return value: a newly-allocated #GtkSelectionData object or %NULL
838  *               if retrieving the given target failed. If non-%NULL,
839  *               this value must be freed with gtk_selection_data_free() 
840  *               when you are finished with it.
841  **/
842 GtkSelectionData *
843 gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
844                                  GdkAtom       target)
845 {
846   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
847   gchar *name;
848   NSData *data;
849   GtkSelectionData *selection_data = NULL;
850
851   if (target == gdk_atom_intern_static_string ("TARGETS")) 
852     {
853       NSArray *types = [clipboard->pasteboard types];
854       int i, count;
855       GList *atom_list, *l;
856       GdkAtom *atoms;
857
858       count = [types count];
859       atom_list = _gtk_quartz_pasteboard_types_to_atom_list (types);
860       
861       selection_data = g_new (GtkSelectionData, 1);
862       selection_data->selection = clipboard->selection;
863       selection_data->target = target;
864       selection_data->type = GDK_SELECTION_TYPE_ATOM;
865       selection_data->format = 32;
866       selection_data->length = count * sizeof (GdkAtom);
867
868       atoms = g_malloc (selection_data->length + 1);
869       
870       for (l = atom_list, i = 0; l ; l = l->next, i++)
871         atoms[i] = GDK_POINTER_TO_ATOM (l->data);
872
873       selection_data->data = (guchar *)atoms;
874       selection_data->data[selection_data->length] = '\0';
875
876       [pool release];
877
878       g_list_free (atom_list);
879       return selection_data;
880     }
881
882   selection_data = _gtk_quartz_get_selection_data_from_pasteboard (clipboard->pasteboard,
883                                                                    target,
884                                                                    clipboard->selection);
885
886   [pool release];
887   return selection_data;
888 }
889
890 /**
891  * gtk_clipboard_wait_for_text:
892  * @clipboard: a #GtkClipboard
893  * 
894  * Requests the contents of the clipboard as text and converts
895  * the result to UTF-8 if necessary. This function waits for
896  * the data to be received using the main loop, so events,
897  * timeouts, etc, may be dispatched during the wait.
898  * 
899  * Return value: a newly-allocated UTF-8 string which must
900  *               be freed with g_free(), or %NULL if retrieving
901  *               the selection data failed. (This could happen
902  *               for various reasons, in particular if the
903  *               clipboard was empty or if the contents of the
904  *               clipboard could not be converted into text form.)
905  **/
906 gchar *
907 gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
908 {
909   GtkSelectionData *data;
910   gchar *result;
911
912   data = gtk_clipboard_wait_for_contents (clipboard, 
913                                           gdk_atom_intern_static_string ("UTF8_STRING"));
914
915   result = (gchar *)gtk_selection_data_get_text (data);
916
917   gtk_selection_data_free (data);
918
919   return result;
920 }
921
922 /**
923  * gtk_clipboard_wait_for_image:
924  * @clipboard: a #GtkClipboard
925  * 
926  * Requests the contents of the clipboard as image and converts
927  * the result to a #GdkPixbuf. This function waits for
928  * the data to be received using the main loop, so events,
929  * timeouts, etc, may be dispatched during the wait.
930  * 
931  * Return value: a newly-allocated #GdkPixbuf object which must
932  *               be disposed with g_object_unref(), or %NULL if 
933  *               retrieving the selection data failed. (This 
934  *               could happen for various reasons, in particular 
935  *               if the clipboard was empty or if the contents of 
936  *               the clipboard could not be converted into an image.)
937  *
938  * Since: 2.6
939  **/
940 GdkPixbuf *
941 gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
942 {
943   const gchar *priority[] = { "image/png", "image/tiff", "image/jpeg", "image/gif", "image/bmp" };
944   int i;
945   GtkSelectionData *data;
946
947   for (i = 0; i < G_N_ELEMENTS (priority); i++) 
948     {    
949       data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string (priority[i]));
950
951       if (data)
952         {
953           GdkPixbuf *pixbuf = gtk_selection_data_get_pixbuf (data);
954
955           gtk_selection_data_free (data);
956
957           return pixbuf;
958         }  
959   }
960
961   return NULL;
962 }
963
964 /**
965  * gtk_clipboard_get_display:
966  * @clipboard: a #GtkClipboard
967  *
968  * Gets the #GdkDisplay associated with @clipboard
969  *
970  * Return value: the #GdkDisplay associated with @clipboard
971  *
972  * Since: 2.2
973  **/
974 GdkDisplay *
975 gtk_clipboard_get_display (GtkClipboard *clipboard)
976 {
977   g_return_val_if_fail (clipboard != NULL, NULL);
978
979   return clipboard->display;
980 }
981
982 /**
983  * gtk_clipboard_wait_is_text_available:
984  * @clipboard: a #GtkClipboard
985  * 
986  * Test to see if there is text available to be pasted
987  * This is done by requesting the TARGETS atom and checking
988  * if it contains any of the supported text targets. This function 
989  * waits for the data to be received using the main loop, so events, 
990  * timeouts, etc, may be dispatched during the wait.
991  *
992  * This function is a little faster than calling
993  * gtk_clipboard_wait_for_text() since it doesn't need to retrieve
994  * the actual text.
995  * 
996  * Return value: %TRUE is there is text available, %FALSE otherwise.
997  **/
998 gboolean
999 gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
1000 {
1001   GtkSelectionData *data;
1002   gboolean result = FALSE;
1003
1004   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1005   if (data)
1006     {
1007       result = gtk_selection_data_targets_include_text (data);
1008       gtk_selection_data_free (data);
1009     }
1010
1011   return result;
1012 }
1013
1014 gboolean
1015 gtk_clipboard_wait_is_rich_text_available (GtkClipboard  *clipboard,
1016                                            GtkTextBuffer *buffer)
1017 {
1018   GtkSelectionData *data;
1019   gboolean result = FALSE;
1020
1021   g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
1022   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1023
1024   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1025   if (data)
1026     {
1027       result = gtk_selection_data_targets_include_rich_text (data, buffer);
1028       gtk_selection_data_free (data);
1029     }
1030
1031   return result;
1032 }
1033
1034 gboolean
1035 gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
1036 {
1037   GtkSelectionData *data;
1038   gboolean result = FALSE;
1039
1040   data = gtk_clipboard_wait_for_contents (clipboard, 
1041                                           gdk_atom_intern_static_string ("TARGETS"));
1042   if (data)
1043     {
1044       result = gtk_selection_data_targets_include_image (data, FALSE);
1045       gtk_selection_data_free (data);
1046     }
1047
1048   return result;
1049 }
1050
1051 /**
1052  * gtk_clipboard_wait_for_targets
1053  * @clipboard: a #GtkClipboard
1054  * @targets: location to store an array of targets. The result
1055  *           stored here must be freed with g_free().
1056  * @n_targets: location to store number of items in @targets.
1057  *
1058  * Returns a list of targets that are present on the clipboard, or %NULL
1059  * if there aren't any targets available. The returned list must be 
1060  * freed with g_free().
1061  * This function waits for the data to be received using the main 
1062  * loop, so events, timeouts, etc, may be dispatched during the wait.
1063  *
1064  * Return value: %TRUE if any targets are present on the clipboard,
1065  *               otherwise %FALSE.
1066  *
1067  * Since: 2.4
1068  */
1069 gboolean
1070 gtk_clipboard_wait_for_targets (GtkClipboard  *clipboard, 
1071                                 GdkAtom      **targets,
1072                                 gint          *n_targets)
1073 {
1074   GtkSelectionData *data;
1075   gboolean result = FALSE;
1076   
1077   g_return_val_if_fail (clipboard != NULL, FALSE);
1078
1079   /* If the display supports change notification we cache targets */
1080   if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)) &&
1081       clipboard->n_cached_targets != -1)
1082     {
1083       if (n_targets)
1084         *n_targets = clipboard->n_cached_targets;
1085  
1086       if (targets)
1087         *targets = g_memdup (clipboard->cached_targets,
1088                              clipboard->n_cached_targets * sizeof (GdkAtom));
1089
1090        return TRUE;
1091     }
1092   
1093   if (n_targets)
1094     *n_targets = 0;
1095       
1096   if (targets)
1097     *targets = NULL;      
1098
1099   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1100
1101   if (data)
1102     {
1103       GdkAtom *tmp_targets;
1104       gint tmp_n_targets;
1105        
1106       result = gtk_selection_data_get_targets (data, &tmp_targets, &tmp_n_targets);
1107  
1108       if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)))
1109         {
1110           clipboard->n_cached_targets = tmp_n_targets;
1111           clipboard->cached_targets = g_memdup (tmp_targets,
1112                                                 tmp_n_targets * sizeof (GdkAtom));
1113         }
1114  
1115       if (n_targets)
1116         *n_targets = tmp_n_targets;
1117  
1118       if (targets)
1119         *targets = tmp_targets;
1120       else
1121         g_free (tmp_targets);
1122       
1123       gtk_selection_data_free (data);
1124     }
1125
1126   return result;
1127 }
1128
1129 static GtkClipboard *
1130 clipboard_peek (GdkDisplay *display, 
1131                 GdkAtom     selection,
1132                 gboolean    only_if_exists)
1133 {
1134   GtkClipboard *clipboard = NULL;
1135   GSList *clipboards;
1136   GSList *tmp_list;
1137
1138   if (selection == GDK_NONE)
1139     selection = GDK_SELECTION_CLIPBOARD;
1140
1141   clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
1142
1143   tmp_list = clipboards;
1144   while (tmp_list)
1145     {
1146       clipboard = tmp_list->data;
1147       if (clipboard->selection == selection)
1148         break;
1149
1150       tmp_list = tmp_list->next;
1151     }
1152
1153   if (!tmp_list && !only_if_exists)
1154     {
1155       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1156       NSString *pasteboard_name;
1157       clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
1158
1159       if (selection == GDK_SELECTION_CLIPBOARD) 
1160         pasteboard_name = NSGeneralPboard;
1161       else 
1162         {
1163           char *atom_string = gdk_atom_name (selection);
1164
1165           pasteboard_name = [NSString stringWithFormat:@"_GTK_%@", 
1166                              [NSString stringWithUTF8String:atom_string]];
1167           g_free (atom_string);
1168         }
1169
1170       clipboard->pasteboard = [NSPasteboard pasteboardWithName:pasteboard_name];
1171
1172       [pool release];
1173
1174       clipboard->selection = selection;
1175       clipboard->display = display;
1176       clipboard->n_cached_targets = -1;
1177       clipboard->n_storable_targets = -1;
1178       clipboards = g_slist_prepend (clipboards, clipboard);
1179       g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
1180       g_signal_connect (display, "closed",
1181                         G_CALLBACK (clipboard_display_closed), clipboard);
1182       gdk_display_request_selection_notification (display, selection);
1183     }
1184   
1185   return clipboard;
1186 }
1187
1188 static void
1189 gtk_clipboard_owner_change (GtkClipboard        *clipboard,
1190                             GdkEventOwnerChange *event)
1191 {
1192   if (clipboard->n_cached_targets != -1)
1193     {
1194       clipboard->n_cached_targets = -1;
1195       g_free (clipboard->cached_targets);
1196     }
1197 }
1198
1199 /**
1200  * gtk_clipboard_wait_is_target_available:
1201  * @clipboard: a #GtkClipboard
1202  * @target:    A #GdkAtom indicating which target to look for.
1203  *
1204  * Checks if a clipboard supports pasting data of a given type. This
1205  * function can be used to determine if a "Paste" menu item should be
1206  * insensitive or not.
1207  *
1208  * If you want to see if there's text available on the clipboard, use
1209  * gtk_clipboard_wait_is_text_available () instead.
1210  *
1211  * Return value: %TRUE if the target is available, %FALSE otherwise.
1212  *
1213  * Since: 2.6
1214  */
1215 gboolean
1216 gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
1217                                         GdkAtom       target)
1218 {
1219   GdkAtom *targets;
1220   gint i, n_targets;
1221   gboolean retval = FALSE;
1222     
1223   if (!gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets))
1224     return FALSE;
1225
1226   for (i = 0; i < n_targets; i++)
1227     {
1228       if (targets[i] == target)
1229         {
1230           retval = TRUE;
1231           break;
1232         }
1233     }
1234
1235   g_free (targets);
1236   
1237   return retval;
1238 }
1239
1240 /**
1241  * _gtk_clipboard_handle_event:
1242  * @event: a owner change event
1243  * 
1244  * Emits the ::owner_change signal on the appropriate @clipboard.
1245  *
1246  * Since: 2.6
1247  **/
1248 void 
1249 _gtk_clipboard_handle_event (GdkEventOwnerChange *event)
1250 {
1251 }
1252
1253
1254 /**
1255  * gtk_clipboard_set_can_store:
1256  * @clipboard: a #GtkClipboard
1257  * @targets: array containing information about which forms should be stored
1258  *           or %NULL to indicate that all forms should be stored.
1259  * @n_targets: number of elements in @targets
1260  *
1261  * Hints that the clipboard data should be stored somewhere when the
1262  * application exits or when gtk_clipboard_store () is called.
1263  *
1264  * This value is reset when the clipboard owner changes.
1265  * Where the clipboard data is stored is platform dependent,
1266  * see gdk_display_store_clipboard () for more information.
1267  * 
1268  * Since: 2.6
1269  */
1270 void
1271 gtk_clipboard_set_can_store (GtkClipboard         *clipboard,
1272                              const GtkTargetEntry *targets,
1273                              gint                  n_targets)
1274 {
1275   /* FIXME: Implement */
1276 }
1277
1278 /**
1279  * gtk_clipboard_store:
1280  * @clipboard: a #GtkClipboard
1281  *
1282  * Stores the current clipboard data somewhere so that it will stay
1283  * around after the application has quit.
1284  *
1285  * Since: 2.6
1286  */
1287 void
1288 gtk_clipboard_store (GtkClipboard *clipboard)
1289 {
1290   /* FIXME: Implement */
1291 }
1292
1293 /* Stores all clipboard selections on all displays, called from
1294  * gtk_main_quit ().
1295  */
1296 void
1297 _gtk_clipboard_store_all (void)
1298 {
1299   /* FIXME: Implement */
1300 }
1301
1302 #define __GTK_CLIPBOARD_C__
1303 #include "gtkaliasdef.c"