Allow for handling the selection data conversion externally from ecore_x, but

provide the same auto-conversion when data is set for the selection.
This should work identically as before, except if the app relied on ecore to
send the notification when no data was present, please test your apps.


SVN revision: 27420
This commit is contained in:
ningerso 2006-12-11 23:05:48 +00:00 committed by ningerso
parent 5cb9a5e8a4
commit 1129668231
3 changed files with 60 additions and 41 deletions

View File

@ -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);

View File

@ -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

View File

@ -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;