File: | ctk/ctkselection.c |
Warning: | line 1553, column 22 Access to field 'message' results in a dereference of a null pointer (loaded from variable 'error') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* CTK - The GIMP Toolkit | |||
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald | |||
3 | * | |||
4 | * This library is free software; you can redistribute it and/or | |||
5 | * modify it under the terms of the GNU Lesser General Public | |||
6 | * License as published by the Free Software Foundation; either | |||
7 | * version 2 of the License, or (at your option) any later version. | |||
8 | * | |||
9 | * This library is distributed in the hope that it will be useful, | |||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
12 | * Lesser General Public License for more details. | |||
13 | * | |||
14 | * You should have received a copy of the GNU Lesser General Public | |||
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. | |||
16 | */ | |||
17 | ||||
18 | /* This file implements most of the work of the ICCCM selection protocol. | |||
19 | * The code was written after an intensive study of the equivalent part | |||
20 | * of John Ousterhout’s Tk toolkit, and does many things in much the | |||
21 | * same way. | |||
22 | * | |||
23 | * The one thing in the ICCCM that isn’t fully supported here (or in Tk) | |||
24 | * is side effects targets. For these to be handled properly, MULTIPLE | |||
25 | * targets need to be done in the order specified. This cannot be | |||
26 | * guaranteed with the way we do things, since if we are doing INCR | |||
27 | * transfers, the order will depend on the timing of the requestor. | |||
28 | * | |||
29 | * By Owen Taylor <owt1@cornell.edu> 8/16/97 | |||
30 | */ | |||
31 | ||||
32 | /* Terminology note: when not otherwise specified, the term "incr" below | |||
33 | * refers to the _sending_ part of the INCR protocol. The receiving | |||
34 | * portion is referred to just as “retrieval”. (Terminology borrowed | |||
35 | * from Tk, because there is no good opposite to “retrieval” in English. | |||
36 | * “send” can’t be made into a noun gracefully and we’re already using | |||
37 | * “emission” for something else ....) | |||
38 | */ | |||
39 | ||||
40 | /* The MOTIF entry widget seems to ask for the TARGETS target, then | |||
41 | (regardless of the reply) ask for the TEXT target. It's slightly | |||
42 | possible though that it somehow thinks we are responding negatively | |||
43 | to the TARGETS request, though I don't really think so ... */ | |||
44 | ||||
45 | /* | |||
46 | * Modified by the CTK+ Team and others 1997-2000. See the AUTHORS | |||
47 | * file for a list of people on the CTK+ Team. See the ChangeLog | |||
48 | * files for a list of changes. These files are distributed with | |||
49 | * CTK+ at ftp://ftp.ctk.org/pub/ctk/. | |||
50 | */ | |||
51 | ||||
52 | /** | |||
53 | * SECTION:ctkselection | |||
54 | * @Title: Selections | |||
55 | * @Short_description: Functions for handling inter-process communication | |||
56 | * via selections | |||
57 | * @See_also: #CtkWidget - Much of the operation of selections happens via | |||
58 | * signals for #CtkWidget. In particular, if you are using the functions | |||
59 | * in this section, you may need to pay attention to | |||
60 | * #CtkWidget::selection-get, #CtkWidget::selection-received and | |||
61 | * #CtkWidget::selection-clear-event signals | |||
62 | * | |||
63 | * The selection mechanism provides the basis for different types | |||
64 | * of communication between processes. In particular, drag and drop and | |||
65 | * #CtkClipboard work via selections. You will very seldom or | |||
66 | * never need to use most of the functions in this section directly; | |||
67 | * #CtkClipboard provides a nicer interface to the same functionality. | |||
68 | * | |||
69 | * If an application is expected to exchange image data and work | |||
70 | * on Windows, it is highly advised to support at least "image/bmp" target | |||
71 | * for the widest possible compatibility with third-party applications. | |||
72 | * #CtkClipboard already does that by using ctk_target_list_add_image_targets() | |||
73 | * and ctk_selection_data_set_pixbuf() or ctk_selection_data_get_pixbuf(), | |||
74 | * which is one of the reasons why it is advised to use #CtkClipboard. | |||
75 | * | |||
76 | * Some of the datatypes defined this section are used in | |||
77 | * the #CtkClipboard and drag-and-drop API’s as well. The | |||
78 | * #CtkTargetEntry and #CtkTargetList objects represent | |||
79 | * lists of data types that are supported when sending or | |||
80 | * receiving data. The #CtkSelectionData object is used to | |||
81 | * store a chunk of data along with the data type and other | |||
82 | * associated information. | |||
83 | */ | |||
84 | ||||
85 | /* We are using deprecated API, here, and we know that */ | |||
86 | #define CDK_DISABLE_DEPRECATION_WARNINGS | |||
87 | ||||
88 | #include "config.h" | |||
89 | ||||
90 | #include "ctkselection.h" | |||
91 | #include "ctkselectionprivate.h" | |||
92 | ||||
93 | #include <stdarg.h> | |||
94 | #include <string.h> | |||
95 | #include "cdk.h" | |||
96 | ||||
97 | #include "ctkmain.h" | |||
98 | #include "ctkdebug.h" | |||
99 | #include "ctktextbufferrichtext.h" | |||
100 | #include "ctkintl.h" | |||
101 | #include "gdk-pixbuf/gdk-pixbuf.h" | |||
102 | ||||
103 | #ifdef CDK_WINDOWING_X11 | |||
104 | #include "x11/cdkx.h" | |||
105 | #endif | |||
106 | ||||
107 | #ifdef CDK_WINDOWING_WIN32 | |||
108 | #include "win32/cdkwin32.h" | |||
109 | #endif | |||
110 | ||||
111 | #ifdef CDK_WINDOWING_WAYLAND | |||
112 | #include <cdk/wayland/cdkwayland.h> | |||
113 | #endif | |||
114 | ||||
115 | #ifdef CDK_WINDOWING_BROADWAY | |||
116 | #include "broadway/cdkbroadway.h" | |||
117 | #endif | |||
118 | ||||
119 | #undef DEBUG_SELECTION | |||
120 | ||||
121 | /* Maximum size of a sent chunk, in bytes. Also the default size of | |||
122 | our buffers */ | |||
123 | #ifdef CDK_WINDOWING_X11 | |||
124 | #define CTK_SELECTION_MAX_SIZE(display)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (display)); GType __t = ((cdk_x11_display_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) ? ((( 262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) ? (262144) : (XExtendedMaxRequestSize (( cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) : 2147483647 \ | |||
125 | CDK_IS_X11_DISPLAY (display)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (display)); GType __t = ((cdk_x11_display_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) ? \ | |||
126 | MIN(262144, \(((262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) ? (262144) : (XExtendedMaxRequestSize (( cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) | |||
127 | XExtendedMaxRequestSize (CDK_DISPLAY_XDISPLAY (display)) == 0 \(((262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) ? (262144) : (XExtendedMaxRequestSize (( cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) | |||
128 | ? XMaxRequestSize (CDK_DISPLAY_XDISPLAY (display)) - 100 \(((262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) ? (262144) : (XExtendedMaxRequestSize (( cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) | |||
129 | : XExtendedMaxRequestSize (CDK_DISPLAY_XDISPLAY (display)) - 100)(((262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) ? (262144) : (XExtendedMaxRequestSize (( cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100))\ | |||
130 | : G_MAXINT2147483647 | |||
131 | #else | |||
132 | /* No chunks on Win32 */ | |||
133 | #define CTK_SELECTION_MAX_SIZE(display)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (display)); GType __t = ((cdk_x11_display_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) ? ((( 262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) ? (262144) : (XExtendedMaxRequestSize (( cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) : 2147483647 G_MAXINT2147483647 | |||
134 | #endif | |||
135 | ||||
136 | #define IDLE_ABORT_TIME30 30 | |||
137 | ||||
138 | enum { | |||
139 | INCR, | |||
140 | MULTIPLE, | |||
141 | TARGETS, | |||
142 | TIMESTAMP, | |||
143 | SAVE_TARGETS, | |||
144 | LAST_ATOM | |||
145 | }; | |||
146 | ||||
147 | typedef struct _CtkSelectionInfo CtkSelectionInfo; | |||
148 | typedef struct _CtkIncrConversion CtkIncrConversion; | |||
149 | typedef struct _CtkIncrInfo CtkIncrInfo; | |||
150 | typedef struct _CtkRetrievalInfo CtkRetrievalInfo; | |||
151 | ||||
152 | struct _CtkSelectionInfo | |||
153 | { | |||
154 | CdkAtom selection; | |||
155 | CtkWidget *widget; /* widget that owns selection */ | |||
156 | guint32 time; /* time used to acquire selection */ | |||
157 | CdkDisplay *display; /* needed in ctk_selection_remove_all */ | |||
158 | }; | |||
159 | ||||
160 | struct _CtkIncrConversion | |||
161 | { | |||
162 | CdkAtom target; /* Requested target */ | |||
163 | CdkAtom property; /* Property to store in */ | |||
164 | CtkSelectionData data; /* The data being supplied */ | |||
165 | gint offset; /* Current offset in sent selection. | |||
166 | * -1 => All done | |||
167 | * -2 => Only the final (empty) portion | |||
168 | * left to send */ | |||
169 | }; | |||
170 | ||||
171 | struct _CtkIncrInfo | |||
172 | { | |||
173 | CdkWindow *requestor; /* Requestor window - we create a CdkWindow | |||
174 | so we can receive events */ | |||
175 | CdkAtom selection; /* Selection we're sending */ | |||
176 | ||||
177 | CtkIncrConversion *conversions; /* Information about requested conversions - | |||
178 | * With MULTIPLE requests (benighted 1980's | |||
179 | * hardware idea), there can be more than | |||
180 | * one */ | |||
181 | gint num_conversions; | |||
182 | gint num_incrs; /* number of remaining INCR style transactions */ | |||
183 | guint32 idle_time; | |||
184 | }; | |||
185 | ||||
186 | ||||
187 | struct _CtkRetrievalInfo | |||
188 | { | |||
189 | CtkWidget *widget; | |||
190 | CdkAtom selection; /* Selection being retrieved. */ | |||
191 | CdkAtom target; /* Form of selection that we requested */ | |||
192 | guint32 idle_time; /* Number of seconds since we last heard | |||
193 | from selection owner */ | |||
194 | guchar *buffer; /* Buffer in which to accumulate results */ | |||
195 | gint offset; /* Current offset in buffer, -1 indicates | |||
196 | not yet started */ | |||
197 | guint32 notify_time; /* Timestamp from SelectionNotify */ | |||
198 | }; | |||
199 | ||||
200 | /* Local Functions */ | |||
201 | static void ctk_selection_init (void); | |||
202 | static gboolean ctk_selection_incr_timeout (CtkIncrInfo *info); | |||
203 | static gboolean ctk_selection_retrieval_timeout (CtkRetrievalInfo *info); | |||
204 | static void ctk_selection_retrieval_report (CtkRetrievalInfo *info, | |||
205 | CdkAtom type, | |||
206 | gint format, | |||
207 | guchar *buffer, | |||
208 | gint length, | |||
209 | guint32 time); | |||
210 | static void ctk_selection_invoke_handler (CtkWidget *widget, | |||
211 | CtkSelectionData *data, | |||
212 | guint time); | |||
213 | static void ctk_selection_default_handler (CtkWidget *widget, | |||
214 | CtkSelectionData *data); | |||
215 | static int ctk_selection_bytes_per_item (gint format); | |||
216 | ||||
217 | /* Local Data */ | |||
218 | static gint initialize = TRUE(!(0)); | |||
219 | static GList *current_retrievals = NULL((void*)0); | |||
220 | static GList *current_incrs = NULL((void*)0); | |||
221 | static GList *current_selections = NULL((void*)0); | |||
222 | ||||
223 | static CdkAtom ctk_selection_atoms[LAST_ATOM]; | |||
224 | static const char ctk_selection_handler_key[] = "ctk-selection-handlers"; | |||
225 | ||||
226 | /**************** | |||
227 | * Target Lists * | |||
228 | ****************/ | |||
229 | ||||
230 | /* | |||
231 | * Target lists | |||
232 | */ | |||
233 | ||||
234 | ||||
235 | /** | |||
236 | * ctk_target_list_new: | |||
237 | * @targets: (array length=ntargets) (allow-none): Pointer to an array | |||
238 | * of #CtkTargetEntry | |||
239 | * @ntargets: number of entries in @targets. | |||
240 | * | |||
241 | * Creates a new #CtkTargetList from an array of #CtkTargetEntry. | |||
242 | * | |||
243 | * Returns: (transfer full): the new #CtkTargetList. | |||
244 | **/ | |||
245 | CtkTargetList * | |||
246 | ctk_target_list_new (const CtkTargetEntry *targets, | |||
247 | guint ntargets) | |||
248 | { | |||
249 | CtkTargetList *result = g_slice_new (CtkTargetList)((CtkTargetList*) g_slice_alloc (sizeof (CtkTargetList))); | |||
250 | result->list = NULL((void*)0); | |||
251 | result->ref_count = 1; | |||
252 | ||||
253 | if (targets) | |||
254 | ctk_target_list_add_table (result, targets, ntargets); | |||
255 | ||||
256 | return result; | |||
257 | } | |||
258 | ||||
259 | /** | |||
260 | * ctk_target_list_ref: | |||
261 | * @list: a #CtkTargetList | |||
262 | * | |||
263 | * Increases the reference count of a #CtkTargetList by one. | |||
264 | * | |||
265 | * Returns: the passed in #CtkTargetList. | |||
266 | **/ | |||
267 | CtkTargetList * | |||
268 | ctk_target_list_ref (CtkTargetList *list) | |||
269 | { | |||
270 | g_return_val_if_fail (list != NULL, NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return ( ((void*)0)); } } while (0); | |||
271 | ||||
272 | list->ref_count++; | |||
273 | ||||
274 | return list; | |||
275 | } | |||
276 | ||||
277 | /** | |||
278 | * ctk_target_list_unref: | |||
279 | * @list: a #CtkTargetList | |||
280 | * | |||
281 | * Decreases the reference count of a #CtkTargetList by one. | |||
282 | * If the resulting reference count is zero, frees the list. | |||
283 | **/ | |||
284 | void | |||
285 | ctk_target_list_unref (CtkTargetList *list) | |||
286 | { | |||
287 | g_return_if_fail (list != NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return; } } while (0); | |||
288 | g_return_if_fail (list->ref_count > 0)do { if ((list->ref_count > 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list->ref_count > 0" ); return; } } while (0); | |||
289 | ||||
290 | list->ref_count--; | |||
291 | if (list->ref_count == 0) | |||
292 | { | |||
293 | GList *tmp_list = list->list; | |||
294 | while (tmp_list) | |||
295 | { | |||
296 | CtkTargetPair *pair = tmp_list->data; | |||
297 | g_slice_free (CtkTargetPair, pair)do { if (1) g_slice_free1 (sizeof (CtkTargetPair), (pair)); else (void) ((CtkTargetPair*) 0 == (pair)); } while (0); | |||
298 | ||||
299 | tmp_list = tmp_list->next; | |||
300 | } | |||
301 | ||||
302 | g_list_free (list->list); | |||
303 | g_slice_free (CtkTargetList, list)do { if (1) g_slice_free1 (sizeof (CtkTargetList), (list)); else (void) ((CtkTargetList*) 0 == (list)); } while (0); | |||
304 | } | |||
305 | } | |||
306 | ||||
307 | /** | |||
308 | * ctk_target_list_add: | |||
309 | * @list: a #CtkTargetList | |||
310 | * @target: the interned atom representing the target | |||
311 | * @flags: the flags for this target | |||
312 | * @info: an ID that will be passed back to the application | |||
313 | * | |||
314 | * Appends another target to a #CtkTargetList. | |||
315 | **/ | |||
316 | void | |||
317 | ctk_target_list_add (CtkTargetList *list, | |||
318 | CdkAtom target, | |||
319 | guint flags, | |||
320 | guint info) | |||
321 | { | |||
322 | CtkTargetPair *pair; | |||
323 | ||||
324 | g_return_if_fail (list != NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return; } } while (0); | |||
325 | ||||
326 | pair = g_slice_new (CtkTargetPair)((CtkTargetPair*) g_slice_alloc (sizeof (CtkTargetPair))); | |||
327 | pair->target = target; | |||
328 | pair->flags = flags; | |||
329 | pair->info = info; | |||
330 | ||||
331 | list->list = g_list_append (list->list, pair); | |||
332 | } | |||
333 | ||||
334 | static CdkAtom utf8_atom; | |||
335 | static CdkAtom text_atom; | |||
336 | static CdkAtom ctext_atom; | |||
337 | static CdkAtom text_plain_atom; | |||
338 | static CdkAtom text_plain_utf8_atom; | |||
339 | static CdkAtom text_plain_locale_atom; | |||
340 | static CdkAtom text_uri_list_atom; | |||
341 | ||||
342 | static void | |||
343 | init_atoms (void) | |||
344 | { | |||
345 | gchar *tmp; | |||
346 | const gchar *charset; | |||
347 | ||||
348 | if (!utf8_atom) | |||
349 | { | |||
350 | utf8_atom = cdk_atom_intern_static_string ("UTF8_STRING"); | |||
351 | text_atom = cdk_atom_intern_static_string ("TEXT"); | |||
352 | ctext_atom = cdk_atom_intern_static_string ("COMPOUND_TEXT"); | |||
353 | text_plain_atom = cdk_atom_intern_static_string ("text/plain"); | |||
354 | text_plain_utf8_atom = cdk_atom_intern_static_string ("text/plain;charset=utf-8"); | |||
355 | g_get_charset (&charset); | |||
356 | tmp = g_strdup_printf ("text/plain;charset=%s", charset); | |||
357 | text_plain_locale_atom = cdk_atom_intern (tmp, FALSE(0)); | |||
358 | g_free (tmp); | |||
359 | ||||
360 | text_uri_list_atom = cdk_atom_intern_static_string ("text/uri-list"); | |||
361 | } | |||
362 | } | |||
363 | ||||
364 | /** | |||
365 | * ctk_target_list_add_text_targets: | |||
366 | * @list: a #CtkTargetList | |||
367 | * @info: an ID that will be passed back to the application | |||
368 | * | |||
369 | * Appends the text targets supported by #CtkSelectionData to | |||
370 | * the target list. All targets are added with the same @info. | |||
371 | * | |||
372 | * Since: 2.6 | |||
373 | **/ | |||
374 | void | |||
375 | ctk_target_list_add_text_targets (CtkTargetList *list, | |||
376 | guint info) | |||
377 | { | |||
378 | g_return_if_fail (list != NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return; } } while (0); | |||
379 | ||||
380 | init_atoms (); | |||
381 | ||||
382 | /* Keep in sync with ctk_selection_data_targets_include_text() | |||
383 | */ | |||
384 | ctk_target_list_add (list, utf8_atom, 0, info); | |||
385 | ctk_target_list_add (list, ctext_atom, 0, info); | |||
386 | ctk_target_list_add (list, text_atom, 0, info); | |||
387 | ctk_target_list_add (list, CDK_TARGET_STRING((CdkAtom)((gpointer) (gulong) (31))), 0, info); | |||
388 | ctk_target_list_add (list, text_plain_utf8_atom, 0, info); | |||
389 | if (!g_get_charset (NULL((void*)0))) | |||
390 | ctk_target_list_add (list, text_plain_locale_atom, 0, info); | |||
391 | ctk_target_list_add (list, text_plain_atom, 0, info); | |||
392 | } | |||
393 | ||||
394 | /** | |||
395 | * ctk_target_list_add_rich_text_targets: | |||
396 | * @list: a #CtkTargetList | |||
397 | * @info: an ID that will be passed back to the application | |||
398 | * @deserializable: if %TRUE, then deserializable rich text formats | |||
399 | * will be added, serializable formats otherwise. | |||
400 | * @buffer: a #CtkTextBuffer. | |||
401 | * | |||
402 | * Appends the rich text targets registered with | |||
403 | * ctk_text_buffer_register_serialize_format() or | |||
404 | * ctk_text_buffer_register_deserialize_format() to the target list. All | |||
405 | * targets are added with the same @info. | |||
406 | * | |||
407 | * Since: 2.10 | |||
408 | **/ | |||
409 | void | |||
410 | ctk_target_list_add_rich_text_targets (CtkTargetList *list, | |||
411 | guint info, | |||
412 | gboolean deserializable, | |||
413 | CtkTextBuffer *buffer) | |||
414 | { | |||
415 | CdkAtom *atoms; | |||
416 | gint n_atoms; | |||
417 | gint i; | |||
418 | ||||
419 | g_return_if_fail (list != NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return; } } while (0); | |||
420 | g_return_if_fail (CTK_IS_TEXT_BUFFER (buffer))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((buffer)); GType __t = ((ctk_text_buffer_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TEXT_BUFFER (buffer)"); return; } } while (0); | |||
421 | ||||
422 | if (deserializable) | |||
423 | atoms = ctk_text_buffer_get_deserialize_formats (buffer, &n_atoms); | |||
424 | else | |||
425 | atoms = ctk_text_buffer_get_serialize_formats (buffer, &n_atoms); | |||
426 | ||||
427 | for (i = 0; i < n_atoms; i++) | |||
428 | ctk_target_list_add (list, atoms[i], 0, info); | |||
429 | ||||
430 | g_free (atoms); | |||
431 | } | |||
432 | ||||
433 | /** | |||
434 | * ctk_target_list_add_image_targets: | |||
435 | * @list: a #CtkTargetList | |||
436 | * @info: an ID that will be passed back to the application | |||
437 | * @writable: whether to add only targets for which CTK+ knows | |||
438 | * how to convert a pixbuf into the format | |||
439 | * | |||
440 | * Appends the image targets supported by #CtkSelectionData to | |||
441 | * the target list. All targets are added with the same @info. | |||
442 | * | |||
443 | * Since: 2.6 | |||
444 | **/ | |||
445 | void | |||
446 | ctk_target_list_add_image_targets (CtkTargetList *list, | |||
447 | guint info, | |||
448 | gboolean writable) | |||
449 | { | |||
450 | GSList *formats, *f; | |||
451 | gchar **mimes, **m; | |||
452 | CdkAtom atom; | |||
453 | ||||
454 | g_return_if_fail (list != NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return; } } while (0); | |||
455 | ||||
456 | formats = gdk_pixbuf_get_formats (); | |||
457 | ||||
458 | /* Make sure png comes first */ | |||
459 | for (f = formats; f; f = f->next) | |||
460 | { | |||
461 | GdkPixbufFormat *fmt = f->data; | |||
462 | gchar *name; | |||
463 | ||||
464 | name = gdk_pixbuf_format_get_name (fmt); | |||
465 | if (strcmp (name, "png") == 0) | |||
466 | { | |||
467 | formats = g_slist_delete_link (formats, f); | |||
468 | formats = g_slist_prepend (formats, fmt); | |||
469 | ||||
470 | g_free (name); | |||
471 | ||||
472 | break; | |||
473 | } | |||
474 | ||||
475 | g_free (name); | |||
476 | } | |||
477 | ||||
478 | for (f = formats; f; f = f->next) | |||
479 | { | |||
480 | GdkPixbufFormat *fmt = f->data; | |||
481 | ||||
482 | if (writable && !gdk_pixbuf_format_is_writable (fmt)) | |||
483 | continue; | |||
484 | ||||
485 | mimes = gdk_pixbuf_format_get_mime_types (fmt); | |||
486 | for (m = mimes; *m; m++) | |||
487 | { | |||
488 | atom = cdk_atom_intern (*m, FALSE(0)); | |||
489 | ctk_target_list_add (list, atom, 0, info); | |||
490 | } | |||
491 | g_strfreev (mimes); | |||
492 | } | |||
493 | ||||
494 | g_slist_free (formats); | |||
495 | } | |||
496 | ||||
497 | /** | |||
498 | * ctk_target_list_add_uri_targets: | |||
499 | * @list: a #CtkTargetList | |||
500 | * @info: an ID that will be passed back to the application | |||
501 | * | |||
502 | * Appends the URI targets supported by #CtkSelectionData to | |||
503 | * the target list. All targets are added with the same @info. | |||
504 | * | |||
505 | * Since: 2.6 | |||
506 | **/ | |||
507 | void | |||
508 | ctk_target_list_add_uri_targets (CtkTargetList *list, | |||
509 | guint info) | |||
510 | { | |||
511 | g_return_if_fail (list != NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return; } } while (0); | |||
512 | ||||
513 | init_atoms (); | |||
514 | ||||
515 | ctk_target_list_add (list, text_uri_list_atom, 0, info); | |||
516 | } | |||
517 | ||||
518 | /** | |||
519 | * ctk_target_list_add_table: | |||
520 | * @list: a #CtkTargetList | |||
521 | * @targets: (array length=ntargets): the table of #CtkTargetEntry | |||
522 | * @ntargets: number of targets in the table | |||
523 | * | |||
524 | * Prepends a table of #CtkTargetEntry to a target list. | |||
525 | **/ | |||
526 | void | |||
527 | ctk_target_list_add_table (CtkTargetList *list, | |||
528 | const CtkTargetEntry *targets, | |||
529 | guint ntargets) | |||
530 | { | |||
531 | gint i; | |||
532 | ||||
533 | for (i=ntargets-1; i >= 0; i--) | |||
534 | { | |||
535 | CtkTargetPair *pair = g_slice_new (CtkTargetPair)((CtkTargetPair*) g_slice_alloc (sizeof (CtkTargetPair))); | |||
536 | pair->target = cdk_atom_intern (targets[i].target, FALSE(0)); | |||
537 | pair->flags = targets[i].flags; | |||
538 | pair->info = targets[i].info; | |||
539 | ||||
540 | list->list = g_list_prepend (list->list, pair); | |||
541 | } | |||
542 | } | |||
543 | ||||
544 | /** | |||
545 | * ctk_target_list_remove: | |||
546 | * @list: a #CtkTargetList | |||
547 | * @target: the interned atom representing the target | |||
548 | * | |||
549 | * Removes a target from a target list. | |||
550 | **/ | |||
551 | void | |||
552 | ctk_target_list_remove (CtkTargetList *list, | |||
553 | CdkAtom target) | |||
554 | { | |||
555 | GList *tmp_list; | |||
556 | ||||
557 | g_return_if_fail (list != NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return; } } while (0); | |||
558 | ||||
559 | tmp_list = list->list; | |||
560 | while (tmp_list) | |||
561 | { | |||
562 | CtkTargetPair *pair = tmp_list->data; | |||
563 | ||||
564 | if (pair->target == target) | |||
565 | { | |||
566 | g_slice_free (CtkTargetPair, pair)do { if (1) g_slice_free1 (sizeof (CtkTargetPair), (pair)); else (void) ((CtkTargetPair*) 0 == (pair)); } while (0); | |||
567 | ||||
568 | list->list = g_list_remove_link (list->list, tmp_list); | |||
569 | g_list_free_1 (tmp_list); | |||
570 | ||||
571 | return; | |||
572 | } | |||
573 | ||||
574 | tmp_list = tmp_list->next; | |||
575 | } | |||
576 | } | |||
577 | ||||
578 | /** | |||
579 | * ctk_target_list_find: | |||
580 | * @list: a #CtkTargetList | |||
581 | * @target: an interned atom representing the target to search for | |||
582 | * @info: (out) (allow-none): a pointer to the location to store | |||
583 | * application info for target, or %NULL | |||
584 | * | |||
585 | * Looks up a given target in a #CtkTargetList. | |||
586 | * | |||
587 | * Returns: %TRUE if the target was found, otherwise %FALSE | |||
588 | **/ | |||
589 | gboolean | |||
590 | ctk_target_list_find (CtkTargetList *list, | |||
591 | CdkAtom target, | |||
592 | guint *info) | |||
593 | { | |||
594 | GList *tmp_list; | |||
595 | ||||
596 | g_return_val_if_fail (list != NULL, FALSE)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return ( (0)); } } while (0); | |||
597 | ||||
598 | tmp_list = list->list; | |||
599 | while (tmp_list) | |||
600 | { | |||
601 | CtkTargetPair *pair = tmp_list->data; | |||
602 | ||||
603 | if (pair->target == target) | |||
604 | { | |||
605 | if (info) | |||
606 | *info = pair->info; | |||
607 | ||||
608 | return TRUE(!(0)); | |||
609 | } | |||
610 | ||||
611 | tmp_list = tmp_list->next; | |||
612 | } | |||
613 | ||||
614 | return FALSE(0); | |||
615 | } | |||
616 | ||||
617 | /** | |||
618 | * ctk_target_table_new_from_list: | |||
619 | * @list: a #CtkTargetList | |||
620 | * @n_targets: (out): return location for the number ot targets in the table | |||
621 | * | |||
622 | * This function creates an #CtkTargetEntry array that contains the | |||
623 | * same targets as the passed %list. The returned table is newly | |||
624 | * allocated and should be freed using ctk_target_table_free() when no | |||
625 | * longer needed. | |||
626 | * | |||
627 | * Returns: (array length=n_targets) (transfer full): the new table. | |||
628 | * | |||
629 | * Since: 2.10 | |||
630 | **/ | |||
631 | CtkTargetEntry * | |||
632 | ctk_target_table_new_from_list (CtkTargetList *list, | |||
633 | gint *n_targets) | |||
634 | { | |||
635 | CtkTargetEntry *targets; | |||
636 | GList *tmp_list; | |||
637 | gint i; | |||
638 | ||||
639 | g_return_val_if_fail (list != NULL, NULL)do { if ((list != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "list != NULL"); return ( ((void*)0)); } } while (0); | |||
640 | g_return_val_if_fail (n_targets != NULL, NULL)do { if ((n_targets != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "n_targets != NULL"); return (((void*)0)); } } while (0); | |||
641 | ||||
642 | *n_targets = g_list_length (list->list); | |||
643 | targets = g_new0 (CtkTargetEntry, *n_targets)((CtkTargetEntry *) g_malloc0_n ((*n_targets), sizeof (CtkTargetEntry ))); | |||
644 | ||||
645 | for (tmp_list = list->list, i = 0; tmp_list; tmp_list = tmp_list->next, i++) | |||
646 | { | |||
647 | CtkTargetPair *pair = tmp_list->data; | |||
648 | ||||
649 | targets[i].target = cdk_atom_name (pair->target); | |||
650 | targets[i].flags = pair->flags; | |||
651 | targets[i].info = pair->info; | |||
652 | } | |||
653 | ||||
654 | return targets; | |||
655 | } | |||
656 | ||||
657 | /** | |||
658 | * ctk_target_table_free: | |||
659 | * @targets: (array length=n_targets): a #CtkTargetEntry array | |||
660 | * @n_targets: the number of entries in the array | |||
661 | * | |||
662 | * This function frees a target table as returned by | |||
663 | * ctk_target_table_new_from_list() | |||
664 | * | |||
665 | * Since: 2.10 | |||
666 | **/ | |||
667 | void | |||
668 | ctk_target_table_free (CtkTargetEntry *targets, | |||
669 | gint n_targets) | |||
670 | { | |||
671 | gint i; | |||
672 | ||||
673 | g_return_if_fail (targets == NULL || n_targets > 0)do { if ((targets == ((void*)0) || n_targets > 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "targets == NULL || n_targets > 0"); return; } } while ( 0); | |||
674 | ||||
675 | for (i = 0; i < n_targets; i++) | |||
676 | g_free (targets[i].target); | |||
677 | ||||
678 | g_free (targets); | |||
679 | } | |||
680 | ||||
681 | /** | |||
682 | * ctk_selection_owner_set_for_display: | |||
683 | * @display: the #CdkDisplay where the selection is set | |||
684 | * @widget: (allow-none): new selection owner (a #CtkWidget), or %NULL. | |||
685 | * @selection: an interned atom representing the selection to claim. | |||
686 | * @time_: timestamp with which to claim the selection | |||
687 | * | |||
688 | * Claim ownership of a given selection for a particular widget, or, | |||
689 | * if @widget is %NULL, release ownership of the selection. | |||
690 | * | |||
691 | * Returns: TRUE if the operation succeeded | |||
692 | * | |||
693 | * Since: 2.2 | |||
694 | */ | |||
695 | gboolean | |||
696 | ctk_selection_owner_set_for_display (CdkDisplay *display, | |||
697 | CtkWidget *widget, | |||
698 | CdkAtom selection, | |||
699 | guint32 time) | |||
700 | { | |||
701 | GList *tmp_list; | |||
702 | CtkWidget *old_owner; | |||
703 | CtkSelectionInfo *selection_info = NULL((void*)0); | |||
704 | CdkWindow *window; | |||
705 | ||||
706 | g_return_val_if_fail (CDK_IS_DISPLAY (display), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((display)); GType __t = ((cdk_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CDK_IS_DISPLAY (display)"); return ((0)); } } while (0); | |||
707 | g_return_val_if_fail (selection != CDK_NONE, FALSE)do { if ((selection != ((CdkAtom)((gpointer) (gulong) (0))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "selection != CDK_NONE"); return ((0)); } } while (0); | |||
708 | g_return_val_if_fail (widget == NULL || ctk_widget_get_realized (widget), FALSE)do { if ((widget == ((void*)0) || ctk_widget_get_realized (widget ))) { } else { g_return_if_fail_warning ("Ctk", ((const char* ) (__func__)), "widget == NULL || ctk_widget_get_realized (widget)" ); return ((0)); } } while (0); | |||
709 | g_return_val_if_fail (widget == NULL || ctk_widget_get_display (widget) == display, FALSE)do { if ((widget == ((void*)0) || ctk_widget_get_display (widget ) == display)) { } else { g_return_if_fail_warning ("Ctk", (( const char*) (__func__)), "widget == NULL || ctk_widget_get_display (widget) == display" ); return ((0)); } } while (0); | |||
710 | ||||
711 | if (widget == NULL((void*)0)) | |||
712 | window = NULL((void*)0); | |||
713 | else | |||
714 | window = ctk_widget_get_window (widget); | |||
715 | ||||
716 | tmp_list = current_selections; | |||
717 | while (tmp_list) | |||
718 | { | |||
719 | if (((CtkSelectionInfo *)tmp_list->data)->selection == selection) | |||
720 | { | |||
721 | selection_info = tmp_list->data; | |||
722 | break; | |||
723 | } | |||
724 | ||||
725 | tmp_list = tmp_list->next; | |||
726 | } | |||
727 | ||||
728 | if (cdk_selection_owner_set_for_display (display, window, selection, time, TRUE(!(0)))) | |||
729 | { | |||
730 | old_owner = NULL((void*)0); | |||
731 | ||||
732 | if (widget == NULL((void*)0)) | |||
733 | { | |||
734 | if (selection_info) | |||
735 | { | |||
736 | old_owner = selection_info->widget; | |||
737 | current_selections = g_list_remove_link (current_selections, | |||
738 | tmp_list); | |||
739 | g_list_free (tmp_list); | |||
740 | g_slice_free (CtkSelectionInfo, selection_info)do { if (1) g_slice_free1 (sizeof (CtkSelectionInfo), (selection_info )); else (void) ((CtkSelectionInfo*) 0 == (selection_info)); } while (0); | |||
741 | } | |||
742 | } | |||
743 | else | |||
744 | { | |||
745 | if (selection_info == NULL((void*)0)) | |||
746 | { | |||
747 | selection_info = g_slice_new (CtkSelectionInfo)((CtkSelectionInfo*) g_slice_alloc (sizeof (CtkSelectionInfo) )); | |||
748 | selection_info->selection = selection; | |||
749 | selection_info->widget = widget; | |||
750 | selection_info->time = time; | |||
751 | selection_info->display = display; | |||
752 | current_selections = g_list_prepend (current_selections, | |||
753 | selection_info); | |||
754 | } | |||
755 | else | |||
756 | { | |||
757 | old_owner = selection_info->widget; | |||
758 | selection_info->widget = widget; | |||
759 | selection_info->time = time; | |||
760 | selection_info->display = display; | |||
761 | } | |||
762 | } | |||
763 | /* If another widget in the application lost the selection, | |||
764 | * send it a CDK_SELECTION_CLEAR event. | |||
765 | */ | |||
766 | if (old_owner && old_owner != widget) | |||
767 | { | |||
768 | CdkEvent *event = cdk_event_new (CDK_SELECTION_CLEAR); | |||
769 | ||||
770 | event->selection.window = g_object_ref (ctk_widget_get_window (old_owner))((__typeof__ (ctk_widget_get_window (old_owner))) (g_object_ref ) (ctk_widget_get_window (old_owner))); | |||
771 | event->selection.selection = selection; | |||
772 | event->selection.time = time; | |||
773 | ||||
774 | ctk_widget_event (old_owner, event); | |||
775 | ||||
776 | cdk_event_free (event); | |||
777 | } | |||
778 | return TRUE(!(0)); | |||
779 | } | |||
780 | else | |||
781 | return FALSE(0); | |||
782 | } | |||
783 | ||||
784 | /** | |||
785 | * ctk_selection_owner_set: | |||
786 | * @widget: (allow-none): a #CtkWidget, or %NULL. | |||
787 | * @selection: an interned atom representing the selection to claim | |||
788 | * @time_: timestamp with which to claim the selection | |||
789 | * | |||
790 | * Claims ownership of a given selection for a particular widget, | |||
791 | * or, if @widget is %NULL, release ownership of the selection. | |||
792 | * | |||
793 | * Returns: %TRUE if the operation succeeded | |||
794 | **/ | |||
795 | gboolean | |||
796 | ctk_selection_owner_set (CtkWidget *widget, | |||
797 | CdkAtom selection, | |||
798 | guint32 time) | |||
799 | { | |||
800 | CdkDisplay *display; | |||
801 | ||||
802 | g_return_val_if_fail (widget == NULL || ctk_widget_get_realized (widget), FALSE)do { if ((widget == ((void*)0) || ctk_widget_get_realized (widget ))) { } else { g_return_if_fail_warning ("Ctk", ((const char* ) (__func__)), "widget == NULL || ctk_widget_get_realized (widget)" ); return ((0)); } } while (0); | |||
803 | g_return_val_if_fail (selection != CDK_NONE, FALSE)do { if ((selection != ((CdkAtom)((gpointer) (gulong) (0))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "selection != CDK_NONE"); return ((0)); } } while (0); | |||
804 | ||||
805 | if (widget) | |||
806 | display = ctk_widget_get_display (widget); | |||
807 | else | |||
808 | { | |||
809 | CTK_NOTE (MULTIHEAD,do { if ((ctk_get_debug_flags () & CTK_DEBUG_MULTIHEAD)) { g_warning ("ctk_selection_owner_set (NULL,...) is not multihead safe" ); }; } while (0) | |||
810 | g_warning ("ctk_selection_owner_set (NULL,...) is not multihead safe"))do { if ((ctk_get_debug_flags () & CTK_DEBUG_MULTIHEAD)) { g_warning ("ctk_selection_owner_set (NULL,...) is not multihead safe" ); }; } while (0); | |||
811 | ||||
812 | display = cdk_display_get_default (); | |||
813 | } | |||
814 | ||||
815 | return ctk_selection_owner_set_for_display (display, widget, | |||
816 | selection, time); | |||
817 | } | |||
818 | ||||
819 | typedef struct _CtkSelectionTargetList CtkSelectionTargetList; | |||
820 | ||||
821 | struct _CtkSelectionTargetList { | |||
822 | CdkAtom selection; | |||
823 | CtkTargetList *list; | |||
824 | }; | |||
825 | ||||
826 | static CtkTargetList * | |||
827 | ctk_selection_target_list_get (CtkWidget *widget, | |||
828 | CdkAtom selection) | |||
829 | { | |||
830 | CtkSelectionTargetList *sellist; | |||
831 | GList *tmp_list; | |||
832 | GList *lists; | |||
833 | ||||
834 | lists = g_object_get_data (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), ctk_selection_handler_key); | |||
835 | ||||
836 | tmp_list = lists; | |||
837 | while (tmp_list) | |||
838 | { | |||
839 | sellist = tmp_list->data; | |||
840 | if (sellist->selection == selection) | |||
841 | return sellist->list; | |||
842 | tmp_list = tmp_list->next; | |||
843 | } | |||
844 | ||||
845 | sellist = g_slice_new (CtkSelectionTargetList)((CtkSelectionTargetList*) g_slice_alloc (sizeof (CtkSelectionTargetList ))); | |||
846 | sellist->selection = selection; | |||
847 | sellist->list = ctk_target_list_new (NULL((void*)0), 0); | |||
848 | ||||
849 | lists = g_list_prepend (lists, sellist); | |||
850 | g_object_set_data (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), I_(ctk_selection_handler_key)g_intern_static_string (ctk_selection_handler_key), lists); | |||
851 | ||||
852 | return sellist->list; | |||
853 | } | |||
854 | ||||
855 | static void | |||
856 | ctk_selection_target_list_remove (CtkWidget *widget) | |||
857 | { | |||
858 | CtkSelectionTargetList *sellist; | |||
859 | GList *tmp_list; | |||
860 | GList *lists; | |||
861 | ||||
862 | lists = g_object_get_data (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), ctk_selection_handler_key); | |||
863 | ||||
864 | tmp_list = lists; | |||
865 | while (tmp_list) | |||
866 | { | |||
867 | sellist = tmp_list->data; | |||
868 | ||||
869 | ctk_target_list_unref (sellist->list); | |||
870 | ||||
871 | g_slice_free (CtkSelectionTargetList, sellist)do { if (1) g_slice_free1 (sizeof (CtkSelectionTargetList), ( sellist)); else (void) ((CtkSelectionTargetList*) 0 == (sellist )); } while (0); | |||
872 | tmp_list = tmp_list->next; | |||
873 | } | |||
874 | ||||
875 | g_list_free (lists); | |||
876 | g_object_set_data (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), I_(ctk_selection_handler_key)g_intern_static_string (ctk_selection_handler_key), NULL((void*)0)); | |||
877 | } | |||
878 | ||||
879 | /** | |||
880 | * ctk_selection_clear_targets: | |||
881 | * @widget: a #CtkWidget | |||
882 | * @selection: an atom representing a selection | |||
883 | * | |||
884 | * Remove all targets registered for the given selection for the | |||
885 | * widget. | |||
886 | **/ | |||
887 | void | |||
888 | ctk_selection_clear_targets (CtkWidget *widget, | |||
889 | CdkAtom selection) | |||
890 | { | |||
891 | CtkSelectionTargetList *sellist; | |||
892 | GList *tmp_list; | |||
893 | GList *lists; | |||
894 | ||||
895 | g_return_if_fail (CTK_IS_WIDGET (widget))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return; } } while (0); | |||
896 | g_return_if_fail (selection != CDK_NONE)do { if ((selection != ((CdkAtom)((gpointer) (gulong) (0))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "selection != CDK_NONE"); return; } } while (0); | |||
897 | ||||
898 | #ifdef CDK_WINDOWING_WAYLAND | |||
899 | if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (ctk_widget_get_display (widget))); GType __t = ((cdk_wayland_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
900 | cdk_wayland_selection_clear_targetscdk_wayland_selection_clear_targets_libctk_only (ctk_widget_get_display (widget), selection); | |||
901 | #endif | |||
902 | #ifdef CDK_WINDOWING_WIN32 | |||
903 | if (CDK_IS_WIN32_DISPLAY (ctk_widget_get_display (widget))) | |||
904 | cdk_win32_selection_clear_targets (ctk_widget_get_display (widget), selection); | |||
905 | #endif | |||
906 | ||||
907 | lists = g_object_get_data (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), ctk_selection_handler_key); | |||
908 | ||||
909 | tmp_list = lists; | |||
910 | while (tmp_list) | |||
911 | { | |||
912 | sellist = tmp_list->data; | |||
913 | if (sellist->selection == selection) | |||
914 | { | |||
915 | lists = g_list_delete_link (lists, tmp_list); | |||
916 | ctk_target_list_unref (sellist->list); | |||
917 | g_slice_free (CtkSelectionTargetList, sellist)do { if (1) g_slice_free1 (sizeof (CtkSelectionTargetList), ( sellist)); else (void) ((CtkSelectionTargetList*) 0 == (sellist )); } while (0); | |||
918 | ||||
919 | break; | |||
920 | } | |||
921 | ||||
922 | tmp_list = tmp_list->next; | |||
923 | } | |||
924 | ||||
925 | g_object_set_data (G_OBJECT (widget)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), (((GType) ((20) << (2)))))))), I_(ctk_selection_handler_key)g_intern_static_string (ctk_selection_handler_key), lists); | |||
926 | } | |||
927 | ||||
928 | /** | |||
929 | * ctk_selection_add_target: | |||
930 | * @widget: a #CtkWidget | |||
931 | * @selection: the selection | |||
932 | * @target: target to add. | |||
933 | * @info: A unsigned integer which will be passed back to the application. | |||
934 | * | |||
935 | * Appends a specified target to the list of supported targets for a | |||
936 | * given widget and selection. | |||
937 | **/ | |||
938 | void | |||
939 | ctk_selection_add_target (CtkWidget *widget, | |||
940 | CdkAtom selection, | |||
941 | CdkAtom target, | |||
942 | guint info) | |||
943 | { | |||
944 | CtkTargetList *list; | |||
945 | ||||
946 | g_return_if_fail (CTK_IS_WIDGET (widget))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return; } } while (0); | |||
947 | g_return_if_fail (selection != CDK_NONE)do { if ((selection != ((CdkAtom)((gpointer) (gulong) (0))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "selection != CDK_NONE"); return; } } while (0); | |||
948 | ||||
949 | list = ctk_selection_target_list_get (widget, selection); | |||
950 | ctk_target_list_add (list, target, 0, info); | |||
951 | #ifdef CDK_WINDOWING_WAYLAND | |||
952 | if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (ctk_widget_get_display (widget))); GType __t = ((cdk_wayland_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
953 | cdk_wayland_selection_add_targetscdk_wayland_selection_add_targets_libctk_only (ctk_widget_get_window (widget), selection, 1, &target); | |||
954 | #endif | |||
955 | #ifdef CDK_WINDOWING_WIN32 | |||
956 | if (CDK_IS_WIN32_DISPLAY (ctk_widget_get_display (widget))) | |||
957 | cdk_win32_selection_add_targets (ctk_widget_get_window (widget), selection, 1, &target); | |||
958 | #endif | |||
959 | } | |||
960 | ||||
961 | /** | |||
962 | * ctk_selection_add_targets: | |||
963 | * @widget: a #CtkWidget | |||
964 | * @selection: the selection | |||
965 | * @targets: (array length=ntargets): a table of targets to add | |||
966 | * @ntargets: number of entries in @targets | |||
967 | * | |||
968 | * Prepends a table of targets to the list of supported targets | |||
969 | * for a given widget and selection. | |||
970 | **/ | |||
971 | void | |||
972 | ctk_selection_add_targets (CtkWidget *widget, | |||
973 | CdkAtom selection, | |||
974 | const CtkTargetEntry *targets, | |||
975 | guint ntargets) | |||
976 | { | |||
977 | CtkTargetList *list; | |||
978 | ||||
979 | g_return_if_fail (CTK_IS_WIDGET (widget))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return; } } while (0); | |||
980 | g_return_if_fail (selection != CDK_NONE)do { if ((selection != ((CdkAtom)((gpointer) (gulong) (0))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "selection != CDK_NONE"); return; } } while (0); | |||
981 | g_return_if_fail (targets != NULL)do { if ((targets != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "targets != NULL"); return ; } } while (0); | |||
982 | ||||
983 | list = ctk_selection_target_list_get (widget, selection); | |||
984 | ctk_target_list_add_table (list, targets, ntargets); | |||
985 | ||||
986 | #ifdef CDK_WINDOWING_WAYLAND | |||
987 | if (CDK_IS_WAYLAND_DISPLAY (ctk_widget_get_display (widget))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (ctk_widget_get_display (widget))); GType __t = ((cdk_wayland_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
988 | { | |||
989 | CdkAtom *atoms = g_new (CdkAtom, ntargets)((CdkAtom *) g_malloc_n ((ntargets), sizeof (CdkAtom))); | |||
990 | guint i; | |||
991 | ||||
992 | for (i = 0; i < ntargets; i++) | |||
993 | atoms[i] = cdk_atom_intern (targets[i].target, FALSE(0)); | |||
994 | ||||
995 | cdk_wayland_selection_add_targetscdk_wayland_selection_add_targets_libctk_only (ctk_widget_get_window (widget), selection, ntargets, atoms); | |||
996 | g_free (atoms); | |||
997 | } | |||
998 | #endif | |||
999 | ||||
1000 | #ifdef CDK_WINDOWING_WIN32 | |||
1001 | if (CDK_IS_WIN32_DISPLAY (ctk_widget_get_display (widget))) | |||
1002 | { | |||
1003 | int i; | |||
1004 | CdkAtom *atoms = g_new (CdkAtom, ntargets)((CdkAtom *) g_malloc_n ((ntargets), sizeof (CdkAtom))); | |||
1005 | ||||
1006 | for (i = 0; i < ntargets; ++i) | |||
1007 | atoms[i] = cdk_atom_intern (targets[i].target, FALSE(0)); | |||
1008 | cdk_win32_selection_add_targets (ctk_widget_get_window (widget), selection, ntargets, atoms); | |||
1009 | g_free (atoms); | |||
1010 | } | |||
1011 | #endif | |||
1012 | } | |||
1013 | ||||
1014 | ||||
1015 | /** | |||
1016 | * ctk_selection_remove_all: | |||
1017 | * @widget: a #CtkWidget | |||
1018 | * | |||
1019 | * Removes all handlers and unsets ownership of all | |||
1020 | * selections for a widget. Called when widget is being | |||
1021 | * destroyed. This function will not generally be | |||
1022 | * called by applications. | |||
1023 | **/ | |||
1024 | void | |||
1025 | ctk_selection_remove_all (CtkWidget *widget) | |||
1026 | { | |||
1027 | GList *tmp_list; | |||
1028 | GList *next; | |||
1029 | CtkSelectionInfo *selection_info; | |||
1030 | ||||
1031 | g_return_if_fail (CTK_IS_WIDGET (widget))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return; } } while (0); | |||
1032 | ||||
1033 | /* Remove pending requests/incrs for this widget */ | |||
1034 | ||||
1035 | tmp_list = current_retrievals; | |||
1036 | while (tmp_list) | |||
1037 | { | |||
1038 | next = tmp_list->next; | |||
1039 | if (((CtkRetrievalInfo *)tmp_list->data)->widget == widget) | |||
1040 | { | |||
1041 | current_retrievals = g_list_remove_link (current_retrievals, | |||
1042 | tmp_list); | |||
1043 | /* structure will be freed in timeout */ | |||
1044 | g_list_free (tmp_list); | |||
1045 | } | |||
1046 | tmp_list = next; | |||
1047 | } | |||
1048 | ||||
1049 | /* Disclaim ownership of any selections */ | |||
1050 | ||||
1051 | tmp_list = current_selections; | |||
1052 | while (tmp_list) | |||
1053 | { | |||
1054 | next = tmp_list->next; | |||
1055 | selection_info = (CtkSelectionInfo *)tmp_list->data; | |||
1056 | ||||
1057 | if (selection_info->widget == widget) | |||
1058 | { | |||
1059 | cdk_selection_owner_set_for_display (selection_info->display, | |||
1060 | NULL((void*)0), | |||
1061 | selection_info->selection, | |||
1062 | CDK_CURRENT_TIME0L, FALSE(0)); | |||
1063 | current_selections = g_list_remove_link (current_selections, | |||
1064 | tmp_list); | |||
1065 | g_list_free (tmp_list); | |||
1066 | g_slice_free (CtkSelectionInfo, selection_info)do { if (1) g_slice_free1 (sizeof (CtkSelectionInfo), (selection_info )); else (void) ((CtkSelectionInfo*) 0 == (selection_info)); } while (0); | |||
1067 | } | |||
1068 | ||||
1069 | tmp_list = next; | |||
1070 | } | |||
1071 | ||||
1072 | /* Remove all selection lists */ | |||
1073 | ctk_selection_target_list_remove (widget); | |||
1074 | } | |||
1075 | ||||
1076 | ||||
1077 | /** | |||
1078 | * ctk_selection_convert: | |||
1079 | * @widget: The widget which acts as requestor | |||
1080 | * @selection: Which selection to get | |||
1081 | * @target: Form of information desired (e.g., STRING) | |||
1082 | * @time_: Time of request (usually of triggering event) | |||
1083 | In emergency, you could use #CDK_CURRENT_TIME | |||
1084 | * | |||
1085 | * Requests the contents of a selection. When received, | |||
1086 | * a “selection-received” signal will be generated. | |||
1087 | * | |||
1088 | * Returns: %TRUE if requested succeeded. %FALSE if we could not process | |||
1089 | * request. (e.g., there was already a request in process for | |||
1090 | * this widget). | |||
1091 | **/ | |||
1092 | gboolean | |||
1093 | ctk_selection_convert (CtkWidget *widget, | |||
1094 | CdkAtom selection, | |||
1095 | CdkAtom target, | |||
1096 | guint32 time_) | |||
1097 | { | |||
1098 | CtkRetrievalInfo *info; | |||
1099 | GList *tmp_list; | |||
1100 | CdkWindow *owner_window; | |||
1101 | CdkDisplay *display; | |||
1102 | guint id; | |||
1103 | ||||
1104 | g_return_val_if_fail (CTK_IS_WIDGET (widget), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return ((0)); } } while (0); | |||
1105 | g_return_val_if_fail (selection != CDK_NONE, FALSE)do { if ((selection != ((CdkAtom)((gpointer) (gulong) (0))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "selection != CDK_NONE"); return ((0)); } } while (0); | |||
1106 | ||||
1107 | if (initialize) | |||
1108 | ctk_selection_init (); | |||
1109 | ||||
1110 | if (!ctk_widget_get_realized (widget)) | |||
1111 | ctk_widget_realize (widget); | |||
1112 | ||||
1113 | /* Check to see if there are already any retrievals in progress for | |||
1114 | this widget. If we changed CDK to use the selection for the | |||
1115 | window property in which to store the retrieved information, then | |||
1116 | we could support multiple retrievals for different selections. | |||
1117 | This might be useful for DND. */ | |||
1118 | ||||
1119 | tmp_list = current_retrievals; | |||
1120 | while (tmp_list) | |||
1121 | { | |||
1122 | info = (CtkRetrievalInfo *)tmp_list->data; | |||
1123 | if (info->widget == widget) | |||
1124 | return FALSE(0); | |||
1125 | tmp_list = tmp_list->next; | |||
1126 | } | |||
1127 | ||||
1128 | info = g_slice_new (CtkRetrievalInfo)((CtkRetrievalInfo*) g_slice_alloc (sizeof (CtkRetrievalInfo) )); | |||
1129 | ||||
1130 | info->widget = widget; | |||
1131 | info->selection = selection; | |||
1132 | info->target = target; | |||
1133 | info->idle_time = 0; | |||
1134 | info->buffer = NULL((void*)0); | |||
1135 | info->offset = -1; | |||
1136 | ||||
1137 | /* Check if this process has current owner. If so, call handler | |||
1138 | procedure directly to avoid deadlocks with INCR. */ | |||
1139 | ||||
1140 | display = ctk_widget_get_display (widget); | |||
1141 | owner_window = cdk_selection_owner_get_for_display (display, selection); | |||
1142 | ||||
1143 | #ifdef CDK_WINDOWING_WIN32 | |||
1144 | /* Special handling for DELETE requests, | |||
1145 | * make sure this goes down into CDK layer. | |||
1146 | */ | |||
1147 | if (CDK_IS_WIN32_DISPLAY (display) && | |||
1148 | target == cdk_atom_intern_static_string ("DELETE")) | |||
1149 | owner_window = NULL((void*)0); | |||
1150 | #endif | |||
1151 | ||||
1152 | if (owner_window != NULL((void*)0)) | |||
1153 | { | |||
1154 | CtkWidget *owner_widget; | |||
1155 | gpointer owner_widget_ptr; | |||
1156 | CtkSelectionData selection_data = {0}; | |||
1157 | ||||
1158 | selection_data.selection = selection; | |||
1159 | selection_data.target = target; | |||
1160 | selection_data.length = -1; | |||
1161 | selection_data.display = display; | |||
1162 | ||||
1163 | cdk_window_get_user_data (owner_window, &owner_widget_ptr); | |||
1164 | owner_widget = owner_widget_ptr; | |||
1165 | ||||
1166 | if (owner_widget != NULL((void*)0)) | |||
1167 | { | |||
1168 | ctk_selection_invoke_handler (owner_widget, | |||
1169 | &selection_data, | |||
1170 | time_); | |||
1171 | ||||
1172 | ctk_selection_retrieval_report (info, | |||
1173 | selection_data.type, | |||
1174 | selection_data.format, | |||
1175 | selection_data.data, | |||
1176 | selection_data.length, | |||
1177 | time_); | |||
1178 | ||||
1179 | g_free (selection_data.data); | |||
1180 | selection_data.data = NULL((void*)0); | |||
1181 | selection_data.length = -1; | |||
1182 | ||||
1183 | g_slice_free (CtkRetrievalInfo, info)do { if (1) g_slice_free1 (sizeof (CtkRetrievalInfo), (info)) ; else (void) ((CtkRetrievalInfo*) 0 == (info)); } while (0); | |||
1184 | return TRUE(!(0)); | |||
1185 | } | |||
1186 | } | |||
1187 | ||||
1188 | #if defined CDK_WINDOWING_BROADWAY | |||
1189 | /* This patch is a workaround to circumvent unimplemented | |||
1190 | clipboard functionality in cdkbroadwayd. It eliminates | |||
1191 | 35s delay on popup menu before first clipboard copy, | |||
1192 | by preventing conversion to be started. | |||
1193 | ||||
1194 | https://gitlab.gnome.org/GNOME/ctk/issues/1630 | |||
1195 | */ | |||
1196 | if (CDK_IS_BROADWAY_DISPLAY (display)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (display)); GType __t = ((cdk_broadway_display_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
1197 | { | |||
1198 | g_debug("ctk_selection_convert: disabled for broadway backend"); | |||
1199 | ||||
1200 | ctk_selection_retrieval_report ( | |||
1201 | info, CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), 0, NULL((void*)0), -1, CDK_CURRENT_TIME0L); | |||
1202 | ||||
1203 | return FALSE(0); | |||
1204 | } | |||
1205 | #endif | |||
1206 | ||||
1207 | /* Otherwise, we need to go through X */ | |||
1208 | ||||
1209 | current_retrievals = g_list_append (current_retrievals, info); | |||
1210 | cdk_selection_convert (ctk_widget_get_window (widget), selection, target, time_); | |||
1211 | id = cdk_threads_add_timeout (1000, | |||
1212 | (GSourceFunc) ctk_selection_retrieval_timeout, info); | |||
1213 | g_source_set_name_by_id (id, "[ctk+] ctk_selection_retrieval_timeout"); | |||
1214 | ||||
1215 | return TRUE(!(0)); | |||
1216 | } | |||
1217 | ||||
1218 | /** | |||
1219 | * ctk_selection_data_get_selection: | |||
1220 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1221 | * | |||
1222 | * Retrieves the selection #CdkAtom of the selection data. | |||
1223 | * | |||
1224 | * Returns: (transfer none): the selection #CdkAtom of the selection data. | |||
1225 | * | |||
1226 | * Since: 2.16 | |||
1227 | **/ | |||
1228 | CdkAtom | |||
1229 | ctk_selection_data_get_selection (const CtkSelectionData *selection_data) | |||
1230 | { | |||
1231 | g_return_val_if_fail (selection_data != NULL, 0)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (0); } } while (0); | |||
1232 | ||||
1233 | return selection_data->selection; | |||
1234 | } | |||
1235 | ||||
1236 | /** | |||
1237 | * ctk_selection_data_get_target: | |||
1238 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1239 | * | |||
1240 | * Retrieves the target of the selection. | |||
1241 | * | |||
1242 | * Returns: (transfer none): the target of the selection. | |||
1243 | * | |||
1244 | * Since: 2.14 | |||
1245 | **/ | |||
1246 | CdkAtom | |||
1247 | ctk_selection_data_get_target (const CtkSelectionData *selection_data) | |||
1248 | { | |||
1249 | g_return_val_if_fail (selection_data != NULL, 0)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (0); } } while (0); | |||
1250 | ||||
1251 | return selection_data->target; | |||
1252 | } | |||
1253 | ||||
1254 | /** | |||
1255 | * ctk_selection_data_get_data_type: | |||
1256 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1257 | * | |||
1258 | * Retrieves the data type of the selection. | |||
1259 | * | |||
1260 | * Returns: (transfer none): the data type of the selection. | |||
1261 | * | |||
1262 | * Since: 2.14 | |||
1263 | **/ | |||
1264 | CdkAtom | |||
1265 | ctk_selection_data_get_data_type (const CtkSelectionData *selection_data) | |||
1266 | { | |||
1267 | g_return_val_if_fail (selection_data != NULL, 0)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (0); } } while (0); | |||
1268 | ||||
1269 | return selection_data->type; | |||
1270 | } | |||
1271 | ||||
1272 | /** | |||
1273 | * ctk_selection_data_get_format: | |||
1274 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1275 | * | |||
1276 | * Retrieves the format of the selection. | |||
1277 | * | |||
1278 | * Returns: the format of the selection. | |||
1279 | * | |||
1280 | * Since: 2.14 | |||
1281 | **/ | |||
1282 | gint | |||
1283 | ctk_selection_data_get_format (const CtkSelectionData *selection_data) | |||
1284 | { | |||
1285 | g_return_val_if_fail (selection_data != NULL, 0)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (0); } } while (0); | |||
1286 | ||||
1287 | return selection_data->format; | |||
1288 | } | |||
1289 | ||||
1290 | /** | |||
1291 | * ctk_selection_data_get_data: (skip) | |||
1292 | * @selection_data: a pointer to a | |||
1293 | * #CtkSelectionData-struct. | |||
1294 | * | |||
1295 | * Retrieves the raw data of the selection. | |||
1296 | * | |||
1297 | * Returns: (array) (element-type guint8): the raw data of the selection. | |||
1298 | * | |||
1299 | * Since: 2.14 | |||
1300 | **/ | |||
1301 | const guchar* | |||
1302 | ctk_selection_data_get_data (const CtkSelectionData *selection_data) | |||
1303 | { | |||
1304 | g_return_val_if_fail (selection_data != NULL, NULL)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (((void*)0)); } } while (0); | |||
1305 | ||||
1306 | return selection_data->data; | |||
1307 | } | |||
1308 | ||||
1309 | /** | |||
1310 | * ctk_selection_data_get_length: | |||
1311 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1312 | * | |||
1313 | * Retrieves the length of the raw data of the selection. | |||
1314 | * | |||
1315 | * Returns: the length of the data of the selection. | |||
1316 | * | |||
1317 | * Since: 2.14 | |||
1318 | */ | |||
1319 | gint | |||
1320 | ctk_selection_data_get_length (const CtkSelectionData *selection_data) | |||
1321 | { | |||
1322 | g_return_val_if_fail (selection_data != NULL, -1)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (-1); } } while (0); | |||
1323 | ||||
1324 | return selection_data->length; | |||
1325 | } | |||
1326 | ||||
1327 | /** | |||
1328 | * ctk_selection_data_get_data_with_length: (rename-to ctk_selection_data_get_data) | |||
1329 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1330 | * @length: (out): return location for length of the data segment | |||
1331 | * | |||
1332 | * Retrieves the raw data of the selection along with its length. | |||
1333 | * | |||
1334 | * Returns: (array length=length): the raw data of the selection | |||
1335 | * | |||
1336 | * Since: 3.0 | |||
1337 | */ | |||
1338 | const guchar* | |||
1339 | ctk_selection_data_get_data_with_length (const CtkSelectionData *selection_data, | |||
1340 | gint *length) | |||
1341 | { | |||
1342 | g_return_val_if_fail (selection_data != NULL, NULL)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (((void*)0)); } } while (0); | |||
1343 | ||||
1344 | *length = selection_data->length; | |||
1345 | ||||
1346 | return selection_data->data; | |||
1347 | } | |||
1348 | ||||
1349 | /** | |||
1350 | * ctk_selection_data_get_display: | |||
1351 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1352 | * | |||
1353 | * Retrieves the display of the selection. | |||
1354 | * | |||
1355 | * Returns: (transfer none): the display of the selection. | |||
1356 | * | |||
1357 | * Since: 2.14 | |||
1358 | **/ | |||
1359 | CdkDisplay * | |||
1360 | ctk_selection_data_get_display (const CtkSelectionData *selection_data) | |||
1361 | { | |||
1362 | g_return_val_if_fail (selection_data != NULL, NULL)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (((void*)0)); } } while (0); | |||
1363 | ||||
1364 | return selection_data->display; | |||
1365 | } | |||
1366 | ||||
1367 | /** | |||
1368 | * ctk_selection_data_set: | |||
1369 | * @selection_data: a pointer to a #CtkSelectionData-struct. | |||
1370 | * @type: the type of selection data | |||
1371 | * @format: format (number of bits in a unit) | |||
1372 | * @data: (array length=length): pointer to the data (will be copied) | |||
1373 | * @length: length of the data | |||
1374 | * | |||
1375 | * Stores new data into a #CtkSelectionData object. Should | |||
1376 | * only be called from a selection handler callback. | |||
1377 | * Zero-terminates the stored data. | |||
1378 | **/ | |||
1379 | void | |||
1380 | ctk_selection_data_set (CtkSelectionData *selection_data, | |||
1381 | CdkAtom type, | |||
1382 | gint format, | |||
1383 | const guchar *data, | |||
1384 | gint length) | |||
1385 | { | |||
1386 | g_return_if_fail (selection_data != NULL)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return; } } while (0); | |||
1387 | ||||
1388 | g_free (selection_data->data); | |||
1389 | ||||
1390 | selection_data->type = type; | |||
1391 | selection_data->format = format; | |||
1392 | ||||
1393 | if (data) | |||
1394 | { | |||
1395 | selection_data->data = g_new (guchar, length+1)((guchar *) g_malloc_n ((length+1), sizeof (guchar))); | |||
1396 | memcpy (selection_data->data, data, length); | |||
1397 | selection_data->data[length] = 0; | |||
1398 | } | |||
1399 | else | |||
1400 | { | |||
1401 | g_return_if_fail (length <= 0)do { if ((length <= 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "length <= 0"); return ; } } while (0); | |||
1402 | ||||
1403 | if (length < 0) | |||
1404 | selection_data->data = NULL((void*)0); | |||
1405 | else | |||
1406 | selection_data->data = (guchar *) g_strdup ("")g_strdup_inline (""); | |||
1407 | } | |||
1408 | ||||
1409 | selection_data->length = length; | |||
1410 | } | |||
1411 | ||||
1412 | static gboolean | |||
1413 | selection_set_string (CtkSelectionData *selection_data, | |||
1414 | const gchar *str, | |||
1415 | gint len) | |||
1416 | { | |||
1417 | gchar *tmp = g_strndup (str, len); | |||
1418 | gchar *latin1 = cdk_utf8_to_string_target (tmp); | |||
1419 | g_free (tmp); | |||
1420 | ||||
1421 | if (latin1) | |||
1422 | { | |||
1423 | ctk_selection_data_set (selection_data, | |||
1424 | CDK_SELECTION_TYPE_STRING((CdkAtom)((gpointer) (gulong) (31))), | |||
1425 | 8, (guchar *) latin1, strlen (latin1)); | |||
1426 | g_free (latin1); | |||
1427 | ||||
1428 | return TRUE(!(0)); | |||
1429 | } | |||
1430 | else | |||
1431 | return FALSE(0); | |||
1432 | } | |||
1433 | ||||
1434 | static gboolean | |||
1435 | selection_set_compound_text (CtkSelectionData *selection_data, | |||
1436 | const gchar *str, | |||
1437 | gint len) | |||
1438 | { | |||
1439 | gboolean result = FALSE(0); | |||
1440 | ||||
1441 | #ifdef CDK_WINDOWING_X11 | |||
1442 | gchar *tmp; | |||
1443 | guchar *text; | |||
1444 | CdkAtom encoding; | |||
1445 | gint format; | |||
1446 | gint new_length; | |||
1447 | ||||
1448 | if (CDK_IS_X11_DISPLAY (selection_data->display)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (selection_data->display)); GType __t = ((cdk_x11_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) | |||
1449 | { | |||
1450 | tmp = g_strndup (str, len); | |||
1451 | if (cdk_x11_display_utf8_to_compound_text (selection_data->display, tmp, | |||
1452 | &encoding, &format, &text, &new_length)) | |||
1453 | { | |||
1454 | ctk_selection_data_set (selection_data, encoding, format, text, new_length); | |||
1455 | cdk_x11_free_compound_text (text); | |||
1456 | ||||
1457 | result = TRUE(!(0)); | |||
1458 | } | |||
1459 | g_free (tmp); | |||
1460 | } | |||
1461 | #endif | |||
1462 | ||||
1463 | return result; | |||
1464 | } | |||
1465 | ||||
1466 | /* Normalize \r and \n into \r\n | |||
1467 | */ | |||
1468 | static gchar * | |||
1469 | normalize_to_crlf (const gchar *str, | |||
1470 | gint len) | |||
1471 | { | |||
1472 | GString *result = g_string_sized_new (len); | |||
1473 | const gchar *p = str; | |||
1474 | const gchar *end = str + len; | |||
1475 | ||||
1476 | while (p < end) | |||
1477 | { | |||
1478 | if (*p == '\n') | |||
1479 | g_string_append_c (result, '\r')g_string_append_c_inline (result, '\r'); | |||
1480 | ||||
1481 | if (*p == '\r') | |||
1482 | { | |||
1483 | g_string_append_c (result, *p)g_string_append_c_inline (result, *p); | |||
1484 | p++; | |||
1485 | if (p == end || *p != '\n') | |||
1486 | g_string_append_c (result, '\n')g_string_append_c_inline (result, '\n'); | |||
1487 | if (p == end) | |||
1488 | break; | |||
1489 | } | |||
1490 | ||||
1491 | g_string_append_c (result, *p)g_string_append_c_inline (result, *p); | |||
1492 | p++; | |||
1493 | } | |||
1494 | ||||
1495 | return g_string_free (result, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((result ), ((0))) : g_string_free_and_steal (result)) : (g_string_free ) ((result), ((0)))); | |||
1496 | } | |||
1497 | ||||
1498 | /* Normalize \r and \r\n into \n | |||
1499 | */ | |||
1500 | static gchar * | |||
1501 | normalize_to_lf (gchar *str, | |||
1502 | gint len) | |||
1503 | { | |||
1504 | GString *result = g_string_sized_new (len); | |||
1505 | const gchar *p = str; | |||
1506 | ||||
1507 | while (1) | |||
1508 | { | |||
1509 | if (*p == '\r') | |||
1510 | { | |||
1511 | p++; | |||
1512 | if (*p != '\n') | |||
1513 | g_string_append_c (result, '\n')g_string_append_c_inline (result, '\n'); | |||
1514 | } | |||
1515 | ||||
1516 | if (*p == '\0') | |||
1517 | break; | |||
1518 | ||||
1519 | g_string_append_c (result, *p)g_string_append_c_inline (result, *p); | |||
1520 | p++; | |||
1521 | } | |||
1522 | ||||
1523 | return g_string_free (result, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((result ), ((0))) : g_string_free_and_steal (result)) : (g_string_free ) ((result), ((0)))); | |||
1524 | } | |||
1525 | ||||
1526 | static gboolean | |||
1527 | selection_set_text_plain (CtkSelectionData *selection_data, | |||
1528 | const gchar *str, | |||
1529 | gint len) | |||
1530 | { | |||
1531 | const gchar *charset = NULL((void*)0); | |||
1532 | gchar *result; | |||
1533 | GError *error = NULL((void*)0); | |||
1534 | ||||
1535 | result = normalize_to_crlf (str, len); | |||
1536 | if (selection_data->target == text_plain_atom) | |||
1537 | charset = "ASCII"; | |||
1538 | else if (selection_data->target == text_plain_locale_atom) | |||
1539 | g_get_charset (&charset); | |||
1540 | ||||
1541 | if (charset
| |||
1542 | { | |||
1543 | gchar *tmp = result; | |||
1544 | result = g_convert_with_fallback (tmp, -1, | |||
1545 | charset, "UTF-8", | |||
1546 | NULL((void*)0), NULL((void*)0), NULL((void*)0), &error); | |||
1547 | g_free (tmp); | |||
1548 | } | |||
1549 | ||||
1550 | if (!result) | |||
1551 | { | |||
1552 | g_warning ("Error converting from %s to %s: %s", | |||
1553 | "UTF-8", charset, error->message); | |||
| ||||
1554 | g_error_free (error); | |||
1555 | ||||
1556 | return FALSE(0); | |||
1557 | } | |||
1558 | ||||
1559 | ctk_selection_data_set (selection_data, | |||
1560 | selection_data->target, | |||
1561 | 8, (guchar *) result, strlen (result)); | |||
1562 | g_free (result); | |||
1563 | ||||
1564 | return TRUE(!(0)); | |||
1565 | } | |||
1566 | ||||
1567 | static guchar * | |||
1568 | selection_get_text_plain (const CtkSelectionData *selection_data) | |||
1569 | { | |||
1570 | const gchar *charset = NULL((void*)0); | |||
1571 | gchar *str, *result; | |||
1572 | gsize len; | |||
1573 | GError *error = NULL((void*)0); | |||
1574 | ||||
1575 | str = g_strdup ((const gchar *) selection_data->data)g_strdup_inline ((const gchar *) selection_data->data); | |||
1576 | len = selection_data->length; | |||
1577 | ||||
1578 | if (selection_data->type == text_plain_atom) | |||
1579 | charset = "ISO-8859-1"; | |||
1580 | else if (selection_data->type == text_plain_locale_atom) | |||
1581 | g_get_charset (&charset); | |||
1582 | ||||
1583 | if (charset) | |||
1584 | { | |||
1585 | gchar *tmp = str; | |||
1586 | str = g_convert_with_fallback (tmp, len, | |||
1587 | "UTF-8", charset, | |||
1588 | NULL((void*)0), NULL((void*)0), &len, &error); | |||
1589 | g_free (tmp); | |||
1590 | ||||
1591 | if (!str) | |||
1592 | { | |||
1593 | g_warning ("Error converting from %s to %s: %s", | |||
1594 | charset, "UTF-8", error->message); | |||
1595 | g_error_free (error); | |||
1596 | ||||
1597 | return NULL((void*)0); | |||
1598 | } | |||
1599 | } | |||
1600 | else if (!g_utf8_validate (str, -1, NULL((void*)0))) | |||
1601 | { | |||
1602 | g_warning ("Error converting from %s to %s: %s", | |||
1603 | "text/plain;charset=utf-8", "UTF-8", "invalid UTF-8"); | |||
1604 | g_free (str); | |||
1605 | ||||
1606 | return NULL((void*)0); | |||
1607 | } | |||
1608 | ||||
1609 | result = normalize_to_lf (str, len); | |||
1610 | g_free (str); | |||
1611 | ||||
1612 | return (guchar *) result; | |||
1613 | } | |||
1614 | ||||
1615 | /** | |||
1616 | * ctk_selection_data_set_text: | |||
1617 | * @selection_data: a #CtkSelectionData | |||
1618 | * @str: a UTF-8 string | |||
1619 | * @len: the length of @str, or -1 if @str is nul-terminated. | |||
1620 | * | |||
1621 | * Sets the contents of the selection from a UTF-8 encoded string. | |||
1622 | * The string is converted to the form determined by | |||
1623 | * @selection_data->target. | |||
1624 | * | |||
1625 | * Returns: %TRUE if the selection was successfully set, | |||
1626 | * otherwise %FALSE. | |||
1627 | **/ | |||
1628 | gboolean | |||
1629 | ctk_selection_data_set_text (CtkSelectionData *selection_data, | |||
1630 | const gchar *str, | |||
1631 | gint len) | |||
1632 | { | |||
1633 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
| ||||
1634 | ||||
1635 | if (len < 0) | |||
1636 | len = strlen (str); | |||
1637 | ||||
1638 | init_atoms (); | |||
1639 | ||||
1640 | if (selection_data->target == utf8_atom) | |||
1641 | { | |||
1642 | ctk_selection_data_set (selection_data, | |||
1643 | utf8_atom, | |||
1644 | 8, (guchar *)str, len); | |||
1645 | return TRUE(!(0)); | |||
1646 | } | |||
1647 | else if (selection_data->target == CDK_TARGET_STRING((CdkAtom)((gpointer) (gulong) (31)))) | |||
1648 | { | |||
1649 | return selection_set_string (selection_data, str, len); | |||
1650 | } | |||
1651 | else if (selection_data->target == ctext_atom || | |||
1652 | selection_data->target == text_atom) | |||
1653 | { | |||
1654 | if (selection_set_compound_text (selection_data, str, len)) | |||
1655 | return TRUE(!(0)); | |||
1656 | else if (selection_data->target == text_atom) | |||
1657 | return selection_set_string (selection_data, str, len); | |||
1658 | } | |||
1659 | else if (selection_data->target == text_plain_atom || | |||
1660 | selection_data->target == text_plain_utf8_atom || | |||
1661 | selection_data->target == text_plain_locale_atom) | |||
1662 | { | |||
1663 | return selection_set_text_plain (selection_data, str, len); | |||
1664 | } | |||
1665 | ||||
1666 | return FALSE(0); | |||
1667 | } | |||
1668 | ||||
1669 | /** | |||
1670 | * ctk_selection_data_get_text: | |||
1671 | * @selection_data: a #CtkSelectionData | |||
1672 | * | |||
1673 | * Gets the contents of the selection data as a UTF-8 string. | |||
1674 | * | |||
1675 | * Returns: (type utf8) (nullable) (transfer full): if the selection data contained a | |||
1676 | * recognized text type and it could be converted to UTF-8, a newly | |||
1677 | * allocated string containing the converted text, otherwise %NULL. | |||
1678 | * If the result is non-%NULL it must be freed with g_free(). | |||
1679 | **/ | |||
1680 | guchar * | |||
1681 | ctk_selection_data_get_text (const CtkSelectionData *selection_data) | |||
1682 | { | |||
1683 | guchar *result = NULL((void*)0); | |||
1684 | ||||
1685 | g_return_val_if_fail (selection_data != NULL, NULL)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (((void*)0)); } } while (0); | |||
1686 | ||||
1687 | init_atoms (); | |||
1688 | ||||
1689 | if (selection_data->length >= 0 && | |||
1690 | (selection_data->type == CDK_TARGET_STRING((CdkAtom)((gpointer) (gulong) (31))) || | |||
1691 | selection_data->type == ctext_atom || | |||
1692 | selection_data->type == utf8_atom)) | |||
1693 | { | |||
1694 | gchar **list; | |||
1695 | gint i; | |||
1696 | gint count = cdk_text_property_to_utf8_list_for_display (selection_data->display, | |||
1697 | selection_data->type, | |||
1698 | selection_data->format, | |||
1699 | selection_data->data, | |||
1700 | selection_data->length, | |||
1701 | &list); | |||
1702 | if (count > 0) | |||
1703 | result = (guchar *) list[0]; | |||
1704 | ||||
1705 | for (i = 1; i < count; i++) | |||
1706 | g_free (list[i]); | |||
1707 | g_free (list); | |||
1708 | } | |||
1709 | else if (selection_data->length >= 0 && | |||
1710 | (selection_data->type == text_plain_atom || | |||
1711 | selection_data->type == text_plain_utf8_atom || | |||
1712 | selection_data->type == text_plain_locale_atom)) | |||
1713 | { | |||
1714 | result = selection_get_text_plain (selection_data); | |||
1715 | } | |||
1716 | ||||
1717 | return result; | |||
1718 | } | |||
1719 | ||||
1720 | /** | |||
1721 | * ctk_selection_data_set_pixbuf: | |||
1722 | * @selection_data: a #CtkSelectionData | |||
1723 | * @pixbuf: a #GdkPixbuf | |||
1724 | * | |||
1725 | * Sets the contents of the selection from a #GdkPixbuf | |||
1726 | * The pixbuf is converted to the form determined by | |||
1727 | * @selection_data->target. | |||
1728 | * | |||
1729 | * Returns: %TRUE if the selection was successfully set, | |||
1730 | * otherwise %FALSE. | |||
1731 | * | |||
1732 | * Since: 2.6 | |||
1733 | **/ | |||
1734 | gboolean | |||
1735 | ctk_selection_data_set_pixbuf (CtkSelectionData *selection_data, | |||
1736 | GdkPixbuf *pixbuf) | |||
1737 | { | |||
1738 | GSList *formats, *f; | |||
1739 | gchar **mimes, **m; | |||
1740 | CdkAtom atom; | |||
1741 | gboolean result; | |||
1742 | gchar *str, *type; | |||
1743 | gsize len; | |||
1744 | ||||
1745 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
1746 | g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((pixbuf)); GType __t = ((gdk_pixbuf_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "GDK_IS_PIXBUF (pixbuf)"); return ((0)); } } while (0); | |||
1747 | ||||
1748 | formats = gdk_pixbuf_get_formats (); | |||
1749 | ||||
1750 | for (f = formats; f; f = f->next) | |||
1751 | { | |||
1752 | GdkPixbufFormat *fmt = f->data; | |||
1753 | ||||
1754 | mimes = gdk_pixbuf_format_get_mime_types (fmt); | |||
1755 | for (m = mimes; *m; m++) | |||
1756 | { | |||
1757 | atom = cdk_atom_intern (*m, FALSE(0)); | |||
1758 | if (selection_data->target == atom) | |||
1759 | { | |||
1760 | str = NULL((void*)0); | |||
1761 | type = gdk_pixbuf_format_get_name (fmt); | |||
1762 | result = gdk_pixbuf_save_to_buffer (pixbuf, &str, &len, | |||
1763 | type, NULL((void*)0), | |||
1764 | ((strcmp (type, "png") == 0) ? | |||
1765 | "compression" : NULL((void*)0)), "2", | |||
1766 | NULL((void*)0)); | |||
1767 | if (result) | |||
1768 | ctk_selection_data_set (selection_data, | |||
1769 | atom, 8, (guchar *)str, len); | |||
1770 | g_free (type); | |||
1771 | g_free (str); | |||
1772 | g_strfreev (mimes); | |||
1773 | g_slist_free (formats); | |||
1774 | ||||
1775 | return result; | |||
1776 | } | |||
1777 | } | |||
1778 | ||||
1779 | g_strfreev (mimes); | |||
1780 | } | |||
1781 | ||||
1782 | g_slist_free (formats); | |||
1783 | ||||
1784 | return FALSE(0); | |||
1785 | } | |||
1786 | ||||
1787 | /** | |||
1788 | * ctk_selection_data_get_pixbuf: | |||
1789 | * @selection_data: a #CtkSelectionData | |||
1790 | * | |||
1791 | * Gets the contents of the selection data as a #GdkPixbuf. | |||
1792 | * | |||
1793 | * Returns: (nullable) (transfer full): if the selection data | |||
1794 | * contained a recognized image type and it could be converted to a | |||
1795 | * #GdkPixbuf, a newly allocated pixbuf is returned, otherwise | |||
1796 | * %NULL. If the result is non-%NULL it must be freed with | |||
1797 | * g_object_unref(). | |||
1798 | * | |||
1799 | * Since: 2.6 | |||
1800 | **/ | |||
1801 | GdkPixbuf * | |||
1802 | ctk_selection_data_get_pixbuf (const CtkSelectionData *selection_data) | |||
1803 | { | |||
1804 | GdkPixbufLoader *loader; | |||
1805 | GdkPixbuf *result = NULL((void*)0); | |||
1806 | ||||
1807 | g_return_val_if_fail (selection_data != NULL, NULL)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (((void*)0)); } } while (0); | |||
1808 | ||||
1809 | if (selection_data->length > 0) | |||
1810 | { | |||
1811 | loader = gdk_pixbuf_loader_new (); | |||
1812 | ||||
1813 | gdk_pixbuf_loader_write (loader, | |||
1814 | selection_data->data, | |||
1815 | selection_data->length, | |||
1816 | NULL((void*)0)); | |||
1817 | gdk_pixbuf_loader_close (loader, NULL((void*)0)); | |||
1818 | result = gdk_pixbuf_loader_get_pixbuf (loader); | |||
1819 | ||||
1820 | if (result) | |||
1821 | g_object_ref (result)((__typeof__ (result)) (g_object_ref) (result)); | |||
1822 | ||||
1823 | g_object_unref (loader); | |||
1824 | } | |||
1825 | ||||
1826 | return result; | |||
1827 | } | |||
1828 | ||||
1829 | /** | |||
1830 | * ctk_selection_data_set_uris: | |||
1831 | * @selection_data: a #CtkSelectionData | |||
1832 | * @uris: (array zero-terminated=1): a %NULL-terminated array of | |||
1833 | * strings holding URIs | |||
1834 | * | |||
1835 | * Sets the contents of the selection from a list of URIs. | |||
1836 | * The string is converted to the form determined by | |||
1837 | * @selection_data->target. | |||
1838 | * | |||
1839 | * Returns: %TRUE if the selection was successfully set, | |||
1840 | * otherwise %FALSE. | |||
1841 | * | |||
1842 | * Since: 2.6 | |||
1843 | **/ | |||
1844 | gboolean | |||
1845 | ctk_selection_data_set_uris (CtkSelectionData *selection_data, | |||
1846 | gchar **uris) | |||
1847 | { | |||
1848 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
1849 | g_return_val_if_fail (uris != NULL, FALSE)do { if ((uris != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "uris != NULL"); return ( (0)); } } while (0); | |||
1850 | ||||
1851 | init_atoms (); | |||
1852 | ||||
1853 | if (selection_data->target == text_uri_list_atom) | |||
1854 | { | |||
1855 | GString *list; | |||
1856 | gint i; | |||
1857 | gchar *result; | |||
1858 | gsize length; | |||
1859 | ||||
1860 | list = g_string_new (NULL((void*)0)); | |||
1861 | for (i = 0; uris[i]; i++) | |||
1862 | { | |||
1863 | g_string_append (list, uris[i])(__builtin_constant_p (uris[i]) ? __extension__ ({ const char * const __val = (uris[i]); g_string_append_len_inline (list, __val, (__val != ((void*)0)) ? (gssize) strlen (((__val) + ! (__val))) : (gssize) -1); }) : g_string_append_len_inline (list , uris[i], (gssize) -1)); | |||
1864 | g_string_append (list, "\r\n")(__builtin_constant_p ("\r\n") ? __extension__ ({ const char * const __val = ("\r\n"); g_string_append_len_inline (list, __val , (__val != ((void*)0)) ? (gssize) strlen (((__val) + !(__val ))) : (gssize) -1); }) : g_string_append_len_inline (list, "\r\n" , (gssize) -1)); | |||
1865 | } | |||
1866 | ||||
1867 | result = g_convert (list->str, list->len, | |||
1868 | "ASCII", "UTF-8", | |||
1869 | NULL((void*)0), &length, NULL((void*)0)); | |||
1870 | g_string_free (list, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) ( (list), ((!(0)))) : g_string_free_and_steal (list)) : (g_string_free ) ((list), ((!(0))))); | |||
1871 | ||||
1872 | if (result) | |||
1873 | { | |||
1874 | ctk_selection_data_set (selection_data, | |||
1875 | text_uri_list_atom, | |||
1876 | 8, (guchar *)result, length); | |||
1877 | ||||
1878 | g_free (result); | |||
1879 | ||||
1880 | return TRUE(!(0)); | |||
1881 | } | |||
1882 | } | |||
1883 | ||||
1884 | return FALSE(0); | |||
1885 | } | |||
1886 | ||||
1887 | /** | |||
1888 | * ctk_selection_data_get_uris: | |||
1889 | * @selection_data: a #CtkSelectionData | |||
1890 | * | |||
1891 | * Gets the contents of the selection data as array of URIs. | |||
1892 | * | |||
1893 | * Returns: (array zero-terminated=1) (element-type utf8) (transfer full): if | |||
1894 | * the selection data contains a list of | |||
1895 | * URIs, a newly allocated %NULL-terminated string array | |||
1896 | * containing the URIs, otherwise %NULL. If the result is | |||
1897 | * non-%NULL it must be freed with g_strfreev(). | |||
1898 | * | |||
1899 | * Since: 2.6 | |||
1900 | **/ | |||
1901 | gchar ** | |||
1902 | ctk_selection_data_get_uris (const CtkSelectionData *selection_data) | |||
1903 | { | |||
1904 | gchar **result = NULL((void*)0); | |||
1905 | ||||
1906 | g_return_val_if_fail (selection_data != NULL, NULL)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return (((void*)0)); } } while (0); | |||
1907 | ||||
1908 | init_atoms (); | |||
1909 | ||||
1910 | if (selection_data->length >= 0 && | |||
1911 | selection_data->type == text_uri_list_atom) | |||
1912 | { | |||
1913 | gchar **list; | |||
1914 | gint count = cdk_text_property_to_utf8_list_for_display (selection_data->display, | |||
1915 | utf8_atom, | |||
1916 | selection_data->format, | |||
1917 | selection_data->data, | |||
1918 | selection_data->length, | |||
1919 | &list); | |||
1920 | if (count > 0) | |||
1921 | result = g_uri_list_extract_uris (list[0]); | |||
1922 | ||||
1923 | g_strfreev (list); | |||
1924 | } | |||
1925 | ||||
1926 | return result; | |||
1927 | } | |||
1928 | ||||
1929 | ||||
1930 | /** | |||
1931 | * ctk_selection_data_get_targets: | |||
1932 | * @selection_data: a #CtkSelectionData object | |||
1933 | * @targets: (out) (array length=n_atoms) (transfer container): | |||
1934 | * location to store an array of targets. The result stored | |||
1935 | * here must be freed with g_free(). | |||
1936 | * @n_atoms: location to store number of items in @targets. | |||
1937 | * | |||
1938 | * Gets the contents of @selection_data as an array of targets. | |||
1939 | * This can be used to interpret the results of getting | |||
1940 | * the standard TARGETS target that is always supplied for | |||
1941 | * any selection. | |||
1942 | * | |||
1943 | * Returns: %TRUE if @selection_data contains a valid | |||
1944 | * array of targets, otherwise %FALSE. | |||
1945 | **/ | |||
1946 | gboolean | |||
1947 | ctk_selection_data_get_targets (const CtkSelectionData *selection_data, | |||
1948 | CdkAtom **targets, | |||
1949 | gint *n_atoms) | |||
1950 | { | |||
1951 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
1952 | ||||
1953 | if (selection_data->length >= 0 && | |||
1954 | selection_data->format == 32 && | |||
1955 | selection_data->type == CDK_SELECTION_TYPE_ATOM((CdkAtom)((gpointer) (gulong) (4)))) | |||
1956 | { | |||
1957 | if (targets) | |||
1958 | *targets = g_memdup2 (selection_data->data, selection_data->length); | |||
1959 | if (n_atoms) | |||
1960 | *n_atoms = selection_data->length / sizeof (CdkAtom); | |||
1961 | ||||
1962 | return TRUE(!(0)); | |||
1963 | } | |||
1964 | else | |||
1965 | { | |||
1966 | if (targets) | |||
1967 | *targets = NULL((void*)0); | |||
1968 | if (n_atoms) | |||
1969 | *n_atoms = -1; | |||
1970 | ||||
1971 | return FALSE(0); | |||
1972 | } | |||
1973 | } | |||
1974 | ||||
1975 | /** | |||
1976 | * ctk_targets_include_text: | |||
1977 | * @targets: (array length=n_targets): an array of #CdkAtoms | |||
1978 | * @n_targets: the length of @targets | |||
1979 | * | |||
1980 | * Determines if any of the targets in @targets can be used to | |||
1981 | * provide text. | |||
1982 | * | |||
1983 | * Returns: %TRUE if @targets include a suitable target for text, | |||
1984 | * otherwise %FALSE. | |||
1985 | * | |||
1986 | * Since: 2.10 | |||
1987 | **/ | |||
1988 | gboolean | |||
1989 | ctk_targets_include_text (CdkAtom *targets, | |||
1990 | gint n_targets) | |||
1991 | { | |||
1992 | gint i; | |||
1993 | gboolean result = FALSE(0); | |||
1994 | ||||
1995 | g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE)do { if ((targets != ((void*)0) || n_targets == 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "targets != NULL || n_targets == 0"); return ((0)); } } while (0); | |||
1996 | ||||
1997 | /* Keep in sync with ctk_target_list_add_text_targets() | |||
1998 | */ | |||
1999 | ||||
2000 | init_atoms (); | |||
2001 | ||||
2002 | for (i = 0; i < n_targets; i++) | |||
2003 | { | |||
2004 | if (targets[i] == utf8_atom || | |||
2005 | targets[i] == text_atom || | |||
2006 | targets[i] == CDK_TARGET_STRING((CdkAtom)((gpointer) (gulong) (31))) || | |||
2007 | targets[i] == ctext_atom || | |||
2008 | targets[i] == text_plain_atom || | |||
2009 | targets[i] == text_plain_utf8_atom || | |||
2010 | targets[i] == text_plain_locale_atom) | |||
2011 | { | |||
2012 | result = TRUE(!(0)); | |||
2013 | break; | |||
2014 | } | |||
2015 | } | |||
2016 | ||||
2017 | return result; | |||
2018 | } | |||
2019 | ||||
2020 | /** | |||
2021 | * ctk_targets_include_rich_text: | |||
2022 | * @targets: (array length=n_targets): an array of #CdkAtoms | |||
2023 | * @n_targets: the length of @targets | |||
2024 | * @buffer: a #CtkTextBuffer | |||
2025 | * | |||
2026 | * Determines if any of the targets in @targets can be used to | |||
2027 | * provide rich text. | |||
2028 | * | |||
2029 | * Returns: %TRUE if @targets include a suitable target for rich text, | |||
2030 | * otherwise %FALSE. | |||
2031 | * | |||
2032 | * Since: 2.10 | |||
2033 | **/ | |||
2034 | gboolean | |||
2035 | ctk_targets_include_rich_text (CdkAtom *targets, | |||
2036 | gint n_targets, | |||
2037 | CtkTextBuffer *buffer) | |||
2038 | { | |||
2039 | CdkAtom *rich_targets; | |||
2040 | gint n_rich_targets; | |||
2041 | gint i, j; | |||
2042 | gboolean result = FALSE(0); | |||
2043 | ||||
2044 | g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE)do { if ((targets != ((void*)0) || n_targets == 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "targets != NULL || n_targets == 0"); return ((0)); } } while (0); | |||
2045 | g_return_val_if_fail (CTK_IS_TEXT_BUFFER (buffer), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((buffer)); GType __t = ((ctk_text_buffer_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TEXT_BUFFER (buffer)"); return ((0)); } } while ( 0); | |||
2046 | ||||
2047 | init_atoms (); | |||
2048 | ||||
2049 | rich_targets = ctk_text_buffer_get_deserialize_formats (buffer, | |||
2050 | &n_rich_targets); | |||
2051 | ||||
2052 | for (i = 0; i < n_targets; i++) | |||
2053 | { | |||
2054 | for (j = 0; j < n_rich_targets; j++) | |||
2055 | { | |||
2056 | if (targets[i] == rich_targets[j]) | |||
2057 | { | |||
2058 | result = TRUE(!(0)); | |||
2059 | goto done; | |||
2060 | } | |||
2061 | } | |||
2062 | } | |||
2063 | ||||
2064 | done: | |||
2065 | g_free (rich_targets); | |||
2066 | ||||
2067 | return result; | |||
2068 | } | |||
2069 | ||||
2070 | /** | |||
2071 | * ctk_selection_data_targets_include_text: | |||
2072 | * @selection_data: a #CtkSelectionData object | |||
2073 | * | |||
2074 | * Given a #CtkSelectionData object holding a list of targets, | |||
2075 | * determines if any of the targets in @targets can be used to | |||
2076 | * provide text. | |||
2077 | * | |||
2078 | * Returns: %TRUE if @selection_data holds a list of targets, | |||
2079 | * and a suitable target for text is included, otherwise %FALSE. | |||
2080 | **/ | |||
2081 | gboolean | |||
2082 | ctk_selection_data_targets_include_text (const CtkSelectionData *selection_data) | |||
2083 | { | |||
2084 | CdkAtom *targets; | |||
2085 | gint n_targets; | |||
2086 | gboolean result = FALSE(0); | |||
2087 | ||||
2088 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
2089 | ||||
2090 | init_atoms (); | |||
2091 | ||||
2092 | if (ctk_selection_data_get_targets (selection_data, &targets, &n_targets)) | |||
2093 | { | |||
2094 | result = ctk_targets_include_text (targets, n_targets); | |||
2095 | g_free (targets); | |||
2096 | } | |||
2097 | ||||
2098 | return result; | |||
2099 | } | |||
2100 | ||||
2101 | /** | |||
2102 | * ctk_selection_data_targets_include_rich_text: | |||
2103 | * @selection_data: a #CtkSelectionData object | |||
2104 | * @buffer: a #CtkTextBuffer | |||
2105 | * | |||
2106 | * Given a #CtkSelectionData object holding a list of targets, | |||
2107 | * determines if any of the targets in @targets can be used to | |||
2108 | * provide rich text. | |||
2109 | * | |||
2110 | * Returns: %TRUE if @selection_data holds a list of targets, | |||
2111 | * and a suitable target for rich text is included, | |||
2112 | * otherwise %FALSE. | |||
2113 | * | |||
2114 | * Since: 2.10 | |||
2115 | **/ | |||
2116 | gboolean | |||
2117 | ctk_selection_data_targets_include_rich_text (const CtkSelectionData *selection_data, | |||
2118 | CtkTextBuffer *buffer) | |||
2119 | { | |||
2120 | CdkAtom *targets; | |||
2121 | gint n_targets; | |||
2122 | gboolean result = FALSE(0); | |||
2123 | ||||
2124 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
2125 | g_return_val_if_fail (CTK_IS_TEXT_BUFFER (buffer), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((buffer)); GType __t = ((ctk_text_buffer_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TEXT_BUFFER (buffer)"); return ((0)); } } while ( 0); | |||
2126 | ||||
2127 | init_atoms (); | |||
2128 | ||||
2129 | if (ctk_selection_data_get_targets (selection_data, &targets, &n_targets)) | |||
2130 | { | |||
2131 | result = ctk_targets_include_rich_text (targets, n_targets, buffer); | |||
2132 | g_free (targets); | |||
2133 | } | |||
2134 | ||||
2135 | return result; | |||
2136 | } | |||
2137 | ||||
2138 | /** | |||
2139 | * ctk_targets_include_image: | |||
2140 | * @targets: (array length=n_targets): an array of #CdkAtoms | |||
2141 | * @n_targets: the length of @targets | |||
2142 | * @writable: whether to accept only targets for which CTK+ knows | |||
2143 | * how to convert a pixbuf into the format | |||
2144 | * | |||
2145 | * Determines if any of the targets in @targets can be used to | |||
2146 | * provide a #GdkPixbuf. | |||
2147 | * | |||
2148 | * Returns: %TRUE if @targets include a suitable target for images, | |||
2149 | * otherwise %FALSE. | |||
2150 | * | |||
2151 | * Since: 2.10 | |||
2152 | **/ | |||
2153 | gboolean | |||
2154 | ctk_targets_include_image (CdkAtom *targets, | |||
2155 | gint n_targets, | |||
2156 | gboolean writable) | |||
2157 | { | |||
2158 | CtkTargetList *list; | |||
2159 | GList *l; | |||
2160 | gint i; | |||
2161 | gboolean result = FALSE(0); | |||
2162 | ||||
2163 | g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE)do { if ((targets != ((void*)0) || n_targets == 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "targets != NULL || n_targets == 0"); return ((0)); } } while (0); | |||
2164 | ||||
2165 | list = ctk_target_list_new (NULL((void*)0), 0); | |||
2166 | ctk_target_list_add_image_targets (list, 0, writable); | |||
2167 | for (i = 0; i < n_targets && !result; i++) | |||
2168 | { | |||
2169 | for (l = list->list; l; l = l->next) | |||
2170 | { | |||
2171 | CtkTargetPair *pair = (CtkTargetPair *)l->data; | |||
2172 | if (pair->target == targets[i]) | |||
2173 | { | |||
2174 | result = TRUE(!(0)); | |||
2175 | break; | |||
2176 | } | |||
2177 | } | |||
2178 | } | |||
2179 | ctk_target_list_unref (list); | |||
2180 | ||||
2181 | return result; | |||
2182 | } | |||
2183 | ||||
2184 | /** | |||
2185 | * ctk_selection_data_targets_include_image: | |||
2186 | * @selection_data: a #CtkSelectionData object | |||
2187 | * @writable: whether to accept only targets for which CTK+ knows | |||
2188 | * how to convert a pixbuf into the format | |||
2189 | * | |||
2190 | * Given a #CtkSelectionData object holding a list of targets, | |||
2191 | * determines if any of the targets in @targets can be used to | |||
2192 | * provide a #GdkPixbuf. | |||
2193 | * | |||
2194 | * Returns: %TRUE if @selection_data holds a list of targets, | |||
2195 | * and a suitable target for images is included, otherwise %FALSE. | |||
2196 | * | |||
2197 | * Since: 2.6 | |||
2198 | **/ | |||
2199 | gboolean | |||
2200 | ctk_selection_data_targets_include_image (const CtkSelectionData *selection_data, | |||
2201 | gboolean writable) | |||
2202 | { | |||
2203 | CdkAtom *targets; | |||
2204 | gint n_targets; | |||
2205 | gboolean result = FALSE(0); | |||
2206 | ||||
2207 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
2208 | ||||
2209 | init_atoms (); | |||
2210 | ||||
2211 | if (ctk_selection_data_get_targets (selection_data, &targets, &n_targets)) | |||
2212 | { | |||
2213 | result = ctk_targets_include_image (targets, n_targets, writable); | |||
2214 | g_free (targets); | |||
2215 | } | |||
2216 | ||||
2217 | return result; | |||
2218 | } | |||
2219 | ||||
2220 | /** | |||
2221 | * ctk_targets_include_uri: | |||
2222 | * @targets: (array length=n_targets): an array of #CdkAtoms | |||
2223 | * @n_targets: the length of @targets | |||
2224 | * | |||
2225 | * Determines if any of the targets in @targets can be used to | |||
2226 | * provide an uri list. | |||
2227 | * | |||
2228 | * Returns: %TRUE if @targets include a suitable target for uri lists, | |||
2229 | * otherwise %FALSE. | |||
2230 | * | |||
2231 | * Since: 2.10 | |||
2232 | **/ | |||
2233 | gboolean | |||
2234 | ctk_targets_include_uri (CdkAtom *targets, | |||
2235 | gint n_targets) | |||
2236 | { | |||
2237 | gint i; | |||
2238 | gboolean result = FALSE(0); | |||
2239 | ||||
2240 | g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE)do { if ((targets != ((void*)0) || n_targets == 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "targets != NULL || n_targets == 0"); return ((0)); } } while (0); | |||
2241 | ||||
2242 | /* Keep in sync with ctk_target_list_add_uri_targets() | |||
2243 | */ | |||
2244 | ||||
2245 | init_atoms (); | |||
2246 | ||||
2247 | for (i = 0; i < n_targets; i++) | |||
2248 | { | |||
2249 | if (targets[i] == text_uri_list_atom) | |||
2250 | { | |||
2251 | result = TRUE(!(0)); | |||
2252 | break; | |||
2253 | } | |||
2254 | } | |||
2255 | ||||
2256 | return result; | |||
2257 | } | |||
2258 | ||||
2259 | /** | |||
2260 | * ctk_selection_data_targets_include_uri: | |||
2261 | * @selection_data: a #CtkSelectionData object | |||
2262 | * | |||
2263 | * Given a #CtkSelectionData object holding a list of targets, | |||
2264 | * determines if any of the targets in @targets can be used to | |||
2265 | * provide a list or URIs. | |||
2266 | * | |||
2267 | * Returns: %TRUE if @selection_data holds a list of targets, | |||
2268 | * and a suitable target for URI lists is included, otherwise %FALSE. | |||
2269 | * | |||
2270 | * Since: 2.10 | |||
2271 | **/ | |||
2272 | gboolean | |||
2273 | ctk_selection_data_targets_include_uri (const CtkSelectionData *selection_data) | |||
2274 | { | |||
2275 | CdkAtom *targets; | |||
2276 | gint n_targets; | |||
2277 | gboolean result = FALSE(0); | |||
2278 | ||||
2279 | g_return_val_if_fail (selection_data != NULL, FALSE)do { if ((selection_data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "selection_data != NULL" ); return ((0)); } } while (0); | |||
2280 | ||||
2281 | init_atoms (); | |||
2282 | ||||
2283 | if (ctk_selection_data_get_targets (selection_data, &targets, &n_targets)) | |||
2284 | { | |||
2285 | result = ctk_targets_include_uri (targets, n_targets); | |||
2286 | g_free (targets); | |||
2287 | } | |||
2288 | ||||
2289 | return result; | |||
2290 | } | |||
2291 | ||||
2292 | ||||
2293 | /************************************************************* | |||
2294 | * ctk_selection_init: | |||
2295 | * Initialize local variables | |||
2296 | * arguments: | |||
2297 | * | |||
2298 | * results: | |||
2299 | *************************************************************/ | |||
2300 | ||||
2301 | static void | |||
2302 | ctk_selection_init (void) | |||
2303 | { | |||
2304 | ctk_selection_atoms[INCR] = cdk_atom_intern_static_string ("INCR"); | |||
2305 | ctk_selection_atoms[MULTIPLE] = cdk_atom_intern_static_string ("MULTIPLE"); | |||
2306 | ctk_selection_atoms[TIMESTAMP] = cdk_atom_intern_static_string ("TIMESTAMP"); | |||
2307 | ctk_selection_atoms[TARGETS] = cdk_atom_intern_static_string ("TARGETS"); | |||
2308 | ctk_selection_atoms[SAVE_TARGETS] = cdk_atom_intern_static_string ("SAVE_TARGETS"); | |||
2309 | ||||
2310 | initialize = FALSE(0); | |||
2311 | } | |||
2312 | ||||
2313 | /** | |||
2314 | * _ctk_selection_clear: | |||
2315 | * @widget: a #CtkWidget | |||
2316 | * @event: the event | |||
2317 | * | |||
2318 | * The default handler for the #CtkWidget::selection-clear-event | |||
2319 | * signal. | |||
2320 | * | |||
2321 | * Returns: %TRUE if the event was handled, otherwise false | |||
2322 | **/ | |||
2323 | gboolean | |||
2324 | _ctk_selection_clear (CtkWidget *widget, | |||
2325 | CdkEventSelection *event) | |||
2326 | { | |||
2327 | /* Note that we filter clear events in cdkselection-x11.c, so | |||
2328 | * that we only will get here if the clear event actually | |||
2329 | * represents a change that we didn't do ourself. | |||
2330 | */ | |||
2331 | GList *tmp_list; | |||
2332 | CtkSelectionInfo *selection_info = NULL((void*)0); | |||
2333 | ||||
2334 | tmp_list = current_selections; | |||
2335 | while (tmp_list) | |||
2336 | { | |||
2337 | selection_info = (CtkSelectionInfo *)tmp_list->data; | |||
2338 | ||||
2339 | if ((selection_info->selection == event->selection) && | |||
2340 | (selection_info->widget == widget)) | |||
2341 | break; | |||
2342 | ||||
2343 | tmp_list = tmp_list->next; | |||
2344 | } | |||
2345 | ||||
2346 | if (tmp_list) | |||
2347 | { | |||
2348 | current_selections = g_list_remove_link (current_selections, tmp_list); | |||
2349 | g_list_free (tmp_list); | |||
2350 | g_slice_free (CtkSelectionInfo, selection_info)do { if (1) g_slice_free1 (sizeof (CtkSelectionInfo), (selection_info )); else (void) ((CtkSelectionInfo*) 0 == (selection_info)); } while (0); | |||
2351 | } | |||
2352 | ||||
2353 | return TRUE(!(0)); | |||
2354 | } | |||
2355 | ||||
2356 | ||||
2357 | /************************************************************* | |||
2358 | * _ctk_selection_request: | |||
2359 | * Handler for “selection_request_event” | |||
2360 | * arguments: | |||
2361 | * widget: | |||
2362 | * event: | |||
2363 | * results: | |||
2364 | *************************************************************/ | |||
2365 | ||||
2366 | gboolean | |||
2367 | _ctk_selection_request (CtkWidget *widget, | |||
2368 | CdkEventSelection *event) | |||
2369 | { | |||
2370 | CdkDisplay *display = ctk_widget_get_display (widget); | |||
2371 | CtkIncrInfo *info; | |||
2372 | GList *tmp_list; | |||
2373 | int i; | |||
2374 | gulong selection_max_size; | |||
2375 | ||||
2376 | if (event->requestor == NULL((void*)0)) | |||
2377 | return FALSE(0); | |||
2378 | ||||
2379 | if (initialize) | |||
2380 | ctk_selection_init (); | |||
2381 | ||||
2382 | selection_max_size = CTK_SELECTION_MAX_SIZE (display)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (display)); GType __t = ((cdk_x11_display_get_type())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) ? ((( 262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) ? (262144) : (XExtendedMaxRequestSize (( cdk_x11_display_get_xdisplay (display))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (display))) - 100)) : 2147483647; | |||
2383 | ||||
2384 | /* Check if we own selection */ | |||
2385 | ||||
2386 | tmp_list = current_selections; | |||
2387 | while (tmp_list) | |||
2388 | { | |||
2389 | CtkSelectionInfo *selection_info = (CtkSelectionInfo *)tmp_list->data; | |||
2390 | ||||
2391 | if ((selection_info->selection == event->selection) && | |||
2392 | (selection_info->widget == widget)) | |||
2393 | break; | |||
2394 | ||||
2395 | tmp_list = tmp_list->next; | |||
2396 | } | |||
2397 | ||||
2398 | if (tmp_list == NULL((void*)0)) | |||
2399 | return FALSE(0); | |||
2400 | ||||
2401 | info = g_slice_new (CtkIncrInfo)((CtkIncrInfo*) g_slice_alloc (sizeof (CtkIncrInfo))); | |||
2402 | ||||
2403 | g_object_ref (widget)((__typeof__ (widget)) (g_object_ref) (widget)); | |||
2404 | ||||
2405 | info->selection = event->selection; | |||
2406 | info->num_incrs = 0; | |||
2407 | info->requestor = g_object_ref (event->requestor)((__typeof__ (event->requestor)) (g_object_ref) (event-> requestor)); | |||
2408 | ||||
2409 | /* Determine conversions we need to perform */ | |||
2410 | if (event->target == ctk_selection_atoms[MULTIPLE]) | |||
2411 | { | |||
2412 | CdkAtom type; | |||
2413 | guchar *mult_atoms; | |||
2414 | gint format; | |||
2415 | gint length; | |||
2416 | ||||
2417 | mult_atoms = NULL((void*)0); | |||
2418 | ||||
2419 | cdk_error_trap_push (); | |||
2420 | if (!cdk_property_get (info->requestor, event->property, CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), /* AnyPropertyType */ | |||
2421 | 0, selection_max_size, FALSE(0), | |||
2422 | &type, &format, &length, &mult_atoms)) | |||
2423 | { | |||
2424 | cdk_selection_send_notify_for_display (display, | |||
2425 | event->requestor, | |||
2426 | event->selection, | |||
2427 | event->target, | |||
2428 | CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), | |||
2429 | event->time); | |||
2430 | g_free (mult_atoms); | |||
2431 | g_slice_free (CtkIncrInfo, info)do { if (1) g_slice_free1 (sizeof (CtkIncrInfo), (info)); else (void) ((CtkIncrInfo*) 0 == (info)); } while (0); | |||
2432 | cdk_error_trap_pop_ignored (); | |||
2433 | return TRUE(!(0)); | |||
2434 | } | |||
2435 | cdk_error_trap_pop_ignored (); | |||
2436 | ||||
2437 | /* This is annoying; the ICCCM doesn't specify the property type | |||
2438 | * used for the property contents, so the autoconversion for | |||
2439 | * ATOM / ATOM_PAIR in CDK doesn't work properly. | |||
2440 | */ | |||
2441 | #ifdef CDK_WINDOWING_X11 | |||
2442 | if (type != CDK_SELECTION_TYPE_ATOM((CdkAtom)((gpointer) (gulong) (4))) && | |||
2443 | type != cdk_atom_intern_static_string ("ATOM_PAIR")) | |||
2444 | { | |||
2445 | info->num_conversions = length / (2*sizeof (glong)); | |||
2446 | info->conversions = g_new (CtkIncrConversion, info->num_conversions)((CtkIncrConversion *) g_malloc_n ((info->num_conversions) , sizeof (CtkIncrConversion))); | |||
2447 | ||||
2448 | for (i=0; i<info->num_conversions; i++) | |||
2449 | { | |||
2450 | info->conversions[i].target = cdk_x11_xatom_to_atom_for_display (display, | |||
2451 | ((glong *)mult_atoms)[2*i]); | |||
2452 | info->conversions[i].property = cdk_x11_xatom_to_atom_for_display (display, | |||
2453 | ((glong *)mult_atoms)[2*i + 1]); | |||
2454 | } | |||
2455 | ||||
2456 | g_free (mult_atoms); | |||
2457 | } | |||
2458 | else | |||
2459 | #endif | |||
2460 | { | |||
2461 | info->num_conversions = length / (2*sizeof (CdkAtom)); | |||
2462 | info->conversions = g_new (CtkIncrConversion, info->num_conversions)((CtkIncrConversion *) g_malloc_n ((info->num_conversions) , sizeof (CtkIncrConversion))); | |||
2463 | ||||
2464 | for (i=0; i<info->num_conversions; i++) | |||
2465 | { | |||
2466 | info->conversions[i].target = ((CdkAtom *)mult_atoms)[2*i]; | |||
2467 | info->conversions[i].property = ((CdkAtom *)mult_atoms)[2*i+1]; | |||
2468 | } | |||
2469 | ||||
2470 | g_free (mult_atoms); | |||
2471 | } | |||
2472 | } | |||
2473 | else /* only a single conversion */ | |||
2474 | { | |||
2475 | info->conversions = g_new (CtkIncrConversion, 1)((CtkIncrConversion *) g_malloc_n ((1), sizeof (CtkIncrConversion ))); | |||
2476 | info->num_conversions = 1; | |||
2477 | info->conversions[0].target = event->target; | |||
2478 | info->conversions[0].property = event->property; | |||
2479 | } | |||
2480 | ||||
2481 | /* Loop through conversions and determine which of these are big | |||
2482 | enough to require doing them via INCR */ | |||
2483 | for (i=0; i<info->num_conversions; i++) | |||
2484 | { | |||
2485 | CtkSelectionData data; | |||
2486 | glong items; | |||
2487 | ||||
2488 | data.selection = event->selection; | |||
2489 | data.target = info->conversions[i].target; | |||
2490 | data.data = NULL((void*)0); | |||
2491 | data.length = -1; | |||
2492 | data.display = ctk_widget_get_display (widget); | |||
2493 | ||||
2494 | #ifdef DEBUG_SELECTION | |||
2495 | g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)", | |||
2496 | event->selection, | |||
2497 | info->conversions[i].target, | |||
2498 | cdk_atom_name (info->conversions[i].target), | |||
2499 | event->requestor, info->conversions[i].property); | |||
2500 | #endif | |||
2501 | ||||
2502 | ctk_selection_invoke_handler (widget, &data, event->time); | |||
2503 | if (data.length < 0) | |||
2504 | { | |||
2505 | info->conversions[i].property = CDK_NONE((CdkAtom)((gpointer) (gulong) (0))); | |||
2506 | continue; | |||
2507 | } | |||
2508 | ||||
2509 | g_return_val_if_fail ((data.format >= 8) && (data.format % 8 == 0), FALSE)do { if (((data.format >= 8) && (data.format % 8 == 0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "(data.format >= 8) && (data.format % 8 == 0)" ); return ((0)); } } while (0); | |||
2510 | ||||
2511 | items = data.length / ctk_selection_bytes_per_item (data.format); | |||
2512 | ||||
2513 | if (data.length > selection_max_size) | |||
2514 | { | |||
2515 | /* Sending via INCR */ | |||
2516 | #ifdef DEBUG_SELECTION | |||
2517 | g_message ("Target larger (%d) than max. request size (%ld), sending incrementally\n", | |||
2518 | data.length, selection_max_size); | |||
2519 | #endif | |||
2520 | ||||
2521 | info->conversions[i].offset = 0; | |||
2522 | info->conversions[i].data = data; | |||
2523 | info->num_incrs++; | |||
2524 | ||||
2525 | cdk_error_trap_push (); | |||
2526 | cdk_property_change (info->requestor, | |||
2527 | info->conversions[i].property, | |||
2528 | ctk_selection_atoms[INCR], | |||
2529 | 32, | |||
2530 | CDK_PROP_MODE_REPLACE, | |||
2531 | (guchar *)&items, 1); | |||
2532 | cdk_error_trap_pop_ignored (); | |||
2533 | } | |||
2534 | else | |||
2535 | { | |||
2536 | info->conversions[i].offset = -1; | |||
2537 | ||||
2538 | cdk_error_trap_push (); | |||
2539 | cdk_property_change (info->requestor, | |||
2540 | info->conversions[i].property, | |||
2541 | data.type, | |||
2542 | data.format, | |||
2543 | CDK_PROP_MODE_REPLACE, | |||
2544 | data.data, items); | |||
2545 | cdk_error_trap_pop_ignored (); | |||
2546 | ||||
2547 | g_free (data.data); | |||
2548 | } | |||
2549 | } | |||
2550 | ||||
2551 | /* If we have some INCR's, we need to send the rest of the data in | |||
2552 | a callback */ | |||
2553 | ||||
2554 | if (info->num_incrs > 0) | |||
2555 | { | |||
2556 | guint id; | |||
2557 | ||||
2558 | /* FIXME: this could be dangerous if window doesn't still | |||
2559 | exist */ | |||
2560 | ||||
2561 | #ifdef DEBUG_SELECTION | |||
2562 | g_message ("Starting INCR..."); | |||
2563 | #endif | |||
2564 | ||||
2565 | cdk_error_trap_push (); | |||
2566 | cdk_window_set_events (info->requestor, | |||
2567 | cdk_window_get_events (info->requestor) | | |||
2568 | CDK_PROPERTY_CHANGE_MASK); | |||
2569 | cdk_error_trap_pop_ignored (); | |||
2570 | current_incrs = g_list_append (current_incrs, info); | |||
2571 | id = cdk_threads_add_timeout (1000, (GSourceFunc) ctk_selection_incr_timeout, info); | |||
2572 | g_source_set_name_by_id (id, "[ctk+] ctk_selection_incr_timeout"); | |||
2573 | } | |||
2574 | ||||
2575 | /* If it was a MULTIPLE request, set the property to indicate which | |||
2576 | conversions succeeded */ | |||
2577 | if (event->target == ctk_selection_atoms[MULTIPLE]) | |||
2578 | { | |||
2579 | CdkAtom *mult_atoms = g_new (CdkAtom, 2 * info->num_conversions)((CdkAtom *) g_malloc_n ((2 * info->num_conversions), sizeof (CdkAtom))); | |||
2580 | for (i = 0; i < info->num_conversions; i++) | |||
2581 | { | |||
2582 | mult_atoms[2*i] = info->conversions[i].target; | |||
2583 | mult_atoms[2*i+1] = info->conversions[i].property; | |||
2584 | } | |||
2585 | ||||
2586 | cdk_error_trap_push (); | |||
2587 | cdk_property_change (info->requestor, event->property, | |||
2588 | cdk_atom_intern_static_string ("ATOM_PAIR"), 32, | |||
2589 | CDK_PROP_MODE_REPLACE, | |||
2590 | (guchar *)mult_atoms, 2*info->num_conversions); | |||
2591 | cdk_error_trap_pop_ignored (); | |||
2592 | g_free (mult_atoms); | |||
2593 | } | |||
2594 | ||||
2595 | if (info->num_conversions == 1 && | |||
2596 | info->conversions[0].property == CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) | |||
2597 | { | |||
2598 | /* Reject the entire conversion */ | |||
2599 | cdk_selection_send_notify_for_display (ctk_widget_get_display (widget), | |||
2600 | event->requestor, | |||
2601 | event->selection, | |||
2602 | event->target, | |||
2603 | CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), | |||
2604 | event->time); | |||
2605 | } | |||
2606 | else | |||
2607 | { | |||
2608 | cdk_selection_send_notify_for_display (ctk_widget_get_display (widget), | |||
2609 | event->requestor, | |||
2610 | event->selection, | |||
2611 | event->target, | |||
2612 | event->property, | |||
2613 | event->time); | |||
2614 | } | |||
2615 | ||||
2616 | if (info->num_incrs == 0) | |||
2617 | { | |||
2618 | g_free (info->conversions); | |||
2619 | g_slice_free (CtkIncrInfo, info)do { if (1) g_slice_free1 (sizeof (CtkIncrInfo), (info)); else (void) ((CtkIncrInfo*) 0 == (info)); } while (0); | |||
2620 | } | |||
2621 | ||||
2622 | g_object_unref (widget); | |||
2623 | ||||
2624 | return TRUE(!(0)); | |||
2625 | } | |||
2626 | ||||
2627 | /************************************************************* | |||
2628 | * _ctk_selection_incr_event: | |||
2629 | * Called whenever an PropertyNotify event occurs for an | |||
2630 | * CdkWindow with user_data == NULL. These will be notifications | |||
2631 | * that a window we are sending the selection to via the | |||
2632 | * INCR protocol has deleted a property and is ready for | |||
2633 | * more data. | |||
2634 | * | |||
2635 | * arguments: | |||
2636 | * window: the requestor window | |||
2637 | * event: the property event structure | |||
2638 | * | |||
2639 | * results: | |||
2640 | *************************************************************/ | |||
2641 | ||||
2642 | gboolean | |||
2643 | _ctk_selection_incr_event (CdkWindow *window, | |||
2644 | CdkEventProperty *event) | |||
2645 | { | |||
2646 | GList *tmp_list; | |||
2647 | CtkIncrInfo *info = NULL((void*)0); | |||
2648 | gint num_bytes; | |||
2649 | guchar *buffer; | |||
2650 | gulong selection_max_size; | |||
2651 | ||||
2652 | int i; | |||
2653 | ||||
2654 | if (event->state != CDK_PROPERTY_DELETE) | |||
2655 | return FALSE(0); | |||
2656 | ||||
2657 | #ifdef DEBUG_SELECTION | |||
2658 | g_message ("PropertyDelete, property %ld", event->atom); | |||
2659 | #endif | |||
2660 | ||||
2661 | selection_max_size = CTK_SELECTION_MAX_SIZE (cdk_window_get_display (window))(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (cdk_window_get_display (window))); GType __t = ((cdk_x11_display_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) ? (((262144) < (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (cdk_window_get_display (window)))) == 0 ? XMaxRequestSize ( (cdk_x11_display_get_xdisplay (cdk_window_get_display (window )))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (cdk_window_get_display (window)))) - 100)) ? (262144) : (XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (cdk_window_get_display (window )))) == 0 ? XMaxRequestSize ((cdk_x11_display_get_xdisplay (cdk_window_get_display (window)))) - 100 : XExtendedMaxRequestSize ((cdk_x11_display_get_xdisplay (cdk_window_get_display (window)))) - 100)) : 2147483647; | |||
2662 | ||||
2663 | /* Now find the appropriate ongoing INCR */ | |||
2664 | tmp_list = current_incrs; | |||
2665 | while (tmp_list) | |||
2666 | { | |||
2667 | info = (CtkIncrInfo *)tmp_list->data; | |||
2668 | if (info->requestor == event->window) | |||
2669 | break; | |||
2670 | ||||
2671 | tmp_list = tmp_list->next; | |||
2672 | } | |||
2673 | ||||
2674 | if (tmp_list == NULL((void*)0)) | |||
2675 | return FALSE(0); | |||
2676 | ||||
2677 | /* Find out which target this is for */ | |||
2678 | for (i=0; i<info->num_conversions; i++) | |||
2679 | { | |||
2680 | if (info->conversions[i].property == event->atom && | |||
2681 | info->conversions[i].offset != -1) | |||
2682 | { | |||
2683 | int bytes_per_item; | |||
2684 | ||||
2685 | info->idle_time = 0; | |||
2686 | ||||
2687 | if (info->conversions[i].offset == -2) /* only the last 0-length | |||
2688 | piece*/ | |||
2689 | { | |||
2690 | num_bytes = 0; | |||
2691 | buffer = NULL((void*)0); | |||
2692 | } | |||
2693 | else | |||
2694 | { | |||
2695 | num_bytes = info->conversions[i].data.length - | |||
2696 | info->conversions[i].offset; | |||
2697 | buffer = info->conversions[i].data.data + | |||
2698 | info->conversions[i].offset; | |||
2699 | ||||
2700 | if (num_bytes > selection_max_size) | |||
2701 | { | |||
2702 | num_bytes = selection_max_size; | |||
2703 | info->conversions[i].offset += selection_max_size; | |||
2704 | } | |||
2705 | else | |||
2706 | info->conversions[i].offset = -2; | |||
2707 | } | |||
2708 | #ifdef DEBUG_SELECTION | |||
2709 | g_message ("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld", | |||
2710 | num_bytes, info->conversions[i].offset, | |||
2711 | CDK_WINDOW_XID(info->requestor)(cdk_x11_window_get_xid (info->requestor)), event->atom); | |||
2712 | #endif | |||
2713 | ||||
2714 | bytes_per_item = ctk_selection_bytes_per_item (info->conversions[i].data.format); | |||
2715 | cdk_error_trap_push (); | |||
2716 | cdk_property_change (info->requestor, event->atom, | |||
2717 | info->conversions[i].data.type, | |||
2718 | info->conversions[i].data.format, | |||
2719 | CDK_PROP_MODE_REPLACE, | |||
2720 | buffer, | |||
2721 | num_bytes / bytes_per_item); | |||
2722 | cdk_error_trap_pop_ignored (); | |||
2723 | ||||
2724 | if (info->conversions[i].offset == -2) | |||
2725 | { | |||
2726 | g_free (info->conversions[i].data.data); | |||
2727 | info->conversions[i].data.data = NULL((void*)0); | |||
2728 | } | |||
2729 | ||||
2730 | if (num_bytes == 0) | |||
2731 | { | |||
2732 | info->num_incrs--; | |||
2733 | info->conversions[i].offset = -1; | |||
2734 | } | |||
2735 | } | |||
2736 | } | |||
2737 | ||||
2738 | /* Check if we're finished with all the targets */ | |||
2739 | ||||
2740 | if (info->num_incrs == 0) | |||
2741 | { | |||
2742 | current_incrs = g_list_remove_link (current_incrs, tmp_list); | |||
2743 | g_list_free (tmp_list); | |||
2744 | /* Let the timeout free it */ | |||
2745 | } | |||
2746 | ||||
2747 | return TRUE(!(0)); | |||
2748 | } | |||
2749 | ||||
2750 | /************************************************************* | |||
2751 | * ctk_selection_incr_timeout: | |||
2752 | * Timeout callback for the sending portion of the INCR | |||
2753 | * protocol | |||
2754 | * arguments: | |||
2755 | * info: Information about this incr | |||
2756 | * results: | |||
2757 | *************************************************************/ | |||
2758 | ||||
2759 | static gint | |||
2760 | ctk_selection_incr_timeout (CtkIncrInfo *info) | |||
2761 | { | |||
2762 | GList *tmp_list; | |||
2763 | gboolean retval; | |||
2764 | ||||
2765 | /* Determine if retrieval has finished by checking if it still in | |||
2766 | list of pending retrievals */ | |||
2767 | ||||
2768 | tmp_list = current_incrs; | |||
2769 | while (tmp_list) | |||
2770 | { | |||
2771 | if (info == (CtkIncrInfo *)tmp_list->data) | |||
2772 | break; | |||
2773 | tmp_list = tmp_list->next; | |||
2774 | } | |||
2775 | ||||
2776 | /* If retrieval is finished */ | |||
2777 | if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME30) | |||
2778 | { | |||
2779 | if (tmp_list && info->idle_time >= IDLE_ABORT_TIME30) | |||
2780 | { | |||
2781 | current_incrs = g_list_remove_link (current_incrs, tmp_list); | |||
2782 | g_list_free (tmp_list); | |||
2783 | } | |||
2784 | ||||
2785 | g_free (info->conversions); | |||
2786 | /* FIXME: we should check if requestor window is still in use, | |||
2787 | and if not, remove it? */ | |||
2788 | ||||
2789 | g_slice_free (CtkIncrInfo, info)do { if (1) g_slice_free1 (sizeof (CtkIncrInfo), (info)); else (void) ((CtkIncrInfo*) 0 == (info)); } while (0); | |||
2790 | ||||
2791 | retval = FALSE(0); /* remove timeout */ | |||
2792 | } | |||
2793 | else | |||
2794 | { | |||
2795 | info->idle_time++; | |||
2796 | ||||
2797 | retval = TRUE(!(0)); /* timeout will happen again */ | |||
2798 | } | |||
2799 | ||||
2800 | return retval; | |||
2801 | } | |||
2802 | ||||
2803 | /************************************************************* | |||
2804 | * _ctk_selection_notify: | |||
2805 | * Handler for “selection-notify-event” signals on windows | |||
2806 | * where a retrieval is currently in process. The selection | |||
2807 | * owner has responded to our conversion request. | |||
2808 | * arguments: | |||
2809 | * widget: Widget getting signal | |||
2810 | * event: Selection event structure | |||
2811 | * info: Information about this retrieval | |||
2812 | * results: | |||
2813 | * was event handled? | |||
2814 | *************************************************************/ | |||
2815 | ||||
2816 | gboolean | |||
2817 | _ctk_selection_notify (CtkWidget *widget, | |||
2818 | CdkEventSelection *event) | |||
2819 | { | |||
2820 | GList *tmp_list; | |||
2821 | CtkRetrievalInfo *info = NULL((void*)0); | |||
2822 | CdkWindow *window; | |||
2823 | guchar *buffer = NULL((void*)0); | |||
2824 | gint length; | |||
2825 | CdkAtom type; | |||
2826 | gint format; | |||
2827 | ||||
2828 | #ifdef DEBUG_SELECTION | |||
2829 | g_message ("Initial receipt of selection %ld, target %ld (property = %ld)", | |||
2830 | event->selection, event->target, event->property); | |||
2831 | #endif | |||
2832 | ||||
2833 | window = ctk_widget_get_window (widget); | |||
2834 | ||||
2835 | tmp_list = current_retrievals; | |||
2836 | while (tmp_list) | |||
2837 | { | |||
2838 | info = (CtkRetrievalInfo *)tmp_list->data; | |||
2839 | if (info->widget == widget && info->selection == event->selection) | |||
2840 | break; | |||
2841 | tmp_list = tmp_list->next; | |||
2842 | } | |||
2843 | ||||
2844 | if (!tmp_list) /* no retrieval in progress */ | |||
2845 | return FALSE(0); | |||
2846 | ||||
2847 | if (event->property != CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) | |||
2848 | length = cdk_selection_property_get (window, &buffer, | |||
2849 | &type, &format); | |||
2850 | else | |||
2851 | length = 0; /* silence gcc */ | |||
2852 | ||||
2853 | if (event->property == CDK_NONE((CdkAtom)((gpointer) (gulong) (0))) || buffer == NULL((void*)0)) | |||
2854 | { | |||
2855 | current_retrievals = g_list_remove_link (current_retrievals, tmp_list); | |||
2856 | g_list_free (tmp_list); | |||
2857 | /* structure will be freed in timeout */ | |||
2858 | ctk_selection_retrieval_report (info, | |||
2859 | CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), 0, NULL((void*)0), -1, event->time); | |||
2860 | ||||
2861 | return TRUE(!(0)); | |||
2862 | } | |||
2863 | ||||
2864 | if (type == ctk_selection_atoms[INCR]) | |||
2865 | { | |||
2866 | /* The remainder of the selection will come through PropertyNotify | |||
2867 | events */ | |||
2868 | ||||
2869 | info->notify_time = event->time; | |||
2870 | info->idle_time = 0; | |||
2871 | info->offset = 0; /* Mark as OK to proceed */ | |||
2872 | cdk_window_set_events (window, | |||
2873 | cdk_window_get_events (window) | |||
2874 | | CDK_PROPERTY_CHANGE_MASK); | |||
2875 | } | |||
2876 | else | |||
2877 | { | |||
2878 | /* We don't delete the info structure - that will happen in timeout */ | |||
2879 | current_retrievals = g_list_remove_link (current_retrievals, tmp_list); | |||
2880 | g_list_free (tmp_list); | |||
2881 | ||||
2882 | info->offset = length; | |||
2883 | ctk_selection_retrieval_report (info, | |||
2884 | type, format, | |||
2885 | buffer, length, event->time); | |||
2886 | } | |||
2887 | ||||
2888 | cdk_property_delete (window, event->property); | |||
2889 | ||||
2890 | g_free (buffer); | |||
2891 | ||||
2892 | return TRUE(!(0)); | |||
2893 | } | |||
2894 | ||||
2895 | /************************************************************* | |||
2896 | * _ctk_selection_property_notify: | |||
2897 | * Handler for “property-notify-event” signals on windows | |||
2898 | * where a retrieval is currently in process. The selection | |||
2899 | * owner has added more data. | |||
2900 | * arguments: | |||
2901 | * widget: Widget getting signal | |||
2902 | * event: Property event structure | |||
2903 | * info: Information about this retrieval | |||
2904 | * results: | |||
2905 | * was event handled? | |||
2906 | *************************************************************/ | |||
2907 | ||||
2908 | gboolean | |||
2909 | _ctk_selection_property_notify (CtkWidget *widget, | |||
2910 | CdkEventProperty *event) | |||
2911 | { | |||
2912 | GList *tmp_list; | |||
2913 | CtkRetrievalInfo *info = NULL((void*)0); | |||
2914 | CdkWindow *window; | |||
2915 | guchar *new_buffer; | |||
2916 | int length; | |||
2917 | CdkAtom type; | |||
2918 | gint format; | |||
2919 | ||||
2920 | g_return_val_if_fail (widget != NULL, FALSE)do { if ((widget != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "widget != NULL"); return ((0)); } } while (0); | |||
2921 | g_return_val_if_fail (event != NULL, FALSE)do { if ((event != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "event != NULL"); return ((0)); } } while (0); | |||
2922 | ||||
2923 | #if defined(CDK_WINDOWING_WIN32) || defined(CDK_WINDOWING_X11) | |||
2924 | if ((event->state != CDK_PROPERTY_NEW_VALUE) || /* property was deleted */ | |||
2925 | (event->atom != cdk_atom_intern_static_string ("CDK_SELECTION"))) /* not the right property */ | |||
2926 | #endif | |||
2927 | return FALSE(0); | |||
2928 | ||||
2929 | #ifdef DEBUG_SELECTION | |||
2930 | g_message ("PropertyNewValue, property %ld", | |||
2931 | event->atom); | |||
2932 | #endif | |||
2933 | ||||
2934 | tmp_list = current_retrievals; | |||
2935 | while (tmp_list) | |||
2936 | { | |||
2937 | info = (CtkRetrievalInfo *)tmp_list->data; | |||
2938 | if (info->widget == widget) | |||
2939 | break; | |||
2940 | tmp_list = tmp_list->next; | |||
2941 | } | |||
2942 | ||||
2943 | if (!tmp_list) /* No retrieval in progress */ | |||
2944 | return FALSE(0); | |||
2945 | ||||
2946 | if (info->offset < 0) /* We haven't got the SelectionNotify | |||
2947 | for this retrieval yet */ | |||
2948 | return FALSE(0); | |||
2949 | ||||
2950 | info->idle_time = 0; | |||
2951 | ||||
2952 | window = ctk_widget_get_window (widget); | |||
2953 | length = cdk_selection_property_get (window, &new_buffer, | |||
2954 | &type, &format); | |||
2955 | cdk_property_delete (window, event->atom); | |||
2956 | ||||
2957 | /* We could do a lot better efficiency-wise by paying attention to | |||
2958 | what length was sent in the initial INCR transaction, instead of | |||
2959 | doing memory allocation at every step. But its only guaranteed to | |||
2960 | be a _lower bound_ (pretty useless!) */ | |||
2961 | ||||
2962 | if (length == 0 || type == CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) /* final zero length portion */ | |||
2963 | { | |||
2964 | /* Info structure will be freed in timeout */ | |||
2965 | current_retrievals = g_list_remove_link (current_retrievals, tmp_list); | |||
2966 | g_list_free (tmp_list); | |||
2967 | ctk_selection_retrieval_report (info, | |||
2968 | type, format, | |||
2969 | (type == CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) ? NULL((void*)0) : info->buffer, | |||
2970 | (type == CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) ? -1 : info->offset, | |||
2971 | info->notify_time); | |||
2972 | } | |||
2973 | else /* append on newly arrived data */ | |||
2974 | { | |||
2975 | if (!info->buffer) | |||
2976 | { | |||
2977 | #ifdef DEBUG_SELECTION | |||
2978 | g_message ("Start - Adding %d bytes at offset 0", | |||
2979 | length); | |||
2980 | #endif | |||
2981 | info->buffer = new_buffer; | |||
2982 | info->offset = length; | |||
2983 | } | |||
2984 | else | |||
2985 | { | |||
2986 | ||||
2987 | #ifdef DEBUG_SELECTION | |||
2988 | g_message ("Appending %d bytes at offset %d", | |||
2989 | length,info->offset); | |||
2990 | #endif | |||
2991 | /* We copy length+1 bytes to preserve guaranteed null termination */ | |||
2992 | info->buffer = g_realloc (info->buffer, info->offset+length+1); | |||
2993 | memcpy (info->buffer + info->offset, new_buffer, length+1); | |||
2994 | info->offset += length; | |||
2995 | g_free (new_buffer); | |||
2996 | } | |||
2997 | } | |||
2998 | ||||
2999 | return TRUE(!(0)); | |||
3000 | } | |||
3001 | ||||
3002 | /************************************************************* | |||
3003 | * ctk_selection_retrieval_timeout: | |||
3004 | * Timeout callback while receiving a selection. | |||
3005 | * arguments: | |||
3006 | * info: Information about this retrieval | |||
3007 | * results: | |||
3008 | *************************************************************/ | |||
3009 | ||||
3010 | static gboolean | |||
3011 | ctk_selection_retrieval_timeout (CtkRetrievalInfo *info) | |||
3012 | { | |||
3013 | GList *tmp_list; | |||
3014 | gboolean retval; | |||
3015 | ||||
3016 | /* Determine if retrieval has finished by checking if it still in | |||
3017 | list of pending retrievals */ | |||
3018 | ||||
3019 | tmp_list = current_retrievals; | |||
3020 | while (tmp_list) | |||
3021 | { | |||
3022 | if (info == (CtkRetrievalInfo *)tmp_list->data) | |||
3023 | break; | |||
3024 | tmp_list = tmp_list->next; | |||
3025 | } | |||
3026 | ||||
3027 | /* If retrieval is finished */ | |||
3028 | if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME30) | |||
3029 | { | |||
3030 | if (tmp_list && info->idle_time >= IDLE_ABORT_TIME30) | |||
3031 | { | |||
3032 | current_retrievals = g_list_remove_link (current_retrievals, tmp_list); | |||
3033 | g_list_free (tmp_list); | |||
3034 | ctk_selection_retrieval_report (info, CDK_NONE((CdkAtom)((gpointer) (gulong) (0))), 0, NULL((void*)0), -1, CDK_CURRENT_TIME0L); | |||
3035 | } | |||
3036 | ||||
3037 | g_free (info->buffer); | |||
3038 | g_slice_free (CtkRetrievalInfo, info)do { if (1) g_slice_free1 (sizeof (CtkRetrievalInfo), (info)) ; else (void) ((CtkRetrievalInfo*) 0 == (info)); } while (0); | |||
3039 | ||||
3040 | retval = FALSE(0); /* remove timeout */ | |||
3041 | } | |||
3042 | else | |||
3043 | { | |||
3044 | info->idle_time++; | |||
3045 | ||||
3046 | retval = TRUE(!(0)); /* timeout will happen again */ | |||
3047 | } | |||
3048 | ||||
3049 | return retval; | |||
3050 | } | |||
3051 | ||||
3052 | /************************************************************* | |||
3053 | * ctk_selection_retrieval_report: | |||
3054 | * Emits a “selection-received” signal. | |||
3055 | * arguments: | |||
3056 | * info: information about the retrieval that completed | |||
3057 | * buffer: buffer containing data (NULL => errror) | |||
3058 | * time: timestamp for data in buffer | |||
3059 | * results: | |||
3060 | *************************************************************/ | |||
3061 | ||||
3062 | static void | |||
3063 | ctk_selection_retrieval_report (CtkRetrievalInfo *info, | |||
3064 | CdkAtom type, gint format, | |||
3065 | guchar *buffer, gint length, | |||
3066 | guint32 time) | |||
3067 | { | |||
3068 | CtkSelectionData data; | |||
3069 | ||||
3070 | data.selection = info->selection; | |||
3071 | data.target = info->target; | |||
3072 | data.type = type; | |||
3073 | data.format = format; | |||
3074 | ||||
3075 | data.length = length; | |||
3076 | data.data = buffer; | |||
3077 | data.display = ctk_widget_get_display (info->widget); | |||
3078 | ||||
3079 | g_signal_emit_by_name (info->widget, | |||
3080 | "selection-received", | |||
3081 | &data, time); | |||
3082 | } | |||
3083 | ||||
3084 | /************************************************************* | |||
3085 | * ctk_selection_invoke_handler: | |||
3086 | * Finds and invokes handler for specified | |||
3087 | * widget/selection/target combination, calls | |||
3088 | * ctk_selection_default_handler if none exists. | |||
3089 | * | |||
3090 | * arguments: | |||
3091 | * widget: selection owner | |||
3092 | * data: selection data [INOUT] | |||
3093 | * time: time from requeset | |||
3094 | * | |||
3095 | * results: | |||
3096 | * Number of bytes written to buffer, -1 if error | |||
3097 | *************************************************************/ | |||
3098 | ||||
3099 | static void | |||
3100 | ctk_selection_invoke_handler (CtkWidget *widget, | |||
3101 | CtkSelectionData *data, | |||
3102 | guint time) | |||
3103 | { | |||
3104 | CtkTargetList *target_list; | |||
3105 | guint info; | |||
3106 | ||||
3107 | ||||
3108 | g_return_if_fail (widget != NULL)do { if ((widget != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "widget != NULL"); return ; } } while (0); | |||
3109 | ||||
3110 | target_list = ctk_selection_target_list_get (widget, data->selection); | |||
3111 | if (data->target != ctk_selection_atoms[SAVE_TARGETS] && | |||
3112 | target_list && | |||
3113 | ctk_target_list_find (target_list, data->target, &info)) | |||
3114 | { | |||
3115 | g_signal_emit_by_name (widget, | |||
3116 | "selection-get", | |||
3117 | data, | |||
3118 | info, time); | |||
3119 | } | |||
3120 | else | |||
3121 | ctk_selection_default_handler (widget, data); | |||
3122 | } | |||
3123 | ||||
3124 | /************************************************************* | |||
3125 | * ctk_selection_default_handler: | |||
3126 | * Handles some default targets that exist for any widget | |||
3127 | * If it can’t fit results into buffer, returns -1. This | |||
3128 | * won’t happen in any conceivable case, since it would | |||
3129 | * require 1000 selection targets! | |||
3130 | * | |||
3131 | * arguments: | |||
3132 | * widget: selection owner | |||
3133 | * data: selection data [INOUT] | |||
3134 | * | |||
3135 | *************************************************************/ | |||
3136 | ||||
3137 | static void | |||
3138 | ctk_selection_default_handler (CtkWidget *widget, | |||
3139 | CtkSelectionData *data) | |||
3140 | { | |||
3141 | if (data->target == ctk_selection_atoms[TIMESTAMP]) | |||
3142 | { | |||
3143 | /* Time which was used to obtain selection */ | |||
3144 | GList *tmp_list; | |||
3145 | CtkSelectionInfo *selection_info; | |||
3146 | ||||
3147 | tmp_list = current_selections; | |||
3148 | while (tmp_list) | |||
3149 | { | |||
3150 | selection_info = (CtkSelectionInfo *)tmp_list->data; | |||
3151 | if ((selection_info->widget == widget) && | |||
3152 | (selection_info->selection == data->selection)) | |||
3153 | { | |||
3154 | gulong time = selection_info->time; | |||
3155 | ||||
3156 | ctk_selection_data_set (data, | |||
3157 | CDK_SELECTION_TYPE_INTEGER((CdkAtom)((gpointer) (gulong) (19))), | |||
3158 | 32, | |||
3159 | (guchar *)&time, | |||
3160 | sizeof (time)); | |||
3161 | return; | |||
3162 | } | |||
3163 | ||||
3164 | tmp_list = tmp_list->next; | |||
3165 | } | |||
3166 | ||||
3167 | data->length = -1; | |||
3168 | } | |||
3169 | else if (data->target == ctk_selection_atoms[TARGETS]) | |||
3170 | { | |||
3171 | /* List of all targets supported for this widget/selection pair */ | |||
3172 | CdkAtom *p; | |||
3173 | guint count; | |||
3174 | GList *tmp_list; | |||
3175 | CtkTargetList *target_list; | |||
3176 | CtkTargetPair *pair; | |||
3177 | ||||
3178 | target_list = ctk_selection_target_list_get (widget, | |||
3179 | data->selection); | |||
3180 | count = g_list_length (target_list->list) + 3; | |||
3181 | ||||
3182 | data->type = CDK_SELECTION_TYPE_ATOM((CdkAtom)((gpointer) (gulong) (4))); | |||
3183 | data->format = 32; | |||
3184 | data->length = count * sizeof (CdkAtom); | |||
3185 | ||||
3186 | /* selection data is always terminated by a trailing \0 | |||
3187 | */ | |||
3188 | p = g_malloc (data->length + 1); | |||
3189 | data->data = (guchar *)p; | |||
3190 | data->data[data->length] = '\0'; | |||
3191 | ||||
3192 | *p++ = ctk_selection_atoms[TIMESTAMP]; | |||
3193 | *p++ = ctk_selection_atoms[TARGETS]; | |||
3194 | *p++ = ctk_selection_atoms[MULTIPLE]; | |||
3195 | ||||
3196 | tmp_list = target_list->list; | |||
3197 | while (tmp_list) | |||
3198 | { | |||
3199 | pair = (CtkTargetPair *)tmp_list->data; | |||
3200 | *p++ = pair->target; | |||
3201 | ||||
3202 | tmp_list = tmp_list->next; | |||
3203 | } | |||
3204 | } | |||
3205 | else if (data->target == ctk_selection_atoms[SAVE_TARGETS]) | |||
3206 | { | |||
3207 | ctk_selection_data_set (data, | |||
3208 | cdk_atom_intern_static_string ("NULL"), | |||
3209 | 32, NULL((void*)0), 0); | |||
3210 | } | |||
3211 | else | |||
3212 | { | |||
3213 | data->length = -1; | |||
3214 | } | |||
3215 | } | |||
3216 | ||||
3217 | ||||
3218 | /** | |||
3219 | * ctk_selection_data_copy: | |||
3220 | * @data: a pointer to a #CtkSelectionData-struct. | |||
3221 | * | |||
3222 | * Makes a copy of a #CtkSelectionData-struct and its data. | |||
3223 | * | |||
3224 | * Returns: a pointer to a copy of @data. | |||
3225 | **/ | |||
3226 | CtkSelectionData* | |||
3227 | ctk_selection_data_copy (const CtkSelectionData *data) | |||
3228 | { | |||
3229 | CtkSelectionData *new_data; | |||
3230 | ||||
3231 | g_return_val_if_fail (data != NULL, NULL)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "data != NULL"); return ( ((void*)0)); } } while (0); | |||
3232 | ||||
3233 | new_data = g_slice_new (CtkSelectionData)((CtkSelectionData*) g_slice_alloc (sizeof (CtkSelectionData) )); | |||
3234 | *new_data = *data; | |||
3235 | ||||
3236 | if (data->data) | |||
3237 | { | |||
3238 | new_data->data = g_malloc (data->length + 1); | |||
3239 | memcpy (new_data->data, data->data, data->length + 1); | |||
3240 | } | |||
3241 | ||||
3242 | return new_data; | |||
3243 | } | |||
3244 | ||||
3245 | /** | |||
3246 | * ctk_selection_data_free: | |||
3247 | * @data: a pointer to a #CtkSelectionData-struct. | |||
3248 | * | |||
3249 | * Frees a #CtkSelectionData-struct returned from | |||
3250 | * ctk_selection_data_copy(). | |||
3251 | **/ | |||
3252 | void | |||
3253 | ctk_selection_data_free (CtkSelectionData *data) | |||
3254 | { | |||
3255 | g_return_if_fail (data != NULL)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "data != NULL"); return; } } while (0); | |||
3256 | ||||
3257 | g_free (data->data); | |||
3258 | ||||
3259 | g_slice_free (CtkSelectionData, data)do { if (1) g_slice_free1 (sizeof (CtkSelectionData), (data)) ; else (void) ((CtkSelectionData*) 0 == (data)); } while (0); | |||
3260 | } | |||
3261 | ||||
3262 | /** | |||
3263 | * ctk_target_entry_new: | |||
3264 | * @target: String identifier for target | |||
3265 | * @flags: Set of flags, see #CtkTargetFlags | |||
3266 | * @info: an ID that will be passed back to the application | |||
3267 | * | |||
3268 | * Makes a new #CtkTargetEntry. | |||
3269 | * | |||
3270 | * Returns: a pointer to a new #CtkTargetEntry. | |||
3271 | * Free with ctk_target_entry_free() | |||
3272 | **/ | |||
3273 | CtkTargetEntry * | |||
3274 | ctk_target_entry_new (const char *target, | |||
3275 | guint flags, | |||
3276 | guint info) | |||
3277 | { | |||
3278 | CtkTargetEntry entry = { (char *) target, flags, info }; | |||
3279 | return ctk_target_entry_copy (&entry); | |||
3280 | } | |||
3281 | ||||
3282 | /** | |||
3283 | * ctk_target_entry_copy: | |||
3284 | * @data: a pointer to a #CtkTargetEntry | |||
3285 | * | |||
3286 | * Makes a copy of a #CtkTargetEntry and its data. | |||
3287 | * | |||
3288 | * Returns: a pointer to a copy of @data. | |||
3289 | * Free with ctk_target_entry_free() | |||
3290 | **/ | |||
3291 | CtkTargetEntry * | |||
3292 | ctk_target_entry_copy (CtkTargetEntry *data) | |||
3293 | { | |||
3294 | CtkTargetEntry *new_data; | |||
3295 | ||||
3296 | g_return_val_if_fail (data != NULL, NULL)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "data != NULL"); return ( ((void*)0)); } } while (0); | |||
3297 | ||||
3298 | new_data = g_slice_new (CtkTargetEntry)((CtkTargetEntry*) g_slice_alloc (sizeof (CtkTargetEntry))); | |||
3299 | new_data->target = g_strdup (data->target)g_strdup_inline (data->target); | |||
3300 | new_data->flags = data->flags; | |||
3301 | new_data->info = data->info; | |||
3302 | ||||
3303 | return new_data; | |||
3304 | } | |||
3305 | ||||
3306 | /** | |||
3307 | * ctk_target_entry_free: | |||
3308 | * @data: a pointer to a #CtkTargetEntry. | |||
3309 | * | |||
3310 | * Frees a #CtkTargetEntry returned from | |||
3311 | * ctk_target_entry_new() or ctk_target_entry_copy(). | |||
3312 | **/ | |||
3313 | void | |||
3314 | ctk_target_entry_free (CtkTargetEntry *data) | |||
3315 | { | |||
3316 | g_return_if_fail (data != NULL)do { if ((data != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "data != NULL"); return; } } while (0); | |||
3317 | ||||
3318 | g_free (data->target); | |||
3319 | ||||
3320 | g_slice_free (CtkTargetEntry, data)do { if (1) g_slice_free1 (sizeof (CtkTargetEntry), (data)); else (void) ((CtkTargetEntry*) 0 == (data)); } while (0); | |||
3321 | } | |||
3322 | ||||
3323 | ||||
3324 | G_DEFINE_BOXED_TYPE (CtkSelectionData, ctk_selection_data,static GType ctk_selection_data_get_type_once (void); GType ctk_selection_data_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_selection_data_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_selection_data_get_type_once (void) { GType (* _g_register_boxed) (const gchar *, union { CtkSelectionData * (*do_copy_type) (CtkSelectionData *); CtkSelectionData * (*do_const_copy_type) (const CtkSelectionData *); GBoxedCopyFunc do_copy_boxed; } __attribute__((__transparent_union__)), union { void (* do_free_type) (CtkSelectionData *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__)) ) = g_boxed_type_register_static ; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkSelectionData"), ctk_selection_data_copy, ctk_selection_data_free ); { {{};} } return g_define_type_id; } | |||
3325 | ctk_selection_data_copy,static GType ctk_selection_data_get_type_once (void); GType ctk_selection_data_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_selection_data_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_selection_data_get_type_once (void) { GType (* _g_register_boxed) (const gchar *, union { CtkSelectionData * (*do_copy_type) (CtkSelectionData *); CtkSelectionData * (*do_const_copy_type) (const CtkSelectionData *); GBoxedCopyFunc do_copy_boxed; } __attribute__((__transparent_union__)), union { void (* do_free_type) (CtkSelectionData *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__)) ) = g_boxed_type_register_static ; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkSelectionData"), ctk_selection_data_copy, ctk_selection_data_free ); { {{};} } return g_define_type_id; } | |||
3326 | ctk_selection_data_free)static GType ctk_selection_data_get_type_once (void); GType ctk_selection_data_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_selection_data_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_selection_data_get_type_once (void) { GType (* _g_register_boxed) (const gchar *, union { CtkSelectionData * (*do_copy_type) (CtkSelectionData *); CtkSelectionData * (*do_const_copy_type) (const CtkSelectionData *); GBoxedCopyFunc do_copy_boxed; } __attribute__((__transparent_union__)), union { void (* do_free_type) (CtkSelectionData *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__)) ) = g_boxed_type_register_static ; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkSelectionData"), ctk_selection_data_copy, ctk_selection_data_free ); { {{};} } return g_define_type_id; } | |||
3327 | ||||
3328 | G_DEFINE_BOXED_TYPE (CtkTargetList, ctk_target_list,static GType ctk_target_list_get_type_once (void); GType ctk_target_list_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_target_list_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_target_list_get_type_once (void ) { GType (* _g_register_boxed) (const gchar *, union { CtkTargetList * (*do_copy_type) (CtkTargetList *); CtkTargetList * (*do_const_copy_type ) (const CtkTargetList *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkTargetList *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkTargetList"), ctk_target_list_ref, ctk_target_list_unref); { {{};} } return g_define_type_id; } | |||
3329 | ctk_target_list_ref,static GType ctk_target_list_get_type_once (void); GType ctk_target_list_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_target_list_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_target_list_get_type_once (void ) { GType (* _g_register_boxed) (const gchar *, union { CtkTargetList * (*do_copy_type) (CtkTargetList *); CtkTargetList * (*do_const_copy_type ) (const CtkTargetList *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkTargetList *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkTargetList"), ctk_target_list_ref, ctk_target_list_unref); { {{};} } return g_define_type_id; } | |||
3330 | ctk_target_list_unref)static GType ctk_target_list_get_type_once (void); GType ctk_target_list_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_target_list_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_target_list_get_type_once (void ) { GType (* _g_register_boxed) (const gchar *, union { CtkTargetList * (*do_copy_type) (CtkTargetList *); CtkTargetList * (*do_const_copy_type ) (const CtkTargetList *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkTargetList *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkTargetList"), ctk_target_list_ref, ctk_target_list_unref); { {{};} } return g_define_type_id; } | |||
3331 | ||||
3332 | G_DEFINE_BOXED_TYPE (CtkTargetEntry, ctk_target_entry,static GType ctk_target_entry_get_type_once (void); GType ctk_target_entry_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_target_entry_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_target_entry_get_type_once ( void) { GType (* _g_register_boxed) (const gchar *, union { CtkTargetEntry * (*do_copy_type) (CtkTargetEntry *); CtkTargetEntry * (*do_const_copy_type ) (const CtkTargetEntry *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkTargetEntry *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkTargetEntry") , ctk_target_entry_copy, ctk_target_entry_free); { {{};} } return g_define_type_id; } | |||
3333 | ctk_target_entry_copy,static GType ctk_target_entry_get_type_once (void); GType ctk_target_entry_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_target_entry_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_target_entry_get_type_once ( void) { GType (* _g_register_boxed) (const gchar *, union { CtkTargetEntry * (*do_copy_type) (CtkTargetEntry *); CtkTargetEntry * (*do_const_copy_type ) (const CtkTargetEntry *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkTargetEntry *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkTargetEntry") , ctk_target_entry_copy, ctk_target_entry_free); { {{};} } return g_define_type_id; } | |||
3334 | ctk_target_entry_free)static GType ctk_target_entry_get_type_once (void); GType ctk_target_entry_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_target_entry_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_target_entry_get_type_once ( void) { GType (* _g_register_boxed) (const gchar *, union { CtkTargetEntry * (*do_copy_type) (CtkTargetEntry *); CtkTargetEntry * (*do_const_copy_type ) (const CtkTargetEntry *); GBoxedCopyFunc do_copy_boxed; } __attribute__ ((__transparent_union__)), union { void (* do_free_type) (CtkTargetEntry *); GBoxedFreeFunc do_free_boxed; } __attribute__((__transparent_union__ )) ) = g_boxed_type_register_static; GType g_define_type_id = _g_register_boxed (g_intern_static_string ("CtkTargetEntry") , ctk_target_entry_copy, ctk_target_entry_free); { {{};} } return g_define_type_id; } | |||
3335 | ||||
3336 | static int | |||
3337 | ctk_selection_bytes_per_item (gint format) | |||
3338 | { | |||
3339 | switch (format) | |||
3340 | { | |||
3341 | case 8: | |||
3342 | return sizeof (char); | |||
3343 | break; | |||
3344 | case 16: | |||
3345 | return sizeof (short); | |||
3346 | break; | |||
3347 | case 32: | |||
3348 | return sizeof (long); | |||
3349 | break; | |||
3350 | default: | |||
3351 | g_assert_not_reached()do { g_assertion_message_expr ("Ctk", "ctkselection.c", 3351, ((const char*) (__func__)), ((void*)0)); } while (0); | |||
3352 | } | |||
3353 | return 0; | |||
3354 | } |