diff --git a/legacy/ecore/src/lib/ecore_x/Ecore_X.h b/legacy/ecore/src/lib/ecore_x/Ecore_X.h index f567986ced..5ec4e86d11 100644 --- a/legacy/ecore/src/lib/ecore_x/Ecore_X.h +++ b/legacy/ecore/src/lib/ecore_x/Ecore_X.h @@ -22,6 +22,11 @@ extern "C" { typedef void Ecore_X_Reply; #endif +typedef struct _Ecore_X_Rectangle { + int x, y; + unsigned int width, height; +} Ecore_X_Rectangle; + #define ECORE_X_SELECTION_TARGET_TEXT "TEXT" #define ECORE_X_SELECTION_TARGET_COMPOUND_TEXT "COMPOUND_TEXT" #define ECORE_X_SELECTION_TARGET_STRING "STRING" @@ -30,13 +35,11 @@ typedef void Ecore_X_Reply; #define ECORE_X_DND_VERSION 5 -typedef enum _Ecore_X_DND_Action { - ECORE_X_DND_ACTION_COPY, - ECORE_X_DND_ACTION_MOVE, - ECORE_X_DND_ACTION_LINK, - ECORE_X_DND_ACTION_ASK, - ECORE_X_DND_ACTION_PRIVATE -} Ecore_X_DND_Action; +extern Ecore_X_Atom ECORE_X_DND_ACTION_COPY; +extern Ecore_X_Atom ECORE_X_DND_ACTION_MOVE; +extern Ecore_X_Atom ECORE_X_DND_ACTION_LINK; +extern Ecore_X_Atom ECORE_X_DND_ACTION_ASK; +extern Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE; typedef enum _Ecore_X_Selection { ECORE_X_SELECTION_PRIMARY, @@ -407,14 +410,14 @@ struct _Ecore_X_Event_Xdnd_Position int x, y; } position; Ecore_X_Time time; - Ecore_X_DND_Action action; + Ecore_X_Atom action; }; struct _Ecore_X_Event_Xdnd_Status { Ecore_X_Window win, target; int drop_accept; - Ecore_X_DND_Action action; + Ecore_X_Atom action; }; struct _Ecore_X_Event_Xdnd_Leave @@ -426,7 +429,7 @@ struct _Ecore_X_Event_Xdnd_Drop { Ecore_X_Window win, source; Ecore_X_Time time; - Ecore_X_DND_Action action; + Ecore_X_Atom action; struct { int x, y; } position; @@ -436,7 +439,7 @@ struct _Ecore_X_Event_Xdnd_Finished { Ecore_X_Window win, target; int completed; - Ecore_X_DND_Action action; + Ecore_X_Atom action; }; struct _Ecore_X_Event_Client_Message @@ -557,6 +560,13 @@ extern int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE; extern int ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE; extern int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE; extern int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE; + +extern int ECORE_X_EVENT_XDND_ENTER; +extern int ECORE_X_EVENT_XDND_POSITION; +extern int ECORE_X_EVENT_XDND_STATUS; +extern int ECORE_X_EVENT_XDND_LEAVE; +extern int ECORE_X_EVENT_XDND_DROP; +extern int ECORE_X_EVENT_XDND_FINISHED; extern int ECORE_X_MODIFIER_SHIFT; extern int ECORE_X_MODIFIER_CTRL; @@ -684,6 +694,9 @@ void ecore_x_selection_converter_atom_add(Ecore_X_Atom target, int ( void ecore_x_selection_converter_del(char *target); void ecore_x_selection_converter_atom_del(Ecore_X_Atom target); +void ecore_x_dnd_aware_set(Ecore_X_Window win, int on); +int ecore_x_dnd_version_get(Ecore_X_Window win); +int ecore_x_dnd_begin (Ecore_X_Window source, unsigned char *data, int size); Ecore_X_Window ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h); 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.c b/legacy/ecore/src/lib/ecore_x/ecore_x.c index 59d05b113b..913bf1b8e9 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x.c @@ -51,10 +51,13 @@ Atom _ecore_x_atom_xdnd_enter = 0; Atom _ecore_x_atom_xdnd_type_list = 0; Atom _ecore_x_atom_xdnd_position = 0; Atom _ecore_x_atom_xdnd_action_copy = 0; +Atom _ecore_x_atom_xdnd_action_move = 0; +Atom _ecore_x_atom_xdnd_action_link = 0; Atom _ecore_x_atom_xdnd_action_private = 0; Atom _ecore_x_atom_xdnd_action_ask = 0; Atom _ecore_x_atom_xdnd_action_list = 0; Atom _ecore_x_atom_xdnd_action_description = 0; +Atom _ecore_x_atom_xdnd_proxy = 0; Atom _ecore_x_atom_xdnd_status = 0; Atom _ecore_x_atom_xdnd_drop = 0; Atom _ecore_x_atom_xdnd_finished = 0; @@ -134,6 +137,13 @@ Atom _ecore_x_atom_compound_text = 0; Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM] = {0}; +/* Xdnd atoms that need to be exposed to the application interface */ +Ecore_X_Atom ECORE_X_DND_ACTION_COPY = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_MOVE = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_LINK = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_ASK = 0; +Ecore_X_Atom ECORE_X_DND_ACTION_PRIVATE = 0; + int ECORE_X_EVENT_KEY_DOWN = 0; int ECORE_X_EVENT_KEY_UP = 0; int ECORE_X_EVENT_MOUSE_BUTTON_DOWN = 0; @@ -178,6 +188,13 @@ int ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = 0; int ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = 0; int ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = 0; +int ECORE_X_EVENT_XDND_ENTER = 0; +int ECORE_X_EVENT_XDND_POSITION = 0; +int ECORE_X_EVENT_XDND_STATUS = 0; +int ECORE_X_EVENT_XDND_LEAVE = 0; +int ECORE_X_EVENT_XDND_DROP = 0; +int ECORE_X_EVENT_XDND_FINISHED = 0; + int ECORE_X_MODIFIER_SHIFT = 0; int ECORE_X_MODIFIER_CTRL = 0; int ECORE_X_MODIFIER_ALT = 0; @@ -301,6 +318,13 @@ ecore_x_init(const char *name) ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE = ecore_event_type_new(); ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE = ecore_event_type_new(); ECORE_X_EVENT_WINDOW_PROP_DESKTOP_CHANGE = ecore_event_type_new(); + + ECORE_X_EVENT_XDND_ENTER = ecore_event_type_new(); + ECORE_X_EVENT_XDND_POSITION = ecore_event_type_new(); + ECORE_X_EVENT_XDND_STATUS = ecore_event_type_new(); + ECORE_X_EVENT_XDND_LEAVE = ecore_event_type_new(); + ECORE_X_EVENT_XDND_DROP = ecore_event_type_new(); + ECORE_X_EVENT_XDND_FINISHED = ecore_event_type_new(); } ECORE_X_MODIFIER_SHIFT = _ecore_x_key_mask_get(XK_Shift_L); @@ -352,14 +376,24 @@ ecore_x_init(const char *name) _ecore_x_atom_xdnd_enter = XInternAtom(_ecore_x_disp, "XdndEnter", False); _ecore_x_atom_xdnd_position = XInternAtom(_ecore_x_disp, "XdndPosition", False); _ecore_x_atom_xdnd_action_copy = XInternAtom(_ecore_x_disp, "XdndActionCopy", False); + _ecore_x_atom_xdnd_action_move = XInternAtom(_ecore_x_disp, "XdndActionMove", False); _ecore_x_atom_xdnd_action_private = XInternAtom(_ecore_x_disp, "XdndActionPrivate", False); _ecore_x_atom_xdnd_action_ask = XInternAtom(_ecore_x_disp, "XdndActionAsk", False); _ecore_x_atom_xdnd_action_list = XInternAtom(_ecore_x_disp, "XdndActionList", False); + _ecore_x_atom_xdnd_action_link = XInternAtom(_ecore_x_disp, "XdndActionLink", False); _ecore_x_atom_xdnd_action_description = XInternAtom(_ecore_x_disp, "XdndActionDescription", False); + _ecore_x_atom_xdnd_proxy = XInternAtom(_ecore_x_disp, "XdndProxy", False); _ecore_x_atom_xdnd_status = XInternAtom(_ecore_x_disp, "XdndStatus", False); _ecore_x_atom_xdnd_leave = XInternAtom(_ecore_x_disp, "XdndLeave", False); _ecore_x_atom_xdnd_drop = XInternAtom(_ecore_x_disp, "XdndDrop", False); _ecore_x_atom_xdnd_finished = XInternAtom(_ecore_x_disp, "XdndFinished", False); + + /* Initialize the globally defined xdnd atoms */ + ECORE_X_DND_ACTION_COPY = _ecore_x_atom_xdnd_action_copy; + ECORE_X_DND_ACTION_MOVE = _ecore_x_atom_xdnd_action_move; + ECORE_X_DND_ACTION_LINK = _ecore_x_atom_xdnd_action_link; + ECORE_X_DND_ACTION_ASK = _ecore_x_atom_xdnd_action_ask; + ECORE_X_DND_ACTION_PRIVATE = _ecore_x_atom_xdnd_action_private; _ecore_x_atom_net_supported = XInternAtom(_ecore_x_disp, "_NET_SUPPORTED", False); _ecore_x_atom_net_supporting_wm_check = XInternAtom(_ecore_x_disp, "_NET_SUPPORTING_WM_CHECK", False); 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 e1711d768c..991566aaa5 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_dnd.c @@ -13,19 +13,20 @@ _ecore_x_dnd_init (void) _xdnd->version = ECORE_X_DND_VERSION; _xdnd->source = None; _xdnd->dest = None; - _xdnd->state = ECORE_X_DND_FINISHED; + _xdnd->state = ECORE_X_DND_IDLE; } void -ecore_x_dnd_enabled_set (Ecore_X_Window win, int on) +ecore_x_dnd_aware_set (Ecore_X_Window win, int on) { - /* FIXME: This property needs to contain the version number */ - unsigned char *prop_data = "5"; + Atom prop_data = ECORE_X_DND_VERSION; + if (on) ecore_x_window_prop_property_set(win, _ecore_x_atom_xdnd_aware, - XA_ATOM, 8, prop_data, 1); + XA_ATOM, 32, &prop_data, 1); else ecore_x_window_prop_property_del(win, _ecore_x_atom_xdnd_aware); + /* TODO: Add dnd typelist to window properties */ } int @@ -35,10 +36,11 @@ ecore_x_dnd_version_get (Ecore_X_Window win) int num; if (ecore_x_window_prop_property_get(win, _ecore_x_atom_xdnd_aware, - XA_ATOM, 8, &prop_data, &num)) + XA_ATOM, 32, &prop_data, &num)) { + int version = (int) *prop_data; free(prop_data); - return 1; + return version; } else return 0; @@ -54,6 +56,9 @@ int ecore_x_dnd_begin (Ecore_X_Window source, unsigned char *data, int size) { unsigned char *buf; + + if (!ecore_x_dnd_version_get(source)) + return 0; /* Take ownership of XdndSelection */ XSetSelectionOwner(_ecore_x_disp, _ecore_x_atom_selection_xdnd, source, @@ -72,7 +77,7 @@ ecore_x_dnd_begin (Ecore_X_Window source, unsigned char *data, int size) _xdnd_selection.data = buf; _xdnd->source = source; - _xdnd->state = ECORE_X_DND_OUT; + _xdnd->state = ECORE_X_DND_DRAGGING; return 1; } 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 f4e40215f2..dbe8924036 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_events.c +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_events.c @@ -1042,34 +1042,83 @@ _ecore_x_event_handle_client_message(XEvent *xevent) { Ecore_X_Event_Xdnd_Enter *e; Ecore_X_DND_Protocol *_xdnd; - short *ldata; + unsigned long three; _xdnd = _ecore_x_dnd_protocol_get(); _xdnd->source = xevent->xclient.data.l[0]; _xdnd->dest = xevent->xclient.window; - /* gcc won't let us do this */ - /* _xdnd->version = (int) (xevent->xclient.data.l >> 24); */ - ldata = (short *) &(xevent->xclient.data.l); - _xdnd->version = (int) ldata[0]; + _xdnd->version = (int) (xevent->xclient.data.l[1] >> 24); if (_xdnd->version > ECORE_X_DND_VERSION) - return 0; + { + printf("DND: Requested version %d, we only support up to %d\n", _xdnd->version, + ECORE_X_DND_VERSION); + return; + } - if (xevent->xclient.data.l[1] & 0x0001) + 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; } + _xdnd->state = ECORE_X_DND_TARGET_ENTERED; + e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)); if (!e) return; e->win = _xdnd->dest; e->source = _xdnd->source; e->time = CurrentTime; + ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_generic, NULL); + } + + else if (xevent->xclient.message_type == _ecore_x_atom_xdnd_position) + { + 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] & 0x00FF; + _xdnd->action = xevent->xclient.data.l[4]; /* Version 2 */ + /* TODO: Resolve a suitable method for enumerating Xdnd actions */ + + 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, _ecore_x_event_free_generic, NULL); } else { 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 9cf174c9af..863e326c57 100644 --- a/legacy/ecore/src/lib/ecore_x/ecore_x_private.h +++ b/legacy/ecore/src/lib/ecore_x/ecore_x_private.h @@ -61,16 +61,26 @@ typedef struct _Ecore_X_DND_Protocol Window source, dest; enum { - ECORE_X_DND_OUT, - ECORE_X_DND_IN, + ECORE_X_DND_IDLE, + ECORE_X_DND_DRAGGING, + ECORE_X_DND_ENTERED, + ECORE_X_DND_TARGET_ENTERED, + ECORE_X_DND_TARGET_CONVERTING, ECORE_X_DND_FINISHED } state; struct { - int x, y, w, h; - } status_rect; + short x, y; + unsigned short width, height; + } rectangle; - Atom types[256]; + struct { + int x, y; + } pos; + + Atom *types; + Atom action; + int num_types; struct { Ecore_Event_Handler *mouse_move; @@ -186,8 +196,6 @@ extern Atom _ecore_x_atom_xdnd_status; extern Atom _ecore_x_atom_xdnd_drop; extern Atom _ecore_x_atom_xdnd_finished; -extern Ecore_X_DND_Protocol *_xdnd; - void _ecore_x_error_handler_init(void); void _ecore_x_event_handle_key_press(XEvent *xevent); void _ecore_x_event_handle_key_release(XEvent *xevent);