Index: src/bin/e_module.h
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/e/src/bin/e_module.h,v
retrieving revision 1.10
diff -u -r1.10 e_module.h
--- src/bin/e_module.h	27 Dec 2005 17:16:57 -0000	1.10
+++ src/bin/e_module.h	19 Feb 2006 05:49:09 -0000
@@ -3,7 +3,7 @@
  */
 #ifdef E_TYPEDEFS
 
-#define E_MODULE_API_VERSION 2
+#define E_MODULE_API_VERSION 3
 
 typedef struct _E_Module     E_Module;
 typedef struct _E_Module_Api E_Module_Api;
@@ -23,6 +23,7 @@
    char                *name;
    char                *dir;
    void                *handle;
+   E_App               *eapp;
    
    struct {
       void * (*init)        (E_Module *m);
@@ -58,6 +59,7 @@
 EAPI int          e_module_shutdown(void);
 
 EAPI E_Module    *e_module_new(char *name);
+EAPI E_Module    *e_module_new_by_eap(E_App *eapp);
 EAPI int          e_module_save(E_Module *m);
 EAPI const char  *e_module_dir_get(E_Module *m);
 EAPI int          e_module_enable(E_Module *m);
@@ -65,7 +67,10 @@
 EAPI int          e_module_enabled_get(E_Module *m);
 EAPI int          e_module_save_all(void);
 EAPI E_Module    *e_module_find(char *name);
+EAPI E_Module    *e_module_find_by_eap(E_App *eapp);
 EAPI Evas_List   *e_module_list(void);
+EAPI Evas_List   *e_module_available_list(void); 
+EAPI Evas_Object *e_module_icon_get(Evas *evas, E_App *app);
 EAPI E_Menu      *e_module_menu_new(void);
 EAPI void         e_module_dialog_show(char *title, char *body);
 
Index: src/bin/e_module.c
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/e/src/bin/e_module.c,v
retrieving revision 1.54
diff -u -r1.54 e_module.c
--- src/bin/e_module.c	18 Feb 2006 04:35:27 -0000	1.54
+++ src/bin/e_module.c	19 Feb 2006 05:49:10 -0000
@@ -18,6 +18,7 @@
 };
 
 /* local subsystem functions */
+static void _e_module_new(E_Module *m, char *name, char *modpath, char *buf);
 static void _e_module_free(E_Module *m);
 static E_Menu *_e_module_control_menu_new(E_Module *mod);
 static void _e_module_menu_free(void *obj);
@@ -26,6 +27,8 @@
 static void _e_module_control_menu_enabled(void *data, E_Menu *m, E_Menu_Item *mi);
 static void _e_module_dialog_disable_show(char *title, char *body, E_Module *m);
 static void _e_module_cb_dialog_disable(void *data, E_Dialog *dia);
+static Evas_List *_e_module_mod_dir_available_get(Evas_List *available, const char *mod_dir);
+static E_App *_e_module_eapp_get(char *path, char *modpath);
 
 /* local subsystem globals */
 static Evas_List *_e_modules = NULL;
@@ -88,10 +91,7 @@
 {
    E_Module *m;
    char buf[4096];
-   char body[4096], title[1024];
-   char *modpath, *s;
-   Evas_List *l;
-   int in_list = 0;
+   char *modpath;
 
    if (!name) return NULL;
    m = E_OBJECT_ALLOC(E_Module, E_MODULE_TYPE, _e_module_free);
@@ -101,7 +101,59 @@
 	modpath = e_path_find(path_modules, buf);
      }
    else
-     modpath = evas_stringshare_add(name);
+     {
+	snprintf(buf, sizeof(buf), "%s", name);
+	modpath = evas_stringshare_add(name);
+     }
+   _e_module_new(m, name, modpath, buf);
+   if (modpath) evas_stringshare_del(modpath);
+
+   m->eapp = _e_module_eapp_get(m->dir, buf);
+
+   return m;
+}
+
+EAPI E_Module *
+e_module_new_by_eap(E_App *eapp)
+{
+   E_Module *m;
+   char *modpath;
+   char name[4096];
+   char *p;
+
+   E_OBJECT_CHECK(eapp);
+   E_OBJECT_TYPE_CHECK(eapp, E_APP_TYPE);
+
+   m = E_OBJECT_ALLOC(E_Module, E_MODULE_TYPE, _e_module_free);
+   modpath = e_path_find(path_modules, eapp->exe);
+   if (modpath)
+     {
+	snprintf(name, sizeof(name), "%s", eapp->exe);
+	p = strchr(name, '/');
+	if (p)
+	  *p = 0;
+     }
+   else
+     {
+	name[0] = 0;
+     }
+   _e_module_new(m, name, modpath, eapp->exe);
+   if (modpath) evas_stringshare_del(modpath);
+
+   m->eapp = eapp;
+   e_object_ref(E_OBJECT(eapp));
+
+   return m;
+}
+
+static void
+_e_module_new(E_Module *m, char *name, char *modpath, char *buf)
+{
+   char body[4096], title[1024];
+   char *s;
+   Evas_List *l;
+   int in_list = 0;
+
    if (!modpath)
      {
 	snprintf(body, sizeof(body), _("There was an error loading module named: %s<br>"
@@ -227,8 +279,6 @@
 	e_config->modules = evas_list_append(e_config->modules, em);
 	e_config_save_queue();
      }
-   if (modpath) evas_stringshare_del(modpath);
-   return m;
 }
 
 EAPI int
@@ -349,12 +399,91 @@
    return NULL;
 }
 
+EAPI E_Module *
+e_module_find_by_eap(E_App *eapp)
+{
+   Evas_List *l;
+   
+   E_OBJECT_CHECK(eapp);
+   E_OBJECT_TYPE_CHECK(eapp, E_APP_TYPE);
+
+   for (l = _e_modules; l; l = l->next)
+     {
+	E_Module *m;
+	
+	m = l->data;
+	if (eapp == m->eapp) 
+	  {
+	     return m;
+	  }
+     }
+   return NULL;
+}
+
 EAPI Evas_List *
 e_module_list(void)
 {
    return _e_modules;
 }
 
+/* 
+ * Return a list of E_Apps for modules that appear to be installed 
+ */
+EAPI Evas_List *
+e_module_available_list(void)
+{
+   Evas_List *dir_list;
+   Evas_List *l;
+   Evas_List *ret = NULL;
+
+   dir_list = e_path_dir_list_get(path_modules);
+   for (l = dir_list; l; l = l->next)
+     {
+	E_Path_Dir *epd = l->data;
+	if (!ecore_file_is_dir(epd->dir))
+	  continue;
+	ret = _e_module_mod_dir_available_get(ret, epd->dir);
+     }
+   e_path_dir_list_free(dir_list);
+   return ret;
+}
+
+/* 
+ * Return an icon object for a module, if an icon of some sort is present
+ */
+EAPI Evas_Object *
+e_module_icon_get(Evas *evas, E_App *eapp)
+{
+   char buf[4096];
+   char *p;
+   Evas_Object *icon = NULL;
+
+   E_OBJECT_CHECK(eapp);
+   E_OBJECT_TYPE_CHECK(eapp, E_APP_TYPE);
+
+   if (!evas) return NULL;
+
+   p = strrchr(eapp->path, '/');
+   if (p) p++;
+   if ((p) && (!strcmp(p, "module.eap")))
+     { 
+	icon = e_icon_add(evas); 
+	e_icon_file_edje_set(icon, eapp->path, "icon"); 
+     }
+   else
+     {
+	/* FIXME: dummy eaps have a path to the module dir, what else
+	 * could we do? */
+	snprintf(buf, sizeof(buf), "%s/module_icon.png", eapp->path); 
+        if (ecore_file_can_read(buf))
+	  {
+	     icon = e_icon_add(evas);
+	     e_icon_file_set(icon, buf);
+	  }
+     }
+   return icon; 
+}
+
 EAPI E_Menu *
 e_module_menu_new(void)
 {
@@ -453,6 +582,7 @@
    if (m->name) evas_stringshare_del(m->name);
    if (m->dir) evas_stringshare_del(m->dir);
    if (m->handle) dlclose(m->handle);
+   if (m->eapp) e_object_unref(E_OBJECT(m->eapp));
    _e_modules = evas_list_remove(_e_modules, m);
    if (m->icon_file) free(m->icon_file);
    if (m->edje_icon_file) free(m->edje_icon_file);
@@ -471,7 +601,7 @@
    m = e_menu_new();
    
    mi = e_menu_item_new(m);
-   e_menu_item_label_set(mi, _("About…"));
+   e_menu_item_label_set(mi, _("About..."));
    e_menu_item_callback_set(mi, _e_module_control_menu_about, mod);
    
    mi = e_menu_item_new(m);
@@ -579,3 +709,69 @@
    e_object_del(E_OBJECT(dia));
    e_config_save_queue();
 }
+
+static Evas_List *
+_e_module_mod_dir_available_get(Evas_List *available, const char *mod_dir)
+{
+   Ecore_List *dirs;
+
+   dirs = ecore_file_ls(mod_dir);
+   if (dirs)
+     {
+	char *mod;
+
+	ecore_list_goto_first(dirs); 
+	while ((mod = ecore_list_next(dirs)))
+	  {
+	     char path[PATH_MAX];
+	     char buff[4096]; 
+	     E_App *eapp;
+	     E_Module *m;
+
+	     m = e_module_find(mod);
+	     if (m)
+	       {
+		  available = evas_list_append(available, m->eapp);
+		  e_object_ref(E_OBJECT(m->eapp));
+	       }
+	     else 
+	       {
+		  snprintf(path, sizeof(path), "%s/%s", mod_dir, mod);
+		  snprintf(buff, sizeof(buff), "%s/%s/module.so", path, MODULE_ARCH);
+		  if (ecore_file_can_read(buff))
+		    {
+		       snprintf(buff, sizeof(buff), "%s/%s/module.so", mod, MODULE_ARCH);
+		       available = evas_list_append(available, _e_module_eapp_get(path, buff));
+		    }
+	       }
+	  }
+	ecore_list_destroy(dirs);
+     }
+   return available;
+}
+
+static E_App *
+_e_module_eapp_get(char *path, char *modpath)
+{
+   char buff[4096]; 
+   E_App *app;
+
+   snprintf(buff, sizeof(buff), "%s/module.eap", path);
+   app = e_app_new(buff, 0);
+   if (!app)
+     {
+	char *p;
+
+	/* Module has no .eap - create a dummy */
+	app = e_app_empty_new(path);
+	p = strrchr(path, '/');
+	if (p) 
+	  {
+	     p++;
+	     app->name = (char *)evas_stringshare_add(p);
+	  }
+	app->exe = (char *)evas_stringshare_add(modpath);
+     }
+   return app;
+}
+
Index: src/bin/e_int_config_modules.c
===================================================================
RCS file: /cvsroot/enlightenment/e17/apps/e/src/bin/e_int_config_modules.c,v
retrieving revision 1.25
diff -u -r1.25 e_int_config_modules.c
--- src/bin/e_int_config_modules.c	16 Feb 2006 11:24:36 -0000	1.25
+++ src/bin/e_int_config_modules.c	19 Feb 2006 05:49:10 -0000
@@ -29,8 +29,7 @@
 
 struct _CFModule
 {
-   char *name;
-   char *path;
+   E_App *app;
    int state;
 };
 
@@ -70,14 +69,27 @@
    Evas_Object *obj;
    E_Module *m;
    const char *v;
+   E_Config_Dialog_Data *cfdata;
+   Evas_List *l;
 
    obj = data;
+   cfdata = data2;
    v = e_widget_ilist_selected_label_get(obj);
-   m = e_module_find((char *)v);
-   if (m)
+   for (l = cfdata->modules; l; l = l->next)
      {
-	if (m->func.config)
-	  m->func.config(m);
+	CFModule *cm;
+
+	cm = l->data;
+	if ((cm) && (cm->app) && (!strcmp(cm->app->name, v)))
+	  {
+	     m = e_module_find_by_eap(cm->app);
+	     if (m)
+	       {
+		  if (m->func.config)
+		    m->func.config(m);
+		  break;
+	       }
+	  }
      }
 }
 
@@ -87,14 +99,34 @@
    Evas_Object *obj;
    E_Module *m;
    const char *v;
+   E_Config_Dialog_Data *cfdata;
+   Evas_List *l;
 
    obj = data;
+   cfdata = data2;
    v = e_widget_ilist_selected_label_get(obj);
-   m = e_module_find((char *)v);
-   if (m)
+   for (l = cfdata->modules; l; l = l->next)
      {
-	if (m->func.about)
-	  m->func.about(m);
+	CFModule *cm;
+
+	cm = l->data;
+	if ((cm) && (cm->app) && (!strcmp(cm->app->name, v)))
+	  {
+	     /* Display info contained in E_App, if there is any */
+	     if (cm->app->comment)
+	       {
+		  e_module_dialog_show(cm->app->name, cm->app->comment);
+		  break;
+	       }
+	     /* Fall back to existing about api call */
+	     m = e_module_find_by_eap(cm->app);
+	     if (m)
+	       {
+		  if (m->func.about)
+		    m->func.about(m);
+		  break;
+	       }
+	  }
      }
 }
 
@@ -102,36 +134,22 @@
 _fill_data(E_Config_Dialog_Data *cfdata)
 {
    Evas_List *l;
-   Ecore_List *dirs = NULL;
 
-   for (l = e_path_dir_list_get(path_modules); l; l = l->next)
+   l = e_module_available_list();
+   while (l)
      {
-	E_Path_Dir *epd;
+	CFModule *m;
+	E_App *mod;
 
-	epd = l->data;
-	if (ecore_file_is_dir(epd->dir))
+	mod = l->data;
+	l = evas_list_remove_list(l, l);
+	if (mod)
 	  {
-	     dirs = ecore_file_ls(epd->dir);
-	     if (dirs)
+	     m = E_NEW(CFModule, 1);
+	     if (m)
 	       {
-		  char *mod;
-
-		  ecore_list_goto_first(dirs);
-		  while ((mod = ecore_list_next(dirs)))
-		    {
-		       CFModule *m;
-		       char buff[4096];
-
-		       m = E_NEW(CFModule, 1);
-		       if (m)
-			 {
-			    snprintf(buff, sizeof(buff), "%s/%s", epd->dir, mod);
-			    m->name = strdup(mod);
-			    m->path = strdup(buff);
-			    cfdata->modules = evas_list_append(cfdata->modules, m);
-			 }
-		    }
-		  ecore_list_destroy(dirs);
+		  m->app = mod;
+		  cfdata->modules = evas_list_append(cfdata->modules, m);
 	       }
 	  }
      }
@@ -139,8 +157,6 @@
    if (cfdata->modules)
      cfdata->modules = evas_list_sort(cfdata->modules, evas_list_count(cfdata->modules), _sort_modules);
 
-   /* Free Lists */
-   if (l) evas_list_free(l);
    return;
 }
 
@@ -165,9 +181,8 @@
         CFModule *m;
 
         m = l->data;
+        e_object_unref(E_OBJECT(m->app));
         cfdata->modules = evas_list_remove_list(cfdata->modules, l);
-        free(m->name);
-        free(m->path);
         E_FREE(m);
      }
    free(cfdata);
@@ -186,17 +201,17 @@
 	CFModule *cm;
 
 	cm = evas_list_nth(cfdata->modules, i);
-	if ((cm) && (!strcmp(cm->name, v)))
+	if ((cm) && (cm->app) && (!strcmp(cm->app->name, v)))
 	  {
 	     if (cm->state != cfdata->state)
 	       {
 		  e_widget_disabled_set(cfdata->gui.configure, 1);
 		  e_widget_disabled_set(cfdata->gui.about, 1);
 		  
-		  m = e_module_find((char *)v);
+		  m = e_module_find_by_eap(cm->app);
 		  if (!m) 
 		    { 
-		       m = e_module_new((char *)v);
+		       m = e_module_new_by_eap(cm->app);
 		       if (!m) break;
 		    }		  
 		  switch (cfdata->state)
@@ -207,10 +222,10 @@
 			 {	 
 			    if (m->func.config)
 			      e_widget_disabled_set(cfdata->gui.configure, 0);
-			    if (m->func.about)
+			    if ((cm->app->comment) || (m->func.about))
 			      e_widget_disabled_set(cfdata->gui.about, 0);
+			    cm->state = MOD_ENABLED;
 			 }
-		       cm->state = MOD_ENABLED;
 		       break;
 		     case MOD_LOADED:
 		       if (m->enabled) 
@@ -218,7 +233,7 @@
 			    e_module_save(m);
 			    e_module_disable(m);
 			 }
-		       if (m->func.about)
+		       if ((cm->app->comment) || (m->func.about))
 			 e_widget_disabled_set(cfdata->gui.about, 0);
 		       
 		       cm->state = MOD_LOADED;
@@ -228,8 +243,8 @@
 			 {
 			    if (m->func.config)
 			      e_widget_disabled_set(cfdata->gui.configure, 1);
-			    if (m->func.about)
-			      e_widget_disabled_set(cfdata->gui.about, 1);
+			    if (cm->app->comment) 
+			      e_widget_disabled_set(cfdata->gui.about, 0);
 			    e_module_disable(m);
 			    e_object_del(E_OBJECT(m));
 			    e_config_save_queue();
@@ -271,17 +286,14 @@
 	if (cm)
 	  {
 	     cm->state = MOD_UNLOADED;
-	     m = e_module_find(cm->name);
+	     m = e_module_find_by_eap(cm->app);
 	     if (m)
 	       {
 		  cm->state = MOD_LOADED;
 		  if (m->enabled) cm->state = MOD_ENABLED;
 	       }
-	     /* This Fails if module author names icon something else */
-	     snprintf(buf, sizeof(buf), "%s/module_icon.png", cm->path);
-	     oc = e_icon_add(evas);
-	     e_icon_file_set(oc, buf);
-	     e_widget_ilist_append(ilist, oc, cm->name, NULL, NULL, NULL);
+	     oc = e_module_icon_get(evas, cm->app);
+	     e_widget_ilist_append(ilist, oc, cm->app->name, NULL, NULL, NULL);
 	  }
      }
 
@@ -313,11 +325,11 @@
    e_widget_table_object_append(ot, of, 2, 0, 2, 2, 1, 1, 1, 1);
 
    of = e_widget_framelist_add(evas, _("Module Actions"), 0);   
-   ob = e_widget_button_add(evas, _("Configure"), NULL, _module_configure, ilist, NULL);
+   ob = e_widget_button_add(evas, _("Configure"), NULL, _module_configure, ilist, cfdata);
    cfdata->gui.configure = ob;
    e_widget_framelist_object_append(of, ob);
 
-   ob = e_widget_button_add(evas, _("About"), NULL, _module_about, ilist, NULL);
+   ob = e_widget_button_add(evas, _("About"), NULL, _module_about, ilist, cfdata);
    cfdata->gui.about = ob;
    e_widget_framelist_object_append(of, ob);
 
@@ -347,7 +359,7 @@
 	CFModule *cm;
 
 	cm = evas_list_nth(cfdata->modules, i);
-	if ((cm) && (!strcmp(cm->name, v)))
+	if ((cm) && (cm->app) && (!strcmp(cm->app->name, v)))
 	  {
 	     cfdata->state = cm->state;
 	     e_widget_disabled_set(cfdata->gui.enabled, 0);
@@ -382,14 +394,16 @@
 	       }
 	     e_widget_disabled_set(cfdata->gui.about, 1);
 	     e_widget_disabled_set(cfdata->gui.configure, 1);
-	     m = e_module_find((char *)v);
+	     if (cm->app->comment)
+	       e_widget_disabled_set(cfdata->gui.about, 0);
+	     m = e_module_find_by_eap(cm->app);
 	     if (m)
 	       {
 		  if (m->func.about)
 		    e_widget_disabled_set(cfdata->gui.about, 0);
 
 		  if (m->enabled && m->func.config) 
-		    e_widget_disabled_set(cfdata->gui.configure, 0);		       
+		    e_widget_disabled_set(cfdata->gui.configure, 0);
 	       }
 	     break;
 	  }
@@ -406,5 +420,5 @@
 
    m1 = data1;
    m2 = data2;
-   return (strcmp((const char*)m1->name, (const char*)m2->name));
+   return (strcmp((const char*)m1->app->name, (const char*)m2->app->name));
 }
