discomfitor pushed a commit to branch master.

commit db20c24837bf1a894b302e7582b10fda4e6fa8d5
Author: Mike Blumenkrantz <[email protected]>
Date:   Wed May 29 09:15:21 2013 +0100

    dnd overhaul
    
    * use separate list for active handlers to avoid unnecessary iterating
    
    * use similar function to efm for detecting supported dnd types
---
 src/bin/e_dnd.c | 192 ++++++++++++++++++++++++++------------------------------
 1 file changed, 89 insertions(+), 103 deletions(-)

diff --git a/src/bin/e_dnd.c b/src/bin/e_dnd.c
index 18c591f..ca23b6b 100644
--- a/src/bin/e_dnd.c
+++ b/src/bin/e_dnd.c
@@ -38,6 +38,7 @@ struct _XDnd
 
 static Eina_List *_event_handlers = NULL;
 static Eina_List *_drop_handlers = NULL;
+static Eina_List *_active_handlers = NULL;
 static Eina_Hash *_drop_win_hash = NULL;
 
 static Ecore_X_Window _drag_win = 0;
@@ -50,10 +51,20 @@ static XDnd *_xdnd = NULL;
 #define XDS_ATOM "XdndDirectSave0"
 static Ecore_X_Atom _xds_atom = 0;
 static Ecore_X_Atom _text_atom = 0;
-static const char *_type_text_uri_list = NULL;
-static const char *_type_xds = NULL;
-static const char *_type_text_x_moz_url = NULL;
-static const char *_type_enlightenment_x_file = NULL;
+
+static Eina_Stringshare *_type_text_uri_list = NULL;
+static Eina_Stringshare *_type_xds = NULL;
+static Eina_Stringshare *_type_text_x_moz_url = NULL;
+static Eina_Stringshare *_type_enlightenment_x_file = NULL;
+
+static Eina_Stringshare **_e_dnd_types[] =
+{
+   &_type_text_uri_list,
+   &_type_xds,
+   //&_type_text_x_moz_url,
+   //&_type_enlightenment_x_file,
+   NULL
+};
 
 static Eina_Hash *_drop_handlers_responsives;
 static Ecore_X_Atom _action;
@@ -94,6 +105,7 @@ e_dnd_shutdown(void)
 {
    E_FREE_LIST(_drag_list, e_object_del);
 
+   _active_handlers = eina_list_free(_active_handlers);
    E_FREE_LIST(_drop_handlers, e_drop_handler_del);
 
    E_FREE_LIST(_event_handlers, ecore_event_handler_del);
@@ -239,13 +251,14 @@ e_drag_start(E_Drag *drag, int x, int y)
    drag->dx = x - drag->x;
    drag->dy = y - drag->y;
 
+   _active_handlers = eina_list_free(_active_handlers);
    EINA_LIST_FOREACH(_drop_handlers, l, h)
      {
         unsigned int i, j;
+        Eina_Bool active = h->active;
 
         h->active = 0;
-        eina_stringshare_del(h->active_type);
-        h->active_type = NULL;
+        eina_stringshare_replace(&h->active_type, NULL);
         for (i = 0; i < h->num_types; i++)
           {
              for (j = 0; j < drag->num_types; j++)
@@ -259,6 +272,13 @@ e_drag_start(E_Drag *drag, int x, int y)
                }
              if (h->active) break;
           }
+        if (h->active != active)
+          {
+             if (h->active)
+               _active_handlers = eina_list_append(_active_handlers, h);
+             else
+               _active_handlers = eina_list_remove(_active_handlers, h);
+          }
         h->entered = 0;
      }
 
@@ -295,14 +315,14 @@ e_drag_xdnd_start(E_Drag *drag, int x, int y)
 
    drag->dx = x - drag->x;
    drag->dy = y - drag->y;
-
+   _active_handlers = eina_list_free(_active_handlers);
    EINA_LIST_FOREACH(_drop_handlers, l, h)
      {
         unsigned int i, j;
+        Eina_Bool active = h->active;
 
         h->active = 0;
-        eina_stringshare_del(h->active_type);
-        h->active_type = NULL;
+        eina_stringshare_replace(&h->active_type, NULL);
         for (i = 0; i < h->num_types; i++)
           {
              for (j = 0; j < drag->num_types; j++)
@@ -316,6 +336,13 @@ e_drag_xdnd_start(E_Drag *drag, int x, int y)
                }
              if (h->active) break;
           }
+        if (h->active != active)
+          {
+             if (h->active)
+               _active_handlers = eina_list_append(_active_handlers, h);
+             else
+               _active_handlers = eina_list_remove(_active_handlers, h);
+          }
         h->entered = 0;
      }
 
@@ -431,6 +458,8 @@ e_drop_handler_del(E_Drop_Handler *handler)
      return;
 
    _drop_handlers = eina_list_remove(_drop_handlers, handler);
+   if (handler->active)
+     _active_handlers = eina_list_remove(_active_handlers, handler);
    for (i = 0; i < handler->num_types; i++)
      eina_stringshare_del(handler->types[i]);
    eina_stringshare_del(handler->active_type);
@@ -544,6 +573,19 @@ e_dnd_util_text_uri_list_convert(char *data, int size)
 
 /* local subsystem functions */
 
+static Eina_Stringshare *
+_e_dnd_type_implemented(const char *type)
+{
+   const char ***t;
+
+   for (t = _e_dnd_types; *t; t++)
+     {
+        if (!strcmp(type, **t))
+          return **t;
+     }
+   return NULL;
+}
+
 static void
 _e_drag_move(E_Drag *drag, int x, int y)
 {
@@ -777,9 +819,8 @@ _e_drag_update(Ecore_X_Window root, int x, int y, 
Ecore_X_Atom action)
         else e_popup_hide(_drag_current->pop);
         _e_drag_move(_drag_current, x, y);
      }
-   EINA_LIST_FOREACH(_drop_handlers, l, h)
+   EINA_LIST_FOREACH(_active_handlers, l, h)
      {
-        if (!h->active) continue;
         _e_drag_coords_update(h, &dx, &dy);
         enter_ev.x = x - dx;
         enter_ev.y = y - dy;
@@ -937,10 +978,8 @@ _e_drag_end(int x, int y)
         leave_ev.x = 0;
         leave_ev.y = 0;
 
-        EINA_LIST_FOREACH(_drop_handlers, l, h)
+        EINA_LIST_FOREACH(_active_handlers, l, h)
           {
-             if (!h->active) continue;
-
              if (h->entered)
                {
                   if (h->cb.leave)
@@ -950,9 +989,8 @@ _e_drag_end(int x, int y)
           }
      }
 
-   EINA_LIST_FOREACH(_drop_handlers, l, h)
+   EINA_LIST_FOREACH(_active_handlers, l, h)
      {
-        if (!h->active) continue;
         _e_drag_coords_update(h, &dx, &dy);
         ev.x = x - dx;
         ev.y = y - dy;
@@ -1022,9 +1060,8 @@ _e_drag_xdnd_end(Ecore_X_Window win, int x, int y)
      {
         E_Drop_Handler *h;
 
-        EINA_LIST_FOREACH(_drop_handlers, l, h)
+        EINA_LIST_FOREACH(_active_handlers, l, h)
           {
-             if (!h->active) continue;
              _e_drag_coords_update(h, &dx, &dy);
              ev.x = x - dx;
              ev.y = y - dy;
@@ -1045,10 +1082,8 @@ _e_drag_xdnd_end(Ecore_X_Window win, int x, int y)
         leave_ev.x = 0;
         leave_ev.y = 0;
 
-        EINA_LIST_FOREACH(_drop_handlers, l, h)
+        EINA_LIST_FOREACH(_active_handlers, l, h)
           {
-             if (!h->active) continue;
-
              if (h->entered)
                {
                   if (h->cb.leave)
@@ -1077,9 +1112,9 @@ _e_drag_free(E_Drag *drag)
 
         leave_ev.x = 0;
         leave_ev.y = 0;
-        EINA_LIST_FOREACH(_drop_handlers, l, h)
+        EINA_LIST_FOREACH(_active_handlers, l, h)
           {
-             if ((h->active) && (h->entered))
+             if (h->entered)
                {
                   if (h->cb.leave)
                     h->cb.leave(h->cb.data, h->active_type, &leave_ev);
@@ -1105,9 +1140,8 @@ _e_drag_free(E_Drag *drag)
 static Eina_Bool
 _e_dnd_cb_key_down(void *data __UNUSED__, int type __UNUSED__, void *event)
 {
-   Ecore_Event_Key *ev;
+   Ecore_Event_Key *ev = event;
 
-   ev = event;
    if (ev->window != _drag_win) return ECORE_CALLBACK_PASS_ON;
 
    if (!_drag_current) return ECORE_CALLBACK_PASS_ON;
@@ -1121,9 +1155,8 @@ _e_dnd_cb_key_down(void *data __UNUSED__, int type 
__UNUSED__, void *event)
 static Eina_Bool
 _e_dnd_cb_key_up(void *data __UNUSED__, int type __UNUSED__, void *event)
 {
-   Ecore_Event_Key *ev;
+   Ecore_Event_Key *ev = event;
 
-   ev = event;
    if (ev->window != _drag_win) return ECORE_CALLBACK_PASS_ON;
 
    if (!_drag_current) return ECORE_CALLBACK_PASS_ON;
@@ -1137,9 +1170,8 @@ _e_dnd_cb_key_up(void *data __UNUSED__, int type 
__UNUSED__, void *event)
 static Eina_Bool
 _e_dnd_cb_mouse_up(void *data __UNUSED__, int type __UNUSED__, void *event)
 {
-   Ecore_Event_Mouse_Button *ev;
+   Ecore_Event_Mouse_Button *ev = event;
 
-   ev = event;
    if (ev->window != _drag_win) return ECORE_CALLBACK_PASS_ON;
 
    _e_drag_end(ev->x, ev->y);
@@ -1150,9 +1182,8 @@ _e_dnd_cb_mouse_up(void *data __UNUSED__, int type 
__UNUSED__, void *event)
 static Eina_Bool
 _e_dnd_cb_mouse_move(void *data __UNUSED__, int type __UNUSED__, void *event)
 {
-   Ecore_Event_Mouse_Move *ev;
+   Ecore_Event_Mouse_Move *ev = event;
 
-   ev = event;
    if (ev->window != _drag_win) return ECORE_CALLBACK_PASS_ON;
 
    if (!_xdnd)
@@ -1165,69 +1196,46 @@ _e_dnd_cb_mouse_move(void *data __UNUSED__, int type 
__UNUSED__, void *event)
 static Eina_Bool
 _e_dnd_cb_event_dnd_enter(void *data __UNUSED__, int type __UNUSED__, void 
*event)
 {
-   Ecore_X_Event_Xdnd_Enter *ev;
+   Ecore_X_Event_Xdnd_Enter *ev = event;
    E_Drop_Handler *h;
    const char *id;
    const Eina_List *l;
    unsigned int j;
    int i;
 
-   ev = event;
    id = e_util_winid_str_get(ev->win);
    if (!eina_hash_find(_drop_win_hash, id)) return ECORE_CALLBACK_PASS_ON;
 
-   EINA_LIST_FOREACH(_drop_handlers, l, h)
+   EINA_LIST_FREE(_active_handlers, h)
      {
         h->active = 0;
-        eina_stringshare_del(h->active_type);
-        h->active_type = NULL;
+        eina_stringshare_replace(&h->active_type, NULL);
         h->entered = 0;
      }
    for (i = 0; i < ev->num_types; i++)
      {
-        const char *t = NULL;
-        /* FIXME: Maybe we want to get something else then files dropped? */
-        if (!strcmp(_type_text_uri_list, ev->types[i]))
-          t = eina_stringshare_ref(_type_text_uri_list);
-        else if (!strcmp(_type_xds, ev->types[i]))
-          t = eina_stringshare_ref(_type_xds);
-        if (t)
+        Eina_Stringshare *t;
+
+        t = eina_stringshare_ref(_e_dnd_type_implemented(ev->types[i]));
+        if (!t) continue;
+        _xdnd = E_NEW(XDnd, 1);
+        _xdnd->type = t;
+        EINA_LIST_FOREACH(_drop_handlers, l, h)
           {
-             _xdnd = E_NEW(XDnd, 1);
-             _xdnd->type = t;
-             EINA_LIST_FOREACH(_drop_handlers, l, h)
+             for (j = 0; j < h->num_types; j++)
                {
-                  h->active = 0;
-                  eina_stringshare_del(h->active_type);
-                  h->active_type = NULL;
-                  for (j = 0; j < h->num_types; j++)
+                  if (h->types[j] == _xdnd->type)
                     {
-                       if (h->types[j] == _xdnd->type)
-                         {
-                            h->active = 1;
-                            h->active_type = eina_stringshare_ref(_xdnd->type);
-                            break;
-                         }
+                       h->active = 1;
+                       h->active_type = eina_stringshare_ref(_xdnd->type);
+                       _active_handlers = eina_list_append(_active_handlers, 
h);
+                       break;
                     }
-
-                  h->entered = 0;
-               }
-             break;
-          }
-#if 0
-        else if ((_type_text_x_moz_url == ev->types[i]) ||
-                 (!strcmp(_type_text_x_moz_url, ev->types[i])))  /* not sure 
it is stringshared */
-          {
-             _xdnd = E_NEW(XDnd, 1);
-             _xdnd->type = eina_stringshare_ref(_type_text_x_moz_url);
-             EINA_LIST_FOREACH(_drop_handlers, l, h)
-               {
-                  h->active = (h->type == _type_enlightenment_x_file);
-                  h->entered = 0;
                }
-             break;
+
+             h->entered = 0;
           }
-#endif
+        break;
      }
    return ECORE_CALLBACK_PASS_ON;
 }
@@ -1235,13 +1243,11 @@ _e_dnd_cb_event_dnd_enter(void *data __UNUSED__, int 
type __UNUSED__, void *even
 static Eina_Bool
 _e_dnd_cb_event_dnd_leave(void *data __UNUSED__, int type __UNUSED__, void 
*event)
 {
-   Ecore_X_Event_Xdnd_Leave *ev;
+   Ecore_X_Event_Xdnd_Leave *ev = event;
    E_Event_Dnd_Leave leave_ev;
    const char *id;
    const Eina_List *l;
 
-   ev = event;
-
    id = e_util_winid_str_get(ev->win);
    if (!eina_hash_find(_drop_win_hash, id)) return ECORE_CALLBACK_PASS_ON;
 
@@ -1252,10 +1258,8 @@ _e_dnd_cb_event_dnd_leave(void *data __UNUSED__, int 
type __UNUSED__, void *even
      {
         E_Drop_Handler *h;
 
-        EINA_LIST_FOREACH(_drop_handlers, l, h)
+        EINA_LIST_FOREACH(_active_handlers, l, h)
           {
-             if (!h->active) continue;
-
              if (h->entered)
                {
                   if (h->cb.leave)
@@ -1273,16 +1277,11 @@ _e_dnd_cb_event_dnd_leave(void *data __UNUSED__, int 
type __UNUSED__, void *even
 static Eina_Bool
 _e_dnd_cb_event_dnd_position(void *data __UNUSED__, int type __UNUSED__, void 
*event)
 {
-   Ecore_X_Event_Xdnd_Position *ev;
+   Ecore_X_Event_Xdnd_Position *ev = event;
    Ecore_X_Rectangle rect;
    const char *id;
-   const Eina_List *l;
-   E_Drop_Handler *h;
-
-   int active;
    int responsive;
 
-   ev = event;
 //   double t1 = ecore_time_get(); ////
    id = e_util_winid_str_get(ev->win);
    if (!eina_hash_find(_drop_win_hash, id))
@@ -1297,16 +1296,7 @@ _e_dnd_cb_event_dnd_position(void *data __UNUSED__, int 
type __UNUSED__, void *e
    rect.width = 0;
    rect.height = 0;
 
-   active = 0;
-   EINA_LIST_FOREACH(_drop_handlers, l, h)
-     {
-        if (h->active)
-          {
-             active = 1;
-             break;
-          }
-     }
-   if (!active)
+   if (!_active_handlers)
      ecore_x_dnd_send_status(0, 0, rect, ECORE_X_DND_ACTION_PRIVATE);
    else
      {
@@ -1324,9 +1314,8 @@ _e_dnd_cb_event_dnd_position(void *data __UNUSED__, int 
type __UNUSED__, void *e
 static Eina_Bool
 _e_dnd_cb_event_dnd_status(void *data __UNUSED__, int type __UNUSED__, void 
*event)
 {
-   Ecore_X_Event_Xdnd_Status *ev;
+   Ecore_X_Event_Xdnd_Status *ev = event;
 
-   ev = event;
    if (ev->win != _drag_win) return ECORE_CALLBACK_PASS_ON;
    return ECORE_CALLBACK_PASS_ON;
 }
@@ -1364,10 +1353,9 @@ _e_dnd_cb_event_dnd_finished(void *data __UNUSED__, int 
type __UNUSED__, void *e
 static Eina_Bool
 _e_dnd_cb_event_dnd_drop(void *data __UNUSED__, int type __UNUSED__, void 
*event)
 {
-   Ecore_X_Event_Xdnd_Drop *ev;
+   Ecore_X_Event_Xdnd_Drop *ev = event;
    const char *id;
 
-   ev = event;
    id = e_util_winid_str_get(ev->win);
    if (!eina_hash_find(_drop_win_hash, id)) return ECORE_CALLBACK_PASS_ON;
 
@@ -1377,9 +1365,8 @@ _e_dnd_cb_event_dnd_drop(void *data __UNUSED__, int type 
__UNUSED__, void *event
         Eina_Bool req = EINA_TRUE;
         Eina_List *l;
 
-        EINA_LIST_FOREACH(_drop_handlers, l, h)
+        EINA_LIST_FOREACH(_active_handlers, l, h)
           {
-             if (!h->active) continue;
              if (_e_drag_win_matches(h, ev->win, 1) && h->entered && h->cb.xds)
                {
                   req = h->cb.xds(h->cb.data, _xdnd->type);
@@ -1404,11 +1391,10 @@ _e_dnd_cb_event_dnd_drop(void *data __UNUSED__, int 
type __UNUSED__, void *event
 static Eina_Bool
 _e_dnd_cb_event_dnd_selection(void *data __UNUSED__, int type __UNUSED__, void 
*event)
 {
-   Ecore_X_Event_Selection_Notify *ev;
+   Ecore_X_Event_Selection_Notify *ev = event;
    const char *id;
    int i;
 
-   ev = event;
    id = e_util_winid_str_get(ev->win);
    if (!eina_hash_find(_drop_win_hash, id)) return ECORE_CALLBACK_PASS_ON;
    if (ev->selection != ECORE_X_SELECTION_XDND) return ECORE_CALLBACK_PASS_ON;

-- 

------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1

Reply via email to