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