forked from enlightenment/efl
Working on dnd drag. Doesn't quite work yet....
SVN revision: 13877
This commit is contained in:
parent
f919722f06
commit
83ea927187
|
@ -473,7 +473,6 @@ struct _Ecore_X_Event_Xdnd_Status
|
|||
{
|
||||
Ecore_X_Window win, target;
|
||||
int will_accept;
|
||||
int suppress;
|
||||
Ecore_X_Rectangle rectangle;
|
||||
Ecore_X_Atom action;
|
||||
};
|
||||
|
@ -826,6 +825,7 @@ EAPI int ecore_x_dnd_version_get(Ecore_X_Window win);
|
|||
EAPI int ecore_x_dnd_type_isset(Ecore_X_Window win, const char *type);
|
||||
EAPI void ecore_x_dnd_type_set(Ecore_X_Window win, const char *type, int on);
|
||||
EAPI int ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size);
|
||||
EAPI void ecore_x_dnd_drop(void);
|
||||
EAPI void ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action);
|
||||
EAPI void ecore_x_dnd_send_finished(void);
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ ecore_x_dnd_aware_set(Ecore_X_Window win, int on)
|
|||
XA_ATOM, 32, &prop_data, 1);
|
||||
else
|
||||
ecore_x_window_prop_property_del(win, ECORE_X_ATOM_XDND_AWARE);
|
||||
ecore_x_dnd_type_set(win, "text/plain", 1);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -180,6 +179,33 @@ ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
ecore_x_dnd_drop(void)
|
||||
{
|
||||
XEvent xev;
|
||||
|
||||
xev.xany.type = ClientMessage;
|
||||
xev.xany.display = _ecore_x_disp;
|
||||
xev.xclient.format = 32;
|
||||
xev.xclient.window = _xdnd->dest;
|
||||
|
||||
if (_xdnd->will_accept)
|
||||
{
|
||||
xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP;
|
||||
xev.xclient.data.l[0] = _xdnd->source;
|
||||
xev.xclient.data.l[1] = 0;
|
||||
xev.xclient.data.l[2] = _xdnd->time;
|
||||
XSendEvent(_ecore_x_disp, _xdnd->dest, False, 0, &xev);
|
||||
}
|
||||
else
|
||||
{
|
||||
xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
|
||||
xev.xclient.data.l[0] = _xdnd->source;
|
||||
xev.xclient.data.l[1] = 0;
|
||||
XSendEvent(_ecore_x_disp, _xdnd->dest, False, 0, &xev);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action)
|
||||
{
|
||||
|
@ -205,6 +231,7 @@ ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectang
|
|||
xev.xclient.window = _xdnd->source;
|
||||
|
||||
xev.xclient.data.l[0] = _xdnd->dest;
|
||||
xev.xclient.data.l[1] = 0;
|
||||
if (will_accept)
|
||||
xev.xclient.data.l[1] |= 0x1UL;
|
||||
if (!suppress)
|
||||
|
@ -244,7 +271,8 @@ ecore_x_dnd_send_finished(void)
|
|||
xev.xclient.window = _xdnd->source;
|
||||
|
||||
xev.xclient.data.l[0] = _xdnd->dest;
|
||||
memset(xev.xclient.data.l + 1, 0, sizeof(long) * 3);
|
||||
xev.xclient.data.l[1] = 0;
|
||||
xev.xclient.data.l[2] = 0;
|
||||
if (_xdnd->will_accept)
|
||||
{
|
||||
xev.xclient.data.l[1] |= 0x1UL;
|
||||
|
@ -271,11 +299,12 @@ _ecore_x_dnd_drag(int x, int y)
|
|||
win = ecore_x_window_parent_get(win);
|
||||
|
||||
/* Send XdndLeave to current destination window if we have left it */
|
||||
if ((win != _xdnd->dest) && (_xdnd->dest))
|
||||
if ((_xdnd->dest) && (win != _xdnd->dest))
|
||||
{
|
||||
xev.xclient.window = _xdnd->dest;
|
||||
xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
|
||||
xev.xclient.data.l[0] = _xdnd->source;
|
||||
xev.xclient.data.l[1] = 0;
|
||||
|
||||
XSendEvent(_ecore_x_disp, _xdnd->dest, False, 0, &xev);
|
||||
}
|
||||
|
@ -298,12 +327,15 @@ _ecore_x_dnd_drag(int x, int y)
|
|||
xev.xclient.window = win;
|
||||
xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER;
|
||||
xev.xclient.data.l[0] = _xdnd->source;
|
||||
xev.xclient.data.l[1] = 0;
|
||||
if (num > 3)
|
||||
xev.xclient.data.l[1] |= 0x1UL;
|
||||
else
|
||||
xev.xclient.data.l[1] &= 0xfffffffeUL;
|
||||
xev.xclient.data.l[1] |= ((unsigned long) _xdnd->version) << 24;
|
||||
|
||||
for (i = 2; i < 5; i++)
|
||||
xev.xclient.data.l[i] = 0;
|
||||
for (i = 0; i < MIN(num, 3); ++i)
|
||||
xev.xclient.data.l[i + 2] = types[i];
|
||||
XFree(data);
|
||||
|
@ -319,7 +351,7 @@ _ecore_x_dnd_drag(int x, int y)
|
|||
xev.xclient.data.l[0] = _xdnd->source;
|
||||
xev.xclient.data.l[1] = 0; /* Reserved */
|
||||
xev.xclient.data.l[2] = ((x << 16) & 0xffff0000) | (y & 0xffff);
|
||||
xev.xclient.data.l[3] = CurrentTime; /* Version 1 */
|
||||
xev.xclient.data.l[3] = _xdnd->time; /* Version 1 */
|
||||
xev.xclient.data.l[4] = _xdnd->action; /* Version 2, Needs to be pre-set */
|
||||
XSendEvent(_ecore_x_disp, win, False, 0, &xev);
|
||||
_xdnd->await_status = 1;
|
||||
|
@ -336,9 +368,7 @@ _ecore_x_dnd_drag(int x, int y)
|
|||
xev.xclient.message_type = ECORE_X_ATOM_XDND_DROP;
|
||||
xev.xclient.data.l[0] = _xdnd->source;
|
||||
xev.xclient.data.l[1] = 0;
|
||||
xev.xclient.data.l[2] = CurrentTime;
|
||||
xev.xclient.data.l[3] = 0;
|
||||
xev.xclient.data.l[4] = 0;
|
||||
xev.xclient.data.l[2] = _xdnd->time;
|
||||
XSendEvent(_ecore_x_disp, win, False, 0, &xev);
|
||||
}
|
||||
else
|
||||
|
@ -346,7 +376,7 @@ _ecore_x_dnd_drag(int x, int y)
|
|||
xev.xclient.window = win;
|
||||
xev.xclient.message_type = ECORE_X_ATOM_XDND_LEAVE;
|
||||
xev.xclient.data.l[0] = _xdnd->source;
|
||||
memset(xev.xclient.data.l + 1, 0, sizeof(long) * 3); /* Evil */
|
||||
xev.xclient.data.l[1] = 0;
|
||||
XSendEvent(_ecore_x_disp, win, False, 0, &xev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,15 +503,16 @@ _ecore_x_event_handle_motion_notify(XEvent *xevent)
|
|||
|
||||
/* Xdnd handling */
|
||||
_xdnd = _ecore_x_dnd_protocol_get();
|
||||
if (_xdnd->state == ECORE_X_DND_DRAGGING)
|
||||
if (_xdnd->state != ECORE_X_DND_IDLE)
|
||||
{
|
||||
/* Determine if we're still in the rectangle from the last status */
|
||||
x1 = _xdnd->rectangle.x;
|
||||
x2 = _xdnd->rectangle.x + _xdnd->rectangle.width;
|
||||
y1 = _xdnd->rectangle.y;
|
||||
y2 = _xdnd->rectangle.y + _xdnd->rectangle.height;
|
||||
if ((e->win != _xdnd->dest) || (e->root.x < x1) || (e->root.x > x2)
|
||||
|| (e->root.y < y1) || (e->root.y > y2))
|
||||
if (!(_xdnd->suppress) ||
|
||||
((e->root.x < x1) || (e->root.x > x2)
|
||||
|| (e->root.y < y1) || (e->root.y > y2)))
|
||||
{
|
||||
_ecore_x_dnd_drag(e->root.x, e->root.y);
|
||||
}
|
||||
|
@ -995,12 +996,12 @@ _ecore_x_event_handle_selection_clear(XEvent *xevent)
|
|||
Atom sel;
|
||||
|
||||
if (!(d = _ecore_x_selection_get(xevent->xselectionclear.selection)))
|
||||
return;
|
||||
return;
|
||||
if (xevent->xselectionclear.time > d->time)
|
||||
{
|
||||
_ecore_x_selection_set(None, NULL, 0,
|
||||
xevent->xselectionclear.selection);
|
||||
}
|
||||
{
|
||||
_ecore_x_selection_set(None, NULL, 0,
|
||||
xevent->xselectionclear.selection);
|
||||
}
|
||||
|
||||
/* Generate event for app cleanup */
|
||||
e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
|
||||
|
@ -1008,13 +1009,13 @@ _ecore_x_event_handle_selection_clear(XEvent *xevent)
|
|||
e->time = xevent->xselectionclear.time;
|
||||
sel = xevent->xselectionclear.selection;
|
||||
if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
|
||||
e->selection = ECORE_X_SELECTION_PRIMARY;
|
||||
e->selection = ECORE_X_SELECTION_PRIMARY;
|
||||
else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
|
||||
e->selection = ECORE_X_SELECTION_SECONDARY;
|
||||
e->selection = ECORE_X_SELECTION_SECONDARY;
|
||||
else
|
||||
e->selection = ECORE_X_SELECTION_CLIPBOARD;
|
||||
e->selection = ECORE_X_SELECTION_CLIPBOARD;
|
||||
ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1022,11 +1023,9 @@ _ecore_x_event_handle_selection_request(XEvent *xevent)
|
|||
{
|
||||
Ecore_X_Selection_Data *sd;
|
||||
XSelectionEvent xnotify;
|
||||
XEvent *xev;
|
||||
XEvent xev;
|
||||
void *data;
|
||||
|
||||
xev = calloc(1, sizeof(XEvent));
|
||||
|
||||
xnotify.type = SelectionNotify;
|
||||
xnotify.display = xevent->xselectionrequest.display;
|
||||
xnotify.requestor = xevent->xselectionrequest.requestor;
|
||||
|
@ -1034,37 +1033,36 @@ _ecore_x_event_handle_selection_request(XEvent *xevent)
|
|||
xnotify.target = xevent->xselectionrequest.target;
|
||||
xnotify.time = CurrentTime;
|
||||
|
||||
if((sd = _ecore_x_selection_get(xnotify.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);
|
||||
}
|
||||
}
|
||||
if ((sd = _ecore_x_selection_get(xnotify.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;
|
||||
}
|
||||
|
||||
xev->xselection = xnotify;
|
||||
{
|
||||
xnotify.property = None;
|
||||
return;
|
||||
}
|
||||
|
||||
xev.xselection = xnotify;
|
||||
XSendEvent(xevent->xselectionrequest.display,
|
||||
xevent->xselectionrequest.requestor, False, 0, xev);
|
||||
XFree(xev);
|
||||
|
||||
xevent->xselectionrequest.requestor, False, 0, &xev);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1082,25 +1080,25 @@ _ecore_x_event_handle_selection_notify(XEvent *xevent)
|
|||
e->target = _ecore_x_selection_target_get(xevent->xselection.target);
|
||||
selection = xevent->xselection.selection;
|
||||
if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
|
||||
e->selection = ECORE_X_SELECTION_PRIMARY;
|
||||
e->selection = ECORE_X_SELECTION_PRIMARY;
|
||||
else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
|
||||
e->selection = ECORE_X_SELECTION_SECONDARY;
|
||||
e->selection = ECORE_X_SELECTION_SECONDARY;
|
||||
else if (selection == ECORE_X_ATOM_SELECTION_XDND)
|
||||
e->selection = ECORE_X_SELECTION_XDND;
|
||||
e->selection = ECORE_X_SELECTION_XDND;
|
||||
else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
|
||||
e->selection = ECORE_X_SELECTION_CLIPBOARD;
|
||||
e->selection = ECORE_X_SELECTION_CLIPBOARD;
|
||||
else
|
||||
{
|
||||
free(e);
|
||||
return;
|
||||
}
|
||||
{
|
||||
free(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ecore_x_window_prop_property_get(e->win, xevent->xselection.property,
|
||||
AnyPropertyType, 8, &data, &num_ret))
|
||||
{
|
||||
free(e);
|
||||
return;
|
||||
}
|
||||
AnyPropertyType, 8, &data, &num_ret))
|
||||
{
|
||||
free(e);
|
||||
return;
|
||||
}
|
||||
|
||||
sel_data.win = e->win;
|
||||
sel_data.selection = selection;
|
||||
|
@ -1108,7 +1106,6 @@ _ecore_x_event_handle_selection_notify(XEvent *xevent)
|
|||
sel_data.length = num_ret;
|
||||
_ecore_x_selection_request_data_set(sel_data);
|
||||
ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1259,7 +1256,6 @@ _ecore_x_event_handle_client_message(XEvent *xevent)
|
|||
e->win = _xdnd->source;
|
||||
e->target = _xdnd->dest;
|
||||
e->will_accept = _xdnd->will_accept;
|
||||
e->suppress = _xdnd->suppress;
|
||||
e->rectangle.x = _xdnd->rectangle.x;
|
||||
e->rectangle.y = _xdnd->rectangle.y;
|
||||
e->rectangle.width = _xdnd->rectangle.width;
|
||||
|
|
|
@ -362,7 +362,7 @@ _ecore_x_selection_target_get(Atom target)
|
|||
else if (target == ECORE_X_ATOM_TEXT)
|
||||
return strdup(ECORE_X_SELECTION_TARGET_TEXT);
|
||||
else
|
||||
return strdup(ECORE_X_SELECTION_TARGET_TEXT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -481,7 +481,7 @@ ecore_x_selection_converter_atom_del(Ecore_X_Atom target)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(prev_cnv)
|
||||
if (prev_cnv)
|
||||
prev_cnv->next = cnv->next;
|
||||
else
|
||||
converters = NULL; /* This was the only converter */
|
||||
|
@ -521,25 +521,34 @@ _ecore_x_selection_convert(Atom selection, Atom target, void **data_ret)
|
|||
sel = _ecore_x_selection_get(selection);
|
||||
tgt_str = _ecore_x_selection_target_get(target);
|
||||
|
||||
for (cnv = converters; cnv; cnv = cnv->next)
|
||||
if (tgt_str)
|
||||
{
|
||||
if (cnv->target == target)
|
||||
for (cnv = converters; cnv; cnv = cnv->next)
|
||||
{
|
||||
int r;
|
||||
r = cnv->convert(tgt_str, sel->data, sel->length, &data, &size);
|
||||
if (r)
|
||||
if (cnv->target == target)
|
||||
{
|
||||
*data_ret = data;
|
||||
return r;
|
||||
int r;
|
||||
r = cnv->convert(tgt_str, sel->data, sel->length, &data, &size);
|
||||
if (r)
|
||||
{
|
||||
*data_ret = data;
|
||||
return r;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(tgt_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
*data_ret = malloc(sel->length);
|
||||
memcpy(*data_ret, sel->data, sel->length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(tgt_str);
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: We need to work out a mechanism for automatic conversion to any requested
|
||||
|
|
Loading…
Reference in New Issue