Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_selection.c
1 #include "ecore_xcb_private.h"
2 //#include "Ecore_X_Atoms.h"
3
4 #define ECORE_XCB_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
5
6 /* local function prototypes */
7 static void *_ecore_xcb_selection_parser_text(const char *target __UNUSED__,
8                                               void       *data,
9                                               int         size,
10                                               int         format __UNUSED__);
11 static void *_ecore_xcb_selection_parser_files(const char *target,
12                                                void       *data,
13                                                int         size,
14                                                int         format __UNUSED__);
15 static void *_ecore_xcb_selection_parser_targets(const char *target __UNUSED__,
16                                                  void       *data,
17                                                  int         size,
18                                                  int         format __UNUSED__);
19
20 //static int _ecore_xcb_selection_data_free(void *data);
21 static int       _ecore_xcb_selection_data_text_free(void *data);
22 static int       _ecore_xcb_selection_data_targets_free(void *data);
23 static int       _ecore_xcb_selection_data_files_free(void *data);
24 static int       _ecore_xcb_selection_data_default_free(void *data);
25 static Eina_Bool _ecore_xcb_selection_set(Ecore_X_Window win,
26                                           const void    *data,
27                                           int            size,
28                                           Ecore_X_Atom   selection);
29 static void _ecore_xcb_selection_request(Ecore_X_Window win,
30                                          Ecore_X_Atom   selection,
31                                          const char    *target);
32 static Ecore_X_Atom _ecore_xcb_selection_target_atom_get(const char *target);
33
34 /* local variables */
35 static Ecore_X_Selection_Intern _selections[4];
36 static Ecore_X_Selection_Converter *_converters = NULL;
37 static Ecore_X_Selection_Parser *_parsers = NULL;
38
39 /* local functions */
40 void
41 _ecore_xcb_selection_init(void)
42 {
43    LOGFN(__FILE__, __LINE__, __FUNCTION__);
44
45    memset(_selections, 0, sizeof(_selections));
46
47    /* init converters */
48    ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT,
49                                         ecore_x_selection_converter_text);
50    ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING,
51                                         ecore_x_selection_converter_text);
52    ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT,
53                                         ecore_x_selection_converter_text);
54    ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING,
55                                         ecore_x_selection_converter_text);
56
57    /* init parsers */
58    ecore_x_selection_parser_add("text/plain",
59                                 _ecore_xcb_selection_parser_text);
60    ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING,
61                                 _ecore_xcb_selection_parser_text);
62    ecore_x_selection_parser_add("text/uri-list",
63                                 _ecore_xcb_selection_parser_files);
64    ecore_x_selection_parser_add("_NETSCAPE_URL",
65                                 _ecore_xcb_selection_parser_files);
66    ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS,
67                                 _ecore_xcb_selection_parser_targets);
68 }
69
70 void
71 _ecore_xcb_selection_shutdown(void)
72 {
73    Ecore_X_Selection_Converter *cnv;
74    Ecore_X_Selection_Parser *prs;
75
76    LOGFN(__FILE__, __LINE__, __FUNCTION__);
77
78    /* free selection converters */
79    cnv = _converters;
80    while (cnv)
81      {
82         Ecore_X_Selection_Converter *tmp;
83
84         tmp = cnv->next;
85         free(cnv);
86         cnv = tmp;
87      }
88    _converters = NULL;
89
90    /* free parsers */
91    prs = _parsers;
92    while (prs)
93      {
94         Ecore_X_Selection_Parser *tmp;
95
96         tmp = prs;
97         prs = prs->next;
98         free(tmp->target);
99         free(tmp);
100      }
101    _parsers = NULL;
102 }
103
104 /* public functions */
105 EAPI void
106 ecore_x_selection_converter_atom_add(Ecore_X_Atom                                          target,
107                                      Eina_Bool                                             (*func)(char *target,
108                                                                              void         *data,
109                                                                              int           size,
110                                                                              void        **data_ret,
111                                                                              int          *size_ret,
112                                                                              Ecore_X_Atom *type,
113                                                                              int          *size_type))
114 {
115    Ecore_X_Selection_Converter *cnv;
116
117    LOGFN(__FILE__, __LINE__, __FUNCTION__);
118
119    cnv = _converters;
120    if (_converters)
121      {
122         while (1)
123           {
124              if (cnv->target == target)
125                {
126                   cnv->convert = func;
127                   return;
128                }
129              if (cnv->next)
130                cnv = cnv->next;
131              else
132                break;
133           }
134         cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter));
135         if (!cnv->next) return;
136         cnv = cnv->next;
137      }
138    else
139      {
140         _converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
141         if (!_converters) return;
142         cnv = _converters;
143      }
144    cnv->target = target;
145    cnv->convert = func;
146 }
147
148 EAPI void
149 ecore_x_selection_converter_add(char                                                 *target,
150                                 Eina_Bool                                             (*func)(char *target,
151                                                                         void         *data,
152                                                                         int           size,
153                                                                         void        **date_ret,
154                                                                         int          *size_ret,
155                                                                         Ecore_X_Atom *atom_ret,
156                                                                         int          *ret))
157 {
158    Ecore_X_Atom atarget;
159
160    LOGFN(__FILE__, __LINE__, __FUNCTION__);
161
162    if ((!func) || (!target)) return;
163    atarget = _ecore_xcb_selection_target_atom_get(target);
164    ecore_x_selection_converter_atom_add(atarget, func);
165 }
166
167 EAPI void
168 ecore_x_selection_converter_del(char *target)
169 {
170    Ecore_X_Atom atarget;
171
172    LOGFN(__FILE__, __LINE__, __FUNCTION__);
173
174    if (!target) return;
175    atarget = _ecore_xcb_selection_target_atom_get(target);
176    ecore_x_selection_converter_atom_del(atarget);
177 }
178
179 EAPI void
180 ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
181 {
182    Ecore_X_Selection_Converter *conv, *pconv = NULL;
183
184    LOGFN(__FILE__, __LINE__, __FUNCTION__);
185
186    conv = _converters;
187    while (conv)
188      {
189         if (conv->target == target)
190           {
191              if (pconv)
192                pconv->next = conv->next;
193              else
194                _converters = conv->next;
195              free(conv);
196              return;
197           }
198         pconv = conv;
199         conv = conv->next;
200      }
201 }
202
203 EAPI void
204 ecore_x_selection_parser_add(const char *target,
205                              void *(*func)(const char *target, void *data, int size, int format))
206 {
207    Ecore_X_Selection_Parser *prs;
208
209    LOGFN(__FILE__, __LINE__, __FUNCTION__);
210
211    if (!target) return;
212    prs = _parsers;
213    if (prs)
214      {
215         while (prs->next)
216           {
217              if (!strcmp(prs->target, target))
218                {
219                   prs->parse = func;
220                   return;
221                }
222              prs = prs->next;
223           }
224         prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser));
225         prs = prs->next;
226      }
227    else
228      {
229         _parsers = calloc(1, sizeof(Ecore_X_Selection_Parser));
230         prs = _parsers;
231      }
232    prs->target = strdup(target);
233    prs->parse = func;
234 }
235
236 EAPI void
237 ecore_x_selection_parser_del(const char *target)
238 {
239    Ecore_X_Selection_Parser *prs, *pprs = NULL;
240
241    LOGFN(__FILE__, __LINE__, __FUNCTION__);
242
243    if (!target) return;
244
245    prs = _parsers;
246    while (prs)
247      {
248         if (!strcmp(prs->target, target))
249           {
250              if (pprs)
251                pprs->next = prs->next;
252              else
253                _parsers = prs->next;
254              free(prs->target);
255              free(prs);
256              return;
257           }
258         pprs = prs;
259         prs = prs->next;
260      }
261 }
262
263 /**
264  * Claim ownership of the PRIMARY selection and set its data.
265  * @param w    The window to which this selection belongs
266  * @param data The data associated with the selection
267  * @param size The size of the data buffer in bytes
268  * @return     Returns 1 if the ownership of the selection was successfully
269  *             claimed, or 0 if unsuccessful.
270  */
271 EAPI Eina_Bool
272 ecore_x_selection_primary_set(Ecore_X_Window win,
273                               const void    *data,
274                               int            size)
275 {
276    LOGFN(__FILE__, __LINE__, __FUNCTION__);
277
278    return _ecore_xcb_selection_set(win, data, size,
279                                    ECORE_X_ATOM_SELECTION_PRIMARY);
280 }
281
282 /**
283  * Release ownership of the primary selection
284  * @return     Returns 1 if the selection was successfully cleared,
285  *             or 0 if unsuccessful.
286  */
287 EAPI Eina_Bool
288 ecore_x_selection_primary_clear(void)
289 {
290    LOGFN(__FILE__, __LINE__, __FUNCTION__);
291
292    return _ecore_xcb_selection_set(XCB_NONE, NULL, 0,
293                                    ECORE_X_ATOM_SELECTION_PRIMARY);
294 }
295
296 EAPI void
297 ecore_x_selection_primary_request(Ecore_X_Window win,
298                                   const char    *target)
299 {
300    LOGFN(__FILE__, __LINE__, __FUNCTION__);
301
302    _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_PRIMARY, target);
303 }
304
305 /**
306  * Claim ownership of the SECONDARY selection and set its data.
307  * @param w    The window to which this selection belongs
308  * @param data The data associated with the selection
309  * @param size The size of the data buffer in bytes
310  * @return     Returns 1 if the ownership of the selection was successfully
311  *             claimed, or 0 if unsuccessful.
312  */
313 EAPI Eina_Bool
314 ecore_x_selection_secondary_set(Ecore_X_Window win,
315                                 const void    *data,
316                                 int            size)
317 {
318    LOGFN(__FILE__, __LINE__, __FUNCTION__);
319
320    return _ecore_xcb_selection_set(win, data, size,
321                                    ECORE_X_ATOM_SELECTION_SECONDARY);
322 }
323
324 /**
325  * Release ownership of the secondary selection
326  * @return     Returns 1 if the selection was successfully cleared,
327  *             or 0 if unsuccessful.
328  */
329 EAPI Eina_Bool
330 ecore_x_selection_secondary_clear(void)
331 {
332    LOGFN(__FILE__, __LINE__, __FUNCTION__);
333
334    return _ecore_xcb_selection_set(XCB_NONE, NULL, 0,
335                                    ECORE_X_ATOM_SELECTION_SECONDARY);
336 }
337
338 EAPI void
339 ecore_x_selection_secondary_request(Ecore_X_Window win,
340                                     const char    *target)
341 {
342    LOGFN(__FILE__, __LINE__, __FUNCTION__);
343
344    _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_SECONDARY, target);
345 }
346
347 /**
348  * Claim ownership of the XDND selection and set its data.
349  * @param w    The window to which this selection belongs
350  * @param data The data associated with the selection
351  * @param size The size of the data buffer in bytes
352  * @return     Returns 1 if the ownership of the selection was successfully
353  *             claimed, or 0 if unsuccessful.
354  */
355 EAPI Eina_Bool
356 ecore_x_selection_xdnd_set(Ecore_X_Window win,
357                            const void    *data,
358                            int            size)
359 {
360    LOGFN(__FILE__, __LINE__, __FUNCTION__);
361
362    return _ecore_xcb_selection_set(win, data, size,
363                                    ECORE_X_ATOM_SELECTION_XDND);
364 }
365
366 /**
367  * Release ownership of the XDND selection
368  * @return     Returns 1 if the selection was successfully cleared,
369  *             or 0 if unsuccessful.
370  */
371 EAPI Eina_Bool
372 ecore_x_selection_xdnd_clear(void)
373 {
374    LOGFN(__FILE__, __LINE__, __FUNCTION__);
375
376    return _ecore_xcb_selection_set(XCB_NONE, NULL, 0,
377                                    ECORE_X_ATOM_SELECTION_XDND);
378 }
379
380 EAPI void
381 ecore_x_selection_xdnd_request(Ecore_X_Window win,
382                                const char    *target)
383 {
384    Ecore_X_Atom atom;
385    Ecore_X_DND_Target *_target;
386
387    LOGFN(__FILE__, __LINE__, __FUNCTION__);
388    CHECK_XCB_CONN;
389
390    _target = _ecore_xcb_dnd_target_get();
391    atom = _ecore_xcb_selection_target_atom_get(target);
392
393    xcb_convert_selection(_ecore_xcb_conn, win, ECORE_X_ATOM_SELECTION_XDND,
394                          atom, ECORE_X_ATOM_SELECTION_PROP_XDND, _target->time);
395 }
396
397 /**
398  * Claim ownership of the CLIPBOARD selection and set its data.
399  * @param w    The window to which this selection belongs
400  * @param data The data associated with the selection
401  * @param size The size of the data buffer in bytes
402  * @return     Returns 1 if the ownership of the selection was successfully
403  *             claimed, or 0 if unsuccessful.
404  *
405  * Get the converted data from a previous CLIPBOARD selection
406  * request. The buffer must be freed when done with.
407  */
408 EAPI Eina_Bool
409 ecore_x_selection_clipboard_set(Ecore_X_Window win,
410                                 const void    *data,
411                                 int            size)
412 {
413    LOGFN(__FILE__, __LINE__, __FUNCTION__);
414
415    return _ecore_xcb_selection_set(win, data, size,
416                                    ECORE_X_ATOM_SELECTION_CLIPBOARD);
417 }
418
419 /**
420  * Release ownership of the clipboard selection
421  * @return     Returns 1 if the selection was successfully cleared,
422  *             or 0 if unsuccessful.
423  */
424 EAPI Eina_Bool
425 ecore_x_selection_clipboard_clear(void)
426 {
427    LOGFN(__FILE__, __LINE__, __FUNCTION__);
428
429    return _ecore_xcb_selection_set(XCB_NONE, NULL, 0,
430                                    ECORE_X_ATOM_SELECTION_CLIPBOARD);
431 }
432
433 EAPI void
434 ecore_x_selection_clipboard_request(Ecore_X_Window win,
435                                     const char    *target)
436 {
437    LOGFN(__FILE__, __LINE__, __FUNCTION__);
438
439    _ecore_xcb_selection_request(win, ECORE_X_ATOM_SELECTION_CLIPBOARD, target);
440 }
441
442 EAPI Eina_Bool
443 ecore_x_selection_convert(Ecore_X_Atom  selection,
444                           Ecore_X_Atom  target,
445                           void        **data_ret,
446                           int          *size,
447                           Ecore_X_Atom *targtype,
448                           int          *typesize)
449 {
450    Ecore_X_Selection_Intern *sel;
451    Ecore_X_Selection_Converter *cnv;
452    void *data;
453    char *tgt_str;
454
455    LOGFN(__FILE__, __LINE__, __FUNCTION__);
456
457    sel = _ecore_xcb_selection_get(selection);
458    tgt_str = _ecore_xcb_selection_target_get(target);
459
460    for (cnv = _converters; cnv; cnv = cnv->next)
461      {
462         if (cnv->target == target)
463           {
464              int r = 0;
465
466              r = cnv->convert(tgt_str, sel->data, sel->length, &data, size,
467                               targtype, typesize);
468              free(tgt_str);
469              if (r)
470                {
471                   if (data_ret) *data_ret = data;
472                   return r;
473                }
474              else
475                return EINA_FALSE;
476           }
477      }
478
479    return EINA_FALSE;
480 }
481
482 EAPI Eina_Bool
483 ecore_x_selection_notify_send(Ecore_X_Window requestor,
484                               Ecore_X_Atom   selection,
485                               Ecore_X_Atom   target,
486                               Ecore_X_Atom   property,
487                               Ecore_X_Time   tim)
488 {
489    xcb_selection_notify_event_t ev;
490
491    LOGFN(__FILE__, __LINE__, __FUNCTION__);
492    CHECK_XCB_CONN;
493
494    memset(&ev, 0, sizeof(xcb_selection_notify_event_t));
495
496    ev.response_type = XCB_SELECTION_NOTIFY;
497    ev.requestor = requestor;
498    ev.selection = selection;
499    ev.target = target;
500    ev.property = property;
501    ev.time = tim;
502
503    xcb_send_event(_ecore_xcb_conn, 0, requestor,
504                   XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
505 //   ecore_x_flush();
506
507    return EINA_TRUE;
508 }
509
510 EAPI void
511 ecore_x_selection_owner_set(Ecore_X_Window win,
512                             Ecore_X_Atom   atom,
513                             Ecore_X_Time   tim)
514 {
515    LOGFN(__FILE__, __LINE__, __FUNCTION__);
516    CHECK_XCB_CONN;
517
518    xcb_set_selection_owner(_ecore_xcb_conn, win, atom, tim);
519 }
520
521 EAPI Ecore_X_Window
522 ecore_x_selection_owner_get(Ecore_X_Atom atom)
523 {
524    xcb_get_selection_owner_cookie_t cookie;
525    xcb_get_selection_owner_reply_t *reply;
526    Ecore_X_Window ret;
527
528    LOGFN(__FILE__, __LINE__, __FUNCTION__);
529    CHECK_XCB_CONN;
530
531    cookie = xcb_get_selection_owner(_ecore_xcb_conn, atom);
532    reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
533    if (!reply) return 0;
534    ret = reply->owner;
535    free(reply);
536    return ret;
537 }
538
539 void *
540 _ecore_xcb_selection_parse(const char *target,
541                            void       *data,
542                            int         size,
543                            int         format)
544 {
545    Ecore_X_Selection_Parser *prs;
546    Ecore_X_Selection_Data *sel;
547
548    for (prs = _parsers; prs; prs = prs->next)
549      {
550         if (!strcmp(prs->target, target))
551           {
552              sel = prs->parse(target, data, size, format);
553              if (sel) return sel;
554           }
555      }
556
557    sel = calloc(1, sizeof(Ecore_X_Selection_Data));
558    if (!sel) return NULL;
559    sel->free = _ecore_xcb_selection_data_default_free;
560    sel->length = size;
561    sel->format = format;
562    sel->data = data;
563
564    return sel;
565 }
566
567 Ecore_X_Selection_Intern *
568 _ecore_xcb_selection_get(Ecore_X_Atom selection)
569 {
570    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
571      return &_selections[0];
572    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
573      return &_selections[1];
574    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
575      return &_selections[2];
576    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
577      return &_selections[3];
578    else
579      return NULL;
580 }
581
582 /* local functions */
583 static Eina_Bool
584 _ecore_xcb_selection_set(Ecore_X_Window win,
585                          const void    *data,
586                          int            size,
587                          Ecore_X_Atom   selection)
588 {
589    xcb_get_selection_owner_cookie_t cookie;
590    xcb_get_selection_owner_reply_t *reply;
591    int in = 0;
592
593    LOGFN(__FILE__, __LINE__, __FUNCTION__);
594    CHECK_XCB_CONN;
595
596    xcb_set_selection_owner(_ecore_xcb_conn, win, selection, XCB_CURRENT_TIME);
597
598    cookie = xcb_get_selection_owner(_ecore_xcb_conn, selection);
599    reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
600    if (!reply) return EINA_FALSE;
601
602    if (reply->owner != win)
603      {
604         free(reply);
605         return EINA_FALSE;
606      }
607    free(reply);
608
609    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
610      in = 0;
611    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
612      in = 1;
613    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
614      in = 2;
615    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
616      in = 3;
617    else
618      return EINA_FALSE;
619
620    if (data)
621      {
622         unsigned char *buff = NULL;
623
624         _selections[in].win = win;
625         _selections[in].selection = selection;
626         _selections[in].length = size;
627         _selections[in].time = _ecore_xcb_events_last_time_get();
628
629         buff = malloc(size);
630         if (!buff) return EINA_FALSE;
631         memcpy(buff, data, size);
632         _selections[in].data = buff;
633      }
634    else if (_selections[in].data)
635      {
636         free(_selections[in].data);
637         memset(&_selections[in], 0, sizeof(Ecore_X_Selection_Data));
638      }
639
640    return EINA_TRUE;
641 }
642
643 static void
644 _ecore_xcb_selection_request(Ecore_X_Window win,
645                              Ecore_X_Atom   selection,
646                              const char    *target)
647 {
648    Ecore_X_Atom atarget, prop;
649
650    LOGFN(__FILE__, __LINE__, __FUNCTION__);
651    CHECK_XCB_CONN;
652
653    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
654      prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
655    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
656      prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
657    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
658      prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
659    else
660      return;
661
662    atarget = _ecore_xcb_selection_target_atom_get(target);
663
664    xcb_convert_selection(_ecore_xcb_conn, win, selection, atarget, prop,
665                          XCB_CURRENT_TIME);
666 }
667
668 EAPI Eina_Bool
669 ecore_x_selection_converter_text(char         *target,
670                                  void         *data,
671                                  int           size,
672                                  void        **data_ret,
673                                  int          *size_ret,
674                                  Ecore_X_Atom *type __UNUSED__,
675                                  int          *size_type __UNUSED__)
676 {
677    Ecore_Xcb_Encoding_Style style;
678    Ecore_Xcb_Textproperty ret;
679    char *str;
680
681    LOGFN(__FILE__, __LINE__, __FUNCTION__);
682    CHECK_XCB_CONN;
683
684    if ((!data) || (!size)) return EINA_FALSE;
685
686    if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
687      style = XcbTextStyle;
688    else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
689      style = XcbCompoundTextStyle;
690    else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
691      style = XcbStringStyle;
692 #ifdef HAVE_ICONV
693    else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
694      style = XcbUTF8StringStyle;
695 #endif
696    else
697      return EINA_FALSE;
698
699    str = alloca(size + 1);
700    memcpy(str, data, size);
701    str[size] = '\0';
702
703 #ifdef HAVE_ICONV
704    if (_ecore_xcb_utf8_textlist_to_textproperty(&str, 1, style, &ret))
705      {
706         int size = 0;
707
708         size = (strlen((char *)ret.value) + 1);
709         *data_ret = malloc(size);
710         if (!*data_ret) return EINA_FALSE;
711         memcpy(*data_ret, ret.value, size);
712         *size_ret = size;
713         if (ret.value) free(ret.value);
714         return EINA_TRUE;
715      }
716 #else
717    if (_ecore_xcb_mb_textlist_to_textproperty(&str, 1, style, &ret))
718      {
719         int size = 0;
720
721         size = (strlen((char *)ret.value) + 1);
722         *data_ret = malloc(size);
723         if (!*data_ret) return EINA_FALSE;
724         memcpy(*data_ret, ret.value, size);
725         *size_ret = size;
726         if (ret.value) free(ret.value);
727         return EINA_TRUE;
728      }
729 #endif
730    else
731      return EINA_TRUE;
732 }
733
734 static void *
735 _ecore_xcb_selection_parser_text(const char *target __UNUSED__,
736                                  void       *data,
737                                  int         size,
738                                  int         format __UNUSED__)
739 {
740    Ecore_X_Selection_Data_Text *sel;
741    unsigned char *_data;
742    void *t;
743
744    LOGFN(__FILE__, __LINE__, __FUNCTION__);
745
746    if (!(_data = data)) return NULL;
747
748    sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
749    if (!sel) return NULL;
750
751    if (_data[size - 1])
752      {
753         size++;
754         t = realloc(_data, size);
755         if (!t)
756           {
757              free(sel);
758              return NULL;
759           }
760         _data = t;
761         _data[size - 1] = 0;
762      }
763    sel->text = (char *)_data;
764    ECORE_XCB_SELECTION_DATA(sel)->length = size;
765    ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT;
766    ECORE_XCB_SELECTION_DATA(sel)->data = _data;
767    ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_text_free;
768    return sel;
769 }
770
771 static void *
772 _ecore_xcb_selection_parser_files(const char *target,
773                                   void       *data,
774                                   int         size,
775                                   int         format __UNUSED__)
776 {
777    Ecore_X_Selection_Data_Files *sel;
778    char *_data, *tmp, *t, **t2;
779    int i = 0, is = 0;
780
781    LOGFN(__FILE__, __LINE__, __FUNCTION__);
782
783    if ((strcmp(target, "text/uri-list")) &&
784        (strcmp(target, "_NETSCAPE_URL"))) return NULL;
785
786    if (!(_data = data)) return NULL;
787
788    sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files));
789    if (!sel) return NULL;
790
791    ECORE_XCB_SELECTION_DATA(sel)->free = _ecore_xcb_selection_data_files_free;
792
793    if (_data[size - 1])
794      {
795         size++;
796         t = realloc(_data, size);
797         if (!t)
798           {
799              free(sel);
800              return NULL;
801           }
802         _data = t;
803         _data[size - 1] = 0;
804      }
805
806    tmp = malloc(size);
807    if (!tmp)
808      {
809         free(sel);
810         return NULL;
811      }
812
813    while ((is < size) && (_data[is]))
814      {
815         if ((i == 0) && (_data[is] == '#'))
816           {
817              for (; ((_data[is]) && (_data[is] != '\n')); is++) ;
818           }
819         else
820           {
821              if ((_data[is] != '\r') && (_data[is] != '\n'))
822                tmp[i++] = _data[is++];
823              else
824                {
825                   while ((_data[is] == '\r') || (_data[is] == '\n'))
826                     is++;
827                   tmp[i] = 0;
828                   sel->num_files++;
829                   t2 = realloc(sel->files, sel->num_files * sizeof(char *));
830                   if (t2)
831                     {
832                        sel->files = t2;
833                        sel->files[sel->num_files - 1] = strdup(tmp);
834                     }
835                   tmp[0] = 0;
836                   i = 0;
837                }
838           }
839      }
840    if (i > 0)
841      {
842         tmp[i] = 0;
843         sel->num_files++;
844         t2 = realloc(sel->files, sel->num_files * sizeof(char *));
845         if (t2)
846           {
847              sel->files = t2;
848              sel->files[sel->num_files - 1] = strdup(tmp);
849           }
850      }
851    if (tmp) free(tmp);
852    if (_data) free(_data);
853
854    ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES;
855    ECORE_XCB_SELECTION_DATA(sel)->length = sel->num_files;
856
857    return ECORE_XCB_SELECTION_DATA(sel);
858 }
859
860 static void *
861 _ecore_xcb_selection_parser_targets(const char *target __UNUSED__,
862                                     void       *data,
863                                     int         size,
864                                     int         format __UNUSED__)
865 {
866    Ecore_X_Selection_Data_Targets *sel;
867    unsigned long *targets;
868    int i = 0;
869
870    LOGFN(__FILE__, __LINE__, __FUNCTION__);
871    CHECK_XCB_CONN;
872
873    if (!(targets = (unsigned long *)data)) return NULL;
874
875    sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets));
876    if (!sel) return NULL;
877
878    sel->num_targets = (size - 2);
879    sel->targets = malloc((size - 2) * sizeof(char *));
880    if (!sel->targets)
881      {
882         free(sel);
883         return NULL;
884      }
885
886    for (i = 2; i < size; i++)
887      {
888         xcb_get_atom_name_cookie_t cookie;
889         xcb_get_atom_name_reply_t *reply;
890         char *name = NULL;
891         int len = 0;
892
893         cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i]);
894         reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL);
895         if (reply)
896           {
897              len = xcb_get_atom_name_name_length(reply);
898              name = (char *)malloc(sizeof(char) * (len + 1));
899              if (name)
900                {
901                   memcpy(name, xcb_get_atom_name_name(reply), len);
902                   name[len] = '\0';
903                   sel->targets[i - 2] = name;
904                }
905              free(reply);
906           }
907      }
908
909    ECORE_XCB_SELECTION_DATA(sel)->free =
910      _ecore_xcb_selection_data_targets_free;
911    ECORE_XCB_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS;
912    ECORE_XCB_SELECTION_DATA(sel)->length = size;
913    ECORE_XCB_SELECTION_DATA(sel)->data = data;
914
915    return sel;
916 }
917
918 /*
919    static int
920    _ecore_xcb_selection_data_free(void *data)
921    {
922    Ecore_X_Selection_Data *sel;
923
924    LOGFN(__FILE__, __LINE__, __FUNCTION__);
925
926    if (!(sel = data)) return 0;
927    if (sel->data) free(sel->data);
928    free(sel);
929    return 1;
930    }
931  */
932
933 static int
934 _ecore_xcb_selection_data_text_free(void *data)
935 {
936    Ecore_X_Selection_Data_Text *sel;
937
938    LOGFN(__FILE__, __LINE__, __FUNCTION__);
939
940    if (!(sel = data)) return 0;
941    if (sel->text) free(sel->text);
942    free(sel);
943    return 1;
944 }
945
946 static int
947 _ecore_xcb_selection_data_targets_free(void *data)
948 {
949    Ecore_X_Selection_Data_Targets *sel;
950
951    LOGFN(__FILE__, __LINE__, __FUNCTION__);
952
953    if (!(sel = data)) return 0;
954    if (sel->targets) free(sel->targets);
955    free(ECORE_XCB_SELECTION_DATA(sel)->data);
956    free(sel);
957    return 1;
958 }
959
960 static int
961 _ecore_xcb_selection_data_files_free(void *data)
962 {
963    Ecore_X_Selection_Data_Files *sel;
964
965    LOGFN(__FILE__, __LINE__, __FUNCTION__);
966
967    if (!(sel = data)) return 0;
968    if (sel->files)
969      {
970         int i = 0;
971
972         for (i = 0; i < sel->num_files; i++)
973           if (sel->files[i]) free(sel->files[i]);
974         if (sel->files) free(sel->files);
975      }
976    free(sel);
977    return 0;
978 }
979
980 static int
981 _ecore_xcb_selection_data_default_free(void *data)
982 {
983    Ecore_X_Selection_Data *sel;
984
985    if (!(sel = data)) return 1;
986    free(sel->data);
987    free(sel);
988    return 1;
989 }
990
991 static Ecore_X_Atom
992 _ecore_xcb_selection_target_atom_get(const char *target)
993 {
994    Ecore_X_Atom x_target;
995
996    if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
997      x_target = ECORE_X_ATOM_TEXT;
998    else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
999      x_target = ECORE_X_ATOM_COMPOUND_TEXT;
1000    else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
1001      x_target = ECORE_X_ATOM_STRING;
1002    else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
1003      x_target = ECORE_X_ATOM_UTF8_STRING;
1004    else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME))
1005      x_target = ECORE_X_ATOM_FILE_NAME;
1006    else
1007      x_target = ecore_x_atom_get(target);
1008
1009    return x_target;
1010 }
1011
1012 char *
1013 _ecore_xcb_selection_target_get(Ecore_X_Atom target)
1014 {
1015    if (target == ECORE_X_ATOM_FILE_NAME)
1016      return strdup(ECORE_X_SELECTION_TARGET_FILENAME);
1017    else if (target == ECORE_X_ATOM_STRING)
1018      return strdup(ECORE_X_SELECTION_TARGET_STRING);
1019    else if (target == ECORE_X_ATOM_UTF8_STRING)
1020      return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING);
1021    else if (target == ECORE_X_ATOM_TEXT)
1022      return strdup(ECORE_X_SELECTION_TARGET_TEXT);
1023    else
1024      return ecore_x_atom_name_get(target);
1025 }
1026