| 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 | } |