diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X.h b/legacy/ecore/src/lib/ecore_x/Ecore_X.h index f2483101fb..03dbf14a63 100644 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X.h +++ b/legacy/ecore/src/lib/ecore_x/Ecore_X.h @@ -456,6 +456,9 @@ struct _Ecore_X_Event_Xdnd_Enter { Ecore_X_Window win, source; Ecore_X_Time time; + + char **types; + int num_types; }; struct _Ecore_X_Event_Xdnd_Position @@ -803,14 +806,17 @@ EAPI int ecore_x_selection_primary_set(Ecore_X_Window w, unsigned c EAPI int ecore_x_selection_primary_clear(void); EAPI int ecore_x_selection_secondary_set(Ecore_X_Window w, unsigned char *data, int size); EAPI int ecore_x_selection_secondary_clear(void); +EAPI int ecore_x_selection_xdnd_set(Ecore_X_Window w, unsigned char *data, int size); +EAPI int ecore_x_selection_xdnd_clear(void); EAPI int ecore_x_selection_clipboard_set(Ecore_X_Window w, unsigned char *data, int size); EAPI int ecore_x_selection_clipboard_clear(void); EAPI void ecore_x_selection_primary_request(Ecore_X_Window w, char *target); -EAPI void ecore_x_selection_secondary_request(Ecore_X_Window w, char *target); -EAPI void ecore_x_selection_clipboard_request(Ecore_X_Window w, char *target); EAPI void ecore_x_selection_primary_request_data_get(void **buf, int *len); +EAPI void ecore_x_selection_secondary_request(Ecore_X_Window w, char *target); EAPI void ecore_x_selection_secondary_request_data_get(void **buf, int *len); +EAPI void ecore_x_selection_xdnd_request(Ecore_X_Window w, char *target); EAPI void ecore_x_selection_xdnd_request_data_get(void **buf, int *len); +EAPI void ecore_x_selection_clipboard_request(Ecore_X_Window w, char *target); EAPI void ecore_x_selection_clipboard_request_data_get(void **buf, int *len); 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)); @@ -823,6 +829,7 @@ EAPI int ecore_x_dnd_type_isset(Ecore_X_Window win, const char *typ 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_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectangle, Ecore_X_Atom action); +EAPI void ecore_x_dnd_send_finished(void); EAPI Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h); 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 c7f379f0e9..ff1798e750 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c @@ -6,7 +6,6 @@ #include "Ecore_X.h" #include "Ecore_X_Atoms.h" -static Ecore_X_Selection_Data _xdnd_selection; static Ecore_X_DND_Protocol *_xdnd = NULL; static int _ecore_x_dnd_init_count = 0; @@ -163,29 +162,14 @@ _ecore_x_dnd_protocol_get(void) int ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size) { - unsigned char *buf; - unsigned char *atoms; - int num; if (!ecore_x_dnd_version_get(source)) return 0; /* Take ownership of XdndSelection */ - XSetSelectionOwner(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, source, - _ecore_x_event_last_time); - if (XGetSelectionOwner(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND) != source) + if (!ecore_x_selection_xdnd_set(source, data, size)) return 0; - /* Initialize Selection Data Struct */ - _xdnd_selection.win = source; - _xdnd_selection.selection = ECORE_X_ATOM_SELECTION_XDND; - _xdnd_selection.length = size; - _xdnd_selection.time = _ecore_x_event_last_time; - - buf = malloc(size); - memcpy(buf, data, size); - _xdnd_selection.data = buf; - _xdnd->source = source; _xdnd->state = ECORE_X_DND_DRAGGING; _xdnd->time = _ecore_x_event_last_time; @@ -193,11 +177,6 @@ ecore_x_dnd_begin(Ecore_X_Window source, unsigned char *data, int size) /* Default Accepted Action: ask */ _xdnd->action = ECORE_X_ATOM_XDND_ACTION_ASK; _xdnd->accepted_action = None; - - ecore_x_window_prop_property_get(source, ECORE_X_ATOM_XDND_TYPE_LIST, - XA_ATOM, 32, &atoms, &num); - _xdnd->num_types = num; - _xdnd->types = (Ecore_X_Atom *)atoms; return 1; } @@ -253,6 +232,27 @@ ecore_x_dnd_send_status(int will_accept, int suppress, Ecore_X_Rectangle rectang XSendEvent(_ecore_x_disp, _xdnd->source, False, 0, &xev); } +void +ecore_x_dnd_send_finished(void) +{ + XEvent xev; + + xev.xany.type = ClientMessage; + xev.xany.display = _ecore_x_disp; + xev.xclient.window = _xdnd->source; + xev.xclient.message_type = ECORE_X_ATOM_XDND_FINISHED; + xev.xclient.format = 32; + + xev.xclient.data.l[0] = _xdnd->dest; + memset(xev.xclient.data.l + 1, 0, sizeof(long) * 3); + if (_xdnd->will_accept) + { + xev.xclient.data.l[1] |= 0x1UL; + xev.xclient.data.l[2] = _xdnd->accepted_action; + } + XSendEvent(_ecore_x_disp, _xdnd->source, False, 0, &xev); +} + void _ecore_x_dnd_drag(int x, int y) { @@ -286,20 +286,27 @@ _ecore_x_dnd_drag(int x, int y) ecore_x_dnd_version_get(win)); if (win != _xdnd->dest) { - int i; + int i, num; + unsigned char *data; + Ecore_X_Atom *types; + + ecore_x_window_prop_property_get(_xdnd->source, ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, 32, &data, &num); + types = (Ecore_X_Atom *)data; /* Entered new window, send XdndEnter */ xev.xclient.window = win; xev.xclient.message_type = ECORE_X_ATOM_XDND_ENTER; xev.xclient.data.l[0] = _xdnd->source; - if(_xdnd->num_types > 3) + 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 = 0; i < MIN(_xdnd->num_types, 3); ++i) - xev.xclient.data.l[i + 2] = _xdnd->types[i]; + for (i = 0; i < MIN(num, 3); ++i) + xev.xclient.data.l[i + 2] = types[i]; + XFree(data); XSendEvent(_ecore_x_disp, win, False, 0, &xev); _xdnd->await_status = 0; } @@ -349,27 +356,3 @@ _ecore_x_dnd_drag(int x, int y) _xdnd->dest = win; } -#if 0 /* Unused? */ -void -_ecore_x_dnd_send_finished(void) -{ - XEvent xev; - - xev.xany.type = ClientMessage; - xev.xany.display = _ecore_x_disp; - xev.xclient.window = _xdnd->source; - xev.xclient.message_type = ECORE_X_ATOM_XDND_FINISHED; - xev.xclient.format = 32; - - xev.xclient.data.l[0] = _xdnd->dest; - memset(xev.xclient.data.l + 1, 0, sizeof(long) * 3); - XSendEvent(_ecore_x_disp, _xdnd->source, False, 0, &xev); -} - -int -_ecore_x_dnd_own_selection(void) -{ - return (!XSetSelectionOwner(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, - _xdnd->source, CurrentTime)); -} -#endif 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 c198a21503..ef6d636cd6 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_events.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_events.c @@ -1,7 +1,6 @@ /* * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ - #include "ecore_private.h" #include "Ecore.h" #include "ecore_x_private.h" @@ -146,6 +145,19 @@ _ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev) free(e); } +static void +_ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev) +{ + Ecore_X_Event_Xdnd_Enter *e; + int i; + + e = ev; + for (i = 0; i < e->num_types; i++) + XFree(e->types[i]); + free(e->types); + free(e); +} + void _ecore_x_event_handle_key_press(XEvent *xevent) { @@ -492,19 +504,19 @@ _ecore_x_event_handle_motion_notify(XEvent *xevent) /* Xdnd handling */ _xdnd = _ecore_x_dnd_protocol_get(); if (_xdnd->state == ECORE_X_DND_DRAGGING) - { - /* 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) - { - _ecore_x_dnd_drag(e->root.x, e->root.y); - } - } - + { + /* 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)) + { + _ecore_x_dnd_drag(e->root.x, e->root.y); + } + } + ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL); } @@ -1123,258 +1135,250 @@ _ecore_x_event_handle_client_message(XEvent *xevent) /* otherwise generate generic client message event. this would handle*/ /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */ if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) && - (xevent->xclient.format == 32) && - (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW)) - { - Ecore_X_Event_Window_Delete_Request *e; - - e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request)); - if (!e) return; - e->win = xevent->xclient.window; - e->time = _ecore_x_event_last_time; - ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL); - } - + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW)) + { + Ecore_X_Event_Window_Delete_Request *e; + + e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request)); + if (!e) return; + e->win = xevent->xclient.window; + e->time = _ecore_x_event_last_time; + ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL); + } + /* Xdnd Client Message Handling Begin */ /* Message Type: XdndEnter */ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER) - { - Ecore_X_Event_Xdnd_Enter *e; - Ecore_X_DND_Protocol *_xdnd; - unsigned long three; - - _xdnd = _ecore_x_dnd_protocol_get(); - _xdnd->source = xevent->xclient.data.l[0]; - _xdnd->dest = xevent->xclient.window; - _xdnd->version = (int) (xevent->xclient.data.l[1] >> 24); - if (_xdnd->version > ECORE_X_DND_VERSION) - { - printf("DND: Requested version %d, we only support up to %d\n", _xdnd->version, - ECORE_X_DND_VERSION); - return; - } - - if ((three = xevent->xclient.data.l[1] & 0x1UL)) - { - /* source supports more than 3 types, fetch property */ - unsigned char *data; - Atom *types; - int i, num_ret; - if (!(ecore_x_window_prop_property_get(_xdnd->source, - ECORE_X_ATOM_XDND_TYPE_LIST, - XA_ATOM, - 32, - &data, - &num_ret))) - { - printf("DND: Could not fetch data type list from source window, aborting.\n"); - return; - } - types = (Atom *) data; - _xdnd->types = calloc(num_ret + 1, sizeof(Atom)); - for (i = 0; i < num_ret; i++) - _xdnd->types[i] = types[i]; - _xdnd->num_types = num_ret; - free(types); - } - else - { - _xdnd->types = calloc(4, sizeof(Atom)); - _xdnd->types[0] = xevent->xclient.data.l[2]; - _xdnd->types[1] = xevent->xclient.data.l[3]; - _xdnd->types[2] = xevent->xclient.data.l[4]; - _xdnd->num_types = 3; - } + { + Ecore_X_Event_Xdnd_Enter *e; + Ecore_X_DND_Protocol *_xdnd; + unsigned long three; - _xdnd->state = ECORE_X_DND_TARGET_ENTERED; + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)); + if (!e) return; + + _xdnd = _ecore_x_dnd_protocol_get(); + _xdnd->source = xevent->xclient.data.l[0]; + _xdnd->dest = xevent->xclient.window; + _xdnd->version = (int) (xevent->xclient.data.l[1] >> 24); + if (_xdnd->version > ECORE_X_DND_VERSION) + { + printf("DND: Requested version %d, we only support up to %d\n", _xdnd->version, + ECORE_X_DND_VERSION); + return; + } + + if ((three = xevent->xclient.data.l[1] & 0x1UL)) + { + /* source supports more than 3 types, fetch property */ + unsigned char *data; + Ecore_X_Atom *types; + int i, num_ret; + if (!(ecore_x_window_prop_property_get(_xdnd->source, + ECORE_X_ATOM_XDND_TYPE_LIST, + XA_ATOM, + 32, + &data, + &num_ret))) + { + printf("DND: Could not fetch data type list from source window, aborting.\n"); + return; + } + types = (Ecore_X_Atom *)data; + e->types = calloc(num_ret, sizeof(char *)); + for (i = 0; i < num_ret; i++) + e->types[i] = XGetAtomName(_ecore_x_disp, types[i]); + e->num_types = num_ret; + } + else + { + e->types = calloc(3, sizeof(char *)); + e->types[0] = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]); + e->types[1] = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[3]); + e->types[2] = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[4]); + e->num_types = 3; + } + + _xdnd->state = ECORE_X_DND_TARGET_ENTERED; + + e->win = _xdnd->dest; + e->source = _xdnd->source; + e->time = CurrentTime; + _ecore_x_event_last_time = e->time; + ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL); + } - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)); - if (!e) return; - e->win = _xdnd->dest; - e->source = _xdnd->source; - e->time = CurrentTime; - _ecore_x_event_last_time = e->time; - ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, NULL, NULL); - } - /* Message Type: XdndPosition */ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION) - { - Ecore_X_Event_Xdnd_Position *e; - Ecore_X_DND_Protocol *_xdnd; + { + Ecore_X_Event_Xdnd_Position *e; + Ecore_X_DND_Protocol *_xdnd; - _xdnd = _ecore_x_dnd_protocol_get(); - _xdnd->source = xevent->xclient.data.l[0]; - _xdnd->dest = xevent->xclient.window; - _xdnd->pos.x = xevent->xclient.data.l[2] >> 16; - _xdnd->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL; - _xdnd->action = xevent->xclient.data.l[4]; /* Version 2 */ - /* TODO: Resolve a suitable method for enumerating Xdnd actions */ + _xdnd = _ecore_x_dnd_protocol_get(); + _xdnd->source = xevent->xclient.data.l[0]; + _xdnd->dest = xevent->xclient.window; + _xdnd->pos.x = xevent->xclient.data.l[2] >> 16; + _xdnd->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL; + _xdnd->action = xevent->xclient.data.l[4]; /* Version 2 */ + /* TODO: Resolve a suitable method for enumerating Xdnd actions */ - /* Would it be feasible to handle the processing of this message - * within ecore? I think not, but someone might have an idea here. */ + /* Would it be feasible to handle the processing of this message + * within ecore? I think not, but someone might have an idea here. */ + + _ecore_x_event_last_time = (_xdnd->version >= 1) ? + (Time)xevent->xclient.data.l[3] : CurrentTime; + + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position)); + if (!e) return; + e->win = _xdnd->dest; + e->source = _xdnd->source; + e->position.x = _xdnd->pos.x; + e->position.y = _xdnd->pos.y; + e->time = xevent->xclient.data.l[3]; /* Version 1 */ + e->action = _xdnd->action; + ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL); + } - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position)); - if (!e) return; - e->win = _xdnd->dest; - e->source = _xdnd->source; - e->position.x = _xdnd->pos.x; - e->position.y = _xdnd->pos.y; - e->time = xevent->xclient.data.l[3]; /* Version 1 */ - e->action = _xdnd->action; - ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL); - } - /* Message Type: XdndStatus */ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS) - { - Ecore_X_Event_Xdnd_Status *e; - Ecore_X_DND_Protocol *_xdnd; + { + Ecore_X_Event_Xdnd_Status *e; + Ecore_X_DND_Protocol *_xdnd; - _xdnd = _ecore_x_dnd_protocol_get(); - /* Make sure source/target match */ - if (_xdnd->source != xevent->xclient.window - || _xdnd->dest != (Window)xevent->xclient.data.l[0]) - return; - _xdnd->will_accept = xevent->xclient.data.l[1] & 0x1UL; - _xdnd->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1; + _xdnd = _ecore_x_dnd_protocol_get(); + /* Make sure source/target match */ + if ((_xdnd->source != xevent->xclient.window ) + || (_xdnd->dest != (Window)xevent->xclient.data.l[0])) + return; + _xdnd->will_accept = xevent->xclient.data.l[1] & 0x1UL; + _xdnd->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1; - _xdnd->rectangle.x = xevent->xclient.data.l[2] >> 16; - _xdnd->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL; - _xdnd->rectangle.width = xevent->xclient.data.l[3] >> 16; - _xdnd->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL; + _xdnd->rectangle.x = xevent->xclient.data.l[2] >> 16; + _xdnd->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL; + _xdnd->rectangle.width = xevent->xclient.data.l[3] >> 16; + _xdnd->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL; - _xdnd->accepted_action = xevent->xclient.data.l[4]; + _xdnd->accepted_action = xevent->xclient.data.l[4]; - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status)); - if (!e) return; - e->win = _xdnd->source; - e->target = _xdnd->dest; - e->will_accept = _xdnd->will_accept; - e->rectangle.x = _xdnd->rectangle.x; - e->rectangle.y = _xdnd->rectangle.y; - e->rectangle.width = _xdnd->rectangle.width; - e->rectangle.height = _xdnd->rectangle.height; - e->action = _xdnd->accepted_action; + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status)); + if (!e) return; + e->win = _xdnd->source; + e->target = _xdnd->dest; + e->will_accept = _xdnd->will_accept; + e->rectangle.x = _xdnd->rectangle.x; + e->rectangle.y = _xdnd->rectangle.y; + e->rectangle.width = _xdnd->rectangle.width; + e->rectangle.height = _xdnd->rectangle.height; + e->action = _xdnd->accepted_action; - ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL); - } + ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL); + } /* Message Type: XdndLeave */ /* Pretend the whole thing never happened, sort of */ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE) - { - Ecore_X_Event_Xdnd_Leave *e; - Ecore_X_DND_Protocol *_xdnd; + { + Ecore_X_Event_Xdnd_Leave *e; + Ecore_X_DND_Protocol *_xdnd; - _xdnd = _ecore_x_dnd_protocol_get(); - /* Match source/target */ - if (_xdnd->source != (Window)xevent->xclient.data.l[0] - || _xdnd->dest != xevent->xclient.window) - return; - if (_xdnd->types) - free(_xdnd->types); - _xdnd->num_types = 0; - /* XXX: May need to reset event handler callbacks as well */ - _xdnd->state = ECORE_X_DND_IDLE; + _xdnd = _ecore_x_dnd_protocol_get(); + /* Match source/target */ + if ((_xdnd->source != (Window)xevent->xclient.data.l[0]) + || (_xdnd->dest != xevent->xclient.window)) + return; + /* XXX: May need to reset event handler callbacks as well */ + _xdnd->state = ECORE_X_DND_IDLE; - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave)); - if (!e) return; - e->win = _xdnd->dest; - e->source = _xdnd->source; - ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL); - } + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave)); + if (!e) return; + e->win = _xdnd->dest; + e->source = _xdnd->source; + ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL); + } else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP) - { - Ecore_X_Event_Xdnd_Drop *e; - Ecore_X_DND_Protocol *_xdnd; - Ecore_X_Time timestamp; + { + Ecore_X_Event_Xdnd_Drop *e; + Ecore_X_DND_Protocol *_xdnd; + Ecore_X_Time timestamp; - _xdnd = _ecore_x_dnd_protocol_get(); - /* Match source/target */ - if (_xdnd->source != (Window)xevent->xclient.data.l[0] - || _xdnd->dest != xevent->xclient.window) - return; - - timestamp = (_xdnd->version >= (int)1) ? - (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time; - - XConvertSelection(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, - _xdnd->dest, ECORE_X_ATOM_SELECTION_PROP_XDND, _xdnd->dest, - timestamp); + _xdnd = _ecore_x_dnd_protocol_get(); + /* Match source/target */ + if ((_xdnd->source != (Window)xevent->xclient.data.l[0]) + || (_xdnd->dest != xevent->xclient.window)) + return; - /* FIXME: Have to wait for SelectionNotify before we can send - * XdndFinished. Stupid, retarded protocols, gah! */ + timestamp = (_xdnd->version >= 1) ? + (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time; - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop)); - if (!e) return; - e->win = _xdnd->dest; - e->source = _xdnd->source; - e->time = timestamp; - e->action = _xdnd->action; - e->position.x = _xdnd->pos.x; - e->position.y = _xdnd->pos.y; - ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL); - } + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop)); + if (!e) return; + e->win = _xdnd->dest; + e->source = _xdnd->source; + e->time = timestamp; + e->action = _xdnd->action; + e->position.x = _xdnd->pos.x; + e->position.y = _xdnd->pos.y; + ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL); + } /* Message Type: XdndFinished */ else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED) - { - Ecore_X_Event_Xdnd_Finished *e; - Ecore_X_DND_Protocol *_xdnd; - int completed = 1; + { + Ecore_X_Event_Xdnd_Finished *e; + Ecore_X_DND_Protocol *_xdnd; + int completed = 1; - _xdnd = _ecore_x_dnd_protocol_get(); - /* Match source/target */ - if (_xdnd->source != xevent->xclient.window - || _xdnd->dest != (Window)xevent->xclient.data.l[0]) - return; + _xdnd = _ecore_x_dnd_protocol_get(); + /* Match source/target */ + if ((_xdnd->source != xevent->xclient.window) + || (_xdnd->dest != (Window)xevent->xclient.data.l[0])) + return; - if (_xdnd->version >= 5 && (xevent->xclient.data.l[1] & 0x1UL)) - { - /* Target successfully performed drop action */ - _xdnd->state = ECORE_X_DND_IDLE; - } else { - completed = 0; - _xdnd->state = ECORE_X_DND_TARGET_CONVERTING; - - /* FIXME: Probably need to add a timer to switch back to idle - * and discard the selection data */ - } + if ((_xdnd->version >= 5) && (xevent->xclient.data.l[1] & 0x1UL)) + { + /* Target successfully performed drop action */ + _xdnd->state = ECORE_X_DND_IDLE; + } else { + completed = 0; + _xdnd->state = ECORE_X_DND_TARGET_CONVERTING; - e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished)); - if (!e) return; - e->win = _xdnd->source; - e->target = _xdnd->dest; - e->completed = completed; - if (_xdnd->version >= 5) - { - _xdnd->accepted_action = xevent->xclient.data.l[2]; - e->action = _xdnd->accepted_action; - } - else - { - _xdnd->accepted_action = 0; - e->action = _xdnd->action; - } + /* FIXME: Probably need to add a timer to switch back to idle + * and discard the selection data */ + } - ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL); + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished)); + if (!e) return; + e->win = _xdnd->source; + e->target = _xdnd->dest; + e->completed = completed; + if (_xdnd->version >= 5) + { + _xdnd->accepted_action = xevent->xclient.data.l[2]; + e->action = _xdnd->accepted_action; + } + else + { + _xdnd->accepted_action = 0; + e->action = _xdnd->action; + } - } + ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL); + } else - { - Ecore_X_Event_Client_Message *e; - int i; - - e = (Ecore_X_Event_Client_Message *) calloc(1, sizeof(Ecore_X_Event_Client_Message)); - e->win = xevent->xclient.window; - e->message_type = xevent->xclient.message_type; - e->format = xevent->xclient.format; - for(i = 0; i < 5; i++) - e->data.l[i] = xevent->xclient.data.l[i]; - - ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL); - } + { + Ecore_X_Event_Client_Message *e; + int i; + + e = (Ecore_X_Event_Client_Message *) calloc(1, sizeof(Ecore_X_Event_Client_Message)); + e->win = xevent->xclient.window; + e->message_type = xevent->xclient.message_type; + e->format = xevent->xclient.format; + for(i = 0; i < 5; i++) + e->data.l[i] = xevent->xclient.data.l[i]; + + ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL); + } } void diff --git a/legacy/ecore/src/lib/ecore_x/ecore_x_private.h b/legacy/ecore/src/lib/ecore_x/ecore_x_private.h index 5b123764fa..1db026f267 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_private.h +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_private.h @@ -91,9 +91,7 @@ typedef struct _Ecore_X_DND_Protocol Time time; - Ecore_X_Atom *types; Ecore_X_Atom action, accepted_action; - int num_types; int will_accept; int suppress; 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 d08d642490..2603c282ab 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_selection.c @@ -6,7 +6,7 @@ #include "Ecore_X.h" #include "Ecore_X_Atoms.h" -static Ecore_X_Selection_Data selections[3]; +static Ecore_X_Selection_Data selections[4]; static Ecore_X_Selection_Data request_data[4]; static Ecore_X_Selection_Converter *converters = NULL; @@ -41,11 +41,12 @@ _ecore_x_selection_shutdown(void) return; /* free the selection converters */ - while (cnv) { + while (cnv) + { tmp = cnv->next; free(cnv); cnv = tmp; - } + } converters = NULL; } @@ -56,22 +57,22 @@ _ecore_x_selection_request_data_get(Ecore_X_Atom selection, void **buf, int *len int i; char *data; if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - i = 0; + i = 0; else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - i = 1; + i = 1; else if (selection == ECORE_X_ATOM_SELECTION_XDND) - i = 2; + i = 2; else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) - i = 3; + i = 3; else - return; + return; if (!request_data[i].data || !request_data[i].length) - { - *len = 0; - *buf = NULL; - return; - } + { + *len = 0; + *buf = NULL; + return; + } data = malloc(request_data[i].length); memcpy(data, request_data[i].data, request_data[i].length); @@ -145,15 +146,15 @@ _ecore_x_selection_request_data_set(Ecore_X_Selection_Data data) { int i; if (data.selection == ECORE_X_ATOM_SELECTION_PRIMARY) - i = 0; + i = 0; else if (data.selection == ECORE_X_ATOM_SELECTION_SECONDARY) - i = 1; + i = 1; else if (data.selection == ECORE_X_ATOM_SELECTION_XDND) - i = 2; + i = 2; else if (data.selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) - i = 3; + i = 3; else - return; + return; request_data[i] = data; } @@ -162,13 +163,15 @@ Ecore_X_Selection_Data * _ecore_x_selection_get(Atom selection) { if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - return &selections[0]; + return &selections[0]; else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - return &selections[1]; + return &selections[1]; + else if (selection == ECORE_X_ATOM_SELECTION_XDND) + return &selections[2]; else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD) - return &selections[2]; + return &selections[3]; else - return NULL; + return NULL; } int @@ -179,35 +182,37 @@ _ecore_x_selection_set(Window w, unsigned char *data, int size, Atom selection) XSetSelectionOwner(_ecore_x_disp, selection, w, _ecore_x_event_last_time); if (XGetSelectionOwner(_ecore_x_disp, selection) != w) - return 0; + return 0; if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - in = 0; + in = 0; else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - in = 1; + in = 1; + else if (selection == ECORE_X_ATOM_SELECTION_XDND) + in = 2; else - in = 2; - + in = 3; + if (data) - { - selections[in].win = w; - selections[in].selection = selection; - selections[in].length = size; - selections[in].time = _ecore_x_event_last_time; - - buf = malloc(size); - memcpy(buf, data, size); - selections[in].data = buf; - } + { + selections[in].win = w; + selections[in].selection = selection; + selections[in].length = size; + selections[in].time = _ecore_x_event_last_time; + + buf = malloc(size); + memcpy(buf, data, size); + selections[in].data = buf; + } else - { - if (selections[in].data) - { - free(selections[in].data); - memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data)); - } - } - + { + if (selections[in].data) + { + free(selections[in].data); + memset(&selections[in], 0, sizeof(Ecore_X_Selection_Data)); + } + } + return 1; } @@ -218,9 +223,6 @@ _ecore_x_selection_set(Window w, unsigned char *data, int size, Atom selection) * @param size The size of the data buffer in bytes * @return Returns 1 if the ownership of the selection was successfully * claimed, or 0 if unsuccessful. - * - * Get the converted data from a previous PRIMARY selection - * request. The buffer must be freed when done with. */ int ecore_x_selection_primary_set(Ecore_X_Window w, unsigned char *data, int size) @@ -247,9 +249,6 @@ ecore_x_selection_primary_clear(void) * @param size The size of the data buffer in bytes * @return Returns 1 if the ownership of the selection was successfully * claimed, or 0 if unsuccessful. - * - * Get the converted data from a previous SECONDARY selection - * request. The buffer must be freed when done with. */ int ecore_x_selection_secondary_set(Ecore_X_Window w, unsigned char *data, int size) @@ -269,6 +268,32 @@ ecore_x_selection_secondary_clear(void) return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_SECONDARY); } +/** + * Claim ownership of the XDND selection and set its data. + * @param w The window to which this selection belongs + * @param data The data associated with the selection + * @param size The size of the data buffer in bytes + * @return Returns 1 if the ownership of the selection was successfully + * claimed, or 0 if unsuccessful. + */ +int +ecore_x_selection_xdnd_set(Ecore_X_Window w, unsigned char *data, int size) +{ + return _ecore_x_selection_set(w, data, size, ECORE_X_ATOM_SELECTION_XDND); +} + +/** + * Release ownership of the XDND selection + * @return Returns 1 if the selection was successfully cleared, + * or 0 if unsuccessful. + * + */ +int +ecore_x_selection_xdnd_clear(void) +{ + return _ecore_x_selection_set(None, NULL, 0, ECORE_X_ATOM_SELECTION_XDND); +} + /** * Claim ownership of the CLIPBOARD selection and set its data. * @param w The window to which this selection belongs @@ -302,25 +327,25 @@ Atom _ecore_x_selection_target_atom_get(char *target) { Atom x_target; - + if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) - x_target = ECORE_X_ATOM_TEXT; + x_target = ECORE_X_ATOM_TEXT; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) - x_target = ECORE_X_ATOM_COMPOUND_TEXT; + x_target = ECORE_X_ATOM_COMPOUND_TEXT; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) - x_target = ECORE_X_ATOM_STRING; + x_target = ECORE_X_ATOM_STRING; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) - x_target = ECORE_X_ATOM_UTF8_STRING; + x_target = ECORE_X_ATOM_UTF8_STRING; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_FILENAME)) - x_target = ECORE_X_ATOM_FILE_NAME; + x_target = ECORE_X_ATOM_FILE_NAME; else - { - char *atom_name; - atom_name = malloc(strlen(target) + 4); - sprintf(atom_name, "_E_%s", target); - x_target = XInternAtom(_ecore_x_disp, atom_name, False); - free(atom_name); - } + { + char *atom_name; + atom_name = malloc(strlen(target) + 4); + sprintf(atom_name, "_E_%s", target); + x_target = XInternAtom(_ecore_x_disp, atom_name, False); + free(atom_name); + } return x_target; } @@ -329,15 +354,15 @@ char * _ecore_x_selection_target_get(Atom target) { if (target == ECORE_X_ATOM_FILE_NAME) - return strdup(ECORE_X_SELECTION_TARGET_FILENAME); + return strdup(ECORE_X_SELECTION_TARGET_FILENAME); else if (target == ECORE_X_ATOM_STRING) - return strdup(ECORE_X_SELECTION_TARGET_STRING); + return strdup(ECORE_X_SELECTION_TARGET_STRING); else if (target == ECORE_X_ATOM_UTF8_STRING) - return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING); + return strdup(ECORE_X_SELECTION_TARGET_UTF8_STRING); else if (target == ECORE_X_ATOM_TEXT) - return strdup(ECORE_X_SELECTION_TARGET_TEXT); + return strdup(ECORE_X_SELECTION_TARGET_TEXT); else - return strdup(ECORE_X_SELECTION_TARGET_TEXT); + return strdup(ECORE_X_SELECTION_TARGET_TEXT); } static void @@ -346,18 +371,16 @@ _ecore_x_selection_request(Ecore_X_Window w, Ecore_X_Atom selection, char *targe Ecore_X_Atom target, prop; target = _ecore_x_selection_target_atom_get(target_str); - + if (selection == ECORE_X_ATOM_SELECTION_PRIMARY) - prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY; + prop = ECORE_X_ATOM_SELECTION_PROP_PRIMARY; else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY) - prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY; - else if (selection == ECORE_X_ATOM_SELECTION_XDND) - prop = ECORE_X_ATOM_SELECTION_PROP_XDND; + prop = ECORE_X_ATOM_SELECTION_PROP_SECONDARY; else - prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; + prop = ECORE_X_ATOM_SELECTION_PROP_CLIPBOARD; XConvertSelection(_ecore_x_disp, selection, target, prop, - w, _ecore_x_event_last_time); + w, _ecore_x_event_last_time); } void @@ -372,6 +395,17 @@ ecore_x_selection_secondary_request(Ecore_X_Window w, char *target) _ecore_x_selection_request(w, ECORE_X_ATOM_SELECTION_SECONDARY, target); } +void +ecore_x_selection_xdnd_request(Ecore_X_Window w, char *target) +{ + Ecore_X_Atom atom; + + atom = ecore_x_atom_get(target); + XConvertSelection(_ecore_x_disp, ECORE_X_ATOM_SELECTION_XDND, atom, + ECORE_X_ATOM_SELECTION_PROP_XDND, w, + _ecore_x_event_last_time); +} + void ecore_x_selection_clipboard_request(Ecore_X_Window w, char *target) { @@ -402,9 +436,11 @@ ecore_x_selection_converter_atom_add(Ecore_X_Atom target, cnv->next = calloc(1, sizeof(Ecore_X_Selection_Converter)); cnv = cnv->next; - } else { - converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); - cnv = converters; + } + else + { + converters = calloc(1, sizeof(Ecore_X_Selection_Converter)); + cnv = converters; } cnv->target = target; cnv->convert = func; @@ -416,12 +452,12 @@ ecore_x_selection_converter_add(char *target, int (*func)(char *target, void *data, int size, void **data_ret, int *size_ret)) { Ecore_X_Atom x_target; - + if (!func || !target) - return; + return; x_target = _ecore_x_selection_target_atom_get(target); - + ecore_x_selection_converter_atom_add(x_target, func); } @@ -429,17 +465,17 @@ void ecore_x_selection_converter_atom_del(Ecore_X_Atom target) { Ecore_X_Selection_Converter *cnv, *prev_cnv; - + prev_cnv = NULL; cnv = converters; - + while (cnv) { if (cnv->target == target) { - if (target == ECORE_X_ATOM_TEXT || - target == ECORE_X_ATOM_COMPOUND_TEXT || - target == ECORE_X_ATOM_STRING) + if ((target == ECORE_X_ATOM_TEXT) || + (target == ECORE_X_ATOM_COMPOUND_TEXT) || + (target == ECORE_X_ATOM_STRING)) { cnv->convert = _ecore_x_selection_converter_text; } @@ -463,10 +499,10 @@ void ecore_x_selection_converter_del(char *target) { Ecore_X_Atom x_target; - + if (!target) - return; - + return; + x_target = _ecore_x_selection_target_atom_get(target); ecore_x_selection_converter_atom_del(x_target); } @@ -484,7 +520,7 @@ _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 (cnv->target == target) @@ -509,31 +545,32 @@ _ecore_x_selection_convert(Atom selection, Atom target, void **data_ret) /* TODO: We need to work out a mechanism for automatic conversion to any requested * locale using Ecore_Txt functions */ /* Converter for standard non-utf8 text targets */ -static int _ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret) +static int +_ecore_x_selection_converter_text(char *target, void *data, int size, void **data_ret, int *size_ret) { XTextProperty text_prop; char *mystr; XICCEncodingStyle style; - + if (!data || !size) - return 0; + return 0; if (!strcmp(target, ECORE_X_SELECTION_TARGET_TEXT)) - style = XTextStyle; + style = XTextStyle; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_COMPOUND_TEXT)) - style = XCompoundTextStyle; + style = XCompoundTextStyle; else if (!strcmp(target, ECORE_X_SELECTION_TARGET_STRING)) - style = XStringStyle; + style = XStringStyle; #ifdef X_HAVE_UTF8_STRING else if (!strcmp(target, ECORE_X_SELECTION_TARGET_UTF8_STRING)) - style = XUTF8StringStyle; + style = XUTF8StringStyle; #endif else - return 0; - + return 0; + if (!(mystr = strdup(data))) - return 0; - + return 0; + if (XmbTextListToTextProperty(_ecore_x_disp, &mystr, 1, style, &text_prop) == Success) { int bufsize = strlen(text_prop.value) + 1;