From 83ea9271877c41e595b29b5b2fa4455f9752ceb5 Mon Sep 17 00:00:00 2001 From: sebastid Date: Wed, 23 Mar 2005 18:33:50 +0000 Subject: [PATCH] Working on dnd drag. Doesn't quite work yet.... SVN revision: 13877 --- legacy/ecore/src/lib/ecore_x/Ecore_X.h | 2 +- legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c | 46 +++++-- legacy/ecore/src/lib/ecore_x/ecore_x_events.c | 114 +++++++++--------- .../ecore/src/lib/ecore_x/ecore_x_selection.c | 37 +++--- 4 files changed, 117 insertions(+), 82 deletions(-) diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X.h b/legacy/ecore/src/lib/ecore_x/Ecore_X.h index fcebfa9d27..b89291556b 100644 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X.h +++ b/legacy/ecore/src/lib/ecore_x/Ecore_X.h @@ -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); diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c b/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c index 1faff4a8f1..04017a26f3 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c @@ -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); } } 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 c501f17c02..8e336dff90 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_events.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_events.c @@ -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; 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 2603c282ab..e02566becc 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c @@ -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