remove xcb support in ecore_x and evas engines as per mailing list
[platform/upstream/efl.git] / src / lib / ecore_evas / ecore_evas_module.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <Ecore.h>
6 #include "ecore_private.h"
7
8 #include "Ecore_Evas.h"
9 #include "ecore_evas_private.h"
10 #include <unistd.h>
11
12 static Eina_Hash *_registered_engines = NULL;
13 static Eina_List *_engines_paths = NULL;
14 static Eina_List *_engines_available = NULL;
15 static Eina_Module *_ecore_evas_vnc = NULL;
16
17 #ifdef _WIN32
18 # define ECORE_EVAS_ENGINE_NAME "module.dll"
19 #else
20 # define ECORE_EVAS_ENGINE_NAME "module.so"
21 #endif
22
23 static Eina_Module *
24 _ecore_evas_vnc_server_module_try_load(const char *prefix,
25                                        Eina_Bool use_prefix_only)
26 {
27    Eina_Module *m;
28
29    if (use_prefix_only)
30      m = eina_module_new(prefix);
31    else
32      {
33         char path[PATH_MAX];
34
35         snprintf(path, sizeof(path), "%s/vnc_server/%s/%s", prefix,
36                  MODULE_ARCH, ECORE_EVAS_ENGINE_NAME);
37         m = eina_module_new(path);
38      }
39
40    if (!m)
41      return NULL;
42    if (!eina_module_load(m))
43      {
44         eina_module_free(m);
45         _ecore_evas_vnc = NULL;
46         return NULL;
47      }
48
49    return m;
50 }
51
52 Eina_Module *
53 _ecore_evas_vnc_server_module_load(void)
54 {
55    char *prefix;
56
57    if (_ecore_evas_vnc)
58      return _ecore_evas_vnc;
59
60 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
61    if (getuid() == geteuid())
62 #endif
63      {
64         if (getenv("EFL_RUN_IN_TREE"))
65           {
66              _ecore_evas_vnc = _ecore_evas_vnc_server_module_try_load(PACKAGE_BUILD_DIR
67                                                                       "/src/modules/ecore_evas/vnc_server/.libs/"
68                                                                       ECORE_EVAS_ENGINE_NAME,
69                                                                       EINA_TRUE);
70              if (_ecore_evas_vnc)
71                return _ecore_evas_vnc;
72           }
73      }
74
75    prefix = eina_module_symbol_path_get(_ecore_evas_vnc_server_module_load,
76                                         "/ecore_evas");
77    _ecore_evas_vnc = _ecore_evas_vnc_server_module_try_load(prefix, EINA_FALSE);
78    free(prefix);
79    //Last try...
80    if (!_ecore_evas_vnc)
81      {
82         _ecore_evas_vnc = _ecore_evas_vnc_server_module_try_load(PACKAGE_LIB_DIR"/ecore_evas",
83                                                                  EINA_FALSE);
84         if (!_ecore_evas_vnc)
85           ERR("Could not find a valid VNC module to load!");
86      }
87    return _ecore_evas_vnc;
88 }
89
90 Eina_Module *
91 _ecore_evas_engine_load(const char *engine)
92 {
93    const char *path;
94    Eina_List *l;
95    Eina_Module *em = NULL;
96    Eina_Bool run_in_tree;
97
98    EINA_SAFETY_ON_NULL_RETURN_VAL(engine, NULL);
99
100    em =  (Eina_Module *)eina_hash_find(_registered_engines, engine);
101    if (em) return em;
102
103    run_in_tree = !!getenv("EFL_RUN_IN_TREE");
104
105    EINA_LIST_FOREACH(_engines_paths, l, path)
106      {
107         char tmp[PATH_MAX] = "";
108
109 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
110         if (getuid() == geteuid())
111 #endif
112           {
113              if (run_in_tree)
114                {
115                   struct stat st;
116                   snprintf(tmp, sizeof(tmp), "%s/%s/.libs/%s",
117                            path, engine, ECORE_EVAS_ENGINE_NAME);
118                   if (stat(tmp, &st) != 0)
119                   tmp[0] = '\0';
120                }
121           }
122
123         if (tmp[0] == '\0')
124           snprintf(tmp, sizeof(tmp), "%s/%s/%s/%s",
125                    path, engine, MODULE_ARCH, ECORE_EVAS_ENGINE_NAME);
126
127         em = eina_module_new(tmp);
128         if (!em) continue;
129
130         if (!eina_module_load(em))
131           {
132              eina_module_free(em);
133              continue;
134           }
135         if (eina_hash_add(_registered_engines, engine, em))
136           return em;
137      }
138
139    return NULL;
140 }
141
142 void
143 _ecore_evas_engine_init(void)
144 {
145    char *paths[2] = { NULL, NULL };
146    unsigned int i;
147    unsigned int j;
148
149 /* avoid freeing modules ever to avoid deferred cb symbol problems */
150 //   _registered_engines = eina_hash_string_small_new(EINA_FREE_CB(eina_module_free));
151    _registered_engines = eina_hash_string_small_new(NULL);
152
153 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
154    if (getuid() == geteuid())
155 #endif
156      {
157         if (getenv("EFL_RUN_IN_TREE"))
158           {
159              struct stat st;
160              const char mp[] = PACKAGE_BUILD_DIR"/src/modules/ecore_evas/engines/";
161              if (stat(mp, &st) == 0)
162                {
163                   _engines_paths = eina_list_append(_engines_paths, strdup(mp));
164                   return;
165                }
166           }
167      }
168
169    /* 1. libecore_evas.so/../ecore_evas/engines/ */
170    paths[0] = eina_module_symbol_path_get(_ecore_evas_engine_init, "/ecore_evas/engines");
171 #ifndef _WIN32
172    /* 3. PREFIX/ecore_evas/engines/ */
173    paths[1] = strdup(PACKAGE_LIB_DIR "/ecore_evas/engines");
174 #else
175    paths[1] = eina_module_symbol_path_get(_ecore_evas_engine_init, "/../lib/ecore_evas/engines");
176 #endif
177
178    for (j = 0; j < ((sizeof (paths) / sizeof (char*)) - 1); ++j)
179      for (i = j + 1; i < sizeof (paths) / sizeof (char*); ++i)
180        if (paths[i] && paths[j] && !strcmp(paths[i], paths[j]))
181          {
182             free(paths[i]);
183             paths[i] = NULL;
184          }
185
186    for (i = 0; i < sizeof (paths) / sizeof (char*); ++i)
187      if (paths[i])
188        _engines_paths = eina_list_append(_engines_paths, paths[i]);
189 }
190
191 void
192 _ecore_evas_engine_shutdown(void)
193 {
194    char *path;
195
196 /* don't free modules to avoid fn callback deferred symbol problems
197    if (_registered_engines)
198      {
199        eina_hash_free(_registered_engines);
200        _registered_engines = NULL;
201      }
202  */
203    
204    EINA_LIST_FREE(_engines_paths, path)
205      free(path);
206
207    EINA_LIST_FREE(_engines_available, path)
208      eina_stringshare_del(path);
209 }
210
211 static Eina_Bool
212 _file_exists(const char *file)
213 {
214    struct stat st;
215    if (!file) return EINA_FALSE;
216
217    if (stat(file, &st) < 0) return EINA_FALSE;
218    return EINA_TRUE;
219 }
220
221 const Eina_List *
222 _ecore_evas_available_engines_get(void)
223 {
224    Eina_File_Direct_Info *info;
225    Eina_Iterator *it;
226    Eina_List *l = NULL, *result = NULL;
227    const char *path;
228
229    if (_engines_available) return _engines_available;
230
231    EINA_LIST_FOREACH(_engines_paths, l, path)
232      {
233         it = eina_file_direct_ls(path);
234
235         if (it)
236           {
237              EINA_ITERATOR_FOREACH(it, info)
238                {
239                   char tmp[PATH_MAX];
240                   snprintf(tmp, sizeof (tmp), "%s/%s/" ECORE_EVAS_ENGINE_NAME,
241                            info->path, MODULE_ARCH);
242
243                   if (_file_exists(tmp))
244                     {
245                        const char *name;
246
247 #ifdef _WIN32
248                        EVIL_PATH_SEP_WIN32_TO_UNIX(info->path);
249 #endif
250                        name = strrchr(info->path, '/');
251                        if (name) name++;
252                        else name = info->path;
253 #define ADDENG(x) result = eina_list_append(result, eina_stringshare_add(x))
254                        if (!strcmp(name, "fb"))
255                          {
256 #ifdef BUILD_ECORE_EVAS_FB
257                             ADDENG("fb");
258 #endif
259                          }
260                        else if (!strcmp(name, "x"))
261                          {
262 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
263                             ADDENG("opengl_x11");
264 #endif
265 #ifdef BUILD_ECORE_EVAS_SOFTWARE_XLIB
266                             ADDENG("software_x11");
267 #endif
268                          }
269                        else if (!strcmp(name, "buffer"))
270                          {
271 #ifdef BUILD_ECORE_EVAS_BUFFER
272                             ADDENG("buffer");
273 #endif
274 #ifdef BUILD_ECORE_EVAS_EWS
275                             ADDENG("ews");
276 #endif
277                          }
278                        else if (!strcmp(name, "cocoa"))
279                          {
280 #ifdef BUILD_ECORE_EVAS_OPENGL_COCOA
281                             ADDENG("opengl_cocoa");
282 #endif
283                          }
284                        else if (!strcmp(name, "psl1ght"))
285                          {
286 #ifdef BUILD_ECORE_EVAS_PSL1GHT
287                             ADDENG("psl1ght");
288 #endif
289                          }
290                        else if (!strcmp(name, "sdl"))
291                          {
292 #ifdef BUILD_ECORE_EVAS_OPENGL_SDL
293                             ADDENG("opengl_sdl");
294 #endif
295 #ifdef BUILD_ECORE_EVAS_SOFTWARE_SDL
296                             ADDENG("sdl");
297 #endif
298                          }
299                        else if (!strcmp(name, "wayland"))
300                          {
301 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
302                             ADDENG("wayland_shm");
303 #endif
304 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
305                             ADDENG("wayland_egl");
306 #endif
307                          }
308                        else if (!strcmp(name, "win32"))
309                          {
310 #ifdef BUILD_ECORE_EVAS_SOFTWARE_GDI
311                             ADDENG("software_gdi");
312 #endif
313 #ifdef BUILD_ECORE_EVAS_SOFTWARE_DDRAW
314                             ADDENG("software_ddraw");
315 #endif
316 #ifdef BUILD_ECORE_EVAS_DIRECT3D
317                             ADDENG("direct3d");
318 #endif
319 #ifdef BUILD_ECORE_EVAS_OPENGL_GLEW
320                             ADDENG("opengl_glew");
321 #endif
322                          }
323                        else if (!strcmp(name, "drm"))
324                          {
325 #ifdef BUILD_ECORE_EVAS_DRM
326                             ADDENG("drm");
327 #endif
328 #ifdef BUILD_ECORE_EVAS_GL_DRM
329                             ADDENG("gl_drm");
330 #endif
331                          }
332                     }
333                }
334              eina_iterator_free(it);
335           }
336      }
337
338    _engines_available = result;
339    return result;
340 }