diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X.h b/legacy/ecore/src/lib/ecore_x/Ecore_X.h index 8d43583c56..aa24beaa49 100644 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X.h +++ b/legacy/ecore/src/lib/ecore_x/Ecore_X.h @@ -539,7 +539,8 @@ struct _Ecore_X_Event_Selection_Clear struct _Ecore_X_Event_Selection_Request { - Ecore_X_Window win; + Ecore_X_Window owner; + Ecore_X_Window requestor; Ecore_X_Time time; Ecore_X_Atom selection; Ecore_X_Atom target; @@ -989,6 +990,7 @@ EAPI int ecore_x_error_code_get(void); EAPI void ecore_x_event_mask_set(Ecore_X_Window w, Ecore_X_Event_Mask mask); EAPI void ecore_x_event_mask_unset(Ecore_X_Window w, Ecore_X_Event_Mask mask); +EAPI int ecore_x_selection_notify_send(Ecore_X_Window requestor, Ecore_X_Atom selection, Ecore_X_Atom target, Ecore_X_Atom property); EAPI int ecore_x_selection_primary_set(Ecore_X_Window w, const void *data, int size); EAPI int ecore_x_selection_primary_clear(void); EAPI int ecore_x_selection_secondary_set(Ecore_X_Window w, const void *data, int size); @@ -1001,6 +1003,7 @@ EAPI void ecore_x_selection_primary_request(Ecore_X_Window w, const EAPI void ecore_x_selection_secondary_request(Ecore_X_Window w, const char *target); EAPI void ecore_x_selection_xdnd_request(Ecore_X_Window w, const char *target); EAPI void ecore_x_selection_clipboard_request(Ecore_X_Window w, const char *target); +EAPI int ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret); EAPI void ecore_x_selection_converter_add(char *target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret)); EAPI void ecore_x_selection_converter_atom_add(Ecore_X_Atom target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret)); EAPI void ecore_x_selection_converter_del(char *target); diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_events.c b/legacy/ecore/src/lib/ecore_x/ecore_x_events.c index 01d97c59ff..f3247d4a27 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_events.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_events.c @@ -1110,59 +1110,55 @@ _ecore_x_event_handle_selection_request(XEvent *xevent) { Ecore_X_Event_Selection_Request *e; Ecore_X_Selection_Intern *sd; - XSelectionEvent xnotify; - XEvent xev; void *data; /* * Generate a selection request event. */ e = malloc(sizeof(Ecore_X_Event_Selection_Request)); - e->win = xevent->xselectionrequest.requestor; + e->owner = xevent->xselectionrequest.owner; + e->requestor = xevent->xselectionrequest.requestor; e->time = xevent->xselectionrequest.time; e->selection = xevent->xselectionrequest.selection; e->target = xevent->xselectionrequest.target; e->property = xevent->xselectionrequest.property; ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL); - xnotify.type = SelectionNotify; - xnotify.display = xevent->xselectionrequest.display; - xnotify.requestor = xevent->xselectionrequest.requestor; - xnotify.selection = xevent->xselectionrequest.selection; - xnotify.target = xevent->xselectionrequest.target; - xnotify.time = CurrentTime; - xnotify.send_event = True; - xnotify.serial = 0; - - if ((sd = _ecore_x_selection_get(xnotify.selection)) && + if ((sd = _ecore_x_selection_get(xevent->xselectionrequest.selection)) && (sd->win == xevent->xselectionrequest.owner)) { - if (!_ecore_x_selection_convert(xnotify.selection, xnotify.target, - &data) == -1) - { - /* Refuse selection, conversion to requested target failed */ - xnotify.property = None; - } - else - { - /* FIXME: This does not properly handle large data transfers */ - ecore_x_window_prop_property_set(xevent->xselectionrequest.requestor, - xevent->xselectionrequest.property, - xevent->xselectionrequest.target, - 8, data, sd->length); - xnotify.property = xevent->xselectionrequest.property; - free(data); - } - } - else - { - xnotify.property = None; - return; - } + Ecore_X_Selection_Intern *si; - xev.xselection = xnotify; - XSendEvent(xevent->xselectionrequest.display, - xevent->xselectionrequest.requestor, False, 0, &xev); + si = _ecore_x_selection_get(xevent->xselectionrequest.selection); + if (si->data) + { + Ecore_X_Atom property; + + if (!ecore_x_selection_convert(xevent->xselectionrequest.selection, + xevent->xselectionrequest.target, + &data) == -1) + { + /* Refuse selection, conversion to requested target failed */ + property = None; + } + else + { + /* FIXME: This does not properly handle large data transfers */ + ecore_x_window_prop_property_set(xevent->xselectionrequest.requestor, + xevent->xselectionrequest.property, + xevent->xselectionrequest.target, + 8, data, sd->length); + property = xevent->xselectionrequest.property; + free(data); + } + + ecore_x_selection_notify_send(xevent->xselectionrequest.requestor, + xevent->xselectionrequest.selection, + xevent->xselectionrequest.target, + property); + } + } + return; } void diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c b/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c index fb99c2c3fa..c761923032 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c @@ -425,9 +425,29 @@ ecore_x_selection_converter_del(char *target) ecore_x_selection_converter_atom_del(x_target); } +EAPI int +ecore_x_selection_notify_send(Ecore_X_Window requestor, Ecore_X_Atom selection, Ecore_X_Atom target, Ecore_X_Atom property) +{ + XEvent xev; + XSelectionEvent xnotify; + + xnotify.type = SelectionNotify; + xnotify.display = _ecore_x_disp; + xnotify.requestor = requestor; + xnotify.selection = selection; + xnotify.target = target; + xnotify.property = property; + xnotify.time = CurrentTime; + xnotify.send_event = True; + xnotify.serial = 0; + + xev.xselection = xnotify; + return ((XSendEvent(_ecore_x_disp, requestor, False, 0, &xev) > 0) ? 1 : 0); +} + /* Locate and run conversion callback for specified selection target */ -int -_ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret) +EAPI int +ecore_x_selection_convert(Ecore_X_Atom selection, Ecore_X_Atom target, void **data_ret) { Ecore_X_Selection_Intern *sel; Ecore_X_Selection_Converter *cnv;