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