summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/elm_cnp.c129
1 files changed, 101 insertions, 28 deletions
diff --git a/src/lib/elm_cnp.c b/src/lib/elm_cnp.c
index 7c08b3fea..337ebcd58 100644
--- a/src/lib/elm_cnp.c
+++ b/src/lib/elm_cnp.c
@@ -665,6 +665,89 @@ static X11_Cnp_Selection _x11_selections[ELM_SEL_TYPE_CLIPBOARD + 1] = {
665 }, 665 },
666}; 666};
667 667
668typedef struct
669{
670 Elm_Sel_Type selection;
671 Elm_Sel_Format requestformat;
672 Evas_Object *requestwidget;
673 Ecore_X_Window xwin;
674 const char *target;
675 Elm_Drop_Cb datacb;
676 void *udata;
677} X11_Cnp_Selection_Request;
678
679static X11_Cnp_Selection_Request *_current_sel_request = NULL;
680static Eina_List *_queued_requests = NULL;
681static Ecore_Timer *_sel_request_timer = NULL;
682static void _request_consume();
683
684static void
685_x11_req_disable(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
686{
687 X11_Cnp_Selection_Request *req = data;
688 req->datacb = NULL;
689 req->udata = NULL;
690 req->requestwidget = NULL;
691 req->requestformat = 0;
692}
693
694static Eina_Bool
695_sel_req_timer_reached(void *data EINA_UNUSED)
696{
697 _sel_request_timer = NULL;
698
699 evas_object_event_callback_del_full
700 (_current_sel_request->requestwidget, EVAS_CALLBACK_DEL,
701 _x11_req_disable, _current_sel_request);
702
703 free(_current_sel_request);
704 _current_sel_request = NULL;
705 _request_consume();
706 return EINA_FALSE;
707}
708
709static void
710_request_consume()
711{
712 if (_sel_request_timer) return;
713
714 _current_sel_request = eina_list_data_get(_queued_requests);
715 _queued_requests = eina_list_remove_list(_queued_requests, _queued_requests);
716
717 cnp_debug("%d elements in queue\n", eina_list_count(_queued_requests));
718 if (!_current_sel_request) return;
719 X11_Cnp_Selection_Request *req = _current_sel_request;
720 X11_Cnp_Selection *sel = _x11_selections + req->selection;
721 sel->request(req->xwin, req->target);
722 cnp_debug("Request %s\n", req->target);
723 _sel_request_timer = ecore_timer_add(5.0, _sel_req_timer_reached, NULL);
724}
725
726static void
727_sel_request(Ecore_X_Window xwin, const Evas_Object *obj, Elm_Sel_Type selection,
728 const char *request_target, Elm_Sel_Format format, Elm_Drop_Cb datacb,
729 void *udata, Eina_Bool priority)
730{
731 X11_Cnp_Selection_Request *req = calloc(1, sizeof(*req));
732 req->selection = selection;
733 req->requestformat = format;
734 req->requestwidget = (Evas_Object *)obj;
735 req->xwin = xwin;
736 req->target = request_target;
737 req->datacb = datacb;
738 req->udata = udata;
739
740 evas_object_event_callback_add
741 (req->requestwidget, EVAS_CALLBACK_DEL, _x11_req_disable, req);
742
743 if (priority)
744 _queued_requests = eina_list_prepend(_queued_requests, req);
745 else
746 _queued_requests = eina_list_append(_queued_requests, req);
747
748 _request_consume();
749}
750
668static void 751static void
669_x11_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) 752_x11_sel_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
670{ 753{
@@ -767,6 +850,7 @@ _x11_selection_notify(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event
767 Elm_Selection_Data ddata; 850 Elm_Selection_Data ddata;
768 Tmp_Info *tmp_info = NULL; 851 Tmp_Info *tmp_info = NULL;
769 Eina_Bool success; 852 Eina_Bool success;
853 X11_Cnp_Selection_Request *req = _current_sel_request;
770 ddata.data = NULL; 854 ddata.data = NULL;
771 cnp_debug("Found something: %s\n", _atoms[i].name); 855 cnp_debug("Found something: %s\n", _atoms[i].name);
772 success = _atoms[i].x_data_preparer(ev, &ddata, &tmp_info); 856 success = _atoms[i].x_data_preparer(ev, &ddata, &tmp_info);
@@ -780,7 +864,7 @@ _x11_selection_notify(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event
780 cnp_debug("drag & drop\n"); 864 cnp_debug("drag & drop\n");
781 EINA_LIST_FOREACH(drops, l, dropable) 865 EINA_LIST_FOREACH(drops, l, dropable)
782 { 866 {
783 if (dropable->obj == sel->requestwidget) break; 867 if (dropable->obj == req->requestwidget) break;
784 dropable = NULL; 868 dropable = NULL;
785 } 869 }
786 if (dropable) 870 if (dropable)
@@ -797,10 +881,10 @@ _x11_selection_notify(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event
797 /* We have to finish DnD, no matter what */ 881 /* We have to finish DnD, no matter what */
798 ecore_x_dnd_send_finished(); 882 ecore_x_dnd_send_finished();
799 } 883 }
800 else if (sel->datacb && success) 884 else if (req->datacb && success)
801 { 885 {
802 ddata.x = ddata.y = 0; 886 ddata.x = ddata.y = 0;
803 sel->datacb(sel->udata, sel->requestwidget, &ddata); 887 req->datacb(req->udata, req->requestwidget, &ddata);
804 } 888 }
805 free(ddata.data); 889 free(ddata.data);
806 if (tmp_info) _tmpinfo_free(tmp_info); 890 if (tmp_info) _tmpinfo_free(tmp_info);
@@ -809,6 +893,8 @@ _x11_selection_notify(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event
809 break; 893 break;
810 } 894 }
811 } 895 }
896 ecore_timer_del(_sel_request_timer);
897 _sel_req_timer_reached(NULL);
812 return ECORE_CALLBACK_PASS_ON; 898 return ECORE_CALLBACK_PASS_ON;
813} 899}
814 900
@@ -916,13 +1002,14 @@ _x11_notify_handler_targets(X11_Cnp_Selection *sel, Ecore_X_Event_Selection_Noti
916 Ecore_X_Selection_Data_Targets *targets; 1002 Ecore_X_Selection_Data_Targets *targets;
917 Ecore_X_Atom *atomlist; 1003 Ecore_X_Atom *atomlist;
918 int i, j; 1004 int i, j;
1005 X11_Cnp_Selection_Request *req = _current_sel_request;
919 1006
920 targets = notify->data; 1007 targets = notify->data;
921 atomlist = (Ecore_X_Atom *)(targets->data.data); 1008 atomlist = (Ecore_X_Atom *)(targets->data.data);
922 for (j = (CNP_ATOM_LISTING_ATOMS + 1); j < CNP_N_ATOMS; j++) 1009 for (j = (CNP_ATOM_LISTING_ATOMS + 1); j < CNP_N_ATOMS; j++)
923 { 1010 {
924 cnp_debug("\t%s %d\n", _atoms[j].name, _atoms[j].x_atom); 1011 cnp_debug("\t%s %d\n", _atoms[j].name, _atoms[j].x_atom);
925 if (!(_atoms[j].formats & sel->requestformat)) continue; 1012 if (!(_atoms[j].formats & req->requestformat)) continue;
926 for (i = 0; i < targets->data.length; i++) 1013 for (i = 0; i < targets->data.length; i++)
927 { 1014 {
928 if ((_atoms[j].x_atom == atomlist[i]) && (_atoms[j].x_data_preparer)) 1015 if ((_atoms[j].x_atom == atomlist[i]) && (_atoms[j].x_data_preparer))
@@ -932,16 +1019,18 @@ _x11_notify_handler_targets(X11_Cnp_Selection *sel, Ecore_X_Event_Selection_Noti
932 if (!_x11_is_uri_type_data(sel, notify)) continue; 1019 if (!_x11_is_uri_type_data(sel, notify)) continue;
933 } 1020 }
934 cnp_debug("Atom %s matches\n", _atoms[j].name); 1021 cnp_debug("Atom %s matches\n", _atoms[j].name);
935 goto done; 1022 cnp_debug("Sending request for %s, xwin=%#llx\n",
1023 _atoms[j].name, (unsigned long long)sel->xwin);
1024 _sel_request(req->xwin, req->requestwidget, req->selection,
1025 _atoms[j].name, req->requestformat, req->datacb, req->udata, EINA_TRUE);
1026 goto end;
936 } 1027 }
937 } 1028 }
938 } 1029 }
939 cnp_debug("Couldn't find anything that matches\n"); 1030 cnp_debug("Couldn't find anything that matches\n");
940 return ECORE_CALLBACK_PASS_ON; 1031end:
941done: 1032 ecore_timer_del(_sel_request_timer);
942 cnp_debug("Sending request for %s, xwin=%#llx\n", 1033 _sel_req_timer_reached(NULL);
943 _atoms[j].name, (unsigned long long)sel->xwin);
944 sel->request(sel->xwin, _atoms[j].name);
945 return ECORE_CALLBACK_PASS_ON; 1034 return ECORE_CALLBACK_PASS_ON;
946} 1035}
947 1036
@@ -1945,25 +2034,9 @@ _x11_elm_cnp_selection_get(Ecore_X_Window xwin, const Evas_Object *obj, Elm_Sel_
1945 Elm_Sel_Format format, Elm_Drop_Cb datacb, 2034 Elm_Sel_Format format, Elm_Drop_Cb datacb,
1946 void *udata) 2035 void *udata)
1947{ 2036{
1948 X11_Cnp_Selection *sel;
1949
1950 _x11_elm_cnp_init(); 2037 _x11_elm_cnp_init();
1951 2038 _sel_request(xwin, obj, selection, ECORE_X_SELECTION_TARGET_TARGETS,
1952 sel = _x11_selections + selection; 2039 format, datacb, udata, EINA_FALSE);
1953
1954 if (sel->requestwidget)
1955 evas_object_event_callback_del_full(sel->requestwidget, EVAS_CALLBACK_DEL,
1956 _x11_sel_obj_del2, sel);
1957 sel->requestformat = format;
1958 sel->requestwidget = (Evas_Object *)obj;
1959 sel->xwin = xwin;
1960 sel->request(xwin, ECORE_X_SELECTION_TARGET_TARGETS);
1961 sel->datacb = datacb;
1962 sel->udata = udata;
1963
1964 evas_object_event_callback_add
1965 (sel->requestwidget, EVAS_CALLBACK_DEL, _x11_sel_obj_del2, sel);
1966
1967 return EINA_TRUE; 2040 return EINA_TRUE;
1968} 2041}
1969 2042