3 #endif /* ifdef HAVE_CONFIG_H */
18 #include "ecore_private.h"
19 #include "ecore_x_private.h"
21 #include "Ecore_X_Atoms.h"
23 static Ecore_X_Selection_Intern selections[4];
24 static Ecore_X_Selection_Converter *converters = NULL;
25 static Ecore_X_Selection_Parser *parsers = NULL;
27 static int _ecore_x_selection_data_default_free(void *data);
28 static void *_ecore_x_selection_parser_files(const char *target,
32 static int _ecore_x_selection_data_files_free(void *data);
33 static void *_ecore_x_selection_parser_text(const char *target,
37 static void *_ecore_x_selection_parser_xmozurl(const char *target,
41 static int _ecore_x_selection_data_text_free(void *data);
42 static void *_ecore_x_selection_parser_targets(const char *target,
46 static int _ecore_x_selection_data_targets_free(void *data);
48 #define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
51 _ecore_x_selection_data_init(void)
53 /* Initialize global data */
54 memset(selections, 0, sizeof(selections));
56 /* Initialize converters */
57 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT,
58 ecore_x_selection_converter_text);
59 #ifdef X_HAVE_UTF8_STRING
60 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING,
61 ecore_x_selection_converter_text);
62 #endif /* ifdef X_HAVE_UTF8_STRING */
63 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT,
64 ecore_x_selection_converter_text);
65 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING,
66 ecore_x_selection_converter_text);
68 /* Initialize parsers */
69 ecore_x_selection_parser_add("text/plain",
70 _ecore_x_selection_parser_text);
71 ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING,
72 _ecore_x_selection_parser_text);
73 ecore_x_selection_parser_add("text/uri-list",
74 _ecore_x_selection_parser_files);
75 ecore_x_selection_parser_add("text/x-moz-url",
76 _ecore_x_selection_parser_xmozurl);
77 ecore_x_selection_parser_add("_NETSCAPE_URL",
78 _ecore_x_selection_parser_files);
79 ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS,
80 _ecore_x_selection_parser_targets);
84 _ecore_x_selection_shutdown(void)
86 Ecore_X_Selection_Converter *cnv;
87 Ecore_X_Selection_Parser *prs;
90 /* free the selection converters */
91 EINA_INLIST_FOREACH_SAFE(converters, inlist, cnv)
95 /* free the selection parsers */
96 EINA_INLIST_FOREACH_SAFE(parsers, inlist, prs)
104 Ecore_X_Selection_Intern *
105 _ecore_x_selection_get(Ecore_X_Atom selection)
107 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
108 return &selections[0];
109 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
110 return &selections[1];
111 else if (selection == ECORE_X_ATOM_SELECTION_XDND)
112 return &selections[2];
113 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
114 return &selections[3];
120 _ecore_x_selection_set(Window w,
123 Ecore_X_Atom selection)
126 unsigned char *buf = NULL;
128 XSetSelectionOwner(_ecore_x_disp, selection, w, _ecore_x_event_last_time);
129 if (XGetSelectionOwner(_ecore_x_disp, selection) != w)
132 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
134 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
136 else if (selection == ECORE_X_ATOM_SELECTION_XDND)
138 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
143 if (selections[in].data)
145 free(selections[in].data);
146 memset(&selections[in], 0, sizeof(Ecore_X_Selection_Intern));
151 selections[in].win = w;
152 selections[in].selection = selection;
153 selections[in].length = size;
154 selections[in].time = _ecore_x_event_last_time;
157 if (!buf) return EINA_FALSE;
158 memcpy(buf, data, size);
159 selections[in].data = buf;
166 * Claim ownership of the PRIMARY selection and set its data.
167 * @param w The window to which this selection belongs
168 * @param data The data associated with the selection
169 * @param size The size of the data buffer in bytes
170 * @return Returns 1 if the ownership of the selection was successfully
171 * claimed, or 0 if unsuccessful.
174 ecore_x_selection_primary_set(Ecore_X_Window w,
178 LOGFN(__FILE__, __LINE__, __FUNCTION__);
179 return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_PRIMARY);
183 * Release ownership of the primary selection
184 * @return Returns 1 if the selection was successfully cleared,
185 * or 0 if unsuccessful.
189 ecore_x_selection_primary_clear(void)
191 LOGFN(__FILE__, __LINE__, __FUNCTION__);
192 return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY);
196 * Claim ownership of the SECONDARY selection and set its data.
197 * @param w The window to which this selection belongs
198 * @param data The data associated with the selection
199 * @param size The size of the data buffer in bytes
200 * @return Returns 1 if the ownership of the selection was successfully
201 * claimed, or 0 if unsuccessful.
204 ecore_x_selection_secondary_set(Ecore_X_Window w,
208 LOGFN(__FILE__, __LINE__, __FUNCTION__);
209 return _ecore_x_selection_set(w,
212 ECORE_X_ATOM_SELECTION_SECONDARY);
216 * Release ownership of the secondary selection
217 * @return Returns 1 if the selection was successfully cleared,
218 * or 0 if unsuccessful.
222 ecore_x_selection_secondary_clear(void)
224 LOGFN(__FILE__, __LINE__, __FUNCTION__);
225 return _ecore_x_selection_set(None,
228 ECORE_X_ATOM_SELECTION_SECONDARY);
232 * Claim ownership of the XDND selection and set its data.
233 * @param w The window to which this selection belongs
234 * @param data The data associated with the selection
235 * @param size The size of the data buffer in bytes
236 * @return Returns 1 if the ownership of the selection was successfully
237 * claimed, or 0 if unsuccessful.
240 ecore_x_selection_xdnd_set(Ecore_X_Window w,
244 LOGFN(__FILE__, __LINE__, __FUNCTION__);
245 return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_XDND);
249 * Release ownership of the XDND selection
250 * @return Returns 1 if the selection was successfully cleared,
251 * or 0 if unsuccessful.
255 ecore_x_selection_xdnd_clear(void)
257 LOGFN(__FILE__, __LINE__, __FUNCTION__);
258 return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_XDND);
262 * Claim ownership of the CLIPBOARD selection and set its data.
263 * @param w The window to which this selection belongs
264 * @param data The data associated with the selection
265 * @param size The size of the data buffer in bytes
266 * @return Returns 1 if the ownership of the selection was successfully
267 * claimed, or 0 if unsuccessful.
269 * Get the converted data from a previous CLIPBOARD selection
270 * request. The buffer must be freed when done with.
273 ecore_x_selection_clipboard_set(Ecore_X_Window w,
277 LOGFN(__FILE__, __LINE__, __FUNCTION__);
278 return _ecore_x_selection_set(w,
281 ECORE_X_ATOM_SELECTION_CLIPBOARD);
285 * Release ownership of the clipboard selection
286 * @return Returns 1 if the selection was successfully cleared,
287 * or 0 if unsuccessful.
291 ecore_x_selection_clipboard_clear(void)
293 LOGFN(__FILE__, __LINE__, __FUNCTION__);
294 return _ecore_x_selection_set(None,
297 ECORE_X_ATOM_SELECTION_CLIPBOARD);
301 _ecore_x_selection_target_atom_get(const char *target)
303 Ecore_X_Atom x_target;
305 if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
306 x_target = ECORE_X_ATOM_TEXT;
307 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
308 x_target = ECORE_X_ATOM_COMPOUND_TEXT;
309 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
310 x_target = ECORE_X_ATOM_STRING;
311 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
312 x_target = ECORE_X_ATOM_UTF8_STRING;
313 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME))
314 x_target = ECORE_X_ATOM_FILE_NAME;
315 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_X_MOZ_URL))
316 x_target = ECORE_X_ATOM_X_MOZ_URL;
318 x_target = ecore_x_atom_get(target);
324 _ecore_x_selection_target_get(Ecore_X_Atom target)
326 /* FIXME: Should not return mem allocated with strdup or X mixed,
327 * one should use free to free, the other XFree */
328 if (target == ECORE_X_ATOM_FILE_NAME)
329 return strdup(ECORE_X_SELECTION_TARGET_FILENAME);
330 else if (target == ECORE_X_ATOM_STRING)
331 return strdup(ECORE_X_SELECTION_TARGET_STRING);
332 else if (target == ECORE_X_ATOM_UTF8_STRING)
333 return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING);
334 else if (target == ECORE_X_ATOM_TEXT)
335 return strdup(ECORE_X_SELECTION_TARGET_TEXT);
336 else if (target == ECORE_X_ATOM_X_MOZ_URL)
337 return strdup(ECORE_X_SELECTION_TARGET_X_MOZ_URL);
339 return XGetAtomName(_ecore_x_disp, target);
343 _ecore_x_selection_request(Ecore_X_Window w,
344 Ecore_X_Atom selection,
345 const char *target_str)
347 Ecore_X_Atom target, prop;
349 target = _ecore_x_selection_target_atom_get(target_str);
351 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
352 prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
353 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
354 prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
355 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
356 prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
360 XConvertSelection(_ecore_x_disp, selection, target, prop,
365 ecore_x_selection_primary_request(Ecore_X_Window w,
368 LOGFN(__FILE__, __LINE__, __FUNCTION__);
369 _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_PRIMARY, target);
373 ecore_x_selection_secondary_request(Ecore_X_Window w,
376 LOGFN(__FILE__, __LINE__, __FUNCTION__);
377 _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_SECONDARY, target);
381 ecore_x_selection_xdnd_request(Ecore_X_Window w,
385 Ecore_X_DND_Target *_target;
387 LOGFN(__FILE__, __LINE__, __FUNCTION__);
388 _target = _ecore_x_dnd_target_get();
389 atom = _ecore_x_selection_target_atom_get(target);
390 XConvertSelection(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, atom,
391 ECORE_X_ATOM_SELECTION_PROP_XDND, w,
393 if (_ecore_xlib_sync) ecore_x_sync();
397 ecore_x_selection_clipboard_request(Ecore_X_Window w,
400 LOGFN(__FILE__, __LINE__, __FUNCTION__);
401 _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_CLIPBOARD, target);
405 ecore_x_selection_converter_atom_add(Ecore_X_Atom target,
406 Eina_Bool (*func)(char *target,
414 Ecore_X_Selection_Converter *cnv;
416 LOGFN(__FILE__, __LINE__, __FUNCTION__);
418 EINA_INLIST_FOREACH(converters, cnv)
419 if (cnv->target == target)
425 cnv = calloc(1, sizeof(Ecore_X_Selection_Converter));
428 cnv->target = target;
430 converters = (Ecore_X_Selection_Converter *)eina_inlist_append
431 (EINA_INLIST_GET(converters), EINA_INLIST_GET(cnv));
435 ecore_x_selection_converter_add(char *target,
436 Eina_Bool (*func)(char *target,
444 Ecore_X_Atom x_target;
446 if (!func || !target)
449 LOGFN(__FILE__, __LINE__, __FUNCTION__);
450 x_target = _ecore_x_selection_target_atom_get(target);
452 ecore_x_selection_converter_atom_add(x_target, func);
456 ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
458 Ecore_X_Selection_Converter *cnv;
460 LOGFN(__FILE__, __LINE__, __FUNCTION__);
462 EINA_INLIST_FOREACH(converters, cnv)
464 if (cnv->target == target)
466 converters = (Ecore_X_Selection_Converter *)eina_inlist_remove
467 (EINA_INLIST_GET(converters), EINA_INLIST_GET(cnv));
475 ecore_x_selection_converter_del(char *target)
477 Ecore_X_Atom x_target;
482 LOGFN(__FILE__, __LINE__, __FUNCTION__);
483 x_target = _ecore_x_selection_target_atom_get(target);
484 ecore_x_selection_converter_atom_del(x_target);
488 ecore_x_selection_notify_send(Ecore_X_Window requestor,
489 Ecore_X_Atom selection,
491 Ecore_X_Atom property,
495 XSelectionEvent xnotify;
497 LOGFN(__FILE__, __LINE__, __FUNCTION__);
498 xnotify.type = SelectionNotify;
499 xnotify.display = _ecore_x_disp;
500 xnotify.requestor = requestor;
501 xnotify.selection = selection;
502 xnotify.target = target;
503 xnotify.property = property;
505 xnotify.send_event = True;
508 xev.xselection = xnotify;
509 return (XSendEvent(_ecore_x_disp, requestor, False, 0, &xev) > 0) ? EINA_TRUE : EINA_FALSE;
512 /* Locate and run conversion callback for specified selection target */
514 ecore_x_selection_convert(Ecore_X_Atom selection,
518 Ecore_X_Atom *targtype,
521 Ecore_X_Selection_Intern *sel;
522 Ecore_X_Selection_Converter *cnv;
526 LOGFN(__FILE__, __LINE__, __FUNCTION__);
527 sel = _ecore_x_selection_get(selection);
528 tgt_str = _ecore_x_selection_target_get(target);
530 EINA_INLIST_FOREACH(converters, cnv)
532 if (cnv->target == target)
535 r = cnv->convert(tgt_str, sel->data, sel->length, &data, size,
540 if (data_ret) *data_ret = data;
549 /* ICCCM says "If the selection cannot be converted into a form based on the target (and parameters, if any), the owner should refuse the SelectionRequest as previously described." */
552 /* Default, just return the data
553 * data_ret = malloc(sel->length);
554 memcpy(*data_ret, sel->data, sel->length);
560 /* TODO: We need to work out a mechanism for automatic conversion to any requested
561 * locale using Ecore_Txt functions */
562 /* Converter for standard non-utf8 text targets */
564 ecore_x_selection_converter_text(char *target,
569 Ecore_X_Atom *targprop EINA_UNUSED,
572 XTextProperty text_prop;
574 XICCEncodingStyle style;
579 LOGFN(__FILE__, __LINE__, __FUNCTION__);
580 if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
582 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
583 style = XCompoundTextStyle;
584 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
585 style = XStringStyle;
587 #ifdef X_HAVE_UTF8_STRING
588 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
589 style = XUTF8StringStyle;
590 #endif /* ifdef X_HAVE_UTF8_STRING */
594 mystr = alloca(size + 1);
595 memcpy(mystr, data, size);
598 #ifdef X_HAVE_UTF8_STRING
599 if (Xutf8TextListToTextProperty(_ecore_x_disp, &mystr, 1, style,
600 &text_prop) == Success)
602 int bufsize = strlen((char *)text_prop.value);
603 char *str = malloc(bufsize + 1);
604 if (!str) return EINA_FALSE;
606 memcpy(str, text_prop.value, bufsize);
609 XFree(text_prop.value);
613 #else /* ifdef X_HAVE_UTF8_STRING */
614 if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style,
615 &text_prop) == Success)
617 int bufsize = strlen(text_prop.value);
618 *data_ret = malloc(bufsize);
619 if (!*data_ret) return EINA_FALSE;
620 memcpy(*data_ret, text_prop.value, bufsize);
622 XFree(text_prop.value);
626 #endif /* ifdef X_HAVE_UTF8_STRING */
634 ecore_x_selection_parser_add(const char *target,
635 void *(*func)(const char *target, void *data,
639 Ecore_X_Selection_Parser *prs;
644 LOGFN(__FILE__, __LINE__, __FUNCTION__);
646 EINA_INLIST_FOREACH(parsers, prs)
647 if (!strcmp(prs->target, target))
653 prs = calloc(1, sizeof(Ecore_X_Selection_Parser));
656 prs->target = strdup(target);
659 parsers = (Ecore_X_Selection_Parser *)eina_inlist_append
660 (EINA_INLIST_GET(parsers), EINA_INLIST_GET(prs));
664 ecore_x_selection_parser_del(const char *target)
666 Ecore_X_Selection_Parser *prs;
671 LOGFN(__FILE__, __LINE__, __FUNCTION__);
673 EINA_INLIST_FOREACH(parsers, prs)
675 if (!strcmp(prs->target, target))
677 parsers = (Ecore_X_Selection_Parser *)eina_inlist_remove
678 (EINA_INLIST_GET(parsers), EINA_INLIST_GET(prs));
687 * Change the owner and last-change time for the specified selection.
688 * @param win The owner of the specified atom.
689 * @param atom The selection atom
690 * @param tim Specifies the time
694 ecore_x_selection_owner_set(Ecore_X_Window win,
698 XSetSelectionOwner(_ecore_x_disp, atom, win, tim);
702 * Return the window that currently owns the specified selection.
704 * @param atom The specified selection atom.
706 * @return The window that currently owns the specified selection.
710 ecore_x_selection_owner_get(Ecore_X_Atom atom)
712 return XGetSelectionOwner(_ecore_x_disp, atom);
715 /* Locate and run conversion callback for specified selection target */
717 _ecore_x_selection_parse(const char *target,
722 Ecore_X_Selection_Parser *prs;
723 Ecore_X_Selection_Data *sel;
725 EINA_INLIST_FOREACH(parsers, prs)
727 if (!strcmp(prs->target, target))
729 sel = prs->parse(target, data, size, format);
734 /* Default, just return the data */
735 sel = calloc(1, sizeof(Ecore_X_Selection_Data));
736 if (!sel) return NULL;
737 sel->free = _ecore_x_selection_data_default_free;
739 sel->format = format;
745 _ecore_x_selection_data_default_free(void *data)
747 Ecore_X_Selection_Data *sel;
756 _ecore_x_selection_parser_files(const char *target,
759 int format EINA_UNUSED)
761 Ecore_X_Selection_Data_Files *sel;
764 if (strcmp(target, "text/uri-list") &&
765 strcmp(target, "_NETSCAPE_URL"))
768 sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files));
769 if (!sel) return NULL;
770 ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free;
772 if (data && (size > 0))
782 /* Isn't nul terminated */
784 t = realloc(data, size);
794 while ((is < size) && (data[is]))
796 if ((i == 0) && (data[is] == '#'))
797 for (; ((data[is]) && (data[is] != '\n')); is++) ;
800 if ((data[is] != '\r') &&
802 tmp[i++] = data[is++];
805 while ((data[is] == '\r') || (data[is] == '\n'))
809 t2 = realloc(sel->files, sel->num_files * sizeof(char *));
813 sel->files[sel->num_files - 1] = strdup(tmp);
824 t2 = realloc(sel->files, sel->num_files * sizeof(char *));
828 sel->files[sel->num_files - 1] = strdup(tmp);
837 ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES;
838 ECORE_X_SELECTION_DATA(sel)->length = sel->num_files;
840 return ECORE_X_SELECTION_DATA(sel);
844 _ecore_x_selection_data_files_free(void *data)
846 Ecore_X_Selection_Data_Files *sel;
852 for (i = 0; i < sel->num_files; i++)
862 _ecore_x_selection_parser_text(const char *target EINA_UNUSED,
865 int format EINA_UNUSED)
867 Ecore_X_Selection_Data_Text *sel;
868 unsigned char *data = _data;
871 sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
872 if (!sel) return NULL;
873 if (data && data[size - 1])
875 /* Isn't nul terminated */
877 t = realloc(data, size);
887 sel->text = (char *)data;
888 ECORE_X_SELECTION_DATA(sel)->length = size;
889 ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT;
890 ECORE_X_SELECTION_DATA(sel)->data = data;
891 ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free;
896 _ecore_x_selection_data_xmozurl_free(void *data)
898 Ecore_X_Selection_Data_X_Moz_Url *sel = data;
901 buf = eina_inarray_nth(sel->links, 0);
903 eina_inarray_free(sel->links);
904 eina_inarray_free(sel->link_names);
913 _ecore_x_selection_parser_xmozurl(const char *target EINA_UNUSED,
916 int format EINA_UNUSED)
918 Ecore_X_Selection_Data_X_Moz_Url *sel;
919 char *prev, *n, *buf, *data = _data;
923 buf = eina_str_convert_len("UTF-16LE", "UTF-8", data, size, &sz);
924 if (!buf) return NULL;
925 sel = calloc(1, sizeof(Ecore_X_Selection_Data_X_Moz_Url));
930 sel->links = eina_inarray_new(sizeof(char*), 0);
934 sel->link_names = eina_inarray_new(sizeof(char*), 0);
935 if (!sel->link_names)
936 goto error_link_names;
939 for (n = memchr(buf, '\n', sz); n; n = memchr(prev, '\n', sz - (prev - buf)))
943 eina_inarray_push(sel->links, &prev);
945 eina_inarray_push(sel->link_names, &prev);
949 eina_inarray_push(sel->link_names, &prev);
951 ECORE_X_SELECTION_DATA(sel)->length = size;
952 ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_X_MOZ_URL;
953 ECORE_X_SELECTION_DATA(sel)->data = (void*)data;
954 ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_xmozurl_free;
958 eina_inarray_free(sel->links);
969 _ecore_x_selection_data_text_free(void *data)
971 Ecore_X_Selection_Data_Text *sel;
980 _ecore_x_selection_parser_targets(const char *target EINA_UNUSED,
983 int format EINA_UNUSED)
985 Ecore_X_Selection_Data_Targets *sel;
989 sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets));
990 if (!sel) return NULL;
993 sel->num_targets = size - 2;
994 sel->targets = malloc((size - 2) * sizeof(char *));
1000 for (i = 2; i < size; i++)
1001 sel->targets[i - 2] = XGetAtomName(_ecore_x_disp, targets[i]);
1003 ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_targets_free;
1004 ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS;
1005 ECORE_X_SELECTION_DATA(sel)->length = size;
1006 ECORE_X_SELECTION_DATA(sel)->data = data;
1011 _ecore_x_selection_data_targets_free(void *data)
1013 Ecore_X_Selection_Data_Targets *sel;
1020 for (i = 0; i < sel->num_targets; i++)
1021 XFree(sel->targets[i]);
1025 free(ECORE_X_SELECTION_DATA(sel)->data);