3 #include "ecore_xcb_private.h"
4 #include "Ecore_X_Atoms.h"
6 static Ecore_X_Selection_Intern selections[4];
7 static Ecore_X_Selection_Converter *converters = NULL;
8 static Ecore_X_Selection_Parser *parsers = NULL;
10 static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *tprop, int *);
11 static int _ecore_x_selection_data_default_free(void *data);
12 static void * _ecore_x_selection_parser_files(const char *target, void *data, int size, int format);
13 static int _ecore_x_selection_data_files_free(void *data);
14 static void * _ecore_x_selection_parser_text(const char *target, void *data, int size, int format);
15 static int _ecore_x_selection_data_text_free(void *data);
16 static void * _ecore_x_selection_parser_targets(const char *target, void *data, int size, int format);
17 static int _ecore_x_selection_data_targets_free(void *data);
19 #define ECORE_X_SELECTION_DATA(x) ((Ecore_X_Selection_Data *)(x))
22 _ecore_x_selection_init(void)
24 /* Initialize global data */
25 memset(selections, 0, sizeof(selections));
27 /* Initialize converters */
28 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_TEXT,
29 _ecore_x_selection_converter_text);
30 #ifdef X_HAVE_UTF8_STRING
31 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_UTF8_STRING,
32 _ecore_x_selection_converter_text);
33 #endif /* ifdef X_HAVE_UTF8_STRING */
34 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_COMPOUND_TEXT,
35 _ecore_x_selection_converter_text);
36 ecore_x_selection_converter_atom_add(ECORE_X_ATOM_STRING,
37 _ecore_x_selection_converter_text);
39 /* Initialize parsers */
40 ecore_x_selection_parser_add("text/plain",
41 _ecore_x_selection_parser_text);
42 ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_UTF8_STRING,
43 _ecore_x_selection_parser_text);
44 ecore_x_selection_parser_add("text/uri-list",
45 _ecore_x_selection_parser_files);
46 ecore_x_selection_parser_add("_NETSCAPE_URL",
47 _ecore_x_selection_parser_files);
48 ecore_x_selection_parser_add(ECORE_X_SELECTION_TARGET_TARGETS,
49 _ecore_x_selection_parser_targets);
50 } /* _ecore_x_selection_init */
53 _ecore_x_selection_shutdown(void)
55 Ecore_X_Selection_Converter *cnv;
56 Ecore_X_Selection_Parser *prs;
58 /* free the selection converters */
62 Ecore_X_Selection_Converter *tmp;
70 /* free the selection parsers */
74 Ecore_X_Selection_Parser *tmp;
82 } /* _ecore_x_selection_shutdown */
84 Ecore_X_Selection_Intern *
85 _ecore_x_selection_get(Ecore_X_Atom selection)
87 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
88 return &selections[0];
89 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
90 return &selections[1];
91 else if (selection == ECORE_X_ATOM_SELECTION_XDND)
92 return &selections[2];
93 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
94 return &selections[3];
97 } /* _ecore_x_selection_get */
100 * Sends the GetSelectionOwner request.
103 _ecore_xcb_get_selection_owner_prefetch(Ecore_X_Atom selection)
105 xcb_get_selection_owner_cookie_t cookie;
107 cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, selection);
108 _ecore_xcb_cookie_cache(cookie.sequence);
109 } /* _ecore_xcb_get_selection_owner_prefetch */
112 * Gets the reply of the GetSelectionOwner request sent by _ecore_xcb_get_selection_owner_prefetch().
115 _ecore_xcb_get_selection_owner_fetch(void)
117 xcb_get_selection_owner_cookie_t cookie;
118 xcb_get_selection_owner_reply_t *reply;
120 cookie.sequence = _ecore_xcb_cookie_get();
121 reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
122 _ecore_xcb_reply_cache(reply);
123 } /* _ecore_xcb_get_selection_owner_fetch */
126 * To use this function, you must call before, and in order,
127 * _ecore_xcb_get_selection_owner_prefetch(), which sends the GetSelectionOwner request,
128 * then _ecore_xcb_get_selection_owner_fetch(), which gets the reply.
131 _ecore_x_selection_set(Ecore_X_Window window,
134 Ecore_X_Atom selection)
136 xcb_get_selection_owner_reply_t *reply;
137 unsigned char *buf = NULL;
140 xcb_set_selection_owner(_ecore_xcb_conn, window, selection, _ecore_xcb_event_last_time);
142 reply = _ecore_xcb_reply_get();
143 if (!reply || (reply->owner != window))
146 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
148 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
150 else if (selection == ECORE_X_ATOM_SELECTION_XDND)
152 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
159 selections[in].win = window;
160 selections[in].selection = selection;
161 selections[in].length = size;
162 selections[in].time = _ecore_xcb_event_last_time;
165 memcpy(buf, data, size);
166 selections[in].data = buf;
170 if (selections[in].data)
172 free(selections[in].data);
173 memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data));
178 } /* _ecore_x_selection_set */
181 * Sends the GetSelectionOwner request.
184 ecore_x_selection_primary_prefetch(void)
186 xcb_get_selection_owner_cookie_t cookie;
188 cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_PRIMARY);
189 _ecore_xcb_cookie_cache(cookie.sequence);
190 } /* ecore_x_selection_primary_prefetch */
193 * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_primary_prefetch().
196 ecore_x_selection_primary_fetch(void)
198 xcb_get_selection_owner_cookie_t cookie;
199 xcb_get_selection_owner_reply_t *reply;
201 cookie.sequence = _ecore_xcb_cookie_get();
202 reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
203 _ecore_xcb_reply_cache(reply);
204 } /* ecore_x_selection_primary_fetch */
207 * Claim ownership of the PRIMARY selection and set its data.
208 * @param window The window to which this selection belongs
209 * @param data The data associated with the selection
210 * @param size The size of the data buffer in bytes
211 * @return Returns 1 if the ownership of the selection was successfully
212 * claimed, or 0 if unsuccessful.
214 * To use this function, you must call before, and in order,
215 * ecore_x_selection_primary_prefetch(), which sends the GetSelectionOwner request,
216 * then ecore_x_selection_primary_fetch(), which gets the reply.
219 ecore_x_selection_primary_set(Ecore_X_Window window,
223 return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_PRIMARY);
224 } /* ecore_x_selection_primary_set */
227 * Release ownership of the primary selection
228 * @return Returns 1 if the selection was successfully cleared,
229 * or 0 if unsuccessful.
231 * To use this function, you must call before, and in order,
232 * ecore_x_selection_primary_prefetch(), which sends the GetSelectionOwner request,
233 * then ecore_x_selection_primary_fetch(), which gets the reply.
236 ecore_x_selection_primary_clear(void)
238 return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_PRIMARY);
239 } /* ecore_x_selection_primary_clear */
242 * Sends the GetSelectionOwner request.
245 ecore_x_selection_secondary_prefetch(void)
247 xcb_get_selection_owner_cookie_t cookie;
249 cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_SECONDARY);
250 _ecore_xcb_cookie_cache(cookie.sequence);
251 } /* ecore_x_selection_secondary_prefetch */
254 * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_secondary_prefetch().
257 ecore_x_selection_secondary_fetch(void)
259 xcb_get_selection_owner_cookie_t cookie;
260 xcb_get_selection_owner_reply_t *reply;
262 cookie.sequence = _ecore_xcb_cookie_get();
263 reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
264 _ecore_xcb_reply_cache(reply);
265 } /* ecore_x_selection_secondary_fetch */
268 * Claim ownership of the SECONDARY selection and set its data.
269 * @param window The window to which this selection belongs
270 * @param data The data associated with the selection
271 * @param size The size of the data buffer in bytes
272 * @return Returns 1 if the ownership of the selection was successfully
273 * claimed, or 0 if unsuccessful.
275 * To use this function, you must call before, and in order,
276 * ecore_x_selection_secondary_prefetch(), which sends the GetSelectionOwner request,
277 * then ecore_x_selection_secondary_fetch(), which gets the reply.
280 ecore_x_selection_secondary_set(Ecore_X_Window window,
284 return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_SECONDARY);
285 } /* ecore_x_selection_secondary_set */
288 * Release ownership of the secondary selection
289 * @return Returns 1 if the selection was successfully cleared,
290 * or 0 if unsuccessful.
292 * To use this function, you must call before, and in order,
293 * ecore_x_selection_secondary_prefetch(), which sends the GetSelectionOwner request,
294 * then ecore_x_selection_secondary_fetch(), which gets the reply.
297 ecore_x_selection_secondary_clear(void)
299 return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_SECONDARY);
300 } /* ecore_x_selection_secondary_clear */
303 * Sends the GetSelectionOwner request.
306 ecore_x_selection_xdnd_prefetch(void)
308 xcb_get_selection_owner_cookie_t cookie;
310 cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_XDND);
311 _ecore_xcb_cookie_cache(cookie.sequence);
312 } /* ecore_x_selection_xdnd_prefetch */
315 * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_xdnd_prefetch().
318 ecore_x_selection_xdnd_fetch(void)
320 xcb_get_selection_owner_cookie_t cookie;
321 xcb_get_selection_owner_reply_t *reply;
323 cookie.sequence = _ecore_xcb_cookie_get();
324 reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
325 _ecore_xcb_reply_cache(reply);
326 } /* ecore_x_selection_xdnd_fetch */
329 * Claim ownership of the XDND selection and set its data.
330 * @param window The window to which this selection belongs
331 * @param data The data associated with the selection
332 * @param size The size of the data buffer in bytes
333 * @return Returns 1 if the ownership of the selection was successfully
334 * claimed, or 0 if unsuccessful.
336 * To use this function, you must call before, and in order,
337 * ecore_x_selection_xdnd_prefetch(), which sends the GetSelectionOwner request,
338 * then ecore_x_selection_xdnd_fetch(), which gets the reply.
341 ecore_x_selection_xdnd_set(Ecore_X_Window window,
345 return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_XDND);
346 } /* ecore_x_selection_xdnd_set */
349 * Release ownership of the XDND selection
350 * @return Returns 1 if the selection was successfully cleared,
351 * or 0 if unsuccessful.
353 * To use this function, you must call before, and in order,
354 * ecore_x_selection_xdnd_prefetch(), which sends the GetSelectionOwner request,
355 * then ecore_x_selection_xdnd_fetch(), which gets the reply.
358 ecore_x_selection_xdnd_clear(void)
360 return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_XDND);
361 } /* ecore_x_selection_xdnd_clear */
364 * Sends the GetSelectionOwner request.
367 ecore_x_selection_clipboard_prefetch(void)
369 xcb_get_selection_owner_cookie_t cookie;
371 cookie = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, ECORE_X_ATOM_SELECTION_CLIPBOARD);
372 _ecore_xcb_cookie_cache(cookie.sequence);
373 } /* ecore_x_selection_clipboard_prefetch */
376 * Gets the reply of the GetSelectionOwner request sent by ecore_x_selection_clipboard_prefetch().
379 ecore_x_selection_clipboard_fetch(void)
381 xcb_get_selection_owner_cookie_t cookie;
382 xcb_get_selection_owner_reply_t *reply;
384 cookie.sequence = _ecore_xcb_cookie_get();
385 reply = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie, NULL);
386 _ecore_xcb_reply_cache(reply);
387 } /* ecore_x_selection_clipboard_fetch */
390 * Claim ownership of the CLIPBOARD selection and set its data.
391 * @param window The window to which this selection belongs
392 * @param data The data associated with the selection
393 * @param size The size of the data buffer in bytes
394 * @return Returns 1 if the ownership of the selection was successfully
395 * claimed, or 0 if unsuccessful.
397 * Get the converted data from a previous CLIPBOARD selection
398 * request. The buffer must be freed when done with.
400 * To use this function, you must call before, and in order,
401 * ecore_x_selection_clipboard_prefetch(), which sends the GetSelectionOwner request,
402 * then ecore_x_selection_clipboard_fetch(), which gets the reply.
405 ecore_x_selection_clipboard_set(Ecore_X_Window window,
409 return _ecore_x_selection_set(window, data, size, ECORE_X_ATOM_SELECTION_CLIPBOARD);
410 } /* ecore_x_selection_clipboard_set */
413 * Release ownership of the clipboard selection
414 * @return Returns 1 if the selection was successfully cleared,
415 * or 0 if unsuccessful.
417 * To use this function, you must call before, and in order,
418 * ecore_x_selection_clipboard_prefetch(), which sends the GetSelectionOwner request,
419 * then ecore_x_selection_clipboard_fetch(), which gets the reply.
422 ecore_x_selection_clipboard_clear(void)
424 return _ecore_x_selection_set(XCB_NONE, NULL, 0, ECORE_X_ATOM_SELECTION_CLIPBOARD);
425 } /* ecore_x_selection_clipboard_clear */
427 /* FIXME: roundtrip if target is not handled in the tests */
429 _ecore_x_selection_target_atom_get(const char *target)
431 Ecore_X_Atom x_target = XCB_NONE;
433 if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT))
434 x_target = ECORE_X_ATOM_TEXT;
435 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT))
436 x_target = ECORE_X_ATOM_COMPOUND_TEXT;
437 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING))
438 x_target = ECORE_X_ATOM_STRING;
439 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING))
440 x_target = ECORE_X_ATOM_UTF8_STRING;
441 else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME))
442 x_target = ECORE_X_ATOM_FILE_NAME;
445 xcb_intern_atom_cookie_t cookie;
446 xcb_intern_atom_reply_t *reply;
448 cookie = xcb_intern_atom_unchecked(_ecore_xcb_conn, 0,
449 strlen(target), target);
450 reply = xcb_intern_atom_reply(_ecore_xcb_conn, cookie, NULL);
454 x_target = reply->atom;
459 } /* _ecore_x_selection_target_atom_get */
461 /* FIXME: roundtrip if target is not handled in the tests */
463 _ecore_x_selection_target_get(Ecore_X_Atom target)
465 if (target == ECORE_X_ATOM_FILE_NAME)
466 return strdup(ECORE_X_SELECTION_TARGET_FILENAME);
467 else if (target == ECORE_X_ATOM_STRING)
468 return strdup(ECORE_X_SELECTION_TARGET_STRING);
469 else if (target == ECORE_X_ATOM_UTF8_STRING)
470 return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING);
471 else if (target == ECORE_X_ATOM_TEXT)
472 return strdup(ECORE_X_SELECTION_TARGET_TEXT);
475 xcb_get_atom_name_cookie_t cookie;
476 xcb_get_atom_name_reply_t *reply;
479 cookie = xcb_get_atom_name_unchecked(_ecore_xcb_conn, target);
480 reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookie, NULL);
484 name = (char *)malloc(sizeof(char) * (reply->length + 1));
491 memcpy(name, xcb_get_atom_name_name(reply), reply->length);
492 name[reply->length] = '\0';
496 } /* _ecore_x_selection_target_get */
499 _ecore_x_selection_request(Ecore_X_Window window,
500 Ecore_X_Atom selection,
501 const char *target_str)
503 Ecore_X_Atom target, prop;
505 target = _ecore_x_selection_target_atom_get(target_str);
507 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
508 prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY;
509 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
510 prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY;
511 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
512 prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD;
516 xcb_convert_selection(_ecore_xcb_conn, window,
517 selection, target, prop,
519 } /* _ecore_x_selection_request */
522 ecore_x_selection_primary_request(Ecore_X_Window window,
525 _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_PRIMARY, target);
526 } /* ecore_x_selection_primary_request */
529 ecore_x_selection_secondary_request(Ecore_X_Window window,
532 _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_SECONDARY, target);
533 } /* ecore_x_selection_secondary_request */
536 ecore_x_selection_xdnd_request(Ecore_X_Window window,
540 Ecore_X_DND_Target *_target;
542 _target = _ecore_x_dnd_target_get();
543 atom = _ecore_x_selection_target_atom_get(target);
544 xcb_convert_selection(_ecore_xcb_conn, window,
545 ECORE_X_ATOM_SELECTION_XDND, atom,
546 ECORE_X_ATOM_SELECTION_PROP_XDND,
548 } /* ecore_x_selection_xdnd_request */
551 ecore_x_selection_clipboard_request(Ecore_X_Window window, const char *target)
553 _ecore_x_selection_request(window, ECORE_X_ATOM_SELECTION_CLIPBOARD, target);
554 } /* ecore_x_selection_clipboard_request */
557 ecore_x_selection_converter_atom_add(Ecore_X_Atom target,
558 int (*func)(char *target,
566 Ecore_X_Selection_Converter *cnv;
573 if (cnv->target == target)
585 cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter));
590 converters = calloc(1, sizeof(Ecore_X_Selection_Converter));
594 cnv->target = target;
596 } /* ecore_x_selection_converter_atom_add */
599 ecore_x_selection_converter_add(char *target,
600 int (*func)(char *target,
608 Ecore_X_Atom x_target;
610 if (!func || !target)
613 x_target = _ecore_x_selection_target_atom_get(target);
615 ecore_x_selection_converter_atom_add(x_target, func);
616 } /* ecore_x_selection_converter_add */
619 ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
621 Ecore_X_Selection_Converter *cnv, *prev_cnv;
628 if (cnv->target == target)
631 prev_cnv->next = cnv->next;
633 converters = cnv->next; /* This was the first converter */
643 } /* ecore_x_selection_converter_atom_del */
646 ecore_x_selection_converter_del(char *target)
648 Ecore_X_Atom x_target;
653 x_target = _ecore_x_selection_target_atom_get(target);
654 ecore_x_selection_converter_atom_del(x_target);
655 } /* ecore_x_selection_converter_del */
658 ecore_x_selection_notify_send(Ecore_X_Window requestor,
659 Ecore_X_Atom selection,
661 Ecore_X_Atom property,
664 xcb_selection_notify_event_t ev;
667 ev.requestor = requestor;
668 ev.selection = selection;
670 ev.property = property;
671 /* send_event is bit 7 (0x80) of response_type */
672 ev.response_type = 0x80;
674 xcb_send_event(_ecore_xcb_conn, 0,
675 requestor, 0, (const char *)&ev);
677 } /* ecore_x_selection_notify_send */
679 /* Locate and run conversion callback for specified selection target */
681 ecore_x_selection_convert(Ecore_X_Atom selection,
685 Ecore_X_Atom *targtype,
688 Ecore_X_Selection_Intern *sel;
689 Ecore_X_Selection_Converter *cnv;
693 sel = _ecore_x_selection_get(selection);
694 tgt_str = _ecore_x_selection_target_get(target);
696 for (cnv = converters; cnv; cnv = cnv->next)
698 if (cnv->target == target)
701 r = cnv->convert(tgt_str, sel->data, sel->length, &data, size, targtype, typesize);
713 /* Default, just return the data */
714 *data_ret = malloc(sel->length);
715 memcpy(*data_ret, sel->data, sel->length);
718 } /* ecore_x_selection_convert */
720 /* TODO: We need to work out a mechanism for automatic conversion to any requested
721 * locale using Ecore_Txt functions */
722 /* Converter for standard non-utf8 text targets */
724 _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret, Ecore_X_Atom *targprop, int *s)
726 /* FIXME: to do... */
728 /* XTextProperty text_prop; */
730 /* XICCEncodingStyle style; */
732 /* if (!data || !size) */
735 /* if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) */
736 /* style = XTextStyle; */
737 /* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) */
738 /* style = XCompoundTextStyle; */
739 /* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) */
740 /* style = XStringStyle; */
741 /* #ifdef X_HAVE_UTF8_STRING */
742 /* else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) */
743 /* style = XUTF8StringStyle; */
748 /* if (!(mystr = strdup(data))) */
751 /* #ifdef X_HAVE_UTF8_STRING */
752 /* if (Xutf8TextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) */
754 /* int bufsize = strlen((char *)text_prop.value) + 1; */
755 /* *data_ret = malloc(bufsize); */
756 /* memcpy(*data_ret, text_prop.value, bufsize); */
757 /* *size_ret = bufsize; */
758 /* XFree(text_prop.value); */
763 /* if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) */
765 /* int bufsize = strlen(text_prop.value) + 1; */
766 /* *data_ret = malloc(bufsize); */
767 /* memcpy(*data_ret, text_prop.value, bufsize); */
768 /* *size_ret = bufsize; */
769 /* XFree(text_prop.value); */
781 } /* _ecore_x_selection_converter_text */
784 ecore_x_selection_parser_add(const char *target,
785 void *(*func)(const char *target,
790 Ecore_X_Selection_Parser *prs;
800 if (!strcmp(prs->target, target))
809 prs->next = calloc(1, sizeof(Ecore_X_Selection_Parser));
814 parsers = calloc(1, sizeof(Ecore_X_Selection_Parser));
818 prs->target = strdup(target);
820 } /* ecore_x_selection_parser_add */
823 ecore_x_selection_parser_del(const char *target)
825 Ecore_X_Selection_Parser *prs, *prev_prs;
835 if (!strcmp(prs->target, target))
838 prev_prs->next = prs->next;
840 parsers = prs->next; /* This was the first parser */
851 } /* ecore_x_selection_parser_del */
853 /* Locate and run conversion callback for specified selection target */
855 _ecore_x_selection_parse(const char *target, void *data, int size, int format)
857 Ecore_X_Selection_Parser *prs;
858 Ecore_X_Selection_Data *sel;
860 for (prs = parsers; prs; prs = prs->next)
862 if (!strcmp(prs->target, target))
864 sel = prs->parse(target, data, size, format);
869 /* Default, just return the data */
870 sel = calloc(1, sizeof(Ecore_X_Selection_Data));
871 sel->free = _ecore_x_selection_data_default_free;
873 sel->format = format;
876 } /* _ecore_x_selection_parse */
879 _ecore_x_selection_data_default_free(void *data)
881 Ecore_X_Selection_Data *sel;
887 } /* _ecore_x_selection_data_default_free */
890 _ecore_x_selection_parser_files(const char *target, void *_data, int size, int format __UNUSED__)
892 Ecore_X_Selection_Data_Files *sel;
897 if (strcmp(target, "text/uri-list") &&
898 strcmp(target, "_NETSCAPE_URL"))
901 sel = calloc(1, sizeof(Ecore_X_Selection_Data_Files));
902 ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_files_free;
906 /* Isn't nul terminated */
908 data = realloc(data, size);
915 while ((is < size) && (data[is]))
917 if ((i == 0) && (data[is] == '#'))
919 for (; ((data[is]) && (data[is] != '\n')); is++) ;
923 if ((data[is] != '\r') &&
926 tmp[i++] = data[is++];
930 while ((data[is] == '\r') || (data[is] == '\n')) is++;
933 sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
934 sel->files[sel->num_files - 1] = strdup(tmp);
944 sel->files = realloc(sel->files, sel->num_files * sizeof(char *));
945 sel->files[sel->num_files - 1] = strdup(tmp);
951 ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_FILES;
952 ECORE_X_SELECTION_DATA(sel)->length = sel->num_files;
954 return ECORE_X_SELECTION_DATA(sel);
955 } /* _ecore_x_selection_parser_files */
958 _ecore_x_selection_data_files_free(void *data)
960 Ecore_X_Selection_Data_Files *sel;
966 for (i = 0; i < sel->num_files; i++)
973 } /* _ecore_x_selection_data_files_free */
976 _ecore_x_selection_parser_text(const char *target __UNUSED__,
979 int format __UNUSED__)
981 Ecore_X_Selection_Data_Text *sel;
984 sel = calloc(1, sizeof(Ecore_X_Selection_Data_Text));
988 /* Isn't nul terminated */
990 data = realloc(data, size);
994 sel->text = (char *)data;
995 ECORE_X_SELECTION_DATA(sel)->length = size;
996 ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TEXT;
997 ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_text_free;
999 } /* _ecore_x_selection_parser_text */
1002 _ecore_x_selection_data_text_free(void *data)
1004 Ecore_X_Selection_Data_Text *sel;
1010 } /* _ecore_x_selection_data_text_free */
1013 _ecore_x_selection_parser_targets(const char *target __UNUSED__,
1016 int format __UNUSED__)
1018 Ecore_X_Selection_Data_Targets *sel;
1020 xcb_get_atom_name_cookie_t *cookies;
1023 sel = calloc(1, sizeof(Ecore_X_Selection_Data_Targets));
1024 targets = (uint32_t *)data;
1026 sel->num_targets = size - 2;
1027 sel->targets = malloc((size - 2) * sizeof(char *));
1028 cookies = (xcb_get_atom_name_cookie_t *)malloc ((size - 2) * sizeof (xcb_get_atom_name_cookie_t));
1029 for (i = 0; i < size - 2; i++)
1030 cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, targets[i + 2]);
1032 /* FIXME: do we let the declaration of reply inside the loop ? */
1033 for (i = 0; i < size - 2; i++)
1035 xcb_get_atom_name_reply_t *reply;
1039 reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
1040 length = xcb_get_atom_name_name_length(reply);
1041 name = (char *)malloc (length + 1);
1042 memcpy(name, xcb_get_atom_name_name(reply), length);
1043 name[length] = '\0';
1044 sel->targets[i - 2] = name;
1049 ECORE_X_SELECTION_DATA(sel)->free = _ecore_x_selection_data_targets_free;
1050 ECORE_X_SELECTION_DATA(sel)->content = ECORE_X_SELECTION_CONTENT_TARGETS;
1051 ECORE_X_SELECTION_DATA(sel)->length = size;
1053 } /* _ecore_x_selection_parser_targets */
1056 _ecore_x_selection_data_targets_free(void *data)
1058 Ecore_X_Selection_Data_Targets *sel;
1065 for (i = 0; i < sel->num_targets; i++)
1066 free(sel->targets[i]);
1072 } /* _ecore_x_selection_data_targets_free */