cleanup memory usage, add stringshare, fix bug.
authorGustavo Sverzut Barbieri <barbieri@gmail.com>
Thu, 19 Mar 2009 00:14:57 +0000 (00:14 +0000)
committerGustavo Sverzut Barbieri <barbieri@gmail.com>
Thu, 19 Mar 2009 00:14:57 +0000 (00:14 +0000)
 * h->active_type was referring to xdnd->type, that could be freed
   already. Now it's a reference to that string.

 * strcmp() are now direct pointer comparison since strings are shared.

 * no more extra "types" allocated member, make it a variable array at
   the end of the structure.

SVN revision: 39564

src/bin/e_dnd.c
src/bin/e_dnd.h

index fbd482d..57f4dbd 100644 (file)
@@ -49,7 +49,7 @@ typedef struct _XDnd XDnd;
 struct _XDnd
 {
    int x, y;
-   char *type;
+   const char *type;
    void *data;
 };
 
@@ -65,6 +65,10 @@ static E_Drag    *_drag_current = NULL;
 
 static XDnd *_xdnd = NULL;
 
+static const char *_type_text_uri_list = NULL;
+static const char *_type_text_x_moz_url = NULL;
+static const char *_type_enlightenment_x_file = NULL;
+
 static Eina_Hash *_drop_handlers_responsives;
 static Ecore_X_Atom _action;
 
@@ -73,6 +77,10 @@ static Ecore_X_Atom _action;
 EAPI int
 e_dnd_init(void)
 {
+   _type_text_uri_list = eina_stringshare_add("text/uri-list");
+   _type_text_x_moz_url = eina_stringshare_add("text/x-moz-url");
+   _type_enlightenment_x_file = eina_stringshare_add("enlightenment/x-file");
+
    _drop_win_hash = eina_hash_string_superfast_new(NULL);
    _drop_handlers_responsives = eina_hash_string_superfast_new(NULL);
 
@@ -140,6 +148,13 @@ e_dnd_shutdown(void)
 
    eina_hash_free(_drop_handlers_responsives);
 
+   eina_stringshare_del(_type_text_uri_list);
+   eina_stringshare_del(_type_text_x_moz_url);
+   eina_stringshare_del(_type_enlightenment_x_file);
+   _type_text_uri_list = NULL;
+   _type_text_x_moz_url = NULL;
+   _type_enlightenment_x_file = NULL;
+
    return 1;
 }
 
@@ -155,7 +170,8 @@ e_drag_new(E_Container *container, int x, int y,
 
    /* No need to create a drag object without type */
    if ((!types) || (!num_types)) return NULL;
-   drag = E_OBJECT_ALLOC(E_Drag, E_DRAG_TYPE, _e_drag_free);
+   drag = e_object_alloc(sizeof(E_Drag) + num_types * sizeof(char *),
+                        E_DRAG_TYPE, E_OBJECT_CLEANUP_FUNC(_e_drag_free));
    if (!drag) return NULL;
 
    drag->x = x;
@@ -206,9 +222,8 @@ e_drag_new(E_Container *container, int x, int y,
 
    drag->type = E_DRAG_NONE;
 
-   drag->types = malloc(num_types * sizeof(char *));
    for (i = 0; i < num_types; i++)
-     drag->types[i] = strdup(types[i]);
+     drag->types[i] = eina_stringshare_add(types[i]);
    drag->num_types = num_types;
    drag->data = data;
    drag->data_size = size;
@@ -295,15 +310,16 @@ e_drag_start(E_Drag *drag, int x, int y)
        int i, j;
 
        h->active = 0;
+       eina_stringshare_del(h->active_type);
        h->active_type = NULL;
        for (i = 0; i < h->num_types; i++)
          {
             for (j = 0; j < drag->num_types; j++)
               {
-                 if (!strcmp(h->types[i], drag->types[j]))
+                 if (h->types[i] == drag->types[j])
                    {
                       h->active = 1;
-                      h->active_type = h->types[i];
+                      h->active_type = eina_stringshare_ref(h->types[i]);
                       break;
                    }
               }
@@ -361,7 +377,7 @@ e_drop_handler_add(E_Object *obj,
    E_Drop_Handler *handler;
    int i;
 
-   handler = E_NEW(E_Drop_Handler, 1);
+   handler = calloc(1, sizeof(E_Drop_Handler) + num_types * sizeof(char *));
    if (!handler) return NULL;
 
    handler->cb.data = data;
@@ -370,12 +386,8 @@ e_drop_handler_add(E_Object *obj,
    handler->cb.leave = leave_cb;
    handler->cb.drop = drop_cb;
    handler->num_types = num_types;
-   if (num_types)
-     {
-       handler->types = malloc(num_types * sizeof(char *));
-       for (i = 0; i < num_types; i++)
-         handler->types[i] = strdup(types[i]);
-     }
+   for (i = 0; i < num_types; i++)
+     handler->types[i] = eina_stringshare_add(types[i]);
    handler->x = x;
    handler->y = y;
    handler->w = w;
@@ -413,12 +425,9 @@ e_drop_handler_del(E_Drop_Handler *handler)
    int i;
 
    _drop_handlers = eina_list_remove(_drop_handlers, handler);
-   if (handler->types)
-     {
-       for (i = 0; i < handler->num_types; i++)
-         free(handler->types[i]);
-       free(handler->types);
-     }
+   for (i = 0; i < handler->num_types; i++)
+     eina_stringshare_del(handler->types[i]);
+   eina_stringshare_del(handler->active_type);
    free(handler);
 }
 
@@ -1077,8 +1086,8 @@ _e_drag_free(E_Drag *drag)
    evas_object_del(drag->object);
    e_canvas_del(drag->ecore_evas);
    ecore_evas_free(drag->ecore_evas);
-   for (i = 0; i < drag->num_types; i++) free(drag->types[i]);
-   free(drag->types);
+   for (i = 0; i < drag->num_types; i++)
+     eina_stringshare_del(drag->types[i]);
    free(drag);
    ecore_x_window_shadow_tree_flush();
 }
@@ -1173,26 +1182,29 @@ _e_dnd_cb_event_dnd_enter(void *data, int type, void *event)
    EINA_LIST_FOREACH(_drop_handlers, l, h)
      {
        h->active = 0;
+       eina_stringshare_del(h->active_type);
        h->active_type = NULL;
        h->entered = 0;
      }
    for (i = 0; i < ev->num_types; i++)
      {
        /* FIXME: Maybe we want to get something else then files dropped? */
-       if (!strcmp("text/uri-list", ev->types[i]))
+       if ((_type_text_uri_list == ev->types[i]) ||
+           (!strcmp(_type_text_uri_list, ev->types[i]))) /* not sure it is stringshared */
          {
             _xdnd = E_NEW(XDnd, 1);
-            _xdnd->type = strdup("text/uri-list");
+            _xdnd->type = eina_stringshare_ref(_type_text_uri_list);
             EINA_LIST_FOREACH(_drop_handlers, l, h)
               {
                  h->active = 0;
+                 eina_stringshare_del(h->active_type);
                  h->active_type = NULL;
                  for (j = 0; j < h->num_types; j++)
                    {
-                      if (!strcmp(h->types[j], _xdnd->type))
+                      if (h->types[j] == _xdnd->type)
                         {
                            h->active = 1;
-                           h->active_type = _xdnd->type;
+                           h->active_type = eina_stringshare_ref(_xdnd->type);
                            break;
                         }
                    }
@@ -1202,13 +1214,14 @@ _e_dnd_cb_event_dnd_enter(void *data, int type, void *event)
             break;
          }
 #if 0
-       else if (!strcmp("text/x-moz-url", ev->types[i]))
+       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 = strdup("text/x-moz-url");
+            _xdnd->type = eina_stringshare_ref(_type_text_x_moz_url);
             EINA_LIST_FOREACH(_drop_handlers, l, h)
               {
-                 h->active = !strcmp(h->type, "enlightenment/x-file");
+                 h->active = (h->type == _type_enlightenment_x_file);
                  h->entered = 0;
               }
             break;
@@ -1250,7 +1263,7 @@ _e_dnd_cb_event_dnd_leave(void *data, int type, void *event)
               }
          }
 
-       free(_xdnd->type);
+       eina_stringshare_del(_xdnd->type);
        free(_xdnd);
        _xdnd = NULL;
      }
@@ -1384,7 +1397,7 @@ _e_dnd_cb_event_dnd_selection(void *data, int type, void *event)
    if (!eina_hash_find(_drop_win_hash, id)) return 1;
    if (ev->selection != ECORE_X_SELECTION_XDND) return 1;
 
-   if (!strcmp("text/uri-list", _xdnd->type))
+   if (_type_text_uri_list == _xdnd->type)
      {
        Ecore_X_Selection_Data_Files   *files;
        Eina_List *l = NULL;
@@ -1396,7 +1409,7 @@ _e_dnd_cb_event_dnd_selection(void *data, int type, void *event)
        _e_drag_xdnd_end(ev->win, _xdnd->x, _xdnd->y);
        eina_list_free(l);
      }
-   else if (!strcmp("text/x-moz-url", _xdnd->type))
+   else if (_type_text_x_moz_url == _xdnd->type)
      {
        /* FIXME: Create a ecore x parser for this type */
        Ecore_X_Selection_Data *data;
@@ -1442,7 +1455,7 @@ _e_dnd_cb_event_dnd_selection(void *data, int type, void *event)
    /* FIXME: When to execute this? It could be executed in ecore_x after getting
     * the drop property... */
    ecore_x_dnd_send_finished();
-   free(_xdnd->type);
+   eina_stringshare_del(_xdnd->type);
    free(_xdnd);
    _xdnd = NULL;
    return 1;
index 2a439da..684784d 100644 (file)
@@ -28,8 +28,6 @@ struct _E_Drag
 {
    E_Object             e_obj_inherit;
 
-   char         **types;
-   unsigned int   num_types;
    void          *data;
    int            data_size;
 
@@ -59,6 +57,9 @@ struct _E_Drag
    unsigned char  visible : 1;
    unsigned char  need_shape_export : 1;
    unsigned char  xy_update : 1;
+
+   unsigned int   num_types;
+   const char    *types[];
 };
 
 struct _E_Drop_Handler
@@ -72,14 +73,13 @@ struct _E_Drop_Handler
    } cb;
 
    E_Object      *obj;
-   char         **types;
-   unsigned int   num_types;
-
    int x, y, w, h;
 
    unsigned char  active : 1;
    unsigned char  entered : 1;
    const char    *active_type;
+   unsigned int   num_types;
+   const char    *types[];
 };
 
 struct _E_Event_Dnd_Enter