aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.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_dnd.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_dnd.c')
-rw-r--r--libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.c689
1 files changed, 689 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.c b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.c
new file mode 100644
index 0000000..677de38
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_dnd.c
@@ -0,0 +1,689 @@
1#include "ecore_xcb_private.h"
2
3#ifndef MIN
4# define MIN(a, b) (((a) < (b)) ? (a) : (b))
5#endif
6
7/* local structures */
8typedef struct _Version_Cache_Item
9{
10 Ecore_X_Window win;
11 int ver;
12} Version_Cache_Item;
13
14/* local function prototypes */
15static Eina_Bool _ecore_xcb_dnd_converter_copy(char *target __UNUSED__,
16 void *data,
17 int size,
18 void **data_ret,
19 int *size_ret,
20 Ecore_X_Atom *tprop __UNUSED__,
21 int *count __UNUSED__);
22
23/* local variables */
24static int _ecore_xcb_dnd_init_count = 0;
25static Ecore_X_DND_Source *_source = NULL;
26static Ecore_X_DND_Target *_target = NULL;
27static Version_Cache_Item *_version_cache = NULL;
28static int _version_cache_num = 0, _version_cache_alloc = 0;
29static void (*_posupdatecb)(void *,
30 Ecore_X_Xdnd_Position *);
31static void *_posupdatedata;
32
33/* external variables */
34EAPI int ECORE_X_EVENT_XDND_ENTER = 0;
35EAPI int ECORE_X_EVENT_XDND_POSITION = 0;
36EAPI int ECORE_X_EVENT_XDND_STATUS = 0;
37EAPI int ECORE_X_EVENT_XDND_LEAVE = 0;
38EAPI int ECORE_X_EVENT_XDND_DROP = 0;
39EAPI int ECORE_X_EVENT_XDND_FINISHED = 0;
40
41void
42_ecore_xcb_dnd_init(void)
43{
44 LOGFN(__FILE__, __LINE__, __FUNCTION__);
45
46 if (!_ecore_xcb_dnd_init_count)
47 {
48 _source = calloc(1, sizeof(Ecore_X_DND_Source));
49 if (!_source) return;
50 _source->version = ECORE_X_DND_VERSION;
51 _source->win = XCB_NONE;
52 _source->dest = XCB_NONE;
53 _source->state = ECORE_X_DND_SOURCE_IDLE;
54 _source->prev.window = 0;
55
56 _target = calloc(1, sizeof(Ecore_X_DND_Target));
57 if (!_target)
58 {
59 free(_source);
60 _source = NULL;
61 return;
62 }
63 _target->win = XCB_NONE;
64 _target->source = XCB_NONE;
65 _target->state = ECORE_X_DND_TARGET_IDLE;
66
67 ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new();
68 ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new();
69 ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new();
70 ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new();
71 ECORE_X_EVENT_XDND_DROP = ecore_event_type_new();
72 ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new();
73 }
74 _ecore_xcb_dnd_init_count++;
75}
76
77void
78_ecore_xcb_dnd_shutdown(void)
79{
80 LOGFN(__FILE__, __LINE__, __FUNCTION__);
81
82 _ecore_xcb_dnd_init_count--;
83 if (_ecore_xcb_dnd_init_count > 0) return;
84 if (_source) free(_source);
85 _source = NULL;
86 if (_target) free(_target);
87 _target = NULL;
88 _ecore_xcb_dnd_init_count = 0;
89}
90
91EAPI void
92ecore_x_dnd_send_status(Eina_Bool will_accept,
93 Eina_Bool suppress,
94 Ecore_X_Rectangle rect,
95 Ecore_X_Atom action)
96{
97 xcb_client_message_event_t ev;
98
99 LOGFN(__FILE__, __LINE__, __FUNCTION__);
100 CHECK_XCB_CONN;
101
102 if (_target->state == ECORE_X_DND_TARGET_IDLE) return;
103
104 memset(&ev, 0, sizeof(xcb_client_message_event_t));
105
106 _target->will_accept = will_accept;
107
108 ev.response_type = XCB_CLIENT_MESSAGE;
109 ev.type = ECORE_X_ATOM_XDND_STATUS;
110 ev.format = 32;
111 ev.window = _target->source;
112 ev.data.data32[0] = _target->win;
113 ev.data.data32[1] = 0;
114 if (will_accept) ev.data.data32[1] |= 0x1UL;
115 if (!suppress) ev.data.data32[1] |= 0x2UL;
116
117 ev.data.data32[2] = rect.x;
118 ev.data.data32[2] <<= 16;
119 ev.data.data32[2] |= rect.y;
120 ev.data.data32[3] = rect.width;
121 ev.data.data32[3] <<= 16;
122 ev.data.data32[3] |= rect.height;
123
124 if (will_accept)
125 ev.data.data32[4] = action;
126 else
127 ev.data.data32[4] = XCB_NONE;
128 _target->accepted_action = action;
129
130 xcb_send_event(_ecore_xcb_conn, 0, _target->source,
131 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
132// ecore_x_flush();
133}
134
135EAPI Eina_Bool
136ecore_x_dnd_drop(void)
137{
138 xcb_client_message_event_t ev;
139 Eina_Bool status = EINA_FALSE;
140
141 LOGFN(__FILE__, __LINE__, __FUNCTION__);
142 CHECK_XCB_CONN;
143
144 memset(&ev, 0, sizeof(xcb_client_message_event_t));
145
146 if (_source->dest)
147 {
148 ev.response_type = XCB_CLIENT_MESSAGE;
149 ev.format = 32;
150 ev.window = _source->dest;
151
152 if (_source->will_accept)
153 {
154 ev.type = ECORE_X_ATOM_XDND_DROP;
155 ev.data.data32[0] = _source->win;
156 ev.data.data32[1] = 0;
157 ev.data.data32[2] = _source->time;
158
159 xcb_send_event(_ecore_xcb_conn, 0, _source->dest,
160 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
161// ecore_x_flush();
162 _source->state = ECORE_X_DND_SOURCE_DROPPED;
163 status = EINA_TRUE;
164 }
165 else
166 {
167 ev.type = ECORE_X_ATOM_XDND_LEAVE;
168 ev.data.data32[0] = _source->win;
169 ev.data.data32[1] = 0;
170
171 xcb_send_event(_ecore_xcb_conn, 0, _source->dest,
172 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
173// ecore_x_flush();
174 _source->state = ECORE_X_DND_SOURCE_IDLE;
175 }
176 }
177 else
178 {
179 ecore_x_selection_xdnd_clear();
180 _source->state = ECORE_X_DND_SOURCE_IDLE;
181 }
182
183 ecore_x_window_ignore_set(_source->win, 0);
184 _source->prev.window = 0;
185
186 return status;
187}
188
189EAPI void
190ecore_x_dnd_aware_set(Ecore_X_Window win,
191 Eina_Bool on)
192{
193 Ecore_X_Atom prop_data = ECORE_X_DND_VERSION;
194
195 LOGFN(__FILE__, __LINE__, __FUNCTION__);
196
197 if (on)
198 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_AWARE,
199 ECORE_X_ATOM_ATOM, 32, &prop_data, 1);
200 else
201 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE);
202}
203
204EAPI int
205ecore_x_dnd_version_get(Ecore_X_Window win)
206{
207 unsigned char *data;
208 int num = 0;
209 Version_Cache_Item *t;
210
211 LOGFN(__FILE__, __LINE__, __FUNCTION__);
212
213 if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
214 {
215 if (_version_cache)
216 {
217 int i = 0;
218
219 for (i = 0; i < _version_cache_num; i++)
220 {
221 if (_version_cache[i].win == win)
222 return _version_cache[i].ver;
223 }
224 }
225 }
226
227 if (ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_AWARE,
228 ECORE_X_ATOM_ATOM, 32, &data, &num))
229 {
230 int version = 0;
231
232 version = (int)*data;
233 free(data);
234 if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
235 {
236 _version_cache_num++;
237 if (_version_cache_num > _version_cache_alloc)
238 _version_cache_alloc += 16;
239 t = realloc(_version_cache,
240 _version_cache_alloc * sizeof(Version_Cache_Item));
241 if (!t) return 0;
242 _version_cache = t;
243 _version_cache[_version_cache_num - 1].win = win;
244 _version_cache[_version_cache_num - 1].ver = version;
245 }
246 return version;
247 }
248
249 if (_source->state == ECORE_X_DND_SOURCE_DRAGGING)
250 {
251 _version_cache_num++;
252 if (_version_cache_num > _version_cache_alloc)
253 _version_cache_alloc += 16;
254 t = realloc(_version_cache,
255 _version_cache_alloc * sizeof(Version_Cache_Item));
256 if (!t) return 0;
257 _version_cache = t;
258 _version_cache[_version_cache_num - 1].win = win;
259 _version_cache[_version_cache_num - 1].ver = 0;
260 }
261
262 return 0;
263}
264
265EAPI Eina_Bool
266ecore_x_dnd_type_isset(Ecore_X_Window win,
267 const char *type)
268{
269 int num = 0, i = 0;
270 Eina_Bool ret = EINA_FALSE;
271 unsigned char *data;
272 Ecore_X_Atom *atoms, atom;
273
274 LOGFN(__FILE__, __LINE__, __FUNCTION__);
275 CHECK_XCB_CONN;
276
277 if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST,
278 ECORE_X_ATOM_ATOM, 32, &data, &num))
279 return ret;
280
281 atom = ecore_x_atom_get(type);
282 atoms = (Ecore_X_Atom *)data;
283 for (i = 0; i < num; ++i)
284 {
285 if (atom == atoms[i])
286 {
287 ret = EINA_TRUE;
288 break;
289 }
290 }
291
292 free(data);
293 return ret;
294}
295
296EAPI void
297ecore_x_dnd_type_set(Ecore_X_Window win,
298 const char *type,
299 Eina_Bool on)
300{
301 Ecore_X_Atom atom, *oldset = NULL, *newset = NULL;
302 int i = 0, j = 0, num = 0;
303 unsigned char *data = NULL, *old_data = NULL;
304
305 LOGFN(__FILE__, __LINE__, __FUNCTION__);
306 CHECK_XCB_CONN;
307
308 atom = ecore_x_atom_get(type);
309 ecore_x_window_prop_property_get(win, ECORE_X_ATOM_XDND_TYPE_LIST,
310 ECORE_X_ATOM_ATOM, 32, &old_data, &num);
311 oldset = (Ecore_X_Atom *)old_data;
312 if (on)
313 {
314 if (ecore_x_dnd_type_isset(win, type))
315 {
316 free(old_data);
317 return;
318 }
319 newset = calloc(num + 1, sizeof(Ecore_X_Atom));
320 if (!newset) return;
321 data = (unsigned char *)newset;
322 for (i = 0; i < num; i++)
323 newset[i + 1] = oldset[i];
324 newset[0] = atom;
325 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
326 ECORE_X_ATOM_ATOM, 32, data, num + 1);
327 }
328 else
329 {
330 if (!ecore_x_dnd_type_isset(win, type))
331 {
332 free(old_data);
333 return;
334 }
335 newset = calloc(num - 1, sizeof(Ecore_X_Atom));
336 if (!newset)
337 {
338 free(old_data);
339 return;
340 }
341 data = (unsigned char *)newset;
342 for (i = 0; i < num; i++)
343 if (oldset[i] != atom)
344 newset[j++] = oldset[i];
345 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
346 ECORE_X_ATOM_ATOM, 32, data, num - 1);
347 }
348 free(oldset);
349 free(newset);
350}
351
352EAPI void
353ecore_x_dnd_types_set(Ecore_X_Window win,
354 const char **types,
355 unsigned int num_types)
356{
357 Ecore_X_Atom *newset = NULL;
358 unsigned int i;
359 unsigned char *data = NULL;
360
361 LOGFN(__FILE__, __LINE__, __FUNCTION__);
362 CHECK_XCB_CONN;
363
364 if (!num_types)
365 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_TYPE_LIST);
366 else
367 {
368 newset = calloc(num_types, sizeof(Ecore_X_Atom));
369 if (!newset) return;
370
371 data = (unsigned char *)newset;
372 for (i = 0; i < num_types; i++)
373 {
374 newset[i] = ecore_x_atom_get(types[i]);
375 ecore_x_selection_converter_atom_add(newset[i],
376 _ecore_xcb_dnd_converter_copy);
377 }
378 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_TYPE_LIST,
379 ECORE_X_ATOM_ATOM, 32, data,
380 num_types);
381 free(newset);
382 }
383}
384
385EAPI void
386ecore_x_dnd_actions_set(Ecore_X_Window win,
387 Ecore_X_Atom *actions,
388 unsigned int num_actions)
389{
390 unsigned int i;
391 unsigned char *data = NULL;
392
393 LOGFN(__FILE__, __LINE__, __FUNCTION__);
394 CHECK_XCB_CONN;
395
396 if (!num_actions)
397 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_ACTION_LIST);
398 else
399 {
400 data = (unsigned char *)actions;
401 for (i = 0; i < num_actions; i++)
402 ecore_x_selection_converter_atom_add(actions[i],
403 _ecore_xcb_dnd_converter_copy);
404 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_XDND_ACTION_LIST,
405 ECORE_X_ATOM_ATOM, 32, data,
406 num_actions);
407 }
408}
409
410/**
411 * The DND position update cb is called Ecore_X sends a DND position to a
412 * client.
413 *
414 * It essentially mirrors some of the data sent in the position message.
415 * Generally this cb should be set just before position update is called.
416 * Please note well you need to look after your own data pointer if someone
417 * trashes you position update cb set.
418 *
419 * It is considered good form to clear this when the dnd event finishes.
420 *
421 * @param cb Callback to updated each time ecore_x sends a position update.
422 * @param data User data.
423 */
424EAPI void
425ecore_x_dnd_callback_pos_update_set(void (*cb)(void *,
426 Ecore_X_Xdnd_Position *data),
427 const void *data)
428{
429 _posupdatecb = cb;
430 _posupdatedata = (void *)data;
431}
432
433EAPI Eina_Bool
434ecore_x_dnd_begin(Ecore_X_Window source,
435 unsigned char *data,
436 int size)
437{
438 LOGFN(__FILE__, __LINE__, __FUNCTION__);
439
440 if (!ecore_x_dnd_version_get(source)) return EINA_FALSE;
441
442 /* Take ownership of XdndSelection */
443 if (!ecore_x_selection_xdnd_set(source, data, size)) return EINA_FALSE;
444
445 if (_version_cache)
446 {
447 free(_version_cache);
448 _version_cache = NULL;
449 _version_cache_num = 0;
450 _version_cache_alloc = 0;
451 }
452
453 ecore_x_window_shadow_tree_flush();
454
455 _source->win = source;
456 ecore_x_window_ignore_set(_source->win, 1);
457 _source->state = ECORE_X_DND_SOURCE_DRAGGING;
458 _source->time = _ecore_xcb_events_last_time_get();
459 _source->prev.window = 0;
460
461 /* Default Accepted Action: move */
462 _source->action = ECORE_X_ATOM_XDND_ACTION_MOVE;
463 _source->accepted_action = XCB_NONE;
464 _source->dest = XCB_NONE;
465
466 return EINA_TRUE;
467}
468
469EAPI void
470ecore_x_dnd_send_finished(void)
471{
472 xcb_client_message_event_t ev;
473
474 LOGFN(__FILE__, __LINE__, __FUNCTION__);
475 CHECK_XCB_CONN;
476
477 if (_target->state == ECORE_X_DND_TARGET_IDLE) return;
478
479 memset(&ev, 0, sizeof(xcb_client_message_event_t));
480
481 ev.response_type = XCB_CLIENT_MESSAGE;
482 ev.format = 32;
483 ev.type = ECORE_X_ATOM_XDND_FINISHED;
484 ev.window = _target->source;
485 ev.data.data32[0] = _target->win;
486 ev.data.data32[1] = 0;
487 ev.data.data32[2] = 0;
488 if (_target->will_accept)
489 {
490 ev.data.data32[1] |= 0x1UL;
491 ev.data.data32[2] = _target->accepted_action;
492 }
493
494 xcb_send_event(_ecore_xcb_conn, 0, _target->source,
495 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
496// ecore_x_flush();
497 _target->state = ECORE_X_DND_TARGET_IDLE;
498}
499
500EAPI void
501ecore_x_dnd_source_action_set(Ecore_X_Atom action)
502{
503 LOGFN(__FILE__, __LINE__, __FUNCTION__);
504
505 _source->action = action;
506 if (_source->prev.window)
507 _ecore_xcb_dnd_drag(_source->prev.window,
508 _source->prev.x, _source->prev.y);
509}
510
511Ecore_X_DND_Source *
512_ecore_xcb_dnd_source_get(void)
513{
514 return _source;
515}
516
517Ecore_X_DND_Target *
518_ecore_xcb_dnd_target_get(void)
519{
520 return _target;
521}
522
523void
524_ecore_xcb_dnd_drag(Ecore_X_Window root,
525 int x,
526 int y)
527{
528 xcb_client_message_event_t ev;
529 Ecore_X_Window win, *skip;
530 Ecore_X_Xdnd_Position pos;
531 int num = 0;
532
533 if (_source->state != ECORE_X_DND_SOURCE_DRAGGING) return;
534
535 LOGFN(__FILE__, __LINE__, __FUNCTION__);
536 CHECK_XCB_CONN;
537
538 memset(&ev, 0, sizeof(xcb_client_message_event_t));
539
540 ev.response_type = XCB_CLIENT_MESSAGE;
541 ev.format = 32;
542
543 skip = ecore_x_window_ignore_list(&num);
544 win = ecore_x_window_shadow_tree_at_xy_with_skip_get(root, x, y, skip, num);
545 while ((win) && !(ecore_x_dnd_version_get(win)))
546 win = ecore_x_window_shadow_parent_get(root, win);
547
548 if ((_source->dest) && (win != _source->dest))
549 {
550 ev.window = _source->dest;
551 ev.type = ECORE_X_ATOM_XDND_LEAVE;
552 ev.data.data32[0] = _source->win;
553 ev.data.data32[1] = 0;
554
555 xcb_send_event(_ecore_xcb_conn, 0, _source->dest,
556 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
557// ecore_x_flush();
558 _source->suppress = 0;
559 }
560
561 if (win)
562 {
563 int x1, x2, y1, y2;
564
565 _source->version = MIN(ECORE_X_DND_VERSION,
566 ecore_x_dnd_version_get(win));
567 if (win != _source->dest)
568 {
569 int i = 0;
570 unsigned char *data;
571 Ecore_X_Atom *types;
572
573 ecore_x_window_prop_property_get(_source->win,
574 ECORE_X_ATOM_XDND_TYPE_LIST,
575 ECORE_X_ATOM_ATOM, 32,
576 &data, &num);
577 types = (Ecore_X_Atom *)data;
578 ev.window = win;
579 ev.type = ECORE_X_ATOM_XDND_ENTER;
580 ev.data.data32[0] = _source->win;
581 ev.data.data32[1] = 0;
582 if (num > 3)
583 ev.data.data32[1] |= 0x1UL;
584 else
585 ev.data.data32[1] &= 0xfffffffeUL;
586 ev.data.data32[1] |= ((unsigned long)_source->version) << 24;
587
588 for (i = 2; i < 5; i++)
589 ev.data.data32[i] = 0;
590 for (i = 0; i < MIN(num, 3); ++i)
591 ev.data.data32[i + 2] = types[i];
592 free(data);
593
594 xcb_send_event(_ecore_xcb_conn, 0, win,
595 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
596// ecore_x_flush();
597 _source->await_status = 0;
598 _source->will_accept = 0;
599 }
600
601 x1 = _source->rectangle.x;
602 x2 = _source->rectangle.x + _source->rectangle.width;
603 y1 = _source->rectangle.y;
604 y2 = _source->rectangle.y + _source->rectangle.height;
605
606 if ((!_source->await_status) || (!_source->suppress) ||
607 ((x < x1) || (x > x2) || (y < y1) || (y > y2)))
608 {
609 ev.window = win;
610 ev.type = ECORE_X_ATOM_XDND_POSITION;
611 ev.data.data32[0] = _source->win;
612 ev.data.data32[1] = 0;
613 ev.data.data32[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
614 ev.data.data32[3] = _source->time;
615 ev.data.data32[4] = _source->action;
616
617 xcb_send_event(_ecore_xcb_conn, 0, win,
618 XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
619// ecore_x_flush();
620 _source->await_status = 1;
621 }
622 }
623
624 if (_posupdatecb)
625 {
626 pos.position.x = x;
627 pos.position.y = y;
628 pos.win = win;
629 pos.prev = _source->dest;
630 _posupdatecb(_posupdatedata, &pos);
631 }
632
633 _source->prev.x = x;
634 _source->prev.y = y;
635 _source->prev.window = root;
636 _source->dest = win;
637}
638
639EAPI Ecore_X_Atom
640ecore_x_dnd_source_action_get(void)
641{
642 return _source->action;
643}
644
645/* local functions */
646static Eina_Bool
647_ecore_xcb_dnd_converter_copy(char *target __UNUSED__,
648 void *data,
649 int size,
650 void **data_ret,
651 int *size_ret,
652 Ecore_X_Atom *tprop __UNUSED__,
653 int *count __UNUSED__)
654{
655 Ecore_Xcb_Textproperty text_prop;
656 Ecore_Xcb_Encoding_Style style = XcbTextStyle;
657 char *mystr;
658
659 LOGFN(__FILE__, __LINE__, __FUNCTION__);
660
661 if ((!data) || (!size)) return EINA_FALSE;
662
663 mystr = calloc(1, size + 1);
664 if (!mystr) return EINA_FALSE;
665
666 memcpy(mystr, data, size);
667 if (_ecore_xcb_mb_textlist_to_textproperty(&mystr, 1, style, &text_prop))
668 {
669 int len;
670
671 len = strlen((char *)text_prop.value) + 1;
672 if (!(*data_ret = malloc(len)))
673 {
674 free(mystr);
675 return EINA_FALSE;
676 }
677 memcpy(*data_ret, text_prop.value, len);
678 *size_ret = len;
679 free(text_prop.value);
680 free(mystr);
681 return EINA_TRUE;
682 }
683 else
684 {
685 free(mystr);
686 return EINA_FALSE;
687 }
688}
689