19 #ifdef HAVE_LANGINFO_H
20 # include <langinfo.h>
23 #ifdef HAVE_SYS_MMAN_H
24 # include <sys/mman.h>
33 #include "ecore_private.h"
38 static Ecore_Version _version = { VERS_MAJ, VERS_MIN, VERS_MIC, VERS_REV };
39 EAPI Ecore_Version *ecore_version = &_version;
41 #define KEEP_MAX(Global, Local) \
42 if (Global < (Local)) \
45 static Eina_Bool _ecore_memory_statistic(void *data);
46 static int _ecore_memory_max_total = 0;
47 static int _ecore_memory_max_free = 0;
48 static pid_t _ecore_memory_pid = 0;
51 static const char *_ecore_magic_string_get(Ecore_Magic m);
52 static int _ecore_init_count = 0;
53 EAPI int _ecore_log_dom = -1;
54 int _ecore_fps_debug = 0;
56 /** OpenBSD does not define CODESET
61 # define CODESET "INVALID"
65 * Set up connections, signal handlers, sockets etc.
66 * @return 1 or greater on success, 0 otherwise
68 * This function sets up all singal handlers and the basic event loop. If it
69 * succeeds, 1 will be returned, otherwise 0 will be returned.
74 * int main(int argc, char **argv)
78 * printf("ERROR: Cannot init Ecore!\n");
81 * ecore_main_loop_begin();
89 if (++_ecore_init_count != 1)
90 return _ecore_init_count;
93 setlocale(LC_CTYPE, "");
96 if (strcmp(nl_langinfo(CODESET), "UTF-8"))
98 WRN("Not a utf8 locale!");
103 return --_ecore_init_count;
107 _ecore_log_dom = eina_log_domain_register("Ecore",ECORE_DEFAULT_LOG_COLOR);
108 if (_ecore_log_dom < 0) {
109 EINA_LOG_ERR("Ecore was unable to create a log domain.");
110 goto shutdown_log_dom;
112 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
113 if (_ecore_fps_debug) _ecore_fps_debug_init();
114 _ecore_main_loop_init();
115 _ecore_signal_init();
117 _ecore_thread_init();
120 _ecore_loop_time = ecore_time_get();
123 if (getenv("ECORE_MEM_STAT"))
125 _ecore_memory_pid = getpid();
126 ecore_animator_add(_ecore_memory_statistic, NULL);
130 #if defined(GLIB_INTEGRATION_ALWAYS)
131 if (_ecore_glib_always_integrate) ecore_main_loop_glib_integrate();
134 return _ecore_init_count;
142 return --_ecore_init_count;
146 * Shut down connections, signal handlers sockets etc.
148 * This function shuts down all things set up in ecore_init() and cleans up all
149 * event queues, handlers, filters, timers, idlers, idle enterers/exiters
150 * etc. set up after ecore_init() was called.
152 * Do not call this function from any callback that may be called from the main
153 * loop, as the main loop will then fall over and not function properly.
158 if (--_ecore_init_count != 0)
159 return _ecore_init_count;
161 if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
162 _ecore_poller_shutdown();
163 _ecore_animator_shutdown();
164 _ecore_glib_shutdown();
165 _ecore_job_shutdown();
166 _ecore_thread_shutdown();
167 _ecore_exe_shutdown();
168 _ecore_idle_enterer_shutdown();
169 _ecore_idle_exiter_shutdown();
170 _ecore_idler_shutdown();
171 _ecore_timer_shutdown();
172 _ecore_event_shutdown();
173 _ecore_main_shutdown();
174 _ecore_signal_shutdown();
175 _ecore_main_loop_shutdown();
178 if (getenv("ECORE_MEM_STAT"))
180 _ecore_memory_statistic(NULL);
182 ERR("[%i] Memory MAX total: %i, free: %i",
184 _ecore_memory_max_total,
185 _ecore_memory_max_free);
189 eina_log_domain_unregister(_ecore_log_dom);
196 return _ecore_init_count;
200 ecore_print_warning(const char *function, const char *sparam)
202 WRN("***** Developer Warning ***** :\n"
203 "\tThis program is calling:\n\n"
205 "\tWith the parameter:\n\n"
207 "\tbeing NULL. Please fix your program.", function, sparam);
208 if (getenv("ECORE_ERROR_ABORT")) abort();
212 _ecore_magic_fail(const void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname)
215 "*** ECORE ERROR: Ecore Magic Check Failed!!!\n"
216 "*** IN FUNCTION: %s()", fname);
218 ERR(" Input handle pointer is NULL!");
219 else if (m == ECORE_MAGIC_NONE)
220 ERR(" Input handle has already been freed!");
222 ERR(" Input handle is wrong type\n"
223 " Expected: %08x - %s\n"
224 " Supplied: %08x - %s",
225 (unsigned int)req_m, _ecore_magic_string_get(req_m),
226 (unsigned int)m, _ecore_magic_string_get(m));
227 ERR("*** NAUGHTY PROGRAMMER!!!\n"
228 "*** SPANK SPANK SPANK!!!\n"
229 "*** Now go fix your code. Tut tut tut!");
230 if (getenv("ECORE_ERROR_ABORT")) abort();
234 _ecore_magic_string_get(Ecore_Magic m)
238 case ECORE_MAGIC_NONE:
239 return "None (Freed Object)";
241 case ECORE_MAGIC_EXE:
242 return "Ecore_Exe (Executable)";
244 case ECORE_MAGIC_TIMER:
245 return "Ecore_Timer (Timer)";
247 case ECORE_MAGIC_IDLER:
248 return "Ecore_Idler (Idler)";
250 case ECORE_MAGIC_IDLE_ENTERER:
251 return "Ecore_Idle_Enterer (Idler Enterer)";
253 case ECORE_MAGIC_IDLE_EXITER:
254 return "Ecore_Idle_Exiter (Idler Exiter)";
256 case ECORE_MAGIC_FD_HANDLER:
257 return "Ecore_Fd_Handler (Fd Handler)";
259 case ECORE_MAGIC_WIN32_HANDLER:
260 return "Ecore_Win32_Handler (Win32 Handler)";
262 case ECORE_MAGIC_EVENT_HANDLER:
263 return "Ecore_Event_Handler (Event Handler)";
265 case ECORE_MAGIC_EVENT:
266 return "Ecore_Event (Event)";
273 /* fps debug calls - for debugging how much time your app actually spends */
274 /* "running" (and the inverse being time spent running)... this does not */
275 /* account for other apps and multitasking... */
277 static int _ecore_fps_debug_init_count = 0;
278 static int _ecore_fps_debug_fd = -1;
279 unsigned int *_ecore_fps_runtime_mmap = NULL;
282 _ecore_fps_debug_init(void)
288 _ecore_fps_debug_init_count++;
289 if (_ecore_fps_debug_init_count > 1) return;
294 tmp = (char *)evil_tmpdir_get ();
295 #endif /* HAVE_EVIL */
297 snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
298 _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
299 if (_ecore_fps_debug_fd < 0)
302 _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
304 if (_ecore_fps_debug_fd >= 0)
306 unsigned int zero = 0;
307 char *buf = (char *)&zero;
308 ssize_t todo = sizeof(unsigned int);
312 ssize_t r = write(_ecore_fps_debug_fd, buf, todo);
318 else if ((r < 0) && (errno == EINTR))
322 ERR("could not write to file '%s' fd %d: %s",
323 tmp, _ecore_fps_debug_fd, strerror(errno));
324 close(_ecore_fps_debug_fd);
325 _ecore_fps_debug_fd = -1;
329 _ecore_fps_runtime_mmap = mmap(NULL, sizeof(unsigned int),
330 PROT_READ | PROT_WRITE,
332 _ecore_fps_debug_fd, 0);
333 if (_ecore_fps_runtime_mmap == MAP_FAILED)
334 _ecore_fps_runtime_mmap = NULL;
339 _ecore_fps_debug_shutdown(void)
341 _ecore_fps_debug_init_count--;
342 if (_ecore_fps_debug_init_count > 0) return;
343 if (_ecore_fps_debug_fd >= 0)
352 tmp = (char *)evil_tmpdir_get ();
353 #endif /* HAVE_EVIL */
355 snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
357 if (_ecore_fps_runtime_mmap)
359 munmap(_ecore_fps_runtime_mmap, sizeof(int));
360 _ecore_fps_runtime_mmap = NULL;
362 close(_ecore_fps_debug_fd);
363 _ecore_fps_debug_fd = -1;
368 _ecore_fps_debug_runtime_add(double t)
370 if ((_ecore_fps_debug_fd >= 0) &&
371 (_ecore_fps_runtime_mmap))
375 tm = (unsigned int)(t * 1000000.0);
376 /* i know its not 100% theoretically guaranteed, but i'd say a write */
377 /* of an int could be considered atomic for all practical purposes */
378 /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */
379 /* this can run for about 4294 seconds becore looping. if you are */
380 /* doing performance testing in one run for over an hour... well */
381 /* time to restart or handle a loop condition :) */
382 *(_ecore_fps_runtime_mmap) += tm;
388 _ecore_memory_statistic(__UNUSED__ void *data)
391 static int uordblks = 0;
392 static int fordblks = 0;
393 Eina_Bool changed = EINA_FALSE;
397 #define HAS_CHANGED(Global, Local) \
398 if (Global != Local) \
401 changed = EINA_TRUE; \
404 HAS_CHANGED(uordblks, mi.uordblks);
405 HAS_CHANGED(fordblks, mi.fordblks);
408 ERR("[%i] Memory total: %i, free: %i",
413 KEEP_MAX(_ecore_memory_max_total, mi.uordblks);
414 KEEP_MAX(_ecore_memory_max_free, mi.fordblks);
416 return ECORE_CALLBACK_RENEW;