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