54e067971048f1a04f5f6c2d602ab386c121e0aa
[framework/uifw/evas.git] / src / lib / canvas / evas_main.c
1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_cs.h"
4
5 #ifdef LKDEBUG
6 EAPI Eina_Bool lockdebug = EINA_FALSE;
7 EAPI int lockmax = 0;
8 #endif
9
10 static int _evas_init_count = 0;
11 int _evas_log_dom_global = -1;
12 EAPI int
13 evas_init(void)
14 {
15    if (++_evas_init_count != 1)
16      return _evas_init_count;
17
18 #ifdef LKDEBUG
19    if (getenv("EVAS_LOCK_DEBUG"))
20       {
21          lockdebug = EINA_TRUE;
22          lockmax = atoi(getenv("EVAS_LOCK_DEBUG"));
23       }
24 #endif
25    
26 #ifdef HAVE_EVIL
27    if (!evil_init())
28      return --_evas_init_count;
29 #endif
30
31    if (!eina_init())
32      goto shutdown_evil;
33
34    _evas_log_dom_global = eina_log_domain_register
35      ("evas_main", EVAS_DEFAULT_LOG_COLOR);
36    if (_evas_log_dom_global < 0)
37      {
38         EINA_LOG_ERR("Can not create a module log domain.");
39         goto shutdown_eina;
40      }
41
42    evas_module_init();
43 #ifdef BUILD_ASYNC_EVENTS
44    if (!evas_async_events_init())
45      goto shutdown_module;
46 #endif
47 #ifdef EVAS_CSERVE
48    if (getenv("EVAS_CSERVE")) evas_cserve_init();
49 #endif
50 #ifdef BUILD_ASYNC_PRELOAD
51    _evas_preload_thread_init();
52 #endif
53 #ifdef EVAS_FRAME_QUEUING
54    evas_common_frameq_init();
55 #endif
56
57    return _evas_init_count;
58
59 #ifdef BUILD_ASYNC_EVENTS
60  shutdown_module:
61    evas_module_shutdown();
62    eina_log_domain_unregister(_evas_log_dom_global);
63 #endif
64  shutdown_eina:
65    eina_shutdown();
66  shutdown_evil:
67 #ifdef HAVE_EVIL
68    evil_shutdown();
69 #endif
70
71    return --_evas_init_count;
72 }
73
74 EAPI int
75 evas_shutdown(void)
76 {
77    if (--_evas_init_count != 0)
78      return _evas_init_count;
79
80 #ifdef EVAS_FRAME_QUEUING
81    if (evas_common_frameq_enabled())
82      {
83         evas_common_frameq_finish();
84         evas_common_frameq_destroy();
85      }
86 #endif
87 #ifdef BUILD_ASYNC_EVENTS
88    _evas_preload_thread_shutdown();
89 #endif
90 #ifdef EVAS_CSERVE
91    if (getenv("EVAS_CSERVE")) evas_cserve_shutdown();
92 #endif
93 #ifdef BUILD_ASYNC_EVENTS
94    evas_async_events_shutdown();
95 #endif
96    evas_font_dir_cache_free();
97    evas_common_shutdown();
98    evas_module_shutdown();
99    eina_log_domain_unregister(_evas_log_dom_global);
100    eina_shutdown();
101 #ifdef HAVE_EVIL
102    evil_shutdown();
103 #endif
104
105    return _evas_init_count;
106 }
107
108
109 EAPI Evas *
110 evas_new(void)
111 {
112    Evas *e;
113
114    e = calloc(1, sizeof(Evas));
115    if (!e) return NULL;
116
117    e->magic = MAGIC_EVAS;
118    e->output.render_method = RENDER_METHOD_INVALID;
119    e->viewport.w = 1;
120    e->viewport.h = 1;
121    e->hinting = EVAS_FONT_HINTING_BYTECODE;
122    e->name_hash = eina_hash_string_superfast_new(NULL);
123
124 #define EVAS_ARRAY_SET(E, Array)                \
125    eina_array_step_set(&E->Array, sizeof (E->Array), 256);
126
127    EVAS_ARRAY_SET(e, delete_objects);
128    EVAS_ARRAY_SET(e, active_objects);
129    EVAS_ARRAY_SET(e, restack_objects);
130    EVAS_ARRAY_SET(e, render_objects);
131    EVAS_ARRAY_SET(e, pending_objects);
132    EVAS_ARRAY_SET(e, obscuring_objects);
133    EVAS_ARRAY_SET(e, temporary_objects);
134    EVAS_ARRAY_SET(e, calculate_objects);
135    EVAS_ARRAY_SET(e, clip_changes);
136
137 #undef EVAS_ARRAY_SET
138
139    return e;
140 }
141
142 EAPI void
143 evas_free(Evas *e)
144 {
145    Eina_Rectangle *r;
146    Evas_Layer *lay;
147    int i;
148    int del;
149
150    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
151    return;
152    MAGIC_CHECK_END();
153
154 #ifdef EVAS_FRAME_QUEUING
155    evas_common_frameq_flush();
156 #endif
157
158    if (e->walking_list == 0) evas_render_idle_flush(e);
159    
160    if (e->walking_list > 0) return;
161
162    if (e->callbacks)
163      {
164         if (e->callbacks->deletions_waiting) return;
165
166         e->callbacks->deletions_waiting = 0;
167         evas_event_callback_list_post_free(&e->callbacks->callbacks);
168         if (!e->callbacks->callbacks)
169           {
170              free(e->callbacks);
171              e->callbacks = NULL;
172           }
173
174         _evas_post_event_callback_free(e);
175      }
176    
177    del = 1;
178    e->walking_list++;
179    e->cleanup = 1;
180    while (del)
181      {
182         del = 0;
183         EINA_INLIST_FOREACH(e->layers, lay)
184           {
185              Evas_Object *o;
186
187              evas_layer_pre_free(lay);
188
189              EINA_INLIST_FOREACH(lay->objects, o)
190                {
191                   if ((o->callbacks) && (o->callbacks->walking_list))
192                     {
193                        /* Defer free */
194                        e->delete_me = 1;
195                        e->walking_list--;
196                        return;
197                     }
198                   if (!o->delete_me)
199                     del = 1;
200                }
201           }
202      }
203    EINA_INLIST_FOREACH(e->layers, lay)
204      evas_layer_free_objects(lay);
205    evas_layer_clean(e);
206
207    e->walking_list--;
208
209    evas_font_path_clear(e);
210    e->pointer.object.in = eina_list_free(e->pointer.object.in);
211
212    if (e->name_hash) eina_hash_free(e->name_hash);
213    e->name_hash = NULL;
214
215    EINA_LIST_FREE(e->damages, r)
216      eina_rectangle_free(r);
217    EINA_LIST_FREE(e->obscures, r)
218      eina_rectangle_free(r);
219
220    evas_fonts_zero_free(e);
221    
222    evas_event_callback_all_del(e);
223    evas_event_callback_cleanup(e);
224
225    if (e->engine.func)
226      {
227         e->engine.func->context_free(e->engine.data.output, e->engine.data.context);
228         e->engine.func->output_free(e->engine.data.output);
229         e->engine.func->info_free(e, e->engine.info);
230      }
231
232    for (i = 0; i < e->modifiers.mod.count; i++)
233      free(e->modifiers.mod.list[i]);
234    if (e->modifiers.mod.list) free(e->modifiers.mod.list);
235
236    for (i = 0; i < e->locks.lock.count; i++)
237      free(e->locks.lock.list[i]);
238    if (e->locks.lock.list) free(e->locks.lock.list);
239
240    if (e->engine.module) evas_module_unref(e->engine.module);
241
242    eina_array_flush(&e->delete_objects);
243    eina_array_flush(&e->active_objects);
244    eina_array_flush(&e->restack_objects);
245    eina_array_flush(&e->render_objects);
246    eina_array_flush(&e->pending_objects);
247    eina_array_flush(&e->obscuring_objects);
248    eina_array_flush(&e->temporary_objects);
249    eina_array_flush(&e->calculate_objects);
250    eina_array_flush(&e->clip_changes);
251
252    e->magic = 0;
253    free(e);
254 }
255
256 EAPI void
257 evas_output_method_set(Evas *e, int render_method)
258 {
259    Evas_Module *em;
260
261    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
262    return;
263    MAGIC_CHECK_END();
264
265    /* if our engine to set it to is invalid - abort */
266    if (render_method == RENDER_METHOD_INVALID) return;
267    /* if the engine is already set up - abort */
268    if (e->output.render_method != RENDER_METHOD_INVALID) return;
269    /* Request the right engine. */
270    em = evas_module_engine_get(render_method);
271    if (!em) return ;
272    if (em->id_engine != render_method) return;
273    if (!evas_module_load(em)) return;
274
275    /* set the correct render */
276    e->output.render_method = render_method;
277    e->engine.func = (em->functions);
278    evas_module_use(em);
279    if (e->engine.module) evas_module_unref(e->engine.module);
280    e->engine.module = em;
281    evas_module_ref(em);
282    /* get the engine info struct */
283    if (e->engine.func->info) e->engine.info = e->engine.func->info(e);
284    return;
285 }
286
287 EAPI int
288 evas_output_method_get(const Evas *e)
289 {
290    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
291    return RENDER_METHOD_INVALID;
292    MAGIC_CHECK_END();
293
294    return e->output.render_method;
295 }
296
297 EAPI Evas_Engine_Info *
298 evas_engine_info_get(const Evas *e)
299 {
300    Evas_Engine_Info *info;
301
302    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
303    return NULL;
304    MAGIC_CHECK_END();
305
306    if (!e->engine.info) return NULL;
307
308    info = e->engine.info;
309    ((Evas *)e)->engine.info_magic = info->magic;
310
311    return info;
312 }
313
314 EAPI Eina_Bool
315 evas_engine_info_set(Evas *e, Evas_Engine_Info *info)
316 {
317    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
318    return EINA_FALSE;
319    MAGIC_CHECK_END();
320    if (!info) return EINA_FALSE;
321    if (info != e->engine.info) return EINA_FALSE;
322    if (info->magic != e->engine.info_magic) return EINA_FALSE;
323    return (Eina_Bool)e->engine.func->setup(e, info);
324 }
325
326 EAPI void
327 evas_output_size_set(Evas *e, int w, int h)
328 {
329    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
330    return;
331    MAGIC_CHECK_END();
332
333    if ((w == e->output.w) && (h == e->output.h)) return;
334    if (w < 1) w = 1;
335    if (h < 1) h = 1;
336
337 #ifdef EVAS_FRAME_QUEUING
338    evas_common_frameq_flush();
339 #endif
340
341    e->output.w = w;
342    e->output.h = h;
343    e->output.changed = 1;
344    e->output_validity++;
345    e->changed = 1;
346    evas_render_invalidate(e);
347 }
348
349 EAPI void
350 evas_output_size_get(const Evas *e, int *w, int *h)
351 {
352    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
353    if (w) *w = 0;
354    if (h) *h = 0;
355    return;
356    MAGIC_CHECK_END();
357
358    if (w) *w = e->output.w;
359    if (h) *h = e->output.h;
360 }
361
362 EAPI void
363 evas_output_viewport_set(Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
364 {
365    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
366    return;
367    MAGIC_CHECK_END();
368
369    if ((x == e->viewport.x) && (y == e->viewport.y) &&
370        (w == e->viewport.w) && (h == e->viewport.h)) return;
371    if (w <= 0) return;
372    if (h <= 0) return;
373    if ((x != 0) || (y != 0))
374      {
375         ERR("Compat error. viewport x,y != 0,0 not supported");
376         x = 0;
377         y = 0;
378      }
379    e->viewport.x = x;
380    e->viewport.y = y;
381    e->viewport.w = w;
382    e->viewport.h = h;
383    e->viewport.changed = 1;
384    e->output_validity++;
385    e->changed = 1;
386 }
387
388 EAPI void
389 evas_output_viewport_get(const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
390 {
391    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
392    if (x) *x = 0;
393    if (y) *y = 0;
394    if (w) *w = 0;
395    if (h) *h = 0;
396    return;
397    MAGIC_CHECK_END();
398
399    if (x) *x = e->viewport.x;
400    if (y) *y = e->viewport.y;
401    if (w) *w = e->viewport.w;
402    if (h) *h = e->viewport.h;
403 }
404
405 EAPI Evas_Coord
406 evas_coord_screen_x_to_world(const Evas *e, int x)
407 {
408    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
409    return 0;
410    MAGIC_CHECK_END();
411    if (e->output.w == e->viewport.w) return e->viewport.x + x;
412    return (long long)e->viewport.x + (((long long)x * (long long)e->viewport.w) / (long long)e->output.w);
413 }
414
415 EAPI Evas_Coord
416 evas_coord_screen_y_to_world(const Evas *e, int y)
417 {
418    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
419    return 0;
420    MAGIC_CHECK_END();
421    if (e->output.h == e->viewport.h) return e->viewport.y + y;
422    return (long long)e->viewport.y + (((long long)y * (long long)e->viewport.h) / (long long)e->output.h);
423 }
424
425 EAPI int
426 evas_coord_world_x_to_screen(const Evas *e, Evas_Coord x)
427 {
428    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
429    return 0;
430    MAGIC_CHECK_END();
431    if (e->output.w == e->viewport.w) return x - e->viewport.x;
432    return (int)((((long long)x - (long long)e->viewport.x) * (long long)e->output.w) /  (long long)e->viewport.w);
433 }
434
435 EAPI int
436 evas_coord_world_y_to_screen(const Evas *e, Evas_Coord y)
437 {
438    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
439    return 0;
440    MAGIC_CHECK_END();
441    if (e->output.h == e->viewport.h) return y - e->viewport.y;
442    return (int)((((long long)y - (long long)e->viewport.y) * (long long)e->output.h) /  (long long)e->viewport.h);
443 }
444
445 EAPI int
446 evas_render_method_lookup(const char *name)
447 {
448    Evas_Module *em;
449
450    if (!name) return RENDER_METHOD_INVALID;
451    /* search on the engines list for the name */
452    em = evas_module_find_type(EVAS_MODULE_TYPE_ENGINE, name);
453    if (!em) return RENDER_METHOD_INVALID;
454
455    return em->id_engine;
456 }
457
458 EAPI Eina_List *
459 evas_render_method_list(void)
460 {
461    Eina_List *methods = NULL;
462
463    /* FIXME: get from modules - this is currently coded-in */
464 #ifdef BUILD_ENGINE_SOFTWARE_GDI
465    methods = eina_list_append(methods, "software_gdi");
466 #endif
467 #ifdef BUILD_ENGINE_SOFTWARE_DDRAW
468    methods = eina_list_append(methods, "software_ddraw");
469 #endif
470 #ifdef BUILD_ENGINE_SOFTWARE_16_DDRAW
471    methods = eina_list_append(methods, "software_16_ddraw");
472 #endif
473 #ifdef BUILD_ENGINE_DIRECT3D
474    methods = eina_list_append(methods, "direct3d");
475 #endif
476 #ifdef BUILD_ENGINE_SOFTWARE_16_WINCE
477    methods = eina_list_append(methods, "software_16_wince");
478 #endif
479 #ifdef BUILD_ENGINE_SOFTWARE_X11
480    methods = eina_list_append(methods, "software_x11");
481 #endif
482 #ifdef BUILD_ENGINE_SOFTWARE_16_X11
483    methods = eina_list_append(methods, "software_16_x11");
484 #endif
485 #ifdef BUILD_ENGINE_GL_X11
486    methods = eina_list_append(methods, "gl_x11");
487 #endif
488 #ifdef BUILD_ENGINE_DIRECTFB
489    methods = eina_list_append(methods, "directfb");
490 #endif
491 #ifdef BUILD_ENGINE_FB
492    methods = eina_list_append(methods, "fb");
493 #endif
494 #ifdef BUILD_ENGINE_BUFFER
495    methods = eina_list_append(methods, "buffer");
496 #endif
497 #ifdef BUILD_ENGINE_SOFTWARE_WIN32_GDI
498    methods = eina_list_append(methods, "software_win32_gdi");
499 #endif
500 #ifdef BUILD_ENGINE_SOFTWARE_SDL
501    methods = eina_list_append(methods, "software_sdl");
502 #endif
503
504    return methods;
505 }
506
507 EAPI void
508 evas_render_method_list_free(Eina_List *list)
509 {
510    eina_list_free(list);
511 }
512
513 EAPI Eina_Bool
514 evas_object_image_extension_can_load_get(const char *file)
515 {
516    const char *tmp;
517    Eina_Bool result;
518
519    tmp = eina_stringshare_add(file);
520    result = evas_common_extension_can_load_get(tmp);
521    eina_stringshare_del(tmp);
522
523    return result;
524 }
525
526 EAPI Eina_Bool
527 evas_object_image_extension_can_load_fast_get(const char *file)
528 {
529    return evas_common_extension_can_load_get(file);
530 }
531
532 EAPI void
533 evas_pointer_output_xy_get(const Evas *e, int *x, int *y)
534 {
535    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
536    if (x) *x = 0;
537    if (y) *y = 0;
538    return;
539    MAGIC_CHECK_END();
540    if (x) *x = e->pointer.x;
541    if (y) *y = e->pointer.y;
542 }
543
544 EAPI void
545 evas_pointer_canvas_xy_get(const Evas *e, Evas_Coord *x, Evas_Coord *y)
546 {
547    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
548    if (x) *x = 0;
549    if (y) *y = 0;
550    return;
551    MAGIC_CHECK_END();
552    if (x) *x = e->pointer.x;
553    if (y) *y = e->pointer.y;
554 }
555
556 EAPI int
557 evas_pointer_button_down_mask_get(const Evas *e)
558 {
559    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
560    return 0;
561    MAGIC_CHECK_END();
562    return (int)e->pointer.button;
563 }
564
565 EAPI Eina_Bool
566 evas_pointer_inside_get(const Evas *e)
567 {
568    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
569    return 0;
570    MAGIC_CHECK_END();
571    return (int)e->pointer.inside;
572 }
573
574 EAPI void
575 evas_data_attach_set(Evas *e, void *data)
576 {
577    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
578    return;
579    MAGIC_CHECK_END();
580    e->attach_data = data;
581 }
582
583 EAPI void *
584 evas_data_attach_get(const Evas *e)
585 {
586    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
587    return NULL;
588    MAGIC_CHECK_END();
589    return e->attach_data;
590 }
591
592 EAPI void
593 evas_focus_in(Evas *e)
594 {
595    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
596    return;
597    MAGIC_CHECK_END();
598    if (e->focus) return;
599    e->focus = 1;
600    evas_event_callback_call(e, EVAS_CALLBACK_CANVAS_FOCUS_IN, NULL);
601 }
602
603 EAPI void
604 evas_focus_out(Evas *e)
605 {
606    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
607    return;
608    MAGIC_CHECK_END();
609    if (!e->focus) return;
610    e->focus = 0;
611    evas_event_callback_call(e, EVAS_CALLBACK_CANVAS_FOCUS_OUT, NULL);
612 }
613
614 EAPI Eina_Bool
615 evas_focus_state_get(const Evas *e)
616 {
617    MAGIC_CHECK(e, Evas, MAGIC_EVAS);
618    return 0;
619    MAGIC_CHECK_END();
620    return e->focus;
621 }
622
623 EAPI void
624 evas_nochange_push(Evas *e)
625 {
626    e->nochange++;
627 }
628
629 EAPI void
630 evas_nochange_pop(Evas *e)
631 {
632    e->nochange--;
633 }
634
635 void
636 _evas_walk(Evas *e)
637 {
638    e->walking_list++;
639 }
640
641 void
642 _evas_unwalk(Evas *e)
643 {
644    e->walking_list--;
645    if ((e->walking_list == 0) && (e->delete_me)) evas_free(e);
646 }
647
648 EAPI const char *
649 evas_load_error_str(Evas_Load_Error error)
650 {
651    switch (error)
652      {
653       case EVAS_LOAD_ERROR_NONE:
654          return "No error on load";
655       case EVAS_LOAD_ERROR_GENERIC:
656          return "A non-specific error occurred";
657       case EVAS_LOAD_ERROR_DOES_NOT_EXIST:
658          return "File (or file path) does not exist";
659       case EVAS_LOAD_ERROR_PERMISSION_DENIED:
660          return "Permission deinied to an existing file (or path)";
661       case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
662          return "Allocation of resources failure prevented load";
663       case EVAS_LOAD_ERROR_CORRUPT_FILE:
664          return "File corrupt (but was detected as a known format)";
665       case EVAS_LOAD_ERROR_UNKNOWN_FORMAT:
666          return "File is not a known format";
667       default:
668          return "Unknown error";
669      }
670 }
671
672 EAPI void
673 evas_color_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b)
674 {
675    evas_common_convert_color_hsv_to_rgb(h, s, v, r, g, b);
676 }
677
678 EAPI void
679 evas_color_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
680 {
681    evas_common_convert_color_rgb_to_hsv(r, g, b, h, s, v);
682 }
683
684 EAPI void
685 evas_color_argb_premul(int a, int *r, int *g, int *b)
686 {
687    evas_common_convert_color_argb_premul(a, r, g, b);
688 }
689
690 EAPI void
691 evas_color_argb_unpremul(int a, int *r, int *g, int *b)
692 {
693    evas_common_convert_color_argb_unpremul(a, r, g, b);
694 }
695
696 EAPI void
697 evas_data_argb_premul(unsigned int *data, unsigned int len)
698 {
699    if (!data || (len < 1)) return;
700    evas_common_convert_argb_premul(data, len);
701 }
702
703 EAPI void
704 evas_data_argb_unpremul(unsigned int *data, unsigned int len)
705 {
706    if (!data || (len < 1)) return;
707    evas_common_convert_argb_unpremul(data, len);
708 }