aboutsummaryrefslogtreecommitdiffstats
path: root/src/bindings/mono/efl_mono/efl_all.cs
blob: 48a79b5a3afe6dd07fe35d417a0fd64fbf11efa5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#pragma warning disable 1591

using System;
using System.Runtime.InteropServices;
using System.Threading;

using static Efl.UnsafeNativeMethods;

namespace Efl
{

static class UnsafeNativeMethods
{
    private delegate void init_func_delegate();
    [DllImport(efl.Libs.Ecore)] public static extern void ecore_init();
    [DllImport(efl.Libs.Ecore)] public static extern void ecore_shutdown();
    // dotnet loads libraries from DllImport with RTLD_LOCAL. Due to the
    // way evas modules are built with meson, currently they do not link directly
    // with libevas, leading to symbol not found errors when trying to open them.
    // The call to FunctionWrapper makes sure evas is loaded with RTLD_GLOBAL,
    // allowing the symbols to remain visible for the modules until the build
    // is sorted out.
    private static Efl.Eo.FunctionWrapper<init_func_delegate> _evas_init;
    [DllImport(efl.Libs.Evas)] public static extern void evas_shutdown();
    [DllImport(efl.Libs.Elementary)] public static extern int elm_init(int argc, IntPtr argv);
    [DllImport(efl.Libs.Elementary)] public static extern void elm_shutdown();
    [DllImport(efl.Libs.Elementary)] public static extern void elm_run();
    [DllImport(efl.Libs.Elementary)] public static extern void elm_exit();

    static UnsafeNativeMethods()
    {
        _evas_init = new Efl.Eo.FunctionWrapper<init_func_delegate>(efl.Libs.Evas, "evas_init");
    }

    public static void evas_init()
    {
        _evas_init.Value.Delegate();
    }
}

public static class All
{
    private static bool InitializedUi = false;

    public static bool MainLoopInitialized {
        get;
        private set;
    }

    public static readonly object InitLock = new object();

    public static void Init(Efl.Csharp.Components components = Efl.Csharp.Components.Basic)
    {
        Eina.Config.Init();
        Efl.Eo.Config.Init();
        ecore_init();
        evas_init();
        eldbus.Config.Init();

        if (components == Efl.Csharp.Components.Ui)
        {
            Efl.Ui.Config.Init();
            InitializedUi = true;
        }
        Monitor.Enter(InitLock);
        MainLoopInitialized = true;
        Monitor.Exit(InitLock);
    }

    /// <summary>Shutdowns all EFL subsystems.</summary>
    public static void Shutdown()
    {
        // Try to cleanup everything before actually shutting down.
        Eina.Log.Debug("Calling GC before shutdown");
        System.GC.Collect();
        System.GC.WaitForPendingFinalizers();

        Monitor.Enter(InitLock);
        MainLoopInitialized = false;
        Monitor.Exit(InitLock);

        if (InitializedUi)
        {
            Eina.Log.Debug("Shutting down Elementary");
            Efl.Ui.Config.Shutdown();
        }

        Eina.Log.Debug("Shutting down Eldbus");
        eldbus.Config.Shutdown();
        Eina.Log.Debug("Shutting down Evas");
        evas_shutdown();
        Eina.Log.Debug("Shutting down Ecore");
        ecore_shutdown();
        Eina.Log.Debug("Shutting down Eo");
        Efl.Eo.Config.Shutdown();
        Eina.Log.Debug("Shutting down Eina");
        Eina.Config.Shutdown();
    }
}

// Placeholder. Will move to elm_config.cs later
namespace Ui
{

public static class Config
{
    public static void Init()
    {
        // TODO Support elm command line arguments
#if WIN32 // Not a native define, we define it in our build system
        // Ecore_Win32 uses OleInitialize, which requires single thread apartments
        if (System.Threading.Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
        {
            throw new InvalidOperationException("UI Applications require STAThreadAttribute in Main()");
        }
#endif
        elm_init(0, IntPtr.Zero);

        Efl.Ui.Win.ExitOnAllWindowsClosed = new Eina.Value(0);
    }

    public static void Shutdown()
    {
        elm_shutdown();
    }

    public static void Run()
    {
        elm_run();
    }

    public static void Exit()
    {
        elm_exit();
    }
}

}

}