7ac32fa723303db44f9a1648741474dda228eb46
[framework/uifw/ecore.git] / src / lib / ecore / ecore.c
1
2 #ifdef HAVE_CONFIG_H
3 # include <config.h>
4 #endif
5
6 #ifdef HAVE_LOCALE_H
7 # include <locale.h>
8 #endif
9
10 #ifdef HAVE_LANGINFO_H
11 # include <langinfo.h>
12 #endif
13
14 #include "Ecore.h"
15 #include "ecore_private.h"
16
17 #ifdef HAVE_EVIL
18 # include <Evil.h>
19 #endif
20
21 static const char *_ecore_magic_string_get(Ecore_Magic m);
22 static int _ecore_init_count = 0;
23
24 int _ecore_fps_debug = 0;
25
26 /** OpenBSD does not define CODESET
27  * FIXME ??
28  */
29
30 #ifndef CODESET
31 # define CODESET "INVALID"
32 #endif
33
34 /**
35  * Set up connections, signal handlers, sockets etc.
36  * @return 1 or greater on success, 0 otherwise
37  *
38  * This function sets up all singal handlers and the basic event loop. If it
39  * succeeds, 1 will be returned, otherwise 0 will be returned.
40  *
41  * @code
42  * #include <Ecore.h>
43  *
44  * int main(int argc, char **argv)
45  * {
46  *   if (!ecore_init())
47  *   {
48  *     printf("ERROR: Cannot init Ecore!\n");
49  *     return -1;
50  *   }
51  *   ecore_main_loop_begin();
52  *   ecore_shutdown();
53  * }
54  * @endcode
55  */
56 EAPI int
57 ecore_init(void)
58 {
59    if (++_ecore_init_count == 1)
60      {
61 #ifdef HAVE_LOCALE_H
62         setlocale(LC_CTYPE, "");
63 #endif
64         /*
65         if (strcmp(nl_langinfo(CODESET), "UTF-8"))
66           {
67              printf("WARNING: not a utf8 locale!\n");
68           }
69          */
70         if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
71         if (_ecore_fps_debug) _ecore_fps_debug_init();
72         _ecore_signal_init();
73         _ecore_exe_init();
74      }
75
76    return _ecore_init_count;
77 }
78
79 /**
80  * Shut down connections, signal handlers sockets etc.
81  *
82  * This function shuts down all things set up in ecore_init() and cleans up all
83  * event queues, handlers, filters, timers, idlers, idle enterers/exiters
84  * etc. set up after ecore_init() was called.
85  *
86  * Do not call this function from any callback that may be called from the main
87  * loop, as the main loop will then fall over and not function properly.
88  */
89 EAPI int
90 ecore_shutdown(void)
91 {
92    if (--_ecore_init_count)
93       return _ecore_init_count;
94
95    if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
96    _ecore_poller_shutdown();
97    _ecore_animator_shutdown();
98    _ecore_exe_shutdown();
99    _ecore_idle_enterer_shutdown();
100    _ecore_idle_exiter_shutdown();
101    _ecore_idler_shutdown();
102    _ecore_timer_shutdown();
103    _ecore_event_shutdown();
104    _ecore_main_shutdown();
105    _ecore_signal_shutdown();
106
107    return _ecore_init_count;
108 }
109
110 EAPI void
111 _ecore_magic_fail(void *d, Ecore_Magic m, Ecore_Magic req_m, const char *fname)
112 {
113    fprintf(stderr,
114            "\n"
115            "*** ECORE ERROR: Ecore Magic Check Failed!!!\n"
116            "*** IN FUNCTION: %s()\n", fname);
117    if (!d)
118      fprintf(stderr, "  Input handle pointer is NULL!\n");
119    else if (m == ECORE_MAGIC_NONE)
120      fprintf(stderr, "  Input handle has already been freed!\n");
121    else if (m != req_m)
122      fprintf(stderr, "  Input handle is wrong type\n"
123                      "    Expected: %08x - %s\n"
124                      "    Supplied: %08x - %s\n",
125              (unsigned int)req_m, _ecore_magic_string_get(req_m),
126              (unsigned int)m, _ecore_magic_string_get(m));
127    fprintf(stderr,
128            "*** NAUGHTY PROGRAMMER!!!\n"
129            "*** SPANK SPANK SPANK!!!\n"
130            "*** Now go fix your code. Tut tut tut!\n"
131            "\n");
132    if (getenv("ECORE_ERROR_ABORT")) abort();
133 }
134
135 static const char *
136 _ecore_magic_string_get(Ecore_Magic m)
137 {
138    switch (m)
139      {
140       case ECORE_MAGIC_NONE:
141         return "None (Freed Object)";
142         break;
143       case ECORE_MAGIC_EXE:
144         return "Ecore_Exe (Executable)";
145         break;
146       case ECORE_MAGIC_TIMER:
147         return "Ecore_Timer (Timer)";
148         break;
149       case ECORE_MAGIC_IDLER:
150         return "Ecore_Idler (Idler)";
151         break;
152       case ECORE_MAGIC_IDLE_ENTERER:
153         return "Ecore_Idle_Enterer (Idler Enterer)";
154         break;
155       case ECORE_MAGIC_IDLE_EXITER:
156         return "Ecore_Idle_Exiter (Idler Exiter)";
157         break;
158       case ECORE_MAGIC_FD_HANDLER:
159         return "Ecore_Fd_Handler (Fd Handler)";
160         break;
161       case ECORE_MAGIC_EVENT_HANDLER:
162         return "Ecore_Event_Handler (Event Handler)";
163         break;
164       case ECORE_MAGIC_EVENT:
165         return "Ecore_Event (Event)";
166         break;
167       default:
168         return "<UNKNOWN>";
169      };
170    return "<UNKNOWN>";
171 }
172
173 /* fps debug calls - for debugging how much time your app actually spends */
174 /* "running" (and the inverse being time spent running)... this does not */
175 /* account for other apps and multitasking... */
176
177 static int _ecore_fps_debug_init_count = 0;
178 static int _ecore_fps_debug_fd = -1;
179 unsigned int *_ecore_fps_runtime_mmap = NULL;
180
181 void
182 _ecore_fps_debug_init(void)
183 {
184    char  buf[4096];
185    char *tmp;
186    int   pid;
187
188    _ecore_fps_debug_init_count++;
189    if (_ecore_fps_debug_init_count > 1) return;
190
191 #ifndef HAVE_EVIL
192    tmp = "/tmp";
193 #else
194    tmp = (char *)evil_tmpdir_get ();
195 #endif /* HAVE_EVIL */
196    pid = (int)getpid();
197    snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
198    _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
199    if (_ecore_fps_debug_fd < 0)
200      {
201         unlink(buf);
202         _ecore_fps_debug_fd = open(buf, O_CREAT | O_TRUNC | O_RDWR, 0644);
203      }
204    if (_ecore_fps_debug_fd >= 0)
205      {
206         unsigned int zero = 0;
207
208         write(_ecore_fps_debug_fd, &zero, sizeof(unsigned int));
209         _ecore_fps_runtime_mmap = mmap(NULL, sizeof(unsigned int),
210                                        PROT_READ | PROT_WRITE,
211                                        MAP_SHARED,
212                                        _ecore_fps_debug_fd, 0);
213         if (_ecore_fps_runtime_mmap == MAP_FAILED)
214           _ecore_fps_runtime_mmap = NULL;
215      }
216 }
217
218 void
219 _ecore_fps_debug_shutdown(void)
220 {
221    _ecore_fps_debug_init_count--;
222    if (_ecore_fps_debug_init_count > 0) return;
223    if (_ecore_fps_debug_fd >= 0)
224      {
225         char buf[4096];
226         char *tmp;
227         int   pid;
228
229 #ifndef HAVE_EVIL
230    tmp = "/tmp";
231 #else
232    tmp = (char *)evil_tmpdir_get ();
233 #endif /* HAVE_EVIL */
234    pid = (int)getpid();
235         snprintf(buf, sizeof(buf), "%s/.ecore_fps_debug-%i", tmp, pid);
236         unlink(buf);
237         if (_ecore_fps_runtime_mmap)
238           {
239              munmap(_ecore_fps_runtime_mmap, sizeof(int));
240              _ecore_fps_runtime_mmap = NULL;
241           }
242         close(_ecore_fps_debug_fd);
243         _ecore_fps_debug_fd = -1;
244      }
245 }
246
247 void
248 _ecore_fps_debug_runtime_add(double t)
249 {
250    if ((_ecore_fps_debug_fd >= 0) &&
251        (_ecore_fps_runtime_mmap))
252      {
253         unsigned int tm;
254
255         tm = (unsigned int)(t * 1000000.0);
256         /* i know its not 100% theoretically guaranteed, but i'd say a write */
257         /* of an int could be considered atomic for all practical purposes */
258         /* oh and since this is cumulative, 1 second = 1,000,000 ticks, so */
259         /* this can run for about 4294 seconds becore looping. if you are */
260         /* doing performance testing in one run for over an hour... well */
261         /* time to restart or handle a loop condition :) */
262         *(_ecore_fps_runtime_mmap) += tm;
263      }
264 }