~canonical-dx-team/ubuntu/maverick/gtk+2.0/menuproxy

« back to all changes in this revision

Viewing changes to gtk/gtkclipboard.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-05-04 12:24:25 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20070504122425-0m8midgzrp40y8w2
Tags: 2.10.12-1ubuntu1
* Sync with Debian
* New upstream version:
  Fixed bugs:
  - 379414 file chooser warnings when changing path in the entry
  - 418585 GtkFileChooserDefault sizing code is not DPI independent
  - 419568 Crash in search if start with special letter
  - 435062 build dies with icon cache validation
  - 379399 Segfault to call gtk_print_operation_run twice.
  - 387889 cups backend has problems when there are too many printers
  - 418531 invalid read to gtkicontheme.c gtk_icon_theme_lookup_icon...
  - 423916 crash in color scheme code
  - 424042 Segmentation fault while quickly pressing Alt+arrows
  - 415260 Protect against negative indices when setting values in G...
  - 419171 XGetVisualInfo() may not set nxvisuals
  - 128852 Gdk cursors don't look good on win32
  - 344657 Ctrl-H doesn't toggle "Show Hidden Files" setting
  - 345345 PrintOperation::paginate is not emitted for class handler
  - 347567 GtkPrintOperation::end-print is not emitted if it's cance...
  - 369112 gtk_ui_manager_add_ui should accept unnamed separator
  - 392015 Selected menu item invisible on Windows Vista
  - 399253 MS-Windows Theme Bottom Tab placement rendering glitches
  - 399425 gtk_input_dialog_fill_axes() adds child to gtkscrolledwin...
  - 403251 [patch] little memory leak in GtkPrintJob
  - 403267 [patch] memory leak in GtkPageSetupUnixDialog
  - 403470 MS-Windows Theme tab placement other than on top leaks a ...
  - 404506 Windows system fonts that have multi-byte font names cann...
  - 405089 Incorrect window placement for GtkEventBox private window
  - 405515 Minor leak in gtkfilesystemmodel.c
  - 405539 gdk_pixbuf_save() for PNG saver can return FALSE without ...
  - 415681 gdk_window_clear_area includes an extra line and column o...
  - 418219 GtkRecentChooser should apply filter before sorting and c...
  - 418403 Scroll to printer after selecting it from settings
  - 421985 _gtk_print_operation_platform_backend_launch_preview
  - 421990 gtk_print_job_get_surface
  - 421993 gtk_print_operation_init
  - 423064 Conditional jump or move depends on uninitialised value(s...
  - 423722 Fix printing header in gtk-demo
  - 424168 gtk_print_operation_run on async preview
  - 425655 Don't install gtk+-unix-print-2.0.pc on non-UNIX platforms
  - 425786 GDK segfaults if XineramaQueryScreens fails
  - 428665 Lpr Backend gets stuck in infinite loop during gtk_enumer...
  - 429902 GtkPrintOperation leaks cairo contextes
  - 431997 First delay of GdkPixbufAnimationIter is wrong
  - 433242 Inconsistent scroll arrow position calculations
  - 433972 Placing gtk.Expander inside a gtk.TextView() changes gtk....
  - 434261 _gtk_toolbar_elide_underscores incorrectly handles some s...
  - 383354 ctrl-L should make 'Location' entry disappear
  - 418673 gtk_recent_manager_add_item
  - 429732 gtk_accel_group_finalize accesses invalid memory
  - 435028 WM_CLIENT_LEADER is wrong on the leader_window
  - 431067 Background of the header window is not updated
  - 338843 add recent files support inside the ui manager
  - 148535 add drop shadow to menus, tooltips, etc. under Windows XP
* debian/control.in:
  - Conflicts on ubuntulooks (<= 0.9.11-1)
* debian/patches/15_default-fallback-icon-theme.patch:
  - patch from Debian, fallback on gnome icon theme

Show diffs side-by-side

added added

removed removed

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