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