summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/elm_cnp.c765
1 files changed, 723 insertions, 42 deletions
diff --git a/src/lib/elm_cnp.c b/src/lib/elm_cnp.c
index 0424e31aa..ffc90e6cd 100644
--- a/src/lib/elm_cnp.c
+++ b/src/lib/elm_cnp.c
@@ -249,6 +249,22 @@ static Eina_Bool _x11_elm_selection_selection_has_owner (Evas_Object *obj EINA_
249 249
250#endif 250#endif
251 251
252#ifdef HAVE_ELEMENTARY_WAYLAND
253typedef struct _Wl_Cnp_Selection Wl_Cnp_Selection;
254
255typedef Eina_Bool (*Wl_Converter_Fn_Cb) (char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret);
256static Eina_Bool _wl_targets_converter (char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret);
257static Eina_Bool _wl_general_converter (char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret);
258static Eina_Bool _wl_text_converter (char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret);
259
260typedef Eina_Bool (*Wl_Notify_Handler_Cb) (Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev);
261static Eina_Bool _wl_notify_handler_targets(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev);
262static Eina_Bool _wl_notify_handler_uri(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev);
263static Eina_Bool _wl_vcard_receive(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev);
264static Eina_Bool _wl_notify_handler_image(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev);
265static Eina_Bool _wl_notify_handler_text(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev);
266#endif
267
252struct _Cnp_Atom 268struct _Cnp_Atom
253{ 269{
254 const char *name; 270 const char *name;
@@ -260,6 +276,10 @@ struct _Cnp_Atom
260 /* Atom */ 276 /* Atom */
261 Ecore_X_Atom x_atom; 277 Ecore_X_Atom x_atom;
262#endif 278#endif
279#ifdef HAVE_ELEMENTARY_WAYLAND
280 Wl_Converter_Fn_Cb wl_converter;
281 Wl_Notify_Handler_Cb wl_notify;
282#endif
263 void *_term; 283 void *_term;
264}; 284};
265 285
@@ -438,6 +458,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
438#ifdef HAVE_ELEMENTARY_X 458#ifdef HAVE_ELEMENTARY_X
439 .x_converter = _x11_targets_converter, 459 .x_converter = _x11_targets_converter,
440#endif 460#endif
461#ifdef HAVE_ELEMENTARY_WAYLAND
462 .wl_converter = _wl_targets_converter,
463 .wl_notify = _wl_notify_handler_targets,
464#endif
441 }, 465 },
442 ARRAYINIT(CNP_ATOM_ATOM) { 466 ARRAYINIT(CNP_ATOM_ATOM) {
443 .name = "ATOM", // for opera browser 467 .name = "ATOM", // for opera browser
@@ -445,6 +469,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
445#ifdef HAVE_ELEMENTARY_X 469#ifdef HAVE_ELEMENTARY_X
446 .x_converter = _x11_targets_converter, 470 .x_converter = _x11_targets_converter,
447#endif 471#endif
472#ifdef HAVE_ELEMENTARY_WAYLAND
473 .wl_converter = _wl_targets_converter,
474 .wl_notify = _wl_notify_handler_targets,
475#endif
448 }, 476 },
449 ARRAYINIT(CNP_ATOM_XELM) { 477 ARRAYINIT(CNP_ATOM_XELM) {
450 .name = "application/x-elementary-markup", 478 .name = "application/x-elementary-markup",
@@ -452,6 +480,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
452#ifdef HAVE_ELEMENTARY_X 480#ifdef HAVE_ELEMENTARY_X
453 .x_converter = _x11_general_converter, 481 .x_converter = _x11_general_converter,
454#endif 482#endif
483#ifdef HAVE_ELEMENTARY_WAYLAND
484 .wl_converter = _wl_general_converter,
485#endif
455 }, 486 },
456 ARRAYINIT(CNP_ATOM_text_urilist) { 487 ARRAYINIT(CNP_ATOM_text_urilist) {
457 .name = "text/uri-list", 488 .name = "text/uri-list",
@@ -460,6 +491,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
460 .x_converter = _x11_general_converter, 491 .x_converter = _x11_general_converter,
461 .x_data_preparer = _x11_data_preparer_uri, 492 .x_data_preparer = _x11_data_preparer_uri,
462#endif 493#endif
494#ifdef HAVE_ELEMENTARY_WAYLAND
495 .wl_converter = _wl_general_converter,
496 .wl_notify = _wl_notify_handler_uri,
497#endif
463 }, 498 },
464 ARRAYINIT(CNP_ATOM_text_x_vcard) { 499 ARRAYINIT(CNP_ATOM_text_x_vcard) {
465 .name = "text/x-vcard", 500 .name = "text/x-vcard",
@@ -468,6 +503,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
468 .x_converter = _x11_vcard_send, 503 .x_converter = _x11_vcard_send,
469 .x_data_preparer = _x11_data_preparer_vcard, 504 .x_data_preparer = _x11_data_preparer_vcard,
470#endif 505#endif
506#ifdef HAVE_ELEMENTARY_WAYLAND
507 .wl_notify = _wl_vcard_receive,
508#endif
471 }, 509 },
472 ARRAYINIT(CNP_ATOM_image_png) { 510 ARRAYINIT(CNP_ATOM_image_png) {
473 .name = "image/png", 511 .name = "image/png",
@@ -476,6 +514,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
476 .x_converter = _x11_image_converter, 514 .x_converter = _x11_image_converter,
477 .x_data_preparer = _x11_data_preparer_image, 515 .x_data_preparer = _x11_data_preparer_image,
478#endif 516#endif
517#ifdef HAVE_ELEMENTARY_WAYLAND
518 .wl_notify = _wl_notify_handler_image,
519#endif
479 }, 520 },
480 ARRAYINIT(CNP_ATOM_image_jpeg) { 521 ARRAYINIT(CNP_ATOM_image_jpeg) {
481 .name = "image/jpeg", 522 .name = "image/jpeg",
@@ -484,6 +525,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
484 .x_converter = _x11_image_converter, 525 .x_converter = _x11_image_converter,
485 .x_data_preparer = _x11_data_preparer_image, 526 .x_data_preparer = _x11_data_preparer_image,
486#endif 527#endif
528#ifdef HAVE_ELEMENTARY_WAYLAND
529 .wl_notify = _wl_notify_handler_image,
530#endif
487 }, 531 },
488 ARRAYINIT(CNP_ATOM_image_bmp) { 532 ARRAYINIT(CNP_ATOM_image_bmp) {
489 .name = "image/x-ms-bmp", 533 .name = "image/x-ms-bmp",
@@ -492,6 +536,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
492 .x_converter = _x11_image_converter, 536 .x_converter = _x11_image_converter,
493 .x_data_preparer = _x11_data_preparer_image, 537 .x_data_preparer = _x11_data_preparer_image,
494#endif 538#endif
539#ifdef HAVE_ELEMENTARY_WAYLAND
540 .wl_notify = _wl_notify_handler_image,
541#endif
495 }, 542 },
496 ARRAYINIT(CNP_ATOM_image_gif) { 543 ARRAYINIT(CNP_ATOM_image_gif) {
497 .name = "image/gif", 544 .name = "image/gif",
@@ -500,6 +547,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
500 .x_converter = _x11_image_converter, 547 .x_converter = _x11_image_converter,
501 .x_data_preparer = _x11_data_preparer_image, 548 .x_data_preparer = _x11_data_preparer_image,
502#endif 549#endif
550#ifdef HAVE_ELEMENTARY_WAYLAND
551 .wl_notify = _wl_notify_handler_image,
552#endif
503 }, 553 },
504 ARRAYINIT(CNP_ATOM_image_tiff) { 554 ARRAYINIT(CNP_ATOM_image_tiff) {
505 .name = "image/tiff", 555 .name = "image/tiff",
@@ -508,6 +558,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
508 .x_converter = _x11_image_converter, 558 .x_converter = _x11_image_converter,
509 .x_data_preparer = _x11_data_preparer_image, 559 .x_data_preparer = _x11_data_preparer_image,
510#endif 560#endif
561#ifdef HAVE_ELEMENTARY_WAYLAND
562 .wl_notify = _wl_notify_handler_image,
563#endif
511 }, 564 },
512 ARRAYINIT(CNP_ATOM_image_svg) { 565 ARRAYINIT(CNP_ATOM_image_svg) {
513 .name = "image/svg+xml", 566 .name = "image/svg+xml",
@@ -516,6 +569,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
516 .x_converter = _x11_image_converter, 569 .x_converter = _x11_image_converter,
517 .x_data_preparer = _x11_data_preparer_image, 570 .x_data_preparer = _x11_data_preparer_image,
518#endif 571#endif
572#ifdef HAVE_ELEMENTARY_WAYLAND
573 .wl_notify = _wl_notify_handler_image,
574#endif
519 }, 575 },
520 ARRAYINIT(CNP_ATOM_image_xpm) { 576 ARRAYINIT(CNP_ATOM_image_xpm) {
521 .name = "image/x-xpixmap", 577 .name = "image/x-xpixmap",
@@ -524,6 +580,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
524 .x_converter = _x11_image_converter, 580 .x_converter = _x11_image_converter,
525 .x_data_preparer = _x11_data_preparer_image, 581 .x_data_preparer = _x11_data_preparer_image,
526#endif 582#endif
583#ifdef HAVE_ELEMENTARY_WAYLAND
584 .wl_notify = _wl_notify_handler_image,
585#endif
527 }, 586 },
528 ARRAYINIT(CNP_ATOM_image_tga) { 587 ARRAYINIT(CNP_ATOM_image_tga) {
529 .name = "image/x-tga", 588 .name = "image/x-tga",
@@ -532,6 +591,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
532 .x_converter = _x11_image_converter, 591 .x_converter = _x11_image_converter,
533 .x_data_preparer = _x11_data_preparer_image, 592 .x_data_preparer = _x11_data_preparer_image,
534#endif 593#endif
594#ifdef HAVE_ELEMENTARY_WAYLAND
595 .wl_notify = _wl_notify_handler_image,
596#endif
535 }, 597 },
536 ARRAYINIT(CNP_ATOM_image_ppm) { 598 ARRAYINIT(CNP_ATOM_image_ppm) {
537 .name = "image/x-portable-pixmap", 599 .name = "image/x-portable-pixmap",
@@ -540,6 +602,9 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
540 .x_converter = _x11_image_converter, 602 .x_converter = _x11_image_converter,
541 .x_data_preparer = _x11_data_preparer_image, 603 .x_data_preparer = _x11_data_preparer_image,
542#endif 604#endif
605#ifdef HAVE_ELEMENTARY_WAYLAND
606 .wl_notify = _wl_notify_handler_image,
607#endif
543 }, 608 },
544/* 609/*
545 ARRAYINIT(CNP_ATOM_text_html_utf8) { 610 ARRAYINIT(CNP_ATOM_text_html_utf8) {
@@ -566,6 +631,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
566 .x_converter = _x11_text_converter, 631 .x_converter = _x11_text_converter,
567 .x_data_preparer = _x11_data_preparer_text, 632 .x_data_preparer = _x11_data_preparer_text,
568#endif 633#endif
634#ifdef HAVE_ELEMENTARY_WAYLAND
635 .wl_converter = _wl_text_converter,
636 .wl_notify = _wl_notify_handler_text,
637#endif
569 }, 638 },
570 ARRAYINIT(CNP_ATOM_STRING) { 639 ARRAYINIT(CNP_ATOM_STRING) {
571 .name = "STRING", 640 .name = "STRING",
@@ -574,6 +643,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
574 .x_converter = _x11_text_converter, 643 .x_converter = _x11_text_converter,
575 .x_data_preparer = _x11_data_preparer_text, 644 .x_data_preparer = _x11_data_preparer_text,
576#endif 645#endif
646#ifdef HAVE_ELEMENTARY_WAYLAND
647 .wl_converter = _wl_text_converter,
648 .wl_notify = _wl_notify_handler_text,
649#endif
577 }, 650 },
578 ARRAYINIT(CNP_ATOM_COMPOUND_TEXT) { 651 ARRAYINIT(CNP_ATOM_COMPOUND_TEXT) {
579 .name = "COMPOUND_TEXT", 652 .name = "COMPOUND_TEXT",
@@ -582,6 +655,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
582 .x_converter = _x11_text_converter, 655 .x_converter = _x11_text_converter,
583 .x_data_preparer = _x11_data_preparer_text, 656 .x_data_preparer = _x11_data_preparer_text,
584#endif 657#endif
658#ifdef HAVE_ELEMENTARY_WAYLAND
659 .wl_converter = _wl_text_converter,
660 .wl_notify = _wl_notify_handler_text,
661#endif
585 }, 662 },
586 ARRAYINIT(CNP_ATOM_TEXT) { 663 ARRAYINIT(CNP_ATOM_TEXT) {
587 .name = "TEXT", 664 .name = "TEXT",
@@ -590,6 +667,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
590 .x_converter = _x11_text_converter, 667 .x_converter = _x11_text_converter,
591 .x_data_preparer = _x11_data_preparer_text, 668 .x_data_preparer = _x11_data_preparer_text,
592#endif 669#endif
670#ifdef HAVE_ELEMENTARY_WAYLAND
671 .wl_converter = _wl_text_converter,
672 .wl_notify = _wl_notify_handler_text,
673#endif
593 }, 674 },
594 ARRAYINIT(CNP_ATOM_text_plain_utf8) { 675 ARRAYINIT(CNP_ATOM_text_plain_utf8) {
595 .name = "text/plain;charset=utf-8", 676 .name = "text/plain;charset=utf-8",
@@ -598,6 +679,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
598 .x_converter = _x11_text_converter, 679 .x_converter = _x11_text_converter,
599 .x_data_preparer = _x11_data_preparer_text, 680 .x_data_preparer = _x11_data_preparer_text,
600#endif 681#endif
682#ifdef HAVE_ELEMENTARY_WAYLAND
683 .wl_converter = _wl_text_converter,
684 .wl_notify = _wl_notify_handler_text,
685#endif
601 }, 686 },
602 ARRAYINIT(CNP_ATOM_text_plain) { 687 ARRAYINIT(CNP_ATOM_text_plain) {
603 .name = "text/plain", 688 .name = "text/plain",
@@ -606,6 +691,10 @@ static Cnp_Atom _atoms[CNP_N_ATOMS] = {
606 .x_converter = _x11_text_converter, 691 .x_converter = _x11_text_converter,
607 .x_data_preparer = _x11_data_preparer_text, 692 .x_data_preparer = _x11_data_preparer_text,
608#endif 693#endif
694#ifdef HAVE_ELEMENTARY_WAYLAND
695 .wl_converter = _wl_text_converter,
696 .wl_notify = _wl_notify_handler_text,
697#endif
609 }, 698 },
610}; 699};
611 700
@@ -2284,8 +2373,6 @@ _x11_elm_selection_selection_has_owner(Evas_Object *obj EINA_UNUSED)
2284#endif 2373#endif
2285 2374
2286#ifdef HAVE_ELEMENTARY_WAYLAND 2375#ifdef HAVE_ELEMENTARY_WAYLAND
2287typedef struct _Wl_Cnp_Selection Wl_Cnp_Selection;
2288
2289struct _Wl_Cnp_Selection 2376struct _Wl_Cnp_Selection
2290{ 2377{
2291 char *selbuf; 2378 char *selbuf;
@@ -2307,6 +2394,7 @@ struct _Wl_Cnp_Selection
2307 Elm_Xdnd_Action action; 2394 Elm_Xdnd_Action action;
2308 2395
2309 Eina_Bool active : 1; 2396 Eina_Bool active : 1;
2397 Eina_Bool requestfinished : 1;
2310}; 2398};
2311 2399
2312static Eina_Bool _wl_elm_cnp_init(void); 2400static Eina_Bool _wl_elm_cnp_init(void);
@@ -2344,7 +2432,7 @@ static Eina_Bool _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void
2344static Eina_Bool _wl_dnd_send(void *data, int type EINA_UNUSED, void *event); 2432static Eina_Bool _wl_dnd_send(void *data, int type EINA_UNUSED, void *event);
2345static Eina_Bool _wl_dnd_receive(void *data, int type EINA_UNUSED, void *event); 2433static Eina_Bool _wl_dnd_receive(void *data, int type EINA_UNUSED, void *event);
2346static Eina_Bool _wl_dnd_end(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED); 2434static Eina_Bool _wl_dnd_end(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
2347static void _wl_dropable_data_handle(Wl_Cnp_Selection *sel, char *data); 2435static void _wl_dropable_data_handle(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev);
2348 2436
2349static Dropable *_wl_dropable_find(unsigned int win); 2437static Dropable *_wl_dropable_find(unsigned int win);
2350static void _wl_dropable_handle(Dropable *drop, Evas_Coord x, Evas_Coord y); 2438static void _wl_dropable_handle(Dropable *drop, Evas_Coord x, Evas_Coord y);
@@ -2353,6 +2441,599 @@ static Eina_Bool _wl_drops_accept(const char *type);
2353static unsigned int _wl_elm_widget_window_get(const Evas_Object *obj); 2441static unsigned int _wl_elm_widget_window_get(const Evas_Object *obj);
2354static Evas * _wl_evas_get_from_win(unsigned int win); 2442static Evas * _wl_evas_get_from_win(unsigned int win);
2355 2443
2444static Eina_Bool
2445_wl_is_uri_type_data(const void *data, int len)
2446{
2447 char *p;
2448 if (len < 6) return EINA_FALSE;
2449
2450 p = (char *)data;
2451 if (!p) return EINA_FALSE;
2452 if (strncmp(p, "file:/", 6))
2453 {
2454 if (*p != '/') return EINA_FALSE;
2455 }
2456 return EINA_TRUE;
2457}
2458
2459static Eina_Bool
2460_wl_targets_converter(char *target, Wl_Cnp_Selection *sel EINA_UNUSED, void *data EINA_UNUSED, int size EINA_UNUSED, void **data_ret, int *size_ret)
2461{
2462 cnp_debug("in\n");
2463 if (!data_ret) return EINA_FALSE;
2464
2465 const char *sep = "\n";
2466 char *aret;
2467 int len = 0;
2468 int i = 0;
2469 Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE;
2470 Eina_Bool is_uri_data = EINA_TRUE;
2471
2472 if (sel->format)
2473 {
2474 formats = sel->format;
2475 is_uri_data = _wl_is_uri_type_data(sel->selbuf, sel->buflen);
2476 }
2477 else
2478 {
2479 Cnp_Atom *atom = eina_hash_find(_types_hash, target);
2480 if (atom)
2481 formats = atom->formats;
2482 }
2483 /* Only provide formats which selection owner can send */
2484 for (i = 0; i < CNP_N_ATOMS; i++)
2485 {
2486 if (formats & _atoms[i].formats)
2487 {
2488 if ((is_uri_data) || (!is_uri_data &&
2489 strcmp(_atoms[i].name, "text/uri-list")))
2490 len += strlen(_atoms[i].name) + strlen(sep);
2491 }
2492 }
2493 aret = calloc(1, len * sizeof(char));
2494 if (!aret) return EINA_FALSE;
2495 for (i = 0; i < CNP_N_ATOMS; i++)
2496 {
2497 if (formats & _atoms[i].formats)
2498 {
2499 if ((is_uri_data) || (!is_uri_data &&
2500 strcmp(_atoms[i].name, "text/uri-list")))
2501 {
2502 aret = strcat(aret, _atoms[i].name);
2503 aret = strcat(aret, sep);
2504 }
2505 }
2506 }
2507 *data_ret = aret;
2508 if (size_ret) *size_ret = len;
2509
2510 return EINA_TRUE;
2511}
2512
2513static Eina_Bool
2514_wl_general_converter(char *target, Wl_Cnp_Selection *sel EINA_UNUSED, void *data, int size, void **data_ret, int *size_ret)
2515{
2516 cnp_debug("in\n");
2517 Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE;
2518 Cnp_Atom *atom = NULL;
2519
2520 atom = eina_hash_find(_types_hash, target);
2521 if (atom)
2522 formats = atom->formats;
2523 if (formats == ELM_SEL_FORMAT_NONE)
2524 {
2525 if (data_ret)
2526 {
2527 *data_ret = malloc(size * sizeof(char) + 1);
2528 if (!*data_ret) return EINA_FALSE;
2529 memcpy(*data_ret, data, size);
2530 ((char**)(data_ret))[0][size] = 0;
2531 }
2532 if (size_ret) *size_ret = size;
2533 }
2534 else
2535 {
2536 if (data)
2537 {
2538 if (data_ret) *data_ret = strdup(data);
2539 if (size_ret) *size_ret = strlen(data);
2540 }
2541 else
2542 {
2543 if (data_ret) *data_ret = NULL;
2544 if (size_ret) *size_ret = 0;
2545 }
2546 }
2547
2548 return EINA_TRUE;
2549}
2550
2551static Eina_Bool
2552_wl_text_converter(char *target, Wl_Cnp_Selection *sel, void *data, int size, void **data_ret, int *size_ret)
2553{
2554 cnp_debug("in\n");
2555 Elm_Sel_Format formats = ELM_SEL_FORMAT_NONE;
2556 Cnp_Atom *atom = NULL;
2557
2558 atom = eina_hash_find(_types_hash, target);
2559 if (atom)
2560 formats = atom->formats;
2561 if (formats == ELM_SEL_FORMAT_NONE)
2562 {
2563 if (data_ret)
2564 {
2565 *data_ret = malloc(size * sizeof(char) + 1);
2566 if (!*data_ret) return EINA_FALSE;
2567 memcpy(*data_ret, data, size);
2568 ((char**)(data_ret))[0][size] = 0;
2569 if (size_ret) *size_ret = size;
2570 return EINA_TRUE;
2571 }
2572 }
2573 else if ((formats & ELM_SEL_FORMAT_MARKUP) ||
2574 (formats & ELM_SEL_FORMAT_HTML))
2575 {
2576 *data_ret = _elm_util_mkup_to_text(data);
2577 if (size_ret && *data_ret) *size_ret = strlen(*data_ret);
2578 }
2579 else if (formats & ELM_SEL_FORMAT_TEXT)
2580 {
2581 *data_ret = strdup(data);
2582 if (size_ret && *data_ret) *size_ret = strlen(*data_ret);
2583 }
2584 else if (formats & ELM_SEL_FORMAT_IMAGE)
2585 {
2586 cnp_debug("Image %s\n", evas_object_type_get(sel->widget));
2587 evas_object_image_file_get(elm_photocam_internal_image_get(sel->widget),
2588 (const char **)data_ret, NULL);
2589 if (!data_ret) *data_ret = strdup("No file");
2590 else *data_ret = strdup(*data_ret);
2591
2592 if (!*data_ret)
2593 {
2594 ERR("Failed to allocate memory!");
2595 *size_ret = 0;
2596 return EINA_FALSE;
2597 }
2598 if (size_ret) *size_ret = strlen(*data_ret);
2599 }
2600 return EINA_TRUE;
2601}
2602
2603static void
2604_wl_selection_parser(void *_data,
2605 int size,
2606 char ***ret_data,
2607 int *ret_count)
2608{
2609 char **files = NULL;
2610 int num_files = 0;
2611 char *data = _data;
2612
2613 if (data && (size > 0))
2614 {
2615 int i, is;
2616 char *tmp;
2617 char **t2;
2618
2619 if (data[size - 1])
2620 {
2621 char *t;
2622
2623 /* Isn't nul terminated */
2624 size++;
2625 t = realloc(data, size);
2626 if (!t) goto done;
2627 data = t;
2628 data[size - 1] = 0;
2629 }
2630
2631 tmp = malloc(size);
2632 if (!tmp) goto done;
2633 i = 0;
2634 is = 0;
2635 while ((is < size) && (data[is]))
2636 {
2637 if ((i == 0) && (data[is] == '#'))
2638 for (; ((data[is]) && (data[is] != '\n')); is++) ;
2639 else
2640 {
2641 if ((data[is] != '\r') &&
2642 (data[is] != '\n'))
2643 tmp[i++] = data[is++];
2644 else
2645 {
2646 while ((data[is] == '\r') || (data[is] == '\n'))
2647 is++;
2648 tmp[i] = 0;
2649 num_files++;
2650 t2 = realloc(files, num_files * sizeof(char *));
2651 if (t2)
2652 {
2653 files = t2;
2654 files[num_files - 1] = strdup(tmp);
2655 }
2656 tmp[0] = 0;
2657 i = 0;
2658 }
2659 }
2660 }
2661 if (i > 0)
2662 {
2663 tmp[i] = 0;
2664 num_files++;
2665 t2 = realloc(files, num_files * sizeof(char *));
2666 if (t2)
2667 {
2668 files = t2;
2669 files[num_files - 1] = strdup(tmp);
2670 }
2671 }
2672
2673 free(tmp);
2674 }
2675done:
2676 if (ret_data) *ret_data = files;
2677 if (ret_count) *ret_count = num_files;
2678}
2679
2680static Eina_Bool
2681_wl_dnd_drag_get_timer_cb(void *data)
2682{
2683 char *type = data;
2684
2685 ecore_wl_dnd_drag_get(ecore_wl_input_get(), type);
2686 return ECORE_CALLBACK_CANCEL;
2687}
2688
2689static Eina_Bool
2690_wl_notify_handler_targets(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev)
2691{
2692 cnp_debug("In\n");
2693 if (!ev) return EINA_FALSE;
2694 char *data = ev->data;
2695 int len = ev->len;
2696 int count = 0, i = 0;
2697 char **data_arr = NULL;
2698 Cnp_Atom *atom = NULL;
2699
2700 _wl_selection_parser(data, len, &data_arr, &count);
2701 for (i = 0; i < count; i++)
2702 {
2703 atom = eina_hash_find(_types_hash, data_arr[i]);
2704 if (atom && (atom->formats != ELM_SEL_FORMAT_TARGETS))
2705 {
2706 cnp_debug("Match found: %s\n", atom->name);
2707 sel->requestfinished = EINA_FALSE;
2708 /* Since we cannot call ecore_wl_dnd_drag_get in here (it causes
2709 ecore callbacks circular dependency and makes drag_send cannot
2710 be called), we use ecore_timer to call it */
2711 ecore_timer_add(0.001, _wl_dnd_drag_get_timer_cb, atom->name);
2712 break;
2713 }
2714 }
2715 free(data_arr);
2716 return EINA_TRUE;
2717}
2718
2719static Eina_Bool
2720_wl_notify_handler_uri(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev)
2721{
2722 cnp_debug("In\n");
2723
2724 char *p, *s, *stripstr = NULL;
2725 char *data = ev->data;
2726 Dropable *drop;
2727 const char *type = NULL;
2728 Dropable *dropable;
2729 Eina_List *l;
2730 Dropable_Cbs *cbs;
2731 Eina_Inlist *itr;
2732 Elm_Selection_Data ddata;
2733
2734 eo_do(sel->requestwidget, drop = eo_key_data_get("__elm_dropable"));
2735 if (drop)
2736 type = drop->last.type;
2737 if (!strcmp(type, "text/uri-list"))
2738 {
2739 int num_files = 0;
2740 char **files = NULL;
2741 int i, len = 0;
2742 Efreet_Uri **uri;
2743
2744 _wl_selection_parser(ev->data, ev->len, &files, &num_files);
2745 cnp_debug("got a files list\n");
2746 //files = ev->data;
2747 /*
2748 if (files->num_files > 1)
2749 {
2750 // Don't handle many items <- this makes mr bigglesworth sad :(
2751 cnp_debug("more then one file: Bailing\n");
2752 return 0;
2753 }
2754 stripstr = p = strdup(files->files[0]);
2755 */
2756
2757 uri = calloc(1, sizeof(*uri) * num_files);
2758 if (!uri) return 0;
2759
2760 for (i = 0; i < num_files ; i++)
2761 {
2762 uri[i] = efreet_uri_decode(files[i]);
2763 if (!uri[i])
2764 {
2765 /* Is there any reason why we care of URI without scheme? */
2766 if (files[i][0] != '/') continue;
2767 len += strlen(files[i]) + 1;
2768 }
2769 else
2770 {
2771 if (strcmp(uri[i]->protocol, "file"))
2772 {
2773 efreet_uri_free(uri[i]);
2774 uri[i] = NULL;
2775 continue;
2776 }
2777 len += strlen(uri[i]->path) + 1;
2778 }
2779 }
2780 p = NULL;
2781 if (len > 0)
2782 {
2783 s = stripstr = malloc(len + 1);
2784 for (i = 0; i < num_files ; i++)
2785 {
2786 if (uri[i])
2787 p = (char *)uri[i]->path;
2788 else
2789 p = files[i];
2790
2791 len = strlen(p);
2792 strcpy(s, p);
2793 if (i < (num_files - 1))
2794 {
2795 s[len] = '\n';
2796 s[len + 1] = 0;
2797 s += len + 1;
2798 }
2799 else
2800 {
2801 s[len] = 0;
2802 s += len;
2803 }
2804
2805 if (uri[i])
2806 efreet_uri_free(uri[i]);
2807 }
2808 }
2809 free(uri);
2810 }
2811 else
2812 {
2813 Efreet_Uri *uri;
2814 int len = 0;
2815
2816 p = (char *)data;
2817 uri = efreet_uri_decode(p);
2818 if (!uri)
2819 {
2820 /* Is there any reason why we care of URI without scheme? */
2821 if (p[0] == '/')
2822 len = ev->len;
2823 }
2824 else
2825 {
2826 p = (char *)uri->path;
2827 len = strlen(p);
2828 }
2829 if (len > 0)
2830 {
2831 stripstr = malloc(len + 1);
2832 if (!stripstr) return 0;
2833 memcpy(stripstr, p, len);
2834 stripstr[len] = 0;
2835 }
2836 }
2837
2838 if (!stripstr)
2839 {
2840 cnp_debug("Couldn't find a file\n");
2841 return 0;
2842 }
2843 free(savedtypes.imgfile);
2844
2845 if (ev->selection == ECORE_WL_SELECTION_DND)
2846 {
2847 EINA_LIST_FOREACH(drops, l, dropable)
2848 {
2849 if (dropable->obj == sel->requestwidget) break;
2850 }
2851 if (!dropable)
2852 {
2853 cnp_debug("Unable to find drop object");
2854 ecore_wl_dnd_drag_end(ecore_wl_input_get());
2855 return 0;
2856 }
2857 dropable = eina_list_data_get(l);
2858 ddata.x = savedtypes.x;
2859 ddata.y = savedtypes.y;
2860 ddata.data = stripstr;
2861 ddata.len = strlen(stripstr);
2862 ddata.action = sel->action;
2863 ddata.format = sel->requestformat;
2864 EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
2865 if ((cbs->types & dropable->last.format) && cbs->dropcb)
2866 cbs->dropcb(cbs->dropdata, dropable->obj, &ddata);
2867 ecore_wl_dnd_drag_end(ecore_wl_input_get());
2868 }
2869 else if (sel->datacb)
2870 {
2871 ddata.x = ddata.y = 0;
2872 ddata.format = ELM_SEL_FORMAT_MARKUP;
2873 ddata.data = stripstr;
2874 ddata.len = strlen(stripstr);
2875 ddata.action = sel->action;
2876 sel->datacb(sel->udata, sel->requestwidget, &ddata);
2877 }
2878 else cnp_debug("Paste request\n");
2879
2880 return 0;
2881}
2882
2883static Eina_Bool
2884_wl_vcard_receive(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev)
2885{
2886 cnp_debug("In\n");
2887 Elm_Selection_Data ddata;
2888
2889 if (ev->selection == ECORE_WL_SELECTION_DND)
2890 {
2891 Dropable *dropable;
2892 Eina_List *l;
2893 Dropable_Cbs *cbs;
2894 Eina_Inlist *itr;
2895 cnp_debug("vcard receive\n");
2896
2897 EINA_LIST_FOREACH(drops, l, dropable)
2898 {
2899 if (dropable->obj == sel->requestwidget) break;
2900 }
2901 if (!dropable)
2902 {
2903 cnp_debug("Unable to find drop object");
2904 ecore_wl_dnd_drag_end(ecore_wl_input_get());
2905 return 0;
2906 }
2907 dropable = eina_list_data_get(l);
2908 ddata.x = savedtypes.x;
2909 ddata.y = savedtypes.y;
2910 ddata.format = ELM_SEL_FORMAT_VCARD;
2911 ddata.data = ev->data;
2912 ddata.len = ev->len;
2913 ddata.action = sel->action;
2914 EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
2915 if ((cbs->types & dropable->last.format) && cbs->dropcb)
2916 cbs->dropcb(cbs->dropdata, dropable->obj, &ddata);
2917 ecore_wl_dnd_drag_end(ecore_wl_input_get());
2918 }
2919 else if (sel->datacb)
2920 {
2921 ddata.x = ddata.y = 0;
2922 ddata.format = ELM_SEL_FORMAT_VCARD;
2923 ddata.data = ev->data;
2924 ddata.len = ev->len;
2925 ddata.action = sel->action;
2926 sel->datacb(sel->udata, sel->requestwidget, &ddata);
2927 }
2928 else cnp_debug("Paste request\n");
2929
2930 return 0;
2931}
2932
2933static Eina_Bool
2934_wl_notify_handler_image(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev)
2935{
2936 cnp_debug("In\n");
2937 Tmp_Info *tmp;
2938 Elm_Selection_Data ddata;
2939
2940 if (ev->selection == ECORE_WL_SELECTION_DND)
2941 {
2942 Eina_List *l;
2943 Dropable *dropable;
2944
2945 tmp = _tempfile_new(ev->len);
2946 if (!tmp)
2947 {
2948 ecore_wl_dnd_drag_end(ecore_wl_input_get());
2949 return 0;
2950 }
2951 memcpy(tmp->map, ev->data, ev->len);
2952 munmap(tmp->map, ev->len);
2953 EINA_LIST_FOREACH(drops, l, dropable)
2954 {
2955 if (dropable->obj == sel->requestwidget) break;
2956 dropable = NULL;
2957 }
2958 if (dropable)
2959 {
2960 Dropable_Cbs *cbs;
2961 Eina_Inlist *itr;
2962 ddata.x = savedtypes.x;
2963 ddata.y = savedtypes.y;
2964 ddata.format = ELM_SEL_FORMAT_IMAGE;
2965 ddata.data = tmp->filename;
2966 ddata.len = strlen(tmp->filename);
2967 ddata.action = sel->action;
2968 EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
2969 if ((cbs->types & dropable->last.format) && cbs->dropcb)
2970 cbs->dropcb(cbs->dropdata, dropable->obj, &ddata);
2971 }
2972 _tmpinfo_free(tmp);
2973 ecore_wl_dnd_drag_end(ecore_wl_input_get());
2974 }
2975 else if (sel->datacb)
2976 {
2977 ddata.x = ddata.y = 0;
2978 ddata.format = ELM_SEL_FORMAT_IMAGE;
2979 ddata.data = ev->data;
2980 ddata.len = ev->len;
2981 ddata.action = sel->action;
2982 sel->datacb(sel->udata, sel->requestwidget, &ddata);
2983 }
2984 else cnp_debug("Paste request\n");
2985
2986 return 0;
2987}
2988
2989static Eina_Bool
2990_wl_notify_handler_text(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev)
2991{
2992 cnp_debug("In\n");
2993
2994 Elm_Selection_Data ddata;
2995
2996 if (ev->selection == ECORE_WL_SELECTION_DND)
2997 {
2998 Eina_List *l;
2999 Dropable *dropable;
3000
3001 cnp_debug("drag & drop\n");
3002 EINA_LIST_FOREACH(drops, l, dropable)
3003 {
3004 if (dropable->obj == sel->requestwidget) break;
3005 dropable = NULL;
3006 }
3007 if (dropable)
3008 {
3009 Dropable_Cbs *cbs;
3010 Eina_Inlist *itr;
3011 ddata.x = savedtypes.x;
3012 ddata.y = savedtypes.y;
3013 ddata.format = ELM_SEL_FORMAT_TEXT;
3014 ddata.data = ev->data;
3015 ddata.len = ev->len;
3016 ddata.action = sel->action;
3017 EINA_INLIST_FOREACH_SAFE(dropable->cbs_list, itr, cbs)
3018 if ((cbs->types & dropable->last.format) && cbs->dropcb)
3019 cbs->dropcb(cbs->dropdata, dropable->obj, &ddata);
3020 }
3021 ecore_wl_dnd_drag_end(ecore_wl_input_get());
3022 }
3023 else if (sel->datacb)
3024 {
3025 ddata.x = ddata.y = 0;
3026 ddata.format = ELM_SEL_FORMAT_TEXT;
3027 ddata.data = ev->data;
3028 ddata.len = ev->len;
3029 ddata.action = sel->action;
3030 sel->datacb(sel->udata, sel->requestwidget, &ddata);
3031 }
3032 else cnp_debug("Paste request\n");
3033
3034 return 0;
3035}
3036
2356static void 3037static void
2357_wl_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) 3038_wl_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
2358{ 3039{
@@ -3105,6 +3786,7 @@ _wl_dnd_drop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
3105 { 3786 {
3106 cnp_debug("Request data of type %s\n", drop->last.type); 3787 cnp_debug("Request data of type %s\n", drop->last.type);
3107 wl_cnp_selection.requestwidget = drop->obj; 3788 wl_cnp_selection.requestwidget = drop->obj;
3789 wl_cnp_selection.requestformat = drop->last.format;
3108 evas_object_event_callback_add(wl_cnp_selection.requestwidget, 3790 evas_object_event_callback_add(wl_cnp_selection.requestwidget,
3109 EVAS_CALLBACK_DEL, 3791 EVAS_CALLBACK_DEL,
3110 _wl_sel_obj_del2, 3792 _wl_sel_obj_del2,
@@ -3126,15 +3808,38 @@ _wl_dnd_send(void *data, int type EINA_UNUSED, void *event)
3126 int len_written = 0; 3808 int len_written = 0;
3127 Wl_Cnp_Selection *sel; 3809 Wl_Cnp_Selection *sel;
3128 Ecore_Wl_Event_Data_Source_Send *ev; 3810 Ecore_Wl_Event_Data_Source_Send *ev;
3811 void *data_ret = NULL;
3812 int len_ret = 0;
3813 Cnp_Atom *atom = NULL;
3129 3814
3130 cnp_debug("In\n"); 3815 cnp_debug("In\n");
3131 ev = event; 3816 ev = event;
3132 sel = data; 3817 sel = data;
3133 3818
3134 len_remained = sel->buflen; 3819 atom = eina_hash_find(_types_hash, ev->type);
3135 buf = sel->selbuf; 3820 if (atom)
3821 {
3822 cnp_debug("Found a type: %s\n", atom->name);
3823 Dropable *drop;
3824 eo_do(sel->requestwidget, drop = eo_key_data_get("__elm_dropable"));
3825 if (drop)
3826 drop->last.type = atom->name;
3827 if (atom->wl_converter)
3828 {
3829 atom->wl_converter(ev->type, sel, sel->selbuf,
3830 sel->buflen, &data_ret, &len_ret);
3831 }
3832 else
3833 {
3834 data_ret = strdup(sel->selbuf);
3835 len_ret = sel->buflen;
3836 }
3837 }
3136 3838
3137 while (len_written < sel->buflen) 3839 len_remained = len_ret;
3840 buf = data_ret;
3841
3842 while (len_written < len_ret)
3138 { 3843 {
3139 ret = write(ev->fd, buf, len_remained); 3844 ret = write(ev->fd, buf, len_remained);
3140 if (ret == -1) break; 3845 if (ret == -1) break;
@@ -3142,6 +3847,7 @@ _wl_dnd_send(void *data, int type EINA_UNUSED, void *event)
3142 len_written += ret; 3847 len_written += ret;
3143 len_remained -= ret; 3848 len_remained -= ret;
3144 } 3849 }
3850 free(data_ret);
3145 3851
3146 close(ev->fd); 3852 close(ev->fd);
3147 return ECORE_CALLBACK_PASS_ON; 3853 return ECORE_CALLBACK_PASS_ON;
@@ -3160,8 +3866,10 @@ _wl_dnd_receive(void *data, int type EINA_UNUSED, void *event)
3160 if (sel->requestwidget) 3866 if (sel->requestwidget)
3161 { 3867 {
3162 if (!ev->done) 3868 if (!ev->done)
3163 _wl_dropable_data_handle(sel, ev->data); 3869 {
3164 else 3870 _wl_dropable_data_handle(sel, ev);
3871 }
3872 else if (sel->requestfinished)
3165 { 3873 {
3166 evas_object_event_callback_del_full(sel->requestwidget, 3874 evas_object_event_callback_del_full(sel->requestwidget,
3167 EVAS_CALLBACK_DEL, 3875 EVAS_CALLBACK_DEL,
@@ -3212,29 +3920,12 @@ _wl_dnd_end(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSE
3212} 3920}
3213 3921
3214static void 3922static void
3215_wl_dropable_data_handle(Wl_Cnp_Selection *sel, char *data) 3923_wl_dropable_data_handle(Wl_Cnp_Selection *sel, Ecore_Wl_Event_Selection_Data_Ready *ev)
3216{ 3924{
3217 cnp_debug("In\n"); 3925 cnp_debug("In\n");
3218 Dropable *drop; 3926 Dropable *drop;
3219 Elm_Selection_Data sdata;
3220 int len = 0;
3221 char *s = NULL;
3222
3223 len = strlen(data);
3224 if (!(s = malloc(len + 1))) return;
3225 memcpy(s, data, len);
3226 s[len] = 0;
3227
3228 if (savedtypes.textreq)
3229 {
3230 savedtypes.textreq = 0;
3231 savedtypes.imgfile = s;
3232 }
3233
3234 sdata.len = len;
3235 sdata.x = savedtypes.x;
3236 sdata.y = savedtypes.y;
3237 3927
3928 sel->requestfinished = EINA_TRUE;
3238 eo_do(sel->requestwidget, drop = eo_key_data_get("__elm_dropable")); 3929 eo_do(sel->requestwidget, drop = eo_key_data_get("__elm_dropable"));
3239 if (drop) 3930 if (drop)
3240 { 3931 {
@@ -3244,23 +3935,13 @@ _wl_dropable_data_handle(Wl_Cnp_Selection *sel, char *data)
3244 { 3935 {
3245 if (cbs->types && drop->last.format) 3936 if (cbs->types && drop->last.format)
3246 { 3937 {
3247 /* If it's markup that also supports images */ 3938 Cnp_Atom *atom = eina_hash_find(_types_hash, drop->last.type);
3248 if (cbs->types & (ELM_SEL_FORMAT_MARKUP | ELM_SEL_FORMAT_IMAGE)) 3939 if (atom && atom->wl_notify)
3249 {
3250 sdata.format = ELM_SEL_FORMAT_MARKUP;
3251 sdata.data = (char *)savedtypes.imgfile;
3252 }
3253 else if (cbs->types & ELM_SEL_FORMAT_IMAGE)
3254 {
3255 sdata.format = ELM_SEL_FORMAT_IMAGE;
3256 sdata.data = (char *)savedtypes.imgfile;
3257 }
3258 else
3259 { 3940 {
3260 sdata.format = drop->last.format; 3941 cnp_debug("call notify: %s\n", drop->last.type);
3261 sdata.data = s; 3942 atom->wl_notify(sel, ev);
3943 return;
3262 } 3944 }
3263 if (cbs->dropcb) cbs->dropcb(cbs->dropdata, drop->obj, &sdata);
3264 } 3945 }
3265 } 3946 }
3266 } 3947 }