diff --git a/src/bindings/mono/ecore_evas_mono/ecore_evas.cs b/src/bindings/mono/ecore_evas_mono/ecore_evas.cs new file mode 100644 index 0000000000..a1c8a6dfe2 --- /dev/null +++ b/src/bindings/mono/ecore_evas_mono/ecore_evas.cs @@ -0,0 +1,37 @@ + +using System; +using System.Runtime.InteropServices; +using System.Threading; + +public class EcoreEvas +{ + [DllImport(efl.Libs.EcoreEvas)] static extern void ecore_evas_init(); + // [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_new([MarshalAs(UnmanagedType.LPStr)] String engine_name, int x, int y, int w, int h + // , [MarshalAs(UnmanagedType.LPStr)] String extra_options); + [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_new(IntPtr engine_name, int x, int y, int w, int h + , IntPtr extra_options); + [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_get(IntPtr ecore_evas); + [DllImport(efl.Libs.EcoreEvas)] static extern IntPtr ecore_evas_show(IntPtr ecore_evas); + + IntPtr handle; + public EcoreEvas() + { +#if WIN32 // Not a native define, we define it in our build system + // Ecore_Win32 uses OleInitialize, which requires single thread apartments + if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) + throw new InvalidOperationException("UI Applications require STAThreadAttribute in Main()"); +#endif + ecore_evas_init(); + handle = ecore_evas_new(IntPtr.Zero, 0, 0, 640, 480, IntPtr.Zero); + if(handle == IntPtr.Zero) + System.Console.WriteLine("Couldn't create a ecore evas"); + ecore_evas_show(handle); + } + + public efl.canvas.Object canvas + { + get { return new efl.canvas.ObjectConcrete(ecore_evas_get(handle)); } + } + +} + diff --git a/src/bindings/mono/efl_mono/.gitignore b/src/bindings/mono/efl_mono/.gitignore new file mode 100644 index 0000000000..cc8a6c3119 --- /dev/null +++ b/src/bindings/mono/efl_mono/.gitignore @@ -0,0 +1 @@ +/efl_libs.cs diff --git a/src/bindings/mono/efl_mono/efl_all.cs b/src/bindings/mono/efl_mono/efl_all.cs new file mode 100644 index 0000000000..697cdf2f94 --- /dev/null +++ b/src/bindings/mono/efl_mono/efl_all.cs @@ -0,0 +1,88 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; + +using static efl.UnsafeNativeMethods; + +namespace efl { + +static class UnsafeNativeMethods { + [DllImport(efl.Libs.Ecore)] public static extern void ecore_init(); + [DllImport(efl.Libs.Ecore)] public static extern void ecore_shutdown(); + [DllImport(efl.Libs.Evas)] public static extern void 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_policy_set(int policy, int policy_detail); + [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(); +} + +public enum Components { + Basic, + Ui +} + +public static class All { + private static bool InitializedUi = false; + + public static void Init(efl.Components components=Components.Basic) { + eina.Config.Init(); + efl.eo.Config.Init(); + ecore_init(); + evas_init(); + eldbus.Config.Init(); + + if (components == Components.Ui) { + efl.ui.Config.Init(); + InitializedUi = true; + } + } + + /// Shutdowns all EFL subsystems. + public static void Shutdown() { + // Try to cleanup everything before actually shutting down. + System.GC.Collect(); + System.GC.WaitForPendingFinalizers(); + + if (InitializedUi) + efl.ui.Config.Shutdown(); + eldbus.Config.Shutdown(); + evas_shutdown(); + ecore_shutdown(); + efl.eo.Config.Shutdown(); + 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 (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) + throw new InvalidOperationException("UI Applications require STAThreadAttribute in Main()"); +#endif + elm_init(0, IntPtr.Zero); + + elm_policy_set((int)elm.Policy.Quit, (int)elm.policy.Quit.Last_window_hidden); + } + public static void Shutdown() { + elm_shutdown(); + } + + public static void Run() { + elm_run(); + } + + public static void Exit() { + elm_exit(); + } +} + +} + +} diff --git a/src/bindings/mono/efl_mono/efl_libs.cs.in b/src/bindings/mono/efl_mono/efl_libs.cs.in new file mode 100644 index 0000000000..e1c7dc6aeb --- /dev/null +++ b/src/bindings/mono/efl_mono/efl_libs.cs.in @@ -0,0 +1,22 @@ + +namespace efl { + +/// +/// Define the name of the libraries to be passed to DllImport statements. +/// +public class Libs { + public const string Efl = "@EFL_DL_MONO@"; + public const string Ecore = "@ECORE_DL_MONO@"; + public const string Eina = "@EINA_DL_MONO@"; + public const string Eo = "@EO_DL_MONO@"; + public const string Evas = "@EVAS_DL_MONO@"; + public const string Evil = "@EVIL_DL_MONO@"; + public const string EcoreEvas = "@ECORE_EVAS_DL_MONO@"; + public const string Edje = "@EDJE_DL_MONO@"; + public const string Elementary = "@ELEMENTARY_DL_MONO@"; + public const string Eldbus = "@ELDBUS_DL_MONO@"; + + public const string CustomExports = "@CUSTOM_EXPORTS_MONO_DL_MONO@"; +} + +} diff --git a/src/bindings/mono/efl_mono/efl_libs.csv.in b/src/bindings/mono/efl_mono/efl_libs.csv.in new file mode 100644 index 0000000000..3e356fe607 --- /dev/null +++ b/src/bindings/mono/efl_mono/efl_libs.csv.in @@ -0,0 +1 @@ +@EFL_MONO_LIBRARY_MAP@ diff --git a/src/bindings/mono/eina_mono/eina_array.cs b/src/bindings/mono/eina_mono/eina_array.cs new file mode 100644 index 0000000000..98e43b88b8 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_array.cs @@ -0,0 +1,291 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using static eina.TraitFunctions; +using static eina.ArrayNativeFunctions; + +namespace eina { + +public static class ArrayNativeFunctions +{ + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_array_new(uint step); + [DllImport(efl.Libs.Eina)] public static extern void + eina_array_free(IntPtr array); + [DllImport(efl.Libs.Eina)] public static extern void + eina_array_flush(IntPtr array); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_array_remove(IntPtr array, IntPtr keep, IntPtr gdata); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_array_push(IntPtr array, IntPtr data); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_array_iterator_new(IntPtr array); + + [DllImport(efl.Libs.CustomExports)] public static extern void + eina_array_clean_custom_export_mono(IntPtr array); + [DllImport(efl.Libs.CustomExports)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_array_push_custom_export_mono(IntPtr array, IntPtr data); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_array_pop_custom_export_mono(IntPtr array); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_array_data_get_custom_export_mono(IntPtr array, uint idx); + [DllImport(efl.Libs.CustomExports)] public static extern void + eina_array_data_set_custom_export_mono(IntPtr array, uint idx, IntPtr data); + [DllImport(efl.Libs.CustomExports)] public static extern uint + eina_array_count_custom_export_mono(IntPtr array); + + [DllImport(efl.Libs.CustomExports)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_array_foreach_custom_export_mono(IntPtr array, IntPtr cb, IntPtr fdata); +} + +public class Array : IEnumerable, IDisposable +{ + public static uint DefaultStep = 32; + + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} + public bool OwnContent {get;set;} + + public int Length + { + get { return Count(); } + } + + + private void InitNew(uint step) + { + Handle = eina_array_new(step); + Own = true; + OwnContent = true; + if (Handle == IntPtr.Zero) + throw new SEHException("Could not alloc array"); + } + + internal bool InternalPush(IntPtr ele) + { + return eina_array_push_custom_export_mono(Handle, ele); + } + + internal IntPtr InternalPop() + { + return eina_array_pop_custom_export_mono(Handle); + } + + internal IntPtr InternalDataGet(int idx) + { + return eina_array_data_get_custom_export_mono(Handle, (uint)idx); // TODO: Check bounds ??? + } + + internal void InternalDataSet(int idx, IntPtr ele) + { + eina_array_data_set_custom_export_mono(Handle, (uint)idx, ele); // TODO: Check bounds ??? + } + + public Array() + { + InitNew(DefaultStep); + } + + public Array(uint step) + { + InitNew(step); + } + + public Array(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + OwnContent = own; + } + + public Array(IntPtr handle, bool own, bool ownContent) + { + Handle = handle; + Own = own; + OwnContent = ownContent; + } + + ~Array() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (OwnContent) + { + int len = (int)eina_array_count_custom_export_mono(h); + for(int i = 0; i < len; ++i) + { + NativeFree(eina_array_data_get_custom_export_mono(h, (uint)i)); + } + } + + if (Own) + eina_array_free(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + private void FreeElementsIfOwned() + { + if (OwnContent) + { + int len = Length; + for(int i = 0; i < len; ++i) + { + NativeFree(InternalDataGet(i)); + } + } + } + + public void Clean() + { + FreeElementsIfOwned(); + eina_array_clean_custom_export_mono(Handle); + } + + public void Flush() + { + FreeElementsIfOwned(); + eina_array_flush(Handle); + } + + public int Count() + { + return (int) eina_array_count_custom_export_mono(Handle); + } + + public void SetOwnership(bool ownAll) + { + Own = ownAll; + OwnContent = ownAll; + } + + public void SetOwnership(bool own, bool ownContent) + { + Own = own; + OwnContent = ownContent; + } + + public bool Push(T val) + { + IntPtr ele = ManagedToNativeAlloc(val); + var r = InternalPush(ele); + if (!r) + NativeFree(ele); + return r; + } + +// TODO ??? +// public void Add(T val) +// { +// if (!Push(val)) +// throw; +// } + + public T Pop() + { + IntPtr ele = InternalPop(); + var r = NativeToManaged(ele); + if (OwnContent && ele != IntPtr.Zero) + NativeFree(ele); + return r; + } + + public T DataGet(int idx) + { + IntPtr ele = InternalDataGet(idx); + return NativeToManaged(ele); + } + + public T At(int idx) + { + return DataGet(idx); + } + + public void DataSet(int idx, T val) + { + IntPtr ele = InternalDataGet(idx); // TODO: check bondaries ?? + if (OwnContent && ele != IntPtr.Zero) + NativeFree(ele); + ele = ManagedToNativeAlloc(val); + InternalDataSet(idx, ele); + } + + public T this[int idx] + { + get + { + return DataGet(idx); + } + set + { + DataSet(idx, value); + } + } + + public T[] ToArray() + { + int len = Length; + var managed = new T[len]; + for(int i = 0; i < len; ++i) + { + managed[i] = DataGet(i); + } + return managed; + } + + public bool Append(T[] values) + { + foreach(T v in values) + if (!Push(v)) + return false; + return true; + } + + + public eina.Iterator GetIterator() + { + return new eina.Iterator(eina_array_iterator_new(Handle), true, false); + } + + public IEnumerator GetEnumerator() + { + int len = Length; + for(int i = 0; i < len; ++i) + { + yield return DataGet(i); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } +} + +} diff --git a/src/bindings/mono/eina_mono/eina_binbuf.cs b/src/bindings/mono/eina_mono/eina_binbuf.cs new file mode 100644 index 0000000000..dd30ab1275 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_binbuf.cs @@ -0,0 +1,210 @@ +using System; +using System.Runtime.InteropServices; + +namespace eina { + +public class Binbuf : IDisposable +{ + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_binbuf_new(); + [DllImport(efl.Libs.Eina)] public static extern void + eina_binbuf_free(IntPtr buf); + [DllImport(efl.Libs.Eina)] public static extern void + eina_binbuf_reset(IntPtr buf); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_append_length(IntPtr buf, byte[] str, UIntPtr length); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_append_slice(IntPtr buf, eina.Slice slice); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_append_buffer(IntPtr buf, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_append_char(IntPtr buf, byte c); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_insert_length(IntPtr buf, byte[] str, UIntPtr length, UIntPtr pos); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_insert_slice(IntPtr buf, eina.Slice slice, UIntPtr pos); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_insert_char(IntPtr buf, byte c, UIntPtr pos); + [DllImport(efl.Libs.Eina)] public static extern byte + eina_binbuf_remove(IntPtr buf, UIntPtr start, UIntPtr end); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_binbuf_string_get(IntPtr buf); + [DllImport(efl.Libs.Eina)] public static extern void + eina_binbuf_string_free(IntPtr buf); + [DllImport(efl.Libs.Eina)] public static extern UIntPtr + eina_binbuf_length_get(IntPtr buf); + [DllImport(efl.Libs.Eina)] public static extern eina.Slice + eina_binbuf_slice_get(IntPtr buf); + + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} + + public int Length + { + get { return (int) GetLength(); } + } + + private void InitNew() + { + Handle = eina_binbuf_new(); + Own = true; + if (Handle == IntPtr.Zero) + throw new SEHException("Could not alloc binbuf"); + } + + public Binbuf() + { + InitNew(); + } + + public Binbuf(byte[] str, uint? length = null) + { + InitNew(); + + if (str != null) + { + if (!Append(str, (length != null ? length.Value : (uint)(str.Length)))) + { + Dispose(); + throw new SEHException("Could not append on binbuf"); + } + } + } + + public Binbuf(Binbuf bb) + { + InitNew(); + + if (bb != null) + { + Append(bb); + } + } + + public Binbuf(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + } + + ~Binbuf() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (Own && h != IntPtr.Zero) { + eina_binbuf_free(Handle); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public void Reset() + { + eina_binbuf_reset(Handle); + } + + public bool Append(byte[] str) + { + return 0 != eina_binbuf_append_length(Handle, str, (UIntPtr)(str.Length)); + } + + public bool Append(byte[] str, uint length) + { + return 0 != eina_binbuf_append_length(Handle, str, (UIntPtr)length); + } + + public bool Append(Binbuf bb) + { + return 0 != eina_binbuf_append_buffer(Handle, bb.Handle); + } + + public bool Append(byte c) + { + return 0 != eina_binbuf_append_char(Handle, c); + } + + public bool Append(eina.Slice slice) + { + return 0 != eina_binbuf_append_slice(Handle, slice); + } + + public bool Insert(byte[] str, uint pos) + { + return 0 != eina_binbuf_insert_length(Handle, str, (UIntPtr)(str.Length), (UIntPtr)pos); + } + + public bool Insert(byte[] str, uint length, uint pos) + { + return 0 != eina_binbuf_insert_length(Handle, str, (UIntPtr)length, (UIntPtr)pos); + } + + public bool Insert(byte c, uint pos) + { + return 0 != eina_binbuf_insert_char(Handle, c, (UIntPtr)pos); + } + + public bool Insert(eina.Slice slice, uint pos) + { + return 0 != eina_binbuf_insert_slice(Handle, slice, (UIntPtr)pos); + } + + public bool Remove(uint start, uint end) + { + return 0 != eina_binbuf_remove(Handle, (UIntPtr)start, (UIntPtr)end); + } + + public byte[] GetBytes() + { + var ptr = eina_binbuf_string_get(Handle); + if (ptr == IntPtr.Zero) + return null; + + var size = (int)(this.GetLength()); + byte[] mArray = new byte[size]; + Marshal.Copy(ptr, mArray, 0, size); + return mArray; + } + + public IntPtr GetStringNative() + { + return eina_binbuf_string_get(Handle); + } + + public void FreeString() + { + eina_binbuf_string_free(Handle); + } + + public UIntPtr GetLength() + { + return eina_binbuf_length_get(Handle); + } + + eina.Slice GetSlice() + { + return eina_binbuf_slice_get(Handle); + } +} + +} diff --git a/src/bindings/mono/eina_mono/eina_common.cs b/src/bindings/mono/eina_mono/eina_common.cs new file mode 100644 index 0000000000..05a562595c --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_common.cs @@ -0,0 +1,132 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace eina +{ +namespace Callbacks +{ + +public delegate int Eina_Compare_Cb(IntPtr data1, IntPtr data2); +public delegate void Eina_Free_Cb(IntPtr data); + +} + +public static class NativeCustomExportFunctions +{ + [DllImport(efl.Libs.CustomExports)] public static extern void + efl_mono_native_free(IntPtr ptr); + [DllImport(efl.Libs.CustomExports)] public static extern void + efl_mono_native_free_ref(IntPtr ptr); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_alloc(uint count); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_alloc_copy(IntPtr val, uint size); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_strdup(string str); + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_ptr_compare_addr_get(); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_str_compare_addr_get(); + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_free_addr_get(); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_efl_unref_addr_get(); +} + +/// Wrapper around native memory DllImport'd functions +public static class MemoryNative { + public static void Free(IntPtr ptr) + { + NativeCustomExportFunctions.efl_mono_native_free(ptr); + } + + public static void FreeRef(IntPtr ptr) + { + NativeCustomExportFunctions.efl_mono_native_free_ref(ptr); + } + + // This public api uses int as Marshal.SizeOf return an int instead of uint. + public static IntPtr Alloc(int count) + { + return NativeCustomExportFunctions.efl_mono_native_alloc(Convert.ToUInt32(count)); + } + + public static IntPtr AllocCopy(IntPtr ptr, int count) + { + return NativeCustomExportFunctions.efl_mono_native_alloc_copy(ptr, Convert.ToUInt32(count)); + } + + public static IntPtr StrDup(string str) + { + return NativeCustomExportFunctions.efl_mono_native_strdup(str); + } + + // IntPtr's for some native functions + public static IntPtr PtrCompareFuncPtrGet() + { + return NativeCustomExportFunctions.efl_mono_native_ptr_compare_addr_get(); + } + + public static IntPtr StrCompareFuncPtrGet() + { + return NativeCustomExportFunctions.efl_mono_native_str_compare_addr_get(); + } + + public static IntPtr FreeFuncPtrGet() + { + return NativeCustomExportFunctions.efl_mono_native_free_addr_get(); + } + + public static IntPtr EflUnrefFuncPtrGet() + { + return NativeCustomExportFunctions.efl_mono_native_efl_unref_addr_get(); + } +} + +public static class StringConversion +{ + public static IntPtr ManagedStringToNativeUtf8Alloc(string managedString) + { + if (managedString == null) + return IntPtr.Zero; + + byte[] strbuf = Encoding.UTF8.GetBytes(managedString); + IntPtr native = MemoryNative.Alloc(strbuf.Length + 1); + Marshal.Copy(strbuf, 0, native, strbuf.Length); + Marshal.WriteByte(native + strbuf.Length, 0); // write the terminating null + return native; + } + + public static string NativeUtf8ToManagedString(IntPtr pNativeData) + { + if (pNativeData == IntPtr.Zero) + return null; + + int len = 0; + while (Marshal.ReadByte(pNativeData, len) != 0) + ++len; + + byte[] strbuf = new byte[len]; + Marshal.Copy(pNativeData, strbuf, 0, strbuf.Length); + return Encoding.UTF8.GetString(strbuf); + } +} + +public struct Unicode { + private uint val; + + public static implicit operator Unicode(uint x) + { + return new Unicode{val=x}; + } + public static implicit operator uint(Unicode x) + { + return x.val; + } +} + + +} diff --git a/src/bindings/mono/eina_mono/eina_config.cs b/src/bindings/mono/eina_mono/eina_config.cs new file mode 100644 index 0000000000..c33dd06601 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_config.cs @@ -0,0 +1,62 @@ +using System; +using System.Runtime.InteropServices; + +namespace eina { + +public class Config { + [DllImport(efl.Libs.Eina)] private static extern int eina_init(); + [DllImport(efl.Libs.Eina)] private static extern int eina_shutdown(); + + public static void Init() { + if (eina_init() == 0) + throw (new efl.EflException("Failed to initialize Eina")); + + // Initialize the submodules here + eina.Log.Init(); + eina.Error.Init(); + } + + public static int Shutdown() { + return eina_shutdown(); + } + +} + +/// +/// Wrapper class for pointers that need some cleanup afterwards +/// like strings. +/// +public class DisposableIntPtr : IDisposable { + + public IntPtr Handle { get; set; } + private bool ShouldFree; + private bool Disposed; + + /// Wraps a new ptr what will be freed based on the + /// value of shouldFree + public DisposableIntPtr(IntPtr ptr, bool shouldFree=false) + { + Handle = ptr; + ShouldFree = shouldFree; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (!Disposed && ShouldFree) { + MemoryNative.Free(this.Handle); + } + Disposed = true; + } + + ~DisposableIntPtr() + { + Dispose(false); + } +} +} diff --git a/src/bindings/mono/eina_mono/eina_container_common.cs b/src/bindings/mono/eina_mono/eina_container_common.cs new file mode 100644 index 0000000000..6cdafdc836 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_container_common.cs @@ -0,0 +1,683 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using eina.Callbacks; +using static eina.HashNativeFunctions; +using static eina.InarrayNativeFunctions; +using static eina.InlistNativeFunctions; +using static eina.NativeCustomExportFunctions; +using static eina.ContainerCommonData; + +namespace eina { + +public enum ElementType { NumericType, StringType, ObjectType }; + +public static class ContainerCommonData +{ + public static IBaseElementTraits intPtrTraits = null; +} + +[StructLayout(LayoutKind.Sequential)] +public struct ConvertWrapper +{ + public T Val {get;set;} +} + +[StructLayout(LayoutKind.Sequential)] +public struct InlistMem +{ + public IntPtr next {get;set;} + public IntPtr prev {get;set;} + public IntPtr last {get;set;} +} + +[StructLayout(LayoutKind.Sequential)] +public struct InlistNode +{ + public InlistMem __in_list {get;set;} + public T Val {get;set;} +} + + +public interface IBaseElementTraits +{ + IntPtr ManagedToNativeAlloc(T man); + IntPtr ManagedToNativeAllocRef(T man, bool refs); + IntPtr ManagedToNativeAllocInlistNode(T man); + IntPtr ManagedToNativeAllocInplace(T man); + void NativeFree(IntPtr nat); + void NativeFreeRef(IntPtr nat, bool unrefs); + void NativeFreeInlistNodeElement(IntPtr nat); + void NativeFreeInlistNode(IntPtr nat, bool freeElement); + void NativeFreeInplace(IntPtr nat); + void ResidueFreeInplace(IntPtr nat); + T NativeToManaged(IntPtr nat); + T NativeToManagedRef(IntPtr nat); + T NativeToManagedInlistNode(IntPtr nat); + T NativeToManagedInplace(IntPtr nat); + IntPtr EinaCompareCb(); + IntPtr EinaFreeCb(); + IntPtr EinaHashNew(); + IntPtr EinaInarrayNew(uint step); + IntPtr EinaHashIteratorKeyNew(IntPtr hash); +} + +public class StringElementTraits : IBaseElementTraits +{ + + public StringElementTraits() + { + if (intPtrTraits == null) + intPtrTraits = TraitFunctions.GetTypeTraits(); + } + + public IntPtr ManagedToNativeAlloc(T man) + { + return MemoryNative.StrDup((string)(object)man); + } + + public IntPtr ManagedToNativeAllocRef(T man, bool refs) + { + // Keep alloc on C# ? + return ManagedToNativeAlloc(man); + } + + public IntPtr ManagedToNativeAllocInlistNode(T man) + { + var node = new InlistNode(); + node.Val = ManagedToNativeAlloc(man); + GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned); + IntPtr ptr = pinnedData.AddrOfPinnedObject(); + IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf >()); + pinnedData.Free(); + return nat; + } + + public IntPtr ManagedToNativeAllocInplace(T man) + { + return intPtrTraits.ManagedToNativeAlloc(ManagedToNativeAlloc(man)); + } + + public void NativeFree(IntPtr nat) + { + if (nat != IntPtr.Zero) + MemoryNative.Free(nat); + } + + public void NativeFreeRef(IntPtr nat, bool unrefs) + { + NativeFree(nat); + } + + public void NativeFreeInlistNodeElement(IntPtr nat) + { + if (nat == IntPtr.Zero) + return; + var node = Marshal.PtrToStructure< InlistNode >(nat); + NativeFree(node.Val); + } + + public void NativeFreeInlistNode(IntPtr nat, bool freeElement) + { + if (nat == IntPtr.Zero) + return; + if (freeElement) + NativeFreeInlistNodeElement(nat); + MemoryNative.Free(nat); + } + + public void NativeFreeInplace(IntPtr nat) + { + MemoryNative.FreeRef(nat); + } + + public void ResidueFreeInplace(IntPtr nat) + { + intPtrTraits.NativeFree(nat); + } + + public T NativeToManaged(IntPtr nat) + { + if (nat == IntPtr.Zero) + return default(T); + return (T)(object)StringConversion.NativeUtf8ToManagedString(nat); + } + + public T NativeToManagedRef(IntPtr nat) + { + return NativeToManaged(nat); + } + + public T NativeToManagedInlistNode(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + eina.Log.Error("Null pointer for Inlist node."); + return default(T); + } + var w = Marshal.PtrToStructure< InlistNode >(nat); + return NativeToManaged(w.Val); + } + + public T NativeToManagedInplace(IntPtr nat) + { + if (nat == IntPtr.Zero) + return default(T); + return NativeToManaged(intPtrTraits.NativeToManaged(nat)); + } + + public IntPtr EinaCompareCb() + { + return MemoryNative.StrCompareFuncPtrGet(); + } + + public IntPtr EinaFreeCb() + { + return MemoryNative.FreeFuncPtrGet(); + } + + public IntPtr EinaHashNew() + { + return eina_hash_string_superfast_new(IntPtr.Zero); + } + + public IntPtr EinaInarrayNew(uint step) + { + return eina_inarray_new((uint)Marshal.SizeOf(), step); + } + + public IntPtr EinaHashIteratorKeyNew(IntPtr hash) + { + return eina_hash_iterator_key_new(hash); + } +} + +public class EflObjectElementTraits : IBaseElementTraits +{ + private System.Type concreteType = null; + + public EflObjectElementTraits(System.Type concrete) + { + if (intPtrTraits == null) + intPtrTraits = TraitFunctions.GetTypeTraits(); + + concreteType = concrete; + } + + public IntPtr ManagedToNativeAlloc(T man) + { + IntPtr h = ((efl.eo.IWrapper)man).raw_handle; + if (h == IntPtr.Zero) + return h; + return efl.eo.Globals.efl_ref(h); + } + + public IntPtr ManagedToNativeAllocRef(T man, bool refs) + { + IntPtr h = refs ? ManagedToNativeAlloc(man) : ((efl.eo.IWrapper)man).raw_handle; + return intPtrTraits.ManagedToNativeAlloc(h); + } + + public IntPtr ManagedToNativeAllocInlistNode(T man) + { + var node = new InlistNode(); + node.Val = ManagedToNativeAlloc(man); + GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned); + IntPtr ptr = pinnedData.AddrOfPinnedObject(); + IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf >()); + pinnedData.Free(); + return nat; + } + + public IntPtr ManagedToNativeAllocInplace(T man) + { + return intPtrTraits.ManagedToNativeAlloc(ManagedToNativeAlloc(man)); + } + + public void NativeFree(IntPtr nat) + { + if (nat != IntPtr.Zero) + efl.eo.Globals.efl_unref(nat); + } + + public void NativeFreeRef(IntPtr nat, bool unrefs) + { + if (unrefs) + NativeFree(intPtrTraits.NativeToManaged(nat)); + intPtrTraits.NativeFree(nat); + } + + public void NativeFreeInlistNodeElement(IntPtr nat) + { + if (nat == IntPtr.Zero) + return; + var node = Marshal.PtrToStructure< InlistNode >(nat); + NativeFree(node.Val); + } + + public void NativeFreeInlistNode(IntPtr nat, bool freeElement) + { + if (nat == IntPtr.Zero) + return; + if (freeElement) + NativeFreeInlistNodeElement(nat); + MemoryNative.Free(nat); + } + + public void NativeFreeInplace(IntPtr nat) + { + NativeFree(intPtrTraits.NativeToManaged(nat)); + } + + public void ResidueFreeInplace(IntPtr nat) + { + intPtrTraits.NativeFree(nat); + } + + public T NativeToManaged(IntPtr nat) + { + if (nat == IntPtr.Zero) + return default(T); + return (T) Activator.CreateInstance(concreteType, efl.eo.Globals.efl_ref(nat)); + } + + public T NativeToManagedRef(IntPtr nat) + { + if (nat == IntPtr.Zero) + return default(T); + return NativeToManaged(intPtrTraits.NativeToManaged(nat)); + } + + public T NativeToManagedInlistNode(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + eina.Log.Error("Null pointer for Inlist node."); + return default(T); + } + var w = Marshal.PtrToStructure< InlistNode >(nat); + return NativeToManaged(w.Val); + } + + public T NativeToManagedInplace(IntPtr nat) + { + if (nat == IntPtr.Zero) + return default(T); + return NativeToManaged(intPtrTraits.NativeToManaged(nat)); + } + + public IntPtr EinaCompareCb() + { + return MemoryNative.PtrCompareFuncPtrGet(); + } + + public IntPtr EinaFreeCb() + { + return MemoryNative.EflUnrefFuncPtrGet(); + } + + public IntPtr EinaHashNew() + { + return eina_hash_pointer_new(IntPtr.Zero); + } + + public IntPtr EinaInarrayNew(uint step) + { + return eina_inarray_new((uint)Marshal.SizeOf(), step); + } + + public IntPtr EinaHashIteratorKeyNew(IntPtr hash) + { + return eina_hash_iterator_ptr_key_wrapper_new_custom_export_mono(hash); + } +} + +public abstract class PrimitiveElementTraits +{ + private Eina_Compare_Cb dlgt = null; + + public IntPtr ManagedToNativeAlloc(T man) + { + GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned); + IntPtr ptr = pinnedData.AddrOfPinnedObject(); + IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf()); + pinnedData.Free(); + return nat; + } + + public IntPtr ManagedToNativeAllocInlistNode(T man) + { + var node = new InlistNode(); + node.Val = man; + GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned); + IntPtr ptr = pinnedData.AddrOfPinnedObject(); + IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf< InlistNode >()); + pinnedData.Free(); + return nat; + } + + public IntPtr ManagedToNativeAllocInplace(T man) + { + return ManagedToNativeAlloc(man); + } + + public void NativeFree(IntPtr nat) + { + MemoryNative.Free(nat); + } + + public void NativeFreeInlistNodeElement(IntPtr nat) + { + // Do nothing + } + + public void NativeFreeInlistNode(IntPtr nat, bool freeElement) + { + MemoryNative.Free(nat); + } + + public void NativeFreeInplace(IntPtr nat) + { + // Do nothing + } + + public void ResidueFreeInplace(IntPtr nat) + { + NativeFree(nat); + } + + public T NativeToManaged(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + eina.Log.Error("Null pointer on primitive/struct container."); + return default(T); + } + var w = Marshal.PtrToStructure >(nat); + return w.Val; + } + + public T NativeToManagedRef(IntPtr nat) + { + return NativeToManaged(nat); + } + + public T NativeToManagedInlistNode(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + eina.Log.Error("Null pointer for Inlist node."); + return default(T); + } + var w = Marshal.PtrToStructure< InlistNode >(nat); + return w.Val; + } + + public T NativeToManagedInplace(IntPtr nat) + { + return NativeToManaged(nat); + } + + private int PrimitiveCompareCb(IntPtr ptr1, IntPtr ptr2) + { + var m1 = (IComparable) NativeToManaged(ptr1); + var m2 = NativeToManaged(ptr2); + return m1.CompareTo(m2); + } + + public IntPtr EinaCompareCb() + { + if (dlgt == null) + dlgt = new Eina_Compare_Cb(PrimitiveCompareCb); + return Marshal.GetFunctionPointerForDelegate(dlgt); + } + + public IntPtr EinaFreeCb() + { + return MemoryNative.FreeFuncPtrGet(); + } + + public IntPtr EinaInarrayNew(uint step) + { + return eina_inarray_new((uint)Marshal.SizeOf(), step); + } + + public IntPtr EinaHashIteratorKeyNew(IntPtr hash) + { + return eina_hash_iterator_key_new(hash); + } +} + +public class Primitive32ElementTraits : PrimitiveElementTraits, IBaseElementTraits +{ + private static IBaseElementTraits int32Traits = null; + + public Primitive32ElementTraits() + { + if (int32Traits == null) + if (typeof(T) == typeof(Int32)) // avoid infinite recursion + int32Traits = (IBaseElementTraits)this; + else + int32Traits = TraitFunctions.GetTypeTraits(); + } + + public IntPtr ManagedToNativeAllocRef(T man, bool refs) + { + return int32Traits.ManagedToNativeAlloc(Convert.ToInt32((object)man)); + } + + public void NativeFreeRef(IntPtr nat, bool unrefs) + { + int32Traits.NativeFree(nat); + } + + public IntPtr EinaHashNew() + { + return eina_hash_int32_new(IntPtr.Zero); + } +} + +public class Primitive64ElementTraits : PrimitiveElementTraits, IBaseElementTraits +{ + private static IBaseElementTraits int64Traits = null; + + public Primitive64ElementTraits() + { + if (int64Traits == null) + if (typeof(T) == typeof(Int64)) // avoid infinite recursion + int64Traits = (IBaseElementTraits)this; + else + int64Traits = TraitFunctions.GetTypeTraits(); + } + + public IntPtr ManagedToNativeAllocRef(T man, bool refs) + { + return int64Traits.ManagedToNativeAlloc(Convert.ToInt64((object)man)); + } + + public void NativeFreeRef(IntPtr nat, bool unrefs) + { + int64Traits.NativeFree(nat); + } + + public IntPtr EinaHashNew() + { + return eina_hash_int64_new(IntPtr.Zero); + } +} + +public static class TraitFunctions +{ + public static bool IsEflObject(System.Type type) + { + return typeof(efl.eo.IWrapper).IsAssignableFrom(type); + } + + public static bool IsString(System.Type type) + { + return type == typeof(string); + } + + public static eina.ElementType GetElementTypeCode(System.Type type) + { + if (IsEflObject(type)) + return ElementType.ObjectType; + else if (IsString(type)) + return ElementType.StringType; + else + return ElementType.NumericType; + } + + private static IDictionary register = new Dictionary(); + + public static object RegisterTypeTraits() + { + object traits; + var type = typeof(T); + if (IsEflObject(type)) + { + System.Type concrete = type; + if (!type.Name.EndsWith("Concrete")) + { + var c = type.Assembly.GetType(type.FullName + "Concrete"); + if (c != null && type.IsAssignableFrom(c)) + concrete = c; + } + traits = new EflObjectElementTraits(concrete); + } + else if (IsString(type)) + traits = new StringElementTraits(); + else if (type.IsValueType) + { + if (Marshal.SizeOf() <= 4) + traits = new Primitive32ElementTraits(); + else + traits = new Primitive64ElementTraits(); + } + else + throw new Exception("No traits registered for this type"); + + register[type] = traits; + return traits; + } + + public static object RegisterTypeTraits(IBaseElementTraits traits) + { + register[typeof(T)] = traits; + return traits; + } + + public static IBaseElementTraits GetTypeTraits() + { + object traits; + if (!register.TryGetValue(typeof(T), out traits)) + traits = RegisterTypeTraits(); + return (IBaseElementTraits) traits; + } + + // // + // Traits functions // + // // + + // Convertion functions // + + public static IntPtr ManagedToNativeAlloc(T man) + { + return GetTypeTraits().ManagedToNativeAlloc(man); + } + + public static IntPtr ManagedToNativeAllocRef(T man, bool refs = false) + { + return GetTypeTraits().ManagedToNativeAllocRef(man, refs); + } + + public static IntPtr ManagedToNativeAllocInplace(T man) + { + return GetTypeTraits().ManagedToNativeAllocInplace(man); + } + + public static IntPtr ManagedToNativeAllocInlistNode(T man) + { + return GetTypeTraits().ManagedToNativeAllocInlistNode(man); + } + + public static void NativeFree(IntPtr nat) + { + GetTypeTraits().NativeFree(nat); + } + + public static void NativeFreeRef(IntPtr nat, bool unrefs = false) + { + GetTypeTraits().NativeFreeRef(nat, unrefs); + } + + public static void NativeFreeInlistNodeElement(IntPtr nat) + { + GetTypeTraits().NativeFreeInlistNodeElement(nat); + } + + public static void NativeFreeInlistNode(IntPtr nat, bool freeElement = true) + { + GetTypeTraits().NativeFreeInlistNode(nat, freeElement); + } + + public static void NativeFreeInplace(IntPtr nat) + { + GetTypeTraits().NativeFreeInplace(nat); + } + + public static void ResidueFreeInplace(IntPtr nat) + { + GetTypeTraits().ResidueFreeInplace(nat); + } + + public static T NativeToManaged(IntPtr nat) + { + return GetTypeTraits().NativeToManaged(nat); + } + + public static T NativeToManagedRef(IntPtr nat) + { + return GetTypeTraits().NativeToManagedRef(nat); + } + + public static T NativeToManagedInlistNode(IntPtr nat) + { + return GetTypeTraits().NativeToManagedInlistNode(nat); + } + + public static T NativeToManagedInplace(IntPtr nat) + { + return GetTypeTraits().NativeToManagedInplace(nat); + } + + // Misc // + + public static IntPtr EinaCompareCb() + { + return GetTypeTraits().EinaCompareCb(); + } + + public static IntPtr EinaFreeCb() + { + return GetTypeTraits().EinaFreeCb(); + } + + public static IntPtr EinaHashNew() + { + return GetTypeTraits().EinaHashNew(); + } + + public static IntPtr EinaInarrayNew(uint step) + { + return GetTypeTraits().EinaInarrayNew(step); + } + + public static IntPtr EinaHashIteratorKeyNew(IntPtr hash) + { + return GetTypeTraits().EinaHashIteratorKeyNew(hash); + } +} + +} diff --git a/src/bindings/mono/eina_mono/eina_error.cs b/src/bindings/mono/eina_mono/eina_error.cs new file mode 100644 index 0000000000..7bd604ecc4 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_error.cs @@ -0,0 +1,92 @@ +using System; +using System.Runtime.InteropServices; + +namespace eina { + +public struct Error : IComparable +{ + int code; + + public string Message + { + get { return MsgGet(this); } + } + + public static Error EFL_ERROR; + + public static Error NO_ERROR = new Error(0); + public static Error EPERM = new Error(1); + public static Error ENOENT = new Error(2); + + public Error(int value) { code = value; } + static public implicit operator Error(int val) + { + return new Error(val); + } + static public implicit operator int(Error error) + { + return error.code; + } + public int CompareTo(Error err) + { + return code.CompareTo(err.code); + } + public override string ToString() + { + return "eina.Error(" + code + ")"; + } + + public static void Init() + { + if (eina_init() == 0) + throw (new efl.EflException("Failed to init Eina")); + + EFL_ERROR = eina_error_msg_register("Managed Code Error"); + } + + [DllImport(efl.Libs.Eina)] private static extern int eina_init(); + [DllImport(efl.Libs.Eina)] static extern Error eina_error_msg_register(string msg); + [DllImport(efl.Libs.Eina)] static extern Error eina_error_get(); + [DllImport(efl.Libs.Eina)] static extern void eina_error_set(Error error); + [DllImport(efl.Libs.Eina)] static extern IntPtr eina_error_msg_get(Error error); + + public static void Set(Error error) + { + eina_error_set(error); + } + + public static Error Get() + { + return eina_error_get(); + } + + public static String MsgGet(Error error) + { + IntPtr cstr = eina_error_msg_get(error); + return eina.StringConversion.NativeUtf8ToManagedString(cstr); + } + + public static void RaiseIfOccurred() + { + Error e = Get(); + Clear(); + Raise(e); + } + + public static void Raise(Error e) + { + if (e != 0) + throw (new efl.EflException(MsgGet(e))); + } + + public static void Clear() + { + Set(0); + } + + public static Error Register(string msg) + { + return eina_error_msg_register(msg); + } +} +} diff --git a/src/bindings/mono/eina_mono/eina_hash.cs b/src/bindings/mono/eina_mono/eina_hash.cs new file mode 100644 index 0000000000..045a9aed10 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_hash.cs @@ -0,0 +1,402 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using static eina.TraitFunctions; +using static eina.IteratorNativeFunctions; +using static eina.HashNativeFunctions; +using eina.Callbacks; + +namespace eina +{ + +[StructLayout(LayoutKind.Sequential)] +public struct HashTupleNative +{ + public IntPtr key; + public IntPtr data; + public uint key_length; +} + +public static class HashNativeFunctions +{ + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_new(IntPtr key_length_cb, IntPtr key_cmp_cb, IntPtr key_hash_cb, IntPtr data_free_cb, int buckets_power_size); + + [DllImport(efl.Libs.Eina)] public static extern void + eina_hash_free_cb_set(IntPtr hash, IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_string_djb2_new(IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_string_superfast_new(IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_string_small_new(IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_int32_new(IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_int64_new(IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_pointer_new(IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_stringshared_new(IntPtr data_free_cb); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_add(IntPtr hash, IntPtr key, IntPtr data); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_direct_add(IntPtr hash, IntPtr key, IntPtr data); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_del(IntPtr hash, IntPtr key, IntPtr data); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_find(IntPtr hash, IntPtr key); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_modify(IntPtr hash, IntPtr key, IntPtr data); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_set(IntPtr hash, IntPtr key, IntPtr data); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_move(IntPtr hash, IntPtr old_key, IntPtr new_key); + + [DllImport(efl.Libs.Eina)] public static extern void + eina_hash_free(IntPtr hash); + + [DllImport(efl.Libs.Eina)] public static extern void + eina_hash_free_buckets(IntPtr hash); + + [DllImport(efl.Libs.Eina)] public static extern int + eina_hash_population(IntPtr hash); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_add_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_direct_add_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_del_by_key_hash(IntPtr hash, IntPtr key, int key_length, int key_hash); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_del_by_key(IntPtr hash, IntPtr key); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_del_by_data(IntPtr hash, IntPtr data); + + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_hash_del_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_find_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_modify_by_hash(IntPtr hash, IntPtr key, int key_length, int key_hash, IntPtr data); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_iterator_key_new(IntPtr hash); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_iterator_data_new(IntPtr hash); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_hash_iterator_tuple_new(IntPtr hash); + + [DllImport(efl.Libs.Eina)] public static extern void + eina_hash_foreach(IntPtr hash, IntPtr func, IntPtr fdata); + + + [DllImport(efl.Libs.Eina)] public static extern void + eina_hash_list_append(IntPtr hash, IntPtr key, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern void + eina_hash_list_prepend(IntPtr hash, IntPtr key, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern void + eina_hash_list_remove(IntPtr hash, IntPtr key, IntPtr data); + + [DllImport(efl.Libs.Eina)] public static extern int + eina_hash_superfast(string key, int len); + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_hash_iterator_ptr_key_wrapper_new_custom_export_mono(IntPtr hash); +} + +public class Hash : IEnumerable>, IDisposable +{ + public IntPtr Handle {get; set;} = IntPtr.Zero; + public bool Own {get; set;} + public bool OwnKey {get; set;} + public bool OwnValue {get; set;} + + public int Count { + get { + return Population(); + } + } + + + private void InitNew() + { + Handle = EinaHashNew(); + SetOwn(true); + SetOwnKey(true); + SetOwnValue(true); + } + + public Hash() + { + InitNew(); + } + + public Hash(IntPtr handle, bool own) + { + Handle = handle; + SetOwnership(own); + } + + public Hash(IntPtr handle, bool own, bool ownKey, bool ownValue) + { + Handle = handle; + SetOwnership(own, ownKey, ownValue); + } + + ~Hash() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (Own) + eina_hash_free(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public void SetOwn(bool own) + { + Own = own; + } + + public void SetOwnKey(bool ownKey) + { + OwnKey = ownKey; + } + + public void SetOwnValue(bool ownValue) + { + OwnValue = ownValue; + + if (ownValue) + eina_hash_free_cb_set(Handle, EinaFreeCb()); + } + + public void SetOwnership(bool ownAll) + { + SetOwn(ownAll); + SetOwnKey(ownAll); + SetOwnValue(ownAll); + } + + public void SetOwnership(bool own, bool ownKey, bool ownValue) + { + SetOwn(own); + SetOwnKey(ownKey); + SetOwnValue(ownValue); + } + + public void UnSetFreeCb() + { + eina_hash_free_cb_set(Handle, IntPtr.Zero); + } + + public bool AddNew(TKey key, TValue val) + { + var nk = ManagedToNativeAllocRef(key, true); + var nv = ManagedToNativeAlloc(val); + var r = eina_hash_add(Handle, nk, nv); + NativeFreeRef(nk); + return r; + } + + public void Add(TKey key, TValue val) + { + Set(key, val); + } + + public bool DelByKey(TKey key) + { + var nk = ManagedToNativeAllocRef(key); + var r = eina_hash_del_by_key(Handle, nk); + NativeFreeRef(nk, OwnKey && r); + return r; + } + + public bool DelByValue(TValue val) + { + var nv = ManagedToNativeAlloc(val); + var r = eina_hash_del_by_data(Handle, nv); + NativeFree(nv); + return r; + } + + public void Remove(TKey key) + { + DelByKey(key); + } + + public TValue Find(TKey key) + { + var nk = ManagedToNativeAllocRef(key); + var found = eina_hash_find(Handle, nk); + NativeFreeRef(nk); + if (found == IntPtr.Zero) + throw new KeyNotFoundException(); + return NativeToManaged(found); + } + + public bool TryGetValue(TKey key, out TValue val) + { + var nk = ManagedToNativeAllocRef(key); + var found = eina_hash_find(Handle, nk); + NativeFreeRef(nk); + if (found == IntPtr.Zero) + { + val = default(TValue); + return false; + } + val = NativeToManaged(found); + return true; + } + + public bool ContainsKey(TKey key) + { + var nk = ManagedToNativeAllocRef(key); + var found = eina_hash_find(Handle, nk); + NativeFreeRef(nk); + return found != IntPtr.Zero; + } + + public bool Modify(TKey key, TValue val) + { + var nk = ManagedToNativeAllocRef(key); + var nv = ManagedToNativeAlloc(val); + var old = eina_hash_modify(Handle, nk, nv); + NativeFreeRef(nk); + if (old == IntPtr.Zero) + { + NativeFree(nv); + return false; + } + if (OwnValue) + NativeFree(old); + return true; + } + + public void Set(TKey key, TValue val) + { + var nk = ManagedToNativeAllocRef(key, true); + var nv = ManagedToNativeAlloc(val); + var old = eina_hash_set(Handle, nk, nv); + NativeFreeRef(nk, old != IntPtr.Zero); + if (old != IntPtr.Zero && OwnValue) + NativeFree(old); + } + + public TValue this[TKey key] + { + get + { + return Find(key); + } + set + { + Set(key, value); + } + } + + public bool Move(TKey key_old, TKey key_new) + { + var nk_old = ManagedToNativeAllocRef(key_old); + var nk_new = ManagedToNativeAllocRef(key_new, true); + var r = eina_hash_move(Handle, nk_old, nk_new); + NativeFreeRef(nk_old, OwnKey && r); + NativeFreeRef(nk_new, !r); + return r; + } + + public void FreeBuckets() + { + eina_hash_free_buckets(Handle); + } + + public int Population() + { + return eina_hash_population(Handle); + } + + public eina.Iterator Keys() + { + return new eina.Iterator(EinaHashIteratorKeyNew(Handle), true, false); + } + + public eina.Iterator Values() + { + return new eina.Iterator(eina_hash_iterator_data_new(Handle), true, false); + } + + public IEnumerator> GetEnumerator() + { + IntPtr itr = eina_hash_iterator_tuple_new(Handle); + try + { + for (IntPtr tuplePtr; eina_iterator_next(itr, out tuplePtr);) + { + var tuple = Marshal.PtrToStructure(tuplePtr); + var key = NativeToManagedRef(tuple.key); + var val = NativeToManaged(tuple.data); + yield return new KeyValuePair(key, val); + } + } + finally + { + eina_iterator_free(itr); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } +} + +} + diff --git a/src/bindings/mono/eina_mono/eina_inarray.cs b/src/bindings/mono/eina_mono/eina_inarray.cs new file mode 100644 index 0000000000..120a4b8820 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_inarray.cs @@ -0,0 +1,324 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using static eina.TraitFunctions; +using static eina.InarrayNativeFunctions; + +namespace eina { + +public static class InarrayNativeFunctions +{ + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_new(uint member_size, uint step); + [DllImport(efl.Libs.Eina)] public static extern void + eina_inarray_free(IntPtr array); + [DllImport(efl.Libs.Eina)] public static extern void + eina_inarray_step_set(IntPtr array, uint sizeof_eina_inarray, uint member_size, uint step); + [DllImport(efl.Libs.Eina)] public static extern void + eina_inarray_flush(IntPtr array); + [DllImport(efl.Libs.Eina)] public static extern int + eina_inarray_push(IntPtr array, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_grow(IntPtr array, uint size); + [DllImport(efl.Libs.Eina)] public static extern int + eina_inarray_insert(IntPtr array, IntPtr data, IntPtr compare); + [DllImport(efl.Libs.Eina)] public static extern int + eina_inarray_insert_sorted(IntPtr array, IntPtr data, IntPtr compare); + [DllImport(efl.Libs.Eina)] public static extern int + eina_inarray_remove(IntPtr array, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_pop(IntPtr array); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_nth(IntPtr array, uint position); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_inarray_insert_at(IntPtr array, uint position, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_alloc_at(IntPtr array, uint position, uint member_count); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_inarray_replace_at(IntPtr array, uint position, IntPtr data); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_inarray_remove_at(IntPtr array, uint position); + [DllImport(efl.Libs.Eina)] public static extern void + eina_inarray_reverse(IntPtr array); + [DllImport(efl.Libs.Eina)] public static extern void + eina_inarray_sort(IntPtr array, IntPtr compare); + [DllImport(efl.Libs.Eina)] public static extern int + eina_inarray_search(IntPtr array, IntPtr data, IntPtr compare); + [DllImport(efl.Libs.Eina)] public static extern int + eina_inarray_search_sorted(IntPtr array, IntPtr data, IntPtr compare); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_inarray_foreach(IntPtr array, IntPtr function, IntPtr user_data); + [DllImport(efl.Libs.Eina)] public static extern int + eina_inarray_foreach_remove(IntPtr array, IntPtr match, IntPtr user_data); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_inarray_resize(IntPtr array, uint new_size); + [DllImport(efl.Libs.Eina)] public static extern uint + eina_inarray_count(IntPtr array); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_iterator_new(IntPtr array); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_iterator_reversed_new(IntPtr array); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inarray_accessor_new(IntPtr array); +} + +public class Inarray : IEnumerable, IDisposable +{ + public static uint DefaultStep = 0; + + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} + public bool OwnContent {get;set;} + + public int Length + { + get { return Count(); } + } + + + private void InitNew(uint step) + { + Handle = EinaInarrayNew(step); + Own = true; + OwnContent = true; + if (Handle == IntPtr.Zero) + throw new SEHException("Could not alloc inarray"); + } + + public Inarray() + { + InitNew(DefaultStep); + } + + public Inarray(uint step) + { + InitNew(step); + } + + public Inarray(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + OwnContent = own; + } + + public Inarray(IntPtr handle, bool own, bool ownContent) + { + Handle = handle; + Own = own; + OwnContent = ownContent; + } + + ~Inarray() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (OwnContent) + { + uint len = eina_inarray_count(h); + for(uint i = 0; i < len; ++i) + { + NativeFreeInplace(eina_inarray_nth(h, i)); + } + } + + if (Own) + eina_inarray_free(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + private void FreeElementsIfOwned() + { + if (OwnContent) + { + int len = Length; + for (int i = 0; i < len; ++i) + { + NativeFreeInplace(eina_inarray_nth(Handle, (uint)i)); + } + } + } + + public void Flush() + { + FreeElementsIfOwned(); + eina_inarray_flush(Handle); + } + + public int Count() + { + return (int) eina_inarray_count(Handle); + } + + public void SetOwnership(bool ownAll) + { + Own = ownAll; + OwnContent = ownAll; + } + + public void SetOwnership(bool own, bool ownContent) + { + Own = own; + OwnContent = ownContent; + } + + public int Push(T val) + { + IntPtr ele = ManagedToNativeAllocInplace(val); + var r = eina_inarray_push(Handle, ele); + if (r == -1) + NativeFreeInplace(ele); + ResidueFreeInplace(ele); + return r; + } + +// TODO ??? +// public void Add(T val) +// { +// if (!Push(val)) +// throw; +// } + + public T Pop() + { + IntPtr ele = eina_inarray_pop(Handle); + var r = NativeToManagedInplace(ele); + if (OwnContent && ele != IntPtr.Zero) + NativeFreeInplace(ele); + return r; + } + + public T Nth(uint idx) + { + IntPtr ele = eina_inarray_nth(Handle, idx); + return NativeToManagedInplace(ele); + } + + public T At(int idx) + { + return Nth((uint)idx); + } + + public bool InsertAt(uint idx, T val) + { + IntPtr ele = ManagedToNativeAllocInplace(val); + var r = eina_inarray_insert_at(Handle, idx, ele); + if (!r) + NativeFreeInplace(ele); + ResidueFreeInplace(ele); + return r; + } + + public bool ReplaceAt(uint idx, T val) + { + var old = eina_inarray_nth(Handle, idx); + if (old == IntPtr.Zero) + return false; + if (OwnContent) + NativeFreeInplace(old); + var ele = ManagedToNativeAllocInplace(val); + var r = eina_inarray_replace_at(Handle, idx, ele); + ResidueFreeInplace(ele); + return r; + } + + public T this[int idx] + { + get + { + return At(idx); + } + set + { + ReplaceAt((uint)idx, value); + } + } + + public bool RemoveAt(uint idx) + { + IntPtr ele = eina_inarray_nth(Handle, idx); + if (ele == IntPtr.Zero) + return false; + if (OwnContent) + NativeFreeInplace(ele); + + return eina_inarray_remove_at(Handle, idx); + } + + public void Reverse() + { + eina_inarray_reverse(Handle); + } + + public T[] ToArray() + { + int len = Length; + var managed = new T[len]; + for(int i = 0; i < len; ++i) + { + managed[i] = At(i); + } + return managed; + } + + public bool Append(T[] values) + { + foreach(T v in values) + if (Push(v) == -1) + return false; + return true; + } + + public eina.Iterator GetIterator() + { + return new eina.Iterator(eina_inarray_iterator_new(Handle), true, false); + } + + public eina.Iterator GetReversedIterator() + { + return new eina.Iterator(eina_inarray_iterator_reversed_new(Handle), true, false); + } + + public IEnumerator GetEnumerator() + { + int len = Length; + for(int i = 0; i < len; ++i) + { + yield return At(i); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } +} + +} diff --git a/src/bindings/mono/eina_mono/eina_inlist.cs b/src/bindings/mono/eina_mono/eina_inlist.cs new file mode 100644 index 0000000000..8257c20593 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_inlist.cs @@ -0,0 +1,316 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using static eina.TraitFunctions; +using static eina.InlistNativeFunctions; +using eina.Callbacks; + +namespace eina { + +public static class InlistNativeFunctions +{ + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_append(IntPtr in_list, IntPtr in_item); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_prepend(IntPtr in_list, IntPtr in_item); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_append_relative(IntPtr in_list, IntPtr in_item, IntPtr in_relative); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_prepend_relative(IntPtr in_list, IntPtr in_item, IntPtr in_relative); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_remove(IntPtr in_list, IntPtr in_item); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_find(IntPtr in_list, IntPtr in_item); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_promote(IntPtr list, IntPtr item); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_demote(IntPtr list, IntPtr item); + + [DllImport(efl.Libs.Eina)] public static extern uint + eina_inlist_count(IntPtr list); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_iterator_new(IntPtr in_list); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_accessor_new(IntPtr in_list); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_sorted_insert(IntPtr list, IntPtr item, IntPtr func); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_sorted_state_new(); + + [DllImport(efl.Libs.Eina)] public static extern int + eina_inlist_sorted_state_init(IntPtr state, IntPtr list); + + [DllImport(efl.Libs.Eina)] public static extern void + eina_inlist_sorted_state_free(IntPtr state); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_sorted_state_insert(IntPtr list, IntPtr item, IntPtr func, IntPtr state); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_inlist_sort(IntPtr head, IntPtr func); + + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_inlist_first_custom_export_mono(IntPtr list); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_inlist_last_custom_export_mono(IntPtr list); + + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_inlist_next_custom_export_mono(IntPtr list); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_inlist_prev_custom_export_mono(IntPtr list); + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_inlist_iterator_wrapper_new_custom_export_mono(IntPtr in_list); +} + +public class Inlist : IEnumerable, IDisposable +{ + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} + public bool OwnContent {get;set;} + + public int Length + { + get { return Count(); } + } + + + private void InitNew() + { + Handle = IntPtr.Zero; + Own = true; + OwnContent = true; + } + + private IntPtr InternalFirst() + { + return eina_inlist_first_custom_export_mono(Handle); + } + + private IntPtr InternalLast() + { + return eina_inlist_last_custom_export_mono(Handle); + } + + private IntPtr InternalAt(int idx) + { + if (idx < 0) + return IntPtr.Zero; + + IntPtr curr = Handle; + for (int n = 0; n != idx && curr != IntPtr.Zero; ++n) + curr = InternalNext(curr); + return curr; + } + + private static IntPtr InternalNext(IntPtr inlist) + { + return eina_inlist_next_custom_export_mono(inlist); + } + + private static IntPtr InternalPrev(IntPtr inlist) + { + return eina_inlist_prev_custom_export_mono(inlist); + } + + + public Inlist() + { + InitNew(); + } + + public Inlist(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + OwnContent = own; + } + + public Inlist(IntPtr handle, bool own, bool ownContent) + { + Handle = handle; + Own = own; + OwnContent = ownContent; + } + + ~Inlist() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (OwnContent) + { + for(IntPtr curr = h; curr != IntPtr.Zero; curr = InternalNext(curr)) + { + NativeFreeInlistNodeElement(curr); + } + } + + if (Own) + { + while (h != IntPtr.Zero) + { + var aux = h; + h = eina_inlist_remove(h, h); + NativeFreeInlistNode(aux, false); + } + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public void SetOwnership(bool ownAll) + { + Own = ownAll; + OwnContent = ownAll; + } + + public void SetOwnership(bool own, bool ownContent) + { + Own = own; + OwnContent = ownContent; + } + + public int Count() + { + return (int) eina_inlist_count(Handle); + } + + public void Clean() + { + while (Handle != IntPtr.Zero) + { + var aux = Handle; + Handle = eina_inlist_remove(Handle, Handle); + NativeFreeInlistNode(aux, OwnContent); + } + } + + public void Append(T val) + { + IntPtr node = ManagedToNativeAllocInlistNode(val); + Handle = eina_inlist_append(Handle, node); + } + + public void Prepend(T val) + { + IntPtr node = ManagedToNativeAllocInlistNode(val); + Handle = eina_inlist_prepend(Handle, node); + } + + public void Remove(int idx) + { + IntPtr node = InternalAt(idx); + Handle = eina_inlist_remove(Handle, node); + NativeFreeInlistNode(node, OwnContent); + } + + public T At(int idx) + { + IntPtr node = InternalAt(idx); + if (node == IntPtr.Zero) + throw new IndexOutOfRangeException(); + return NativeToManagedInlistNode(node); + } + + public void DataSet(int idx, T val) + { + IntPtr old = InternalAt(idx); + if (old == IntPtr.Zero) + throw new IndexOutOfRangeException(); + + IntPtr new_node = ManagedToNativeAllocInlistNode(val); + + Handle = eina_inlist_append_relative(Handle, new_node, old); + Handle = eina_inlist_remove(Handle, old); + + NativeFreeInlistNode(old, OwnContent); + } + + public T this[int idx] + { + get + { + return At(idx); + } + set + { + DataSet(idx, value); + } + } + + public T[] ToArray() + { + var managed = new T[Count()]; + int i = 0; + for(IntPtr curr = Handle; curr != IntPtr.Zero; ++i, curr = InternalNext(curr)) + { + managed[i] = NativeToManagedInlistNode(curr); + } + return managed; + } + + public void AppendArray(T[] values) + { + foreach (T v in values) + Append(v); + } + + + public eina.Iterator GetIterator() + { + return new eina.Iterator(eina_inlist_iterator_wrapper_new_custom_export_mono(Handle), true, false); + } + + public IEnumerator GetEnumerator() + { + for(IntPtr curr = Handle; curr != IntPtr.Zero; curr = InternalNext(curr)) + { + yield return NativeToManagedInlistNode(curr); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } +} + +} diff --git a/src/bindings/mono/eina_mono/eina_iterator.cs b/src/bindings/mono/eina_mono/eina_iterator.cs new file mode 100644 index 0000000000..854a68c084 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_iterator.cs @@ -0,0 +1,144 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using static eina.TraitFunctions; +using static eina.IteratorNativeFunctions; + +namespace eina { + +public static class IteratorNativeFunctions +{ + [DllImport(efl.Libs.Eina)] public static extern void + eina_iterator_free(IntPtr iterator); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_iterator_container_get(IntPtr iterator); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_iterator_next(IntPtr iterator, out IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern void + eina_iterator_foreach(IntPtr iterator, IntPtr callback, IntPtr fdata); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_iterator_lock(IntPtr iterator); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_iterator_unlock(IntPtr iterator); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_carray_iterator_new(IntPtr array); +} + +public class Iterator : IEnumerable, IDisposable +{ + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} = true; + public bool OwnContent {get;set;} = false; + + public Iterator(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + OwnContent = own; + } + + public Iterator(IntPtr handle, bool own, bool ownContent) + { + Handle = handle; + Own = own; + OwnContent = ownContent; + } + + ~Iterator() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + var h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (OwnContent) + { + for(IntPtr data; eina_iterator_next(h, out data);) + { + NativeFree(data); + } + } + + if (Own) + eina_iterator_free(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public void SetOwnership(bool ownAll) + { + Own = ownAll; + OwnContent = ownAll; + } + + public void SetOwnership(bool own, bool ownContent) + { + Own = own; + OwnContent = ownContent; + } + + public bool Next(out T res) + { + IntPtr data; + if (!eina_iterator_next(Handle, out data)) + { + res = default(T); + return false; + } + + res = NativeToManaged(data); + + if (OwnContent) + NativeFree(data); + + return true; + } + + public bool Lock() + { + return eina_iterator_lock(Handle); + } + + public bool Unlock() + { + return eina_iterator_unlock(Handle); + } + + public IEnumerator GetEnumerator() + { + for(T curr; Next(out curr);) + { + yield return curr; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } +} + +} diff --git a/src/bindings/mono/eina_mono/eina_list.cs b/src/bindings/mono/eina_mono/eina_list.cs new file mode 100644 index 0000000000..c972c82ed5 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_list.cs @@ -0,0 +1,352 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using static eina.TraitFunctions; +using static eina.ListNativeFunctions; +using eina.Callbacks; + +namespace eina { + +public static class ListNativeFunctions +{ + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_append(IntPtr list, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_prepend(IntPtr list, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_append_relative(IntPtr list, IntPtr data, IntPtr relative); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_append_relative_list(IntPtr list, IntPtr data, IntPtr relative); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_prepend_relative(IntPtr list, IntPtr data, IntPtr relative); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_prepend_relative_list(IntPtr list, IntPtr data, IntPtr relative); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_sorted_insert(IntPtr list, IntPtr func, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_remove(IntPtr list, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_remove_list(IntPtr list, IntPtr remove_list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_promote_list(IntPtr list, IntPtr move_list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_demote_list(IntPtr list, IntPtr move_list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_data_find(IntPtr list, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_data_find_list(IntPtr list, IntPtr data); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_list_move(ref IntPtr to, ref IntPtr from, IntPtr data); + [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eina_list_move_list(ref IntPtr to, ref IntPtr from, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_free(IntPtr list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_nth(IntPtr list, uint n); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_nth_list(IntPtr list, uint n); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_reverse(IntPtr list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_reverse_clone(IntPtr list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_clone(IntPtr list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_sort(IntPtr list, uint limit, IntPtr func); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_shuffle(IntPtr list, IntPtr func); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_merge(IntPtr left, IntPtr right); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_sorted_merge(IntPtr left, IntPtr right, IntPtr func); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_split_list(IntPtr list, IntPtr relative, ref IntPtr right); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_search_sorted_near_list(IntPtr list, IntPtr func, IntPtr data, IntPtr result_cmp); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_search_sorted_list(IntPtr list, IntPtr func, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_search_sorted(IntPtr list, IntPtr func, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_search_unsorted_list(IntPtr list, IntPtr func, IntPtr data); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_search_unsorted(IntPtr list, IntPtr func, IntPtr data); + + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_iterator_new(IntPtr list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_iterator_reversed_new(IntPtr list); + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_list_accessor_new(IntPtr list); + [DllImport(efl.Libs.Eina)] public static extern int + eina_list_data_idx(IntPtr list, IntPtr data); + + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_list_last_custom_export_mono(IntPtr list); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_list_next_custom_export_mono(IntPtr list); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_list_prev_custom_export_mono(IntPtr list); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_list_data_get_custom_export_mono(IntPtr list); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_list_data_set_custom_export_mono(IntPtr list, IntPtr data); + [DllImport(efl.Libs.CustomExports)] public static extern uint + eina_list_count_custom_export_mono(IntPtr list); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + eina_list_last_data_get_custom_export_mono(IntPtr list); +} + +public class List : IEnumerable, IDisposable +{ + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} + public bool OwnContent {get;set;} + + public int Length + { + get { return Count(); } + } + + + private void InitNew() + { + Handle = IntPtr.Zero; + Own = true; + OwnContent = true; + } + + private IntPtr InternalLast() + { + return eina_list_last_custom_export_mono(Handle); + } + + private static IntPtr InternalNext(IntPtr list) + { + return eina_list_next_custom_export_mono(list); + } + + private static IntPtr InternalPrev(IntPtr list) + { + return eina_list_prev_custom_export_mono(list); + } + + private static IntPtr InternalDataGet(IntPtr list) + { + return eina_list_data_get_custom_export_mono(list); + } + + private static IntPtr InternalDataSet(IntPtr list, IntPtr data) + { + return eina_list_data_set_custom_export_mono(list, data); + } + + + public List() + { + InitNew(); + } + + public List(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + OwnContent = own; + } + + public List(IntPtr handle, bool own, bool ownContent) + { + Handle = handle; + Own = own; + OwnContent = ownContent; + } + + ~List() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (OwnContent) + { + for(IntPtr curr = h; curr != IntPtr.Zero; curr = InternalNext(curr)) + { + NativeFree(InternalDataGet(curr)); + } + } + + if (Own) + eina_list_free(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public void SetOwnership(bool ownAll) + { + Own = ownAll; + OwnContent = ownAll; + } + + public void SetOwnership(bool own, bool ownContent) + { + Own = own; + OwnContent = ownContent; + } + + public int Count() + { + return (int) eina_list_count_custom_export_mono(Handle); + } + + public void Append(T val) + { + IntPtr ele = ManagedToNativeAlloc(val); + Handle = eina_list_append(Handle, ele); + } + + public void Prepend(T val) + { + IntPtr ele = ManagedToNativeAlloc(val); + Handle = eina_list_prepend(Handle, ele); + } + + public void SortedInsert(T val) + { + IntPtr ele = ManagedToNativeAlloc(val); + Handle = eina_list_sorted_insert(Handle, EinaCompareCb(), ele); + } + + public void SortedInsert(Eina_Compare_Cb compareCb, T val) + { + IntPtr ele = ManagedToNativeAlloc(val); + Handle = eina_list_sorted_insert(Handle, Marshal.GetFunctionPointerForDelegate(compareCb), ele); + } + + public void Sort(int limit = 0) + { + Handle = eina_list_sort(Handle, (uint)limit, EinaCompareCb()); + } + + public void Sort(Eina_Compare_Cb compareCb) + { + Handle = eina_list_sort(Handle, 0, Marshal.GetFunctionPointerForDelegate(compareCb)); + } + + public void Sort(int limit, Eina_Compare_Cb compareCb) + { + Handle = eina_list_sort(Handle, (uint)limit, Marshal.GetFunctionPointerForDelegate(compareCb)); + } + + public T Nth(int n) + { + // TODO: check bounds ??? + IntPtr ele = eina_list_nth(Handle, (uint)n); + return NativeToManaged(ele); + } + + public void DataSet(int idx, T val) + { + IntPtr pos = eina_list_nth_list(Handle, (uint)idx); + if (pos == IntPtr.Zero) + throw new IndexOutOfRangeException(); + if (OwnContent) + NativeFree(InternalDataGet(pos)); + IntPtr ele = ManagedToNativeAlloc(val); + InternalDataSet(pos, ele); + } + + public T this[int idx] + { + get + { + return Nth(idx); + } + set + { + DataSet(idx, value); + } + } + + public T LastDataGet() + { + IntPtr ele = eina_list_last_data_get_custom_export_mono(Handle); + return NativeToManaged(ele); + } + + public void Reverse() + { + Handle = eina_list_reverse(Handle); + } + + public void Shuffle() + { + Handle = eina_list_shuffle(Handle, IntPtr.Zero); + } + + public T[] ToArray() + { + var managed = new T[Count()]; + int i = 0; + for(IntPtr curr = Handle; curr != IntPtr.Zero; curr = InternalNext(curr), ++i) + { + managed[i] = NativeToManaged(InternalDataGet(curr)); + } + return managed; + } + + public void AppendArray(T[] values) + { + foreach (T v in values) + Append(v); + } + + + public eina.Iterator GetIterator() + { + return new eina.Iterator(eina_list_iterator_new(Handle), true, false); + } + + public eina.Iterator GetReversedIterator() + { + return new eina.Iterator(eina_list_iterator_reversed_new(Handle), true, false); + } + + public IEnumerator GetEnumerator() + { + for(IntPtr curr = Handle; curr != IntPtr.Zero; curr = InternalNext(curr)) + { + yield return NativeToManaged(InternalDataGet(curr)); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } +} + +} diff --git a/src/bindings/mono/eina_mono/eina_log.cs b/src/bindings/mono/eina_mono/eina_log.cs new file mode 100644 index 0000000000..a2a1e45927 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_log.cs @@ -0,0 +1,121 @@ +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Diagnostics.Contracts; + +namespace eina { // Manual wrappers around eina functions + +public class Log +{ + [DllImport(efl.Libs.Eina)] private static extern int eina_init(); + + [DllImport(efl.Libs.Eina)] private static extern void eina_log_print( + int domain, + Level level, + [MarshalAs(UnmanagedType.LPStr)] String file, + [MarshalAs(UnmanagedType.LPStr)] String function, + int line, + [MarshalAs(UnmanagedType.LPStr)] String message); + + [DllImport(efl.Libs.Eina)] private static extern int eina_log_domain_register( + [MarshalAs(UnmanagedType.LPStr)] String name, + [MarshalAs(UnmanagedType.LPStr)] String color); + + [DllImport(efl.Libs.Eina)] private static extern void eina_log_level_set(Level level); + + [DllImport(efl.Libs.Eina)] private static extern Level eina_log_level_get(); + + public enum Level + { + Critical, + Error, + Warning, + Info, + Debug, + Unkown = (-2147483647 - 1) + } + + public class Color + { + public static string LIGHTRED = "\033[31;1m"; + public static string RED = "\033[31m"; + public static string LIGHTBLUE = "\033[34;1m"; + public static string BLUE = "\033[34m"; + public static string GREEN = "\033[32;1m"; + public static string YELLOW = "\033[33;1m"; + public static string ORANGE = "\033[0;33m"; + public static string WHITE = "\033[37;1m"; + public static string LIGHTCYAN = "\033[36;1m"; + public static string CYAN = "\033[36m"; + public static string RESET = "\033[0m"; + public static string HIGH = "\033[1m"; + } + + private static int domain = -1; + + public static void Init(String name="mono", String color="\033[32;1m") + { + if (domain == -1) + { + // Maybe move this check outside when other eina stuff get support? + if (eina_init() == 0) + { + Console.WriteLine("Error: Can't initialize Eina for logging."); + return; + } + domain = eina_log_domain_register(name, color); + if (domain < 0) + Console.WriteLine("Error: Couldn't register Eina log domain for name {0}.", name); + else + Info($"Registered mono domain with number {domain}"); + } + else + { + Warning("Trying to initialize the log system again."); + // TODO Export the domain registration to the binding user to allow custom domains. + } + } + + private static void EnsureDomainRegistered() + { + if (domain < 0) + throw new InvalidOperationException("Log domain is not registered."); + } + + public static void Critical(String message, [CallerLineNumber] int line=0, [CallerFilePath] string file=null, [CallerMemberName] string member = null) + { + EnsureDomainRegistered(); + eina_log_print(domain, Level.Critical, file, member, line, message); + } + public static void Error(String message, [CallerLineNumber] int line=0, [CallerFilePath] string file=null, [CallerMemberName] string member = null) + { + EnsureDomainRegistered(); + eina_log_print(domain, Level.Error, file, member, line, message); + } + public static void Warning(String message, [CallerLineNumber] int line=0, [CallerFilePath] string file=null, [CallerMemberName] string member = null) + { + EnsureDomainRegistered(); + eina_log_print(domain, Level.Warning, file, member, line, message); + } + public static void Info(String message, [CallerLineNumber] int line=0, [CallerFilePath] string file=null, [CallerMemberName] string member = null) + { + EnsureDomainRegistered(); + eina_log_print(domain, Level.Info, file, member, line, message); + } + public static void Debug(String message, [CallerLineNumber] int line=0, [CallerFilePath] string file=null, [CallerMemberName] string member = null) + { + EnsureDomainRegistered(); + eina_log_print(domain, Level.Debug, file, member, line, message); + } + + public static void GlobalLevelSet(Level level) + { + eina_log_level_set(level); + } + + public static Level GlobalLevelGet() + { + return eina_log_level_get(); + } +} +} diff --git a/src/bindings/mono/eina_mono/eina_slice.cs b/src/bindings/mono/eina_mono/eina_slice.cs new file mode 100644 index 0000000000..189e9a57c7 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_slice.cs @@ -0,0 +1,85 @@ +using System; +using System.Runtime.InteropServices; + +namespace eina { + +public interface ISliceBase +{ + UIntPtr Len {get;set;} + IntPtr Mem {get;set;} + + int Length {get;set;} +}; + +[StructLayout(LayoutKind.Sequential)] +public struct Slice : ISliceBase +{ + public UIntPtr Len {get;set;} + public IntPtr Mem {get;set;} + + public int Length + { + get { return (int) Len; } + set { Len = (UIntPtr) value; } + } + + public Slice(IntPtr mem, UIntPtr len) + { + Mem = mem; + Len = len; + } + + public Slice PinnedDataSet(IntPtr mem, UIntPtr len) + { + Mem = mem; + Len = len; + return this; + } +} + +[StructLayout(LayoutKind.Sequential)] +public struct Rw_Slice : ISliceBase +{ + public UIntPtr Len {get;set;} + public IntPtr Mem {get;set;} + + public int Length + { + get { return (int) Len; } + set { Len = (UIntPtr) value; } + } + + public Rw_Slice(IntPtr mem, UIntPtr len) + { + Mem = mem; + Len = len; + } + + public Rw_Slice PinnedDataSet(IntPtr mem, UIntPtr len) + { + Mem = mem; + Len = len; + return this; + } + + Slice ToSlice() + { + var r = new Slice(); + r.Mem = Mem; + r.Len = Len; + return r; + } +} + +} + +public static class Eina_SliceUtils +{ + public static byte[] GetBytes(this eina.ISliceBase slc) + { + var size = (int)(slc.Len); + byte[] mArray = new byte[size]; + Marshal.Copy(slc.Mem, mArray, 0, size); + return mArray; + } +} diff --git a/src/bindings/mono/eina_mono/eina_stringshare.cs b/src/bindings/mono/eina_mono/eina_stringshare.cs new file mode 100644 index 0000000000..825103d864 --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_stringshare.cs @@ -0,0 +1,18 @@ + +using System; +using System.Runtime.InteropServices; + + +namespace eina { + +public class Stringshare { + [DllImport(efl.Libs.Eina)] public static extern System.IntPtr + eina_stringshare_add_length(string str, System.UInt32 slen); + [DllImport(efl.Libs.Eina)] public static extern System.IntPtr + eina_stringshare_add(string str); + [DllImport(efl.Libs.Eina)] public static extern void + eina_stringshare_del(System.IntPtr str); +} + +} + diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs new file mode 100644 index 0000000000..4ded15b10e --- /dev/null +++ b/src/bindings/mono/eina_mono/eina_value.cs @@ -0,0 +1,1590 @@ +#define CODE_ANALYSIS + +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using System.Security.Permissions; +using System.Security; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.Serialization; + +using static eina.EinaNative.UnsafeNativeMethods; +using static eina.TraitFunctions; + + +namespace eina { + +namespace EinaNative { + +// Structs to be passed from/to C when dealing with containers and +// optional values. +[StructLayout(LayoutKind.Sequential)] +struct Value_Array +{ + public IntPtr subtype; + public uint step; + public IntPtr subarray; +} + +[StructLayout(LayoutKind.Sequential)] +struct Value_List +{ + public IntPtr subtype; + public IntPtr sublist; +} + +[SuppressUnmanagedCodeSecurityAttribute] +static internal class UnsafeNativeMethods { + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_convert(IntPtr handle, IntPtr convert); + + // Wrapped and helper methods + [DllImport(efl.Libs.CustomExports)] + internal static extern int eina_value_sizeof(); + + [DllImport(efl.Libs.CustomExports, CharSet=CharSet.Ansi)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, string value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, byte value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, sbyte value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, short value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, ushort value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, int value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, uint value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, long value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, ulong value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, float value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, double value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_set_wrapper(IntPtr handle, IntPtr value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_setup_wrapper(IntPtr handle, IntPtr type); + + [DllImport(efl.Libs.CustomExports)] + internal static extern void eina_value_flush_wrapper(IntPtr handle); + + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr eina_value_type_get_wrapper(IntPtr handle); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out IntPtr output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out Value_List output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out Value_Array output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out byte output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out sbyte output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out short output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out ushort output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out int output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out uint output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out long output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out ulong output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out float output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_get_wrapper(IntPtr handle, out double output); + + [DllImport(efl.Libs.CustomExports)] + internal static extern int eina_value_compare_wrapper(IntPtr handle, IntPtr other); + + [DllImport(efl.Libs.Eina, CharSet=CharSet.Ansi)] + internal static extern IntPtr eina_value_to_string(IntPtr handle); // We take ownership of the returned string. + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_array_setup_wrapper(IntPtr handle, IntPtr subtype, uint step); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_list_setup_wrapper(IntPtr handle, IntPtr subtype); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_array_append_wrapper(IntPtr handle, IntPtr data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_list_append_wrapper(IntPtr handle, IntPtr data); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_array_get_wrapper(IntPtr handle, int index, out IntPtr output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_list_get_wrapper(IntPtr handle, int index, out IntPtr output); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_array_set_wrapper(IntPtr handle, int index, IntPtr value); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_list_set_wrapper(IntPtr handle, int index, IntPtr value); + + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr eina_value_array_subtype_get_wrapper(IntPtr handle); + + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr eina_value_list_subtype_get_wrapper(IntPtr handle); + + [DllImport(efl.Libs.CustomExports)] + internal static extern uint eina_value_array_count_wrapper(IntPtr handle); + + [DllImport(efl.Libs.CustomExports)] + internal static extern uint eina_value_list_count_wrapper(IntPtr handle); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_empty_is_wrapper(IntPtr handle, [MarshalAsAttribute(UnmanagedType.U1)] out bool empty); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref byte value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref sbyte value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref short value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref ushort value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref int value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref uint value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref long value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref ulong value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref float value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref double value); + + [DllImport(efl.Libs.Eina, CharSet=CharSet.Ansi)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref string value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, IntPtr value); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_reset(IntPtr handle); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out eina.EinaNative.Value_Array output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out eina.EinaNative.Value_List output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out IntPtr output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out byte output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out sbyte output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out short output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out ushort output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out int output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out uint output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out long output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out ulong output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out float output); + + [DllImport(efl.Libs.Eina)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_optional_pget(IntPtr handle, out double output); + + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr eina_value_optional_type_get_wrapper(IntPtr handle); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_pset_wrapper(IntPtr handle, ref eina.EinaNative.Value_Array ptr); + + [DllImport(efl.Libs.CustomExports)] + [return: MarshalAsAttribute(UnmanagedType.U1)] + internal static extern bool eina_value_pset_wrapper(IntPtr handle, ref eina.EinaNative.Value_List ptr); + + // Supported types + + // 8 bits byte + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_byte(); + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_sbyte(); + + // 16 bits short + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_short(); + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_ushort(); + + // 32 bits ints + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_int32(); + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_uint32(); + + // 64 bit longs + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_long(); + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_ulong(); + + // In C# long and int 64 are synonyms, but in Eina Value they are separate types. + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_int64(); + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_uint64(); + + // Floating point + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_float(); + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_double(); + + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_string(); + + // Collections + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_array(); + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_list(); + + // Optional + [DllImport(efl.Libs.CustomExports)] + internal static extern IntPtr type_optional(); +} +} + +/// Struct for passing Values by value to Unmanaged functions. +[StructLayout(LayoutKind.Sequential)] +public struct Value_Native +{ + IntPtr type; + IntPtr value; // Atually an Eina_Value_Union, but it is padded to 8 bytes. +} + + +/// Exception for trying to access flushed values. +[Serializable] +public class ValueFlushedException : Exception +{ + /// Default constructor. + public ValueFlushedException() : base () { } + /// Most commonly used contructor. + public ValueFlushedException(string msg) : base(msg) { } + /// Wraps an inner exception. + public ValueFlushedException(string msg, Exception inner) : base(msg, inner) { } + /// Serializable constructor. + protected ValueFlushedException(SerializationInfo info, StreamingContext context) : base(info, context) { } +} + +/// Exception for failures when setting an container item. +[Serializable] +public class SetItemFailedException : Exception +{ + /// Default constructor. + public SetItemFailedException() : base () { } + /// Most commonly used contructor. + public SetItemFailedException(string msg) : base(msg) { } + /// Wraps an inner exception. + public SetItemFailedException(string msg, Exception inner) : base(msg, inner) { } + /// Serializable constructor. + protected SetItemFailedException(SerializationInfo info, StreamingContext context) : base(info, context) { } +} + +/// Exception for methods that must have been called on a container. +[Serializable] +public class InvalidValueTypeException: Exception +{ + /// Default constructor. + public InvalidValueTypeException() : base () { } + /// Most commonly used contructor. + public InvalidValueTypeException(string msg) : base(msg) { } + /// Wraps an inner exception. + public InvalidValueTypeException(string msg, Exception inner) : base(msg, inner) { } + /// Serializable constructor. + protected InvalidValueTypeException(SerializationInfo info, StreamingContext context) : base(info, context) { } +} + +/// Internal enum to handle value ownership between managed and unmanaged code. +public enum ValueOwnership { + /// The value is owned by the managed code. It'll free the handle on disposal. + Managed, + /// The value is owned by the unmanaged code. It won't be freed on disposal. + Unmanaged +} + +/// Managed-side Enum to represent Eina_Value_Type constants +public enum ValueType { + /// Signed 8 bit integer. Same as 'sbyte' + SByte, + /// Unsigned 8 bit integer. Same as 'byte' + Byte, + /// Signed 16 bit integer. Same as 'short' + Short, + /// Unsigned 16 bit integer. Same as 'ushort' + UShort, + /// Signed 32 bit integer. Same as 'int' + Int32, + /// Unsigned 32 bit integer. Same as 'uint' + UInt32, + /// Signed long integer. Same as 'long' + Long, + /// Unsigned long integer. Same as 'ulong' + ULong, + /// Signed 64 bit integer. Same as 'long' + Int64, + /// Unsigned 64 bit integer. Same as 'ulong' + UInt64, + /// 4-byte float. Same as 'float' + Float, + /// 8-byte double. Same as 'double' + Double, + /// Strings + String, + /// Array of Value items. + Array, + /// Linked list of Value items. + List, + /// Map of string keys to Value items. + Hash, + /// Optional (aka empty) values. + Optional, +} + +static class ValueTypeMethods { + public static bool IsNumeric(this ValueType val) + { + switch (val) { + case ValueType.SByte: + case ValueType.Byte: + case ValueType.Short: + case ValueType.UShort: + case ValueType.Int32: + case ValueType.UInt32: + case ValueType.Long: + case ValueType.ULong: + case ValueType.Int64: + case ValueType.UInt64: + case ValueType.Float: + case ValueType.Double: + return true; + default: + return false; + } + } + + public static bool IsString(this ValueType val) + { + switch(val) { + case ValueType.String: + return true; + default: + return false; + } + } + + public static bool IsContainer(this ValueType val) + { + switch(val) { + case ValueType.Array: + case ValueType.List: + case ValueType.Hash: + return true; + default: + return false; + } + } + + public static bool IsOptional(this ValueType val) + { + return val == ValueType.Optional; + } + + /// Returns the Marshal.SizeOf for the given ValueType native structure. + public static int MarshalSizeOf(this ValueType val) + { + switch (val) { + case ValueType.Array: + return Marshal.SizeOf(typeof(EinaNative.Value_Array)); + case ValueType.List: + return Marshal.SizeOf(typeof(EinaNative.Value_List)); + default: + return 0; + } + } +} +static class ValueTypeBridge +{ + private static Dictionary ManagedToNative = new Dictionary(); + private static Dictionary NativeToManaged = new Dictionary(); + private static bool TypesLoaded; // CLR defaults to false; + + public static ValueType GetManaged(IntPtr native) + { + if (!TypesLoaded) + LoadTypes(); + + return NativeToManaged[native]; + } + + public static IntPtr GetNative(ValueType valueType) + { + if (!TypesLoaded) + LoadTypes(); + + return ManagedToNative[valueType]; + } + + private static void LoadTypes() + { + eina.Config.Init(); // Make sure eina is initialized. + + ManagedToNative.Add(ValueType.SByte, type_sbyte()); + NativeToManaged.Add(type_sbyte(), ValueType.SByte); + + ManagedToNative.Add(ValueType.Byte, type_byte()); + NativeToManaged.Add(type_byte(), ValueType.Byte); + + ManagedToNative.Add(ValueType.Short, type_short()); + NativeToManaged.Add(type_short(), ValueType.Short); + + ManagedToNative.Add(ValueType.UShort, type_ushort()); + NativeToManaged.Add(type_ushort(), ValueType.UShort); + + ManagedToNative.Add(ValueType.Int32, type_int32()); + NativeToManaged.Add(type_int32(), ValueType.Int32); + + ManagedToNative.Add(ValueType.UInt32, type_uint32()); + NativeToManaged.Add(type_uint32(), ValueType.UInt32); + + ManagedToNative.Add(ValueType.Long, type_long()); + NativeToManaged.Add(type_long(), ValueType.Long); + + ManagedToNative.Add(ValueType.ULong, type_ulong()); + NativeToManaged.Add(type_ulong(), ValueType.ULong); + + ManagedToNative.Add(ValueType.Int64, type_int64()); + NativeToManaged.Add(type_int64(), ValueType.Int64); + + ManagedToNative.Add(ValueType.UInt64, type_uint64()); + NativeToManaged.Add(type_uint64(), ValueType.UInt64); + + ManagedToNative.Add(ValueType.Float, type_float()); + NativeToManaged.Add(type_float(), ValueType.Float); + + ManagedToNative.Add(ValueType.Double, type_double()); + NativeToManaged.Add(type_double(), ValueType.Double); + + ManagedToNative.Add(ValueType.String, type_string()); + NativeToManaged.Add(type_string(), ValueType.String); + + ManagedToNative.Add(ValueType.Array, type_array()); + NativeToManaged.Add(type_array(), ValueType.Array); + + ManagedToNative.Add(ValueType.List, type_list()); + NativeToManaged.Add(type_list(), ValueType.List); + + ManagedToNative.Add(ValueType.Optional, type_optional()); + NativeToManaged.Add(type_optional(), ValueType.Optional); + + TypesLoaded = true; + } +} + +/// Wrapper around Eina_Value generic storage. +/// +/// Eina_Value is EFL's main workhorse to deal with storing generic data in +/// an uniform way. +/// +/// It comes with predefined types for numbers, strings, array, list, hash, +/// blob and structs. It is able to convert between data types, including +/// to string. +/// +public class Value : IDisposable, IComparable, IEquatable +{ + + // Unmanaged type - Managed type mapping + // Ok EINA_VALUE_TYPE_UCHAR: unsigned char -- byte + // Ok EINA_VALUE_TYPE_USHORT: unsigned short -- ushort + // Ok EINA_VALUE_TYPE_UINT: unsigned int -- uint + // Ok EINA_VALUE_TYPE_ULONG: unsigned long -- ulong + // Ok EINA_VALUE_TYPE_UINT64: uint64_t -- ulong + // Ok EINA_VALUE_TYPE_CHAR: char -- sbyte + // Ok EINA_VALUE_TYPE_SHORT: short -- short + // Ok EINA_VALUE_TYPE_INT: int -- int + // Ok EINA_VALUE_TYPE_LONG: long -- long + // OK EINA_VALUE_TYPE_INT64: int64_t -- long + // Ok EINA_VALUE_TYPE_FLOAT: float -- float + // Ok EINA_VALUE_TYPE_DOUBLE: double -- double + // EINA_VALUE_TYPE_STRINGSHARE: const char * -- string + // Ok EINA_VALUE_TYPE_STRING: const char * -- string + // Ok EINA_VALUE_TYPE_ARRAY: Eina_Value_Array -- eina.Array? + // Ok EINA_VALUE_TYPE_LIST: Eina_Value_List -- eina.List? + // EINA_VALUE_TYPE_HASH: Eina_Value_Hash -- eina.Hash? + // EINA_VALUE_TYPE_TIMEVAL: struct timeval -- FIXME + // EINA_VALUE_TYPE_BLOB: Eina_Value_Blob -- FIXME + // EINA_VALUE_TYPE_STRUCT: Eina_Value_Struct -- FIXME + + + public IntPtr Handle { get; protected set;} + public ValueOwnership Ownership { get; protected set;} + private bool Disposed; + public bool Flushed { get; protected set;} + public bool Optional { + get { + return GetValueType() == eina.ValueType.Optional; + } + /* protected set { + // Should we expose this? + // Something like { + // flush(handle)/free(handle) + // handle = eina_value_optional_empty_new() + // } + } */ + } + public bool Empty { + get { + OptionalSanityChecks(); + bool empty; + if (!eina_value_optional_empty_is_wrapper(this.Handle, out empty)) + throw new System.InvalidOperationException("Couldn't get the empty information"); + else + return empty; + } + } + + // Constructor to be used by the "FromContainerDesc" methods. + private Value() { + this.Handle = MemoryNative.Alloc(eina_value_sizeof()); + this.Ownership = ValueOwnership.Managed; + } + + internal Value(IntPtr handle, ValueOwnership ownership=ValueOwnership.Managed) { + this.Handle = handle; + this.Ownership = ownership; + } + + /// Creates a new value storage for values of type 'type'. + public Value(ValueType type) + { + if (type.IsContainer()) + throw new ArgumentException("To use container types you must provide a subtype"); + this.Handle = MemoryNative.Alloc(eina_value_sizeof()); + this.Ownership = ValueOwnership.Managed; + Setup(type); + } + + /// Constructor for container values, like Array, Hash. + public Value(ValueType containerType, ValueType subtype, uint step=0) + { + if (!containerType.IsContainer()) + throw new ArgumentException("First type must be a container type."); + + this.Handle = MemoryNative.Alloc(eina_value_sizeof()); + this.Ownership = ValueOwnership.Managed; + + Setup(containerType, subtype, step); + } + + /// Constructor to build value from Values_Natives passed by value from C + public Value(Value_Native value) + { + this.Handle = MemoryNative.Alloc(Marshal.SizeOf(typeof(Value_Native))); + try { + Marshal.StructureToPtr(value, this.Handle, false); + } catch { + MemoryNative.Free(this.Handle); + throw; + } + this.Ownership = ValueOwnership.Managed; + } + + /// Implicit conversion from managed value to native struct representation + public static implicit operator Value_Native(Value v) + { + return v.GetNative(); + } + + /// + public static implicit operator Value(Value_Native v) + { + return new Value(v); + } + + /// Creates an Value instance from a given array description. + private static Value FromArrayDesc(eina.EinaNative.Value_Array arrayDesc) + { + Value value = new Value(); + value.Setup(ValueType.Array, ValueType.String); // Placeholder values to be overwritten by the following pset call. + + eina_value_pset_wrapper(value.Handle, ref arrayDesc); + return value; + } + + /// Creates an Value instance from a given array description. + private static Value FromListDesc(eina.EinaNative.Value_List listDesc) + { + Value value = new Value(); + value.Setup(ValueType.List, ValueType.String); // Placeholder values to be overwritten by the following pset call. + + eina_value_pset_wrapper(value.Handle, ref listDesc); + return value; + } + + /// Releases the ownership of the underlying value to C. + public void ReleaseOwnership() + { + this.Ownership = ValueOwnership.Unmanaged; + } + + /// Takes the ownership of the underlying value to the Managed runtime. + public void TakeOwnership() + { + this.Ownership = ValueOwnership.Managed; + } + + /// Public method to explicitly free the wrapped eina value. + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// Actually free the wrapped eina value. Can be called from Dispose() or through the GC. + protected virtual void Dispose(bool disposing) + { + if (this.Ownership == ValueOwnership.Unmanaged) { + Disposed = true; + return; + } + + if (!Disposed && (Handle != IntPtr.Zero)) { + if (!Flushed) + eina_value_flush_wrapper(this.Handle); + + MemoryNative.Free(this.Handle); + } + Disposed = true; + } + + /// Finalizer to be called from the Garbage Collector. + ~Value() + { + Dispose(false); + } + + /// Returns the native handle wrapped by this object. + public IntPtr NativeHandle() + { + if (Disposed) + throw new ObjectDisposedException(base.GetType().Name); + return this.Handle; + } + + /// Converts this storage to type 'type' + public bool Setup(ValueType type) + { + if (Disposed) + throw new ObjectDisposedException(base.GetType().Name); + + if (type.IsContainer()) + throw new ArgumentException("To setup a container you must provide a subtype."); + + bool ret = eina_value_setup_wrapper(this.Handle, ValueTypeBridge.GetNative(type)); + if (ret) + Flushed = false; + return ret; + } + + public bool Setup(ValueType containerType, ValueType subtype, uint step=0) { + IntPtr native_subtype = ValueTypeBridge.GetNative(subtype); + bool ret = false; + switch (containerType) { + case ValueType.Array: + ret = eina_value_array_setup_wrapper(this.Handle, native_subtype, step); + break; + case ValueType.List: + ret = eina_value_list_setup_wrapper(this.Handle, native_subtype); + break; + } + + if (ret) + Flushed = false; + + return ret; + } + + private void SanityChecks() + { + if (Disposed) + throw new ObjectDisposedException(GetType().Name); + if (Flushed) + throw new ValueFlushedException("Trying to use value that has been flushed. Setup it again."); + } + + private void ContainerSanityChecks(int targetIndex=-1) + { + SanityChecks(); + uint size = 0; + ValueType type = GetValueType(); + + if (!type.IsContainer()) + throw new InvalidValueTypeException("Value type must be a container"); + + if (targetIndex == -1) // Some methods (e.g. append) don't care about size + return; + + switch (type) { + case ValueType.Array: + size = eina_value_array_count_wrapper(this.Handle); + break; + case ValueType.List: + size = eina_value_list_count_wrapper(this.Handle); + break; + } + + if (targetIndex >= size) + throw new System.ArgumentOutOfRangeException( + $"Index {targetIndex} is larger than max array index {size-1}"); + } + + private void OptionalSanityChecks() + { + SanityChecks(); + ValueType type = GetValueType(); + + if (!type.IsOptional()) + throw new InvalidValueTypeException("Value is not an Optional one"); + } + + /// Releases the memory stored by this value. It can be reused by calling setup again. + /// + public void Flush() + { + if (Disposed) + throw new ObjectDisposedException(GetType().Name); + eina_value_flush_wrapper(this.Handle); + Flushed = true; + } + + /// Get a Value_Native struct with the *value* pointed by this eina.Value. + public Value_Native GetNative() + { + Value_Native value = (Value_Native)Marshal.PtrToStructure(this.Handle, typeof(Value_Native)); + return value; + } + + public bool Set(byte value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.Byte), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + public bool Set(sbyte value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.SByte), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + public bool Set(short value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.Short), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + public bool Set(ushort value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.UShort), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given uint value. + public bool Set(uint value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.UInt32), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given int value. + public bool Set(int value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.Int32), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given ulong value. + public bool Set(ulong value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.ULong), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given int value. + public bool Set(long value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.Long), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given int value. + public bool Set(float value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.Float), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + + Console.WriteLine("Wrapper Set({0})", value); + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given int value. + public bool Set(double value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.Double), + ref value); + + if (!GetValueType().IsNumeric()) + throw (new ArgumentException( + "Trying to set numeric value on a non-numeric eina.Value")); + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given string value. + public bool Set(string value) + { + SanityChecks(); + + if (this.Optional) + return eina_value_optional_pset(this.Handle, + ValueTypeBridge.GetNative(ValueType.String), + ref value); + + if (!GetValueType().IsString()) + throw (new ArgumentException( + "Trying to set non-string value on a string eina.Value")); + // No need to worry about ownership as eina_value_set will copy the passed string. + return eina_value_set_wrapper(this.Handle, value); + } + + /// Stores the given value into this value. The target value must be an optional. + public bool Set(Value value) + { + OptionalSanityChecks(); + ValueType subtype = value.GetValueType(); + + IntPtr ptr_val = MemoryNative.Alloc(subtype.MarshalSizeOf()); + IntPtr native_type = ValueTypeBridge.GetNative(subtype); + + try { + switch (subtype) { + // PSet on Container types require an Eina_Value_, which is the structure + // that contains subtype, etc. + case ValueType.Array: + EinaNative.Value_Array value_array; + if (!eina_value_get_wrapper(value.Handle, out value_array)) + return false; + Marshal.StructureToPtr(value_array, ptr_val, false); + break; + case ValueType.List: + EinaNative.Value_List value_list; + if (!eina_value_get_wrapper(value.Handle, out value_list)) + return false; + Marshal.StructureToPtr(value_list, ptr_val, false); + break; + default: + throw new InvalidValueTypeException("Only containers can be passed as raw eina.Values"); + } + + return eina_value_optional_pset(this.Handle, native_type, ptr_val); + } finally { + MemoryNative.Free(ptr_val); + } + } + + /// Gets the currently stored value as a byte. + public bool Get(out byte value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as a sbyte. + public bool Get(out sbyte value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as a short. + public bool Get(out short value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as an ushort. + public bool Get(out ushort value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as an int. + public bool Get(out int value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as an uint. + public bool Get(out uint value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as a long. + public bool Get(out long value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as an ulong. + public bool Get(out ulong value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as a float. + public bool Get(out float value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as a double. + public bool Get(out double value) + { + SanityChecks(); + if (this.Optional) + return eina_value_optional_pget(this.Handle, out value); + else + return eina_value_get_wrapper(this.Handle, out value); + } + + /// Gets the currently stored value as a string. + public bool Get(out string value) + { + SanityChecks(); + IntPtr output = IntPtr.Zero; + if (this.Optional) { + if (!eina_value_optional_pget(this.Handle, out output)) { + value = String.Empty; + return false; + } + } else if (!eina_value_get_wrapper(this.Handle, out output)) { + value = String.Empty; + return false; + } + value = StringConversion.NativeUtf8ToManagedString(output); + return true; + } + + /// Gets the currently stored value as an complex (e.g. container) eina.Value. + public bool Get(out Value value) + { + SanityChecks(); + value = null; + + if (!this.Optional) + throw new InvalidValueTypeException("Values can only be retreived"); + + IntPtr nativeType = eina_value_optional_type_get_wrapper(this.Handle); + ValueType managedType = ValueTypeBridge.GetManaged(nativeType); + + switch (managedType) { + case ValueType.Array: + eina.EinaNative.Value_Array array_desc; + + if (!eina_value_optional_pget(this.Handle, out array_desc)) + return false; + value = Value.FromArrayDesc(array_desc); + break; + case ValueType.List: + eina.EinaNative.Value_List list_desc; + + if (!eina_value_optional_pget(this.Handle, out list_desc)) + return false; + value = Value.FromListDesc(list_desc); + break; + } + + return true; + } + + /// Gets the 'Type' this value is currently configured to store. + public ValueType GetValueType() + { + if (Disposed) + throw new ObjectDisposedException(base.GetType().Name); + IntPtr native_type = eina_value_type_get_wrapper(this.Handle); + return ValueTypeBridge.GetManaged(native_type); + } + + /// Converts the value on this storage to the type of 'target' and stores + /// the result in 'target'. + public bool ConvertTo(Value target) + { + if (target == null) + return false; + + SanityChecks(); + + return eina_value_convert(this.Handle, target.Handle); + } + + /// Compare two eina values. + public int CompareTo(Value other) + { + if (other == null) + return 1; + SanityChecks(); + other.SanityChecks(); + return eina_value_compare_wrapper(this.Handle, other.Handle); + } + + public int Compare(Value other) + { + return this.CompareTo(other); + } + + public override bool Equals(object obj) + { + if (obj == null) + return false; + + Value v = obj as Value; + if (v == null) + return false; + + return this.Equals(v); + } + + public bool Equals(Value other) + { + try { + return this.CompareTo(other) == 0; + } catch (ObjectDisposedException) { + return false; + } catch (ValueFlushedException) { + return false; + } + } + + public override int GetHashCode() + { + return this.Handle.ToInt32(); + } + + public static bool operator==(Value x, Value y) + { + if (object.ReferenceEquals(x, null)) + return object.ReferenceEquals(y, null); + + return x.Equals(y); + } + + public static bool operator!=(Value x, Value y) + { + if (object.ReferenceEquals(x, null)) + return !object.ReferenceEquals(y, null); + return !x.Equals(y); + } + + public static bool operator>(Value x, Value y) + { + if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null)) + return false; + return x.CompareTo(y) > 0; + } + + public static bool operator<(Value x, Value y) + { + if (object.ReferenceEquals(x, null) || object.ReferenceEquals(y, null)) + return false; + return x.CompareTo(y) < 0; + } + + + /// Converts value to string. + public override String ToString() + { + SanityChecks(); + IntPtr ptr = eina_value_to_string(this.Handle); + String str = Marshal.PtrToStringAnsi(ptr); + MemoryNative.Free(ptr); + return str; + } + + /// Empties an optional eina.Value, freeing what was previously contained. + public bool Reset() + { + OptionalSanityChecks(); + return eina_value_optional_reset(this.Handle); + } + + // Container methods methods + public int Count() { + ContainerSanityChecks(); + switch(GetValueType()) { + case ValueType.Array: + return (int)eina_value_array_count_wrapper(this.Handle); + case ValueType.List: + return (int)eina_value_list_count_wrapper(this.Handle); + } + return -1; + } + public bool Append(object o) { + ContainerSanityChecks(); + using (DisposableIntPtr marshalled_value = MarshalValue(o)) { + switch (GetValueType()) { + case ValueType.Array: + return eina_value_array_append_wrapper(this.Handle, marshalled_value.Handle); + case ValueType.List: + return eina_value_list_append_wrapper(this.Handle, marshalled_value.Handle); + } + } + return false; + } + + public object this[int i] + { + get { + ContainerSanityChecks(i); + + IntPtr output = IntPtr.Zero; + switch (GetValueType()) { + case ValueType.Array: + if (!eina_value_array_get_wrapper(this.Handle, i, out output)) + return null; + break; + case ValueType.List: + if (!eina_value_list_get_wrapper(this.Handle, i, out output)) + return null; + break; + } + return UnMarshalPtr(output); + } + set { + ContainerSanityChecks(i); + + switch (GetValueType()) { + case ValueType.Array: + ArraySet(i, value); + break; + case ValueType.List: + ListSet(i, value); + break; + } + } + } + + private void ArraySet(int i, object value) { + using (DisposableIntPtr marshalled_value = MarshalValue(value)) + { + if (!eina_value_array_set_wrapper(this.Handle, i, + marshalled_value.Handle)) { + throw new SetItemFailedException($"Failed to set item at index {i}"); + } + } + } + + private void ListSet(int i, object value) { + using (DisposableIntPtr marshalled_value = MarshalValue(value)) + { + if (!eina_value_list_set_wrapper(this.Handle, i, + marshalled_value.Handle)) { + throw new SetItemFailedException($"Failed to set item at index {i}"); + } + } + } + + public ValueType GetValueSubType() + { + ContainerSanityChecks(); + + IntPtr native_subtype = IntPtr.Zero; + + switch (GetValueType()) { + case ValueType.Array: + native_subtype = eina_value_array_subtype_get_wrapper(this.Handle); + break; + case ValueType.List: + native_subtype = eina_value_list_subtype_get_wrapper(this.Handle); + break; + } + return ValueTypeBridge.GetManaged(native_subtype); + } + + private DisposableIntPtr MarshalValue(object value) + { + IntPtr ret = IntPtr.Zero; + bool shouldFree = false; + switch(GetValueSubType()) { + case ValueType.Int32: + { + int x = Convert.ToInt32(value); + ret = new IntPtr(x); + } + break; + case ValueType.UInt32: + { + uint x = Convert.ToUInt32(value); + ret = new IntPtr((int)x); + } + break; + case ValueType.String: + { + string x = value as string; + if (x == null) + ret = IntPtr.Zero; + else { + ret = StringConversion.ManagedStringToNativeUtf8Alloc(x); + shouldFree = true; + } + } + break; + } + + return new DisposableIntPtr(ret, shouldFree); + } + + private object UnMarshalPtr(IntPtr data) + { + switch(GetValueSubType()) { + case ValueType.Int32: + return Convert.ToInt32(data.ToInt32()); + case ValueType.UInt32: + return Convert.ToUInt32(data.ToInt32()); + case ValueType.String: + return StringConversion.NativeUtf8ToManagedString(data); + default: + return null; + } + } + +} + +/// Custom marshaler to convert value pointers to managed values and back, +/// without changing ownership. +public class ValueMarshaler : ICustomMarshaler { + + /// Creates a managed value from a C pointer, whitout taking ownership of it. + public object MarshalNativeToManaged(IntPtr pNativeData) { + return new Value(pNativeData, ValueOwnership.Unmanaged); + } + + /// Retrieves the C pointer from a given managed value, + /// keeping the managed ownership. + public IntPtr MarshalManagedToNative(object managedObj) { + try { + Value v = (Value)managedObj; + return v.Handle; + } catch (InvalidCastException) { + return IntPtr.Zero; + } + } + + public void CleanUpNativeData(IntPtr pNativeData) { + } + + public void CleanUpManagedData(object managedObj) { + } + + public int GetNativeDataSize() { + return -1; + } + + public static ICustomMarshaler GetInstance(string cookie) { + if (marshaler == null) { + marshaler = new ValueMarshaler(); + } + return marshaler; + } + static private ValueMarshaler marshaler; +} + +/// Custom marshaler to convert value pointers to managed values and back, +/// also transferring the ownership to the other side. +public class ValueMarshalerOwn : ICustomMarshaler { + /// Creates a managed value from a C pointer, taking the ownership. + public object MarshalNativeToManaged(IntPtr pNativeData) { + return new Value(pNativeData, ValueOwnership.Managed); + } + + /// Retrieves the C pointer from a given managed value, + /// transferring the ownership to the unmanaged side, which should release it + /// when not needed. + public IntPtr MarshalManagedToNative(object managedObj) { + try { + Value v = (Value)managedObj; + v.ReleaseOwnership(); + return v.Handle; + } catch (InvalidCastException) { + return IntPtr.Zero; + } + } + + public void CleanUpNativeData(IntPtr pNativeData) { + } + + public void CleanUpManagedData(object managedObj) { + } + + public int GetNativeDataSize() { + return -1; + } + + public static ICustomMarshaler GetInstance(string cookie) { + if (marshaler == null) { + marshaler = new ValueMarshalerOwn(); + } + return marshaler; + } + static private ValueMarshalerOwn marshaler; +} +} diff --git a/src/bindings/mono/eldbus_mono/eldbus_common.cs b/src/bindings/mono/eldbus_mono/eldbus_common.cs new file mode 100644 index 0000000000..95138581f0 --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_common.cs @@ -0,0 +1,561 @@ +using System; +using System.Runtime.InteropServices; + +using static eldbus.EldbusMessageNativeFunctions; + +namespace eldbus { + +public static class Timeout +{ + public static int Infinite = 0x7fffffff; +} + +[StructLayout(LayoutKind.Sequential)] +public struct ObjectPath +{ + public string value; + + public ObjectPath(string str) + { + value = str; + } + + public static implicit operator ObjectPath(string str) + { + return new ObjectPath(str); + } + public static implicit operator string(ObjectPath path) + { + return path.value; + } +} + +[StructLayout(LayoutKind.Sequential)] +public struct SignatureString +{ + public string value; + + public SignatureString(string str) + { + value = str; + } + + public static implicit operator SignatureString(string str) + { + return new SignatureString(str); + } + public static implicit operator string(SignatureString sig) + { + return sig.value; + } +} + +[StructLayout(LayoutKind.Sequential)] +public struct UnixFd +{ + public Int32 value; + + public UnixFd(Int32 fd) + { + value = fd; + } + + public static implicit operator UnixFd(Int32 fd) + { + return new UnixFd(fd); + } + public static implicit operator Int32(UnixFd unix_fd) + { + return unix_fd.value; + } +} + + +public static class Argument +{ + public class ByteType { public const char Code = 'y'; public const string Signature = "y"; } + public class BooleanType { public const char Code = 'b'; public const string Signature = "b"; } + public class Int16Type { public const char Code = 'n'; public const string Signature = "n"; } + public class UInt16Type { public const char Code = 'q'; public const string Signature = "q"; } + public class Int32Type { public const char Code = 'i'; public const string Signature = "i"; } + public class UInt32Type { public const char Code = 'u'; public const string Signature = "u"; } + public class Int64Type { public const char Code = 'x'; public const string Signature = "x"; } + public class UInt64Type { public const char Code = 't'; public const string Signature = "t"; } + public class DoubleType { public const char Code = 'd'; public const string Signature = "d"; } + public class StringType { public const char Code = 's'; public const string Signature = "s"; } + public class ObjectPathType { public const char Code = 'o'; public const string Signature = "o"; } + public class SignatureType { public const char Code = 'g'; public const string Signature = "g"; } + public class ArrayType { public const char Code = 'a'; public const string Signature = "a"; } + public class StructType { public const char Code = 'r'; public const string Signature = "r"; } + public class VariantType { public const char Code = 'v'; public const string Signature = "v"; } + public class DictEntryType { public const char Code = 'e'; public const string Signature = "e"; } + public class UnixFdType { public const char Code = 'h'; public const string Signature = "h"; } + +// public static readonly ByteType ByteT = new ByteType(); +// public static readonly BooleanType BooleanT = new BooleanType(); +// public static readonly Int16Type Int16T = new Int16Type(); +// public static readonly UInt16Type UInt16T = new UInt16Type(); +// public static readonly Int32Type Int32T = new Int32Type(); +// public static readonly UInt32Type UInt32T = new UInt32Type(); +// public static readonly Int64Type Int64T = new Int64Type(); +// public static readonly UInt64Type UInt64T = new UInt64Type(); +// public static readonly DoubleType DoubleT = new DoubleType(); +// public static readonly StringType StringT = new StringType(); +// public static readonly ObjectPathType ObjectPathT = new ObjectPathType(); +// public static readonly SignatureType SignatureT = new SignatureType(); +// public static readonly ArrayType ArrayT = new ArrayType(); +// public static readonly StructType StructT = new StructType(); +// public static readonly VariantType VariantT = new VariantType(); +// public static readonly DictEntryType DictEntryT = new DictEntryType(); +// public static readonly UnixFdType UnixFdT = new UnixFdType(); +// +// public static readonly ByteType y = ByteT; +// public static readonly BooleanType b = BooleanT; +// public static readonly Int16Type n = Int16T; +// public static readonly UInt16Type q = UInt16T; +// public static readonly Int32Type i = Int32T; +// public static readonly UInt32Type u = UInt32T; +// public static readonly Int64Type x = Int64T; +// public static readonly UInt64Type t = UInt64T; +// public static readonly DoubleType d = DoubleT; +// public static readonly StringType s = StringT; +// public static readonly ObjectPathType o = ObjectPathT; +// public static readonly SignatureType g = SignatureT; +// public static readonly ArrayType a = ArrayT; +// public static readonly StructType r = StructT; +// public static readonly VariantType v = VariantT; +// public static readonly DictEntryType e = DictEntryT; +// public static readonly UnixFdType h = UnixFdT; +} + +public abstract class BasicMessageArgument +{ + public void AppendTo(eldbus.Message msg) + { + if (!InternalAppendTo(msg)) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not append basic type to eldbus.Message"); + } + } + + public void AppendTo(eldbus.MessageIterator iter) + { + if (!InternalAppendTo(iter)) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not append basic type to eldbus.MessageIterator"); + } + } + + public abstract char TypeCode {get;} + public abstract string Signature {get;} + protected abstract bool InternalAppendTo(eldbus.Message msg); + protected abstract bool InternalAppendTo(eldbus.MessageIterator iter); + + public static implicit operator BasicMessageArgument(byte arg) + { + return new ByteMessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(bool arg) + { + return new BoolMessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(Int16 arg) + { + return new Int16MessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(UInt16 arg) + { + return new UInt16MessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(Int32 arg) + { + return new Int32MessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(UInt32 arg) + { + return new UInt32MessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(Int64 arg) + { + return new Int64MessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(UInt64 arg) + { + return new UInt64MessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(string arg) + { + return new StringMessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(SignatureString arg) + { + return new SignatureMessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(ObjectPath arg) + { + return new ObjectPathMessageArgument(arg); + } + + public static implicit operator BasicMessageArgument(UnixFd arg) + { + return new UnixFdMessageArgument(arg); + } +} + +public class ByteMessageArgument : BasicMessageArgument +{ + private byte value; + + public ByteMessageArgument(byte arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.ByteType.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class BoolMessageArgument : BasicMessageArgument +{ + private Int32 value; + + public BoolMessageArgument(bool arg) + { + value = Convert.ToInt32(arg); + } + + public override char TypeCode { get { return Argument.BooleanType.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class Int16MessageArgument : BasicMessageArgument +{ + private Int16 value; + + public Int16MessageArgument(Int16 arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.Int16Type.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class UInt16MessageArgument : BasicMessageArgument +{ + private UInt16 value; + + public UInt16MessageArgument(UInt16 arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.UInt16Type.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class Int32MessageArgument : BasicMessageArgument +{ + private Int32 value; + + public Int32MessageArgument(Int32 arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.Int32Type.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class UInt32MessageArgument : BasicMessageArgument +{ + private UInt32 value; + + public UInt32MessageArgument(UInt32 arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.UInt32Type.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class Int64MessageArgument : BasicMessageArgument +{ + private Int64 value; + + public Int64MessageArgument(Int64 arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.Int64Type.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class UInt64MessageArgument : BasicMessageArgument +{ + private UInt64 value; + + public UInt64MessageArgument(UInt64 arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.UInt64Type.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class DoubleMessageArgument : BasicMessageArgument +{ + private double value; + + public DoubleMessageArgument(double arg) + { + value = arg; + } + + public override char TypeCode { get { return Argument.DoubleType.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public abstract class StringLikeMessageArgument : BasicMessageArgument +{ + private string value; + + public StringLikeMessageArgument(string arg) + { + value = arg; + } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public class StringMessageArgument : StringLikeMessageArgument +{ + public StringMessageArgument(string arg) + : base(arg) + {} + + public override char TypeCode { get { return Argument.StringType.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } +} + +public class ObjectPathMessageArgument : StringLikeMessageArgument +{ + public ObjectPathMessageArgument(ObjectPath arg) + : base(arg.value) + {} + + public override char TypeCode { get { return Argument.ObjectPathType.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } +} + +public class SignatureMessageArgument : StringLikeMessageArgument +{ + public SignatureMessageArgument(SignatureString arg) + : base(arg.value) + {} + + public override char TypeCode { get { return Argument.SignatureType.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } +} + +public class UnixFdMessageArgument : BasicMessageArgument +{ + private Int32 value; + + public UnixFdMessageArgument(UnixFd arg) + { + value = arg.value; + } + + public override char TypeCode { get { return Argument.UnixFdType.Code; } } + public override string Signature { get { return Argument.ByteType.Signature; } } + + protected override bool InternalAppendTo(eldbus.Message msg) + { + return eldbus_message_arguments_append(msg.Handle, Signature, value); + } + + protected override bool InternalAppendTo(eldbus.MessageIterator iter) + { + return eldbus_message_iter_basic_append(iter.Handle, TypeCode, value); + } +} + +public delegate void MessageDelegate(eldbus.Message msg, eldbus.Pending pending); + +public static class Common +{ + public static void RaiseNullHandle() + { + if (NullHandleError == 0) + NullHandleError = eina.Error.Register("Eldbus: null handle"); + eina.Error.Raise(NullHandleError); + } + + public delegate void Eldbus_Message_Cb(IntPtr data, IntPtr msg, IntPtr pending); + + public static IntPtr GetMessageCbWrapperPtr() + { + return Marshal.GetFunctionPointerForDelegate(GetMessageCbWrapper()); + } + + public static Eldbus_Message_Cb GetMessageCbWrapper() + { + if (message_cb_wrapper == null) + message_cb_wrapper = new Eldbus_Message_Cb(MessageCbWrapper); + return message_cb_wrapper; + } + + public static void MessageCbWrapper(IntPtr data, IntPtr msg_hdl, IntPtr pending_hdl) + { + MessageDelegate dlgt = Marshal.GetDelegateForFunctionPointer(data, typeof(MessageDelegate)) as MessageDelegate; + if (dlgt == null) + { + eina.Log.Error("Eldbus: invalid delegate pointer from Eldbus_Message_Cb"); + return; + } + + eldbus.Message msg; + eldbus.Pending pending; + + try + { + msg = new eldbus.Message(msg_hdl, false); + pending = new eldbus.Pending(pending_hdl, false); + } + catch(Exception e) + { + eina.Log.Error("Eldbus: could not convert Eldbus_Message_Cb parameters. Exception: " + e.ToString()); + return; + } + + try + { + dlgt(msg, pending); + } + catch(Exception e) + { + eina.Log.Error("Eldbus: Eldbus_Message_Cb delegate error. Exception: " + e.ToString()); + } + } + + private static Eldbus_Message_Cb message_cb_wrapper = null; + private static eina.Error NullHandleError = 0; +} + +} + + diff --git a/src/bindings/mono/eldbus_mono/eldbus_config.cs b/src/bindings/mono/eldbus_mono/eldbus_config.cs new file mode 100644 index 0000000000..f6054815ff --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_config.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.InteropServices; + +namespace eldbus { + +public static class Config +{ + [DllImport(efl.Libs.Eldbus)] private static extern int eldbus_init(); + [DllImport(efl.Libs.Eldbus)] private static extern int eldbus_shutdown(); + + public static void Init() + { + if (eldbus_init() == 0) + throw new efl.EflException("Failed to initialize Eldbus"); + } + + public static void Shutdown() + { + eldbus_shutdown(); + } + +} + +} diff --git a/src/bindings/mono/eldbus_mono/eldbus_connection.cs b/src/bindings/mono/eldbus_mono/eldbus_connection.cs new file mode 100644 index 0000000000..87d09cbd18 --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_connection.cs @@ -0,0 +1,373 @@ +using System; +using System.Runtime.InteropServices; + +using static eldbus.EldbusConnectionNativeFunctions; + +namespace eldbus { + + +public static class EldbusConnectionNativeFunctions +{ + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_connection_get(eldbus.Connection.Type type); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_private_connection_get(eldbus.Connection.Type type); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_address_connection_get(string address); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_private_address_connection_get(string address); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_connection_ref(IntPtr conn); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_connection_unref(IntPtr conn); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_connection_free_cb_add(IntPtr conn, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_connection_free_cb_del(IntPtr conn, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_connection_data_set(IntPtr conn, IntPtr key, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_connection_data_get(IntPtr conn, IntPtr key); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_connection_data_del(IntPtr conn, IntPtr key); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_connection_event_callback_add(IntPtr conn, int type, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_connection_event_callback_del(IntPtr conn, int type, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_connection_send(IntPtr conn, IntPtr msg, IntPtr cb, IntPtr cb_data, double timeout); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_connection_unique_name_get(IntPtr conn); + + // FreeDesktop.Org Methods + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_name_request(IntPtr conn, string bus, uint flags, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_name_release(IntPtr conn, string bus, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_name_owner_get(IntPtr conn, string bus, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_name_owner_has(IntPtr conn, string bus, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_names_list(IntPtr conn, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_names_activatable_list(IntPtr conn, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_hello(IntPtr conn, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_name_start(IntPtr conn, string bus, uint flags, IntPtr cb, IntPtr cb_data); + +// typedef void (*Eldbus_Name_Owner_Changed_Cb)(void *data, const char *bus, const char *old_id, const char *new_id); +// [DllImport(efl.Libs.Eldbus)] public static extern void +// eldbus_name_owner_changed_callback_add(IntPtr conn, string bus, Eldbus_Name_Owner_Changed_Cb cb, IntPtr cb_data, [MarshalAs(UnmanagedType.U1)] bool allow_initial_call); +// [DllImport(efl.Libs.Eldbus)] public static extern void +// eldbus_name_owner_changed_callback_del(IntPtr conn, string bus, Eldbus_Name_Owner_Changed_Cb cb, IntPtr cb_data); +} + +public class Connection : IDisposable +{ + public enum Type + { + Unknown = 0, // sentinel, not a real type + Session, + System, + Starter, + Address, + Last // sentinel, not a real type + }; + + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} = true; + + private void InitNew(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + CheckHandle(); + } + + private void CheckHandle() + { + if (Handle == IntPtr.Zero) + { + eldbus.Common.RaiseNullHandle(); + } + } + + public Connection(IntPtr handle, bool own) + { + InitNew(handle, own); + } + + + public Connection(eldbus.Connection.Type type) + { + InitNew(eldbus_connection_get(type), true); + } + + public Connection(string address) + { + InitNew(eldbus_address_connection_get(address), true); + } + + public static eldbus.Connection GetPrivate(eldbus.Connection.Type type) + { + return new eldbus.Connection(eldbus_private_connection_get(type), true); + } + + public static eldbus.Connection GetPrivate(string address) + { + return new eldbus.Connection(eldbus_private_address_connection_get(address), true); + } + + + ~Connection() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (Own) + eldbus_connection_unref(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public eldbus.Pending Send(eldbus.Message msg, eldbus.MessageDelegate dlgt = null, double timeout = -1) + { + CheckHandle(); + + if (msg == null) + throw new ArgumentNullException("msg"); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_connection_send(Handle, msg.Handle, cb_wrapper, cb_data, timeout); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_connection_send"); + } + + msg.Ref(); + + return new eldbus.Pending(pending_hdl, false); + } + + public string GetUniqueName() + { + CheckHandle(); + var ptr = eldbus_connection_unique_name_get(Handle); + if (ptr == IntPtr.Zero) + return null; + return Marshal.PtrToStringAuto(ptr); + } + + public eldbus.Pending NameRequest(string bus, uint flags, eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + if (bus == null) + throw new ArgumentNullException("bus"); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_name_request(Handle, bus, flags, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_name_request"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending NameRelease(string bus, eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + if (bus == null) + throw new ArgumentNullException("bus"); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_name_release(Handle, bus, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_name_release"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending GetNameOwner(string bus, eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + if (bus == null) + throw new ArgumentNullException("bus"); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_name_owner_get(Handle, bus, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_name_owner_get"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending HasNameOwner(string bus, eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + if (bus == null) + throw new ArgumentNullException("bus"); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_name_owner_has(Handle, bus, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_name_owner_has"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending NameList(eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_names_list(Handle, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_names_list"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending ActivableList(eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_names_activatable_list(Handle, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_names_activatable_list"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending Hello(eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_hello(Handle, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_hello"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending NameStart(string bus, uint flags, eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + if (bus == null) + throw new ArgumentNullException("bus"); + + IntPtr cb_wrapper = (dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr()); + IntPtr cb_data = (dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt)); + + var pending_hdl = eldbus_name_start(Handle, bus, flags, cb_wrapper, cb_data); + + if(pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_name_start"); + } + + return new eldbus.Pending(pending_hdl, false); + } + +} + +} diff --git a/src/bindings/mono/eldbus_mono/eldbus_message.cs b/src/bindings/mono/eldbus_mono/eldbus_message.cs new file mode 100644 index 0000000000..2ebc90c722 --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_message.cs @@ -0,0 +1,924 @@ +using System; +using System.Runtime.InteropServices; + +using static eldbus.EldbusMessageNativeFunctions; + +namespace eldbus { + +public static class EldbusMessageNativeFunctions +{ + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_ref(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_unref(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_path_get(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_interface_get(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_member_get(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_destination_get(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_sender_get(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_signature_get(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_method_call_new(string dest, string path, string iface, string method); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_signal_new(string path, string _interface, string name); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_error_new(IntPtr msg, string error_name, string error_msg); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_method_return_new(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_error_get(IntPtr msg, out IntPtr name, out IntPtr text); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out byte value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out Int16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out UInt16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out Int32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out UInt32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out Int64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out UInt64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out double value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_get(IntPtr msg, string signature, out IntPtr value); + +// [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool +// eldbus_message_arguments_vget(IntPtr msg, string signature, va_list ap); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, byte value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, Int16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, UInt16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, Int32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, UInt32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, Int64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, UInt64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, double value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_arguments_append(IntPtr msg, string signature, string value); + +// [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool +// eldbus_message_arguments_vappend(IntPtr msg, string signature, va_list ap); + + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_iter_container_new(IntPtr iter, int type, string contained_signature); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, byte value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, Int16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, UInt16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, Int32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, UInt32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, Int64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, UInt64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, double value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_basic_append(IntPtr iter, int type, string value); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_arguments_append(IntPtr iter, string signature, out IntPtr value); + +// [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool +// eldbus_message_iter_arguments_vappend(IntPtr iter, string signature, va_list ap); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_fixed_array_append(IntPtr iter, int type, IntPtr array, uint size); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_container_close(IntPtr iter, IntPtr sub); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_message_iter_get(IntPtr msg); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out byte value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out Int16 value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out UInt16 value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out Int32 value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out UInt32 value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out Int64 value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out UInt64 value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out double value); + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_basic_get(IntPtr iter, out IntPtr value); + + [DllImport(efl.Libs.Eldbus)] public static extern string + eldbus_message_iter_signature_get(IntPtr iter); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_next(IntPtr iter); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out byte value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out Int16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out UInt16 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out Int32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out UInt32 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out Int64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out UInt64 value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out double value); + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_get_and_next(IntPtr iter, char signature, out IntPtr value); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_fixed_array_get(IntPtr iter, int signature, out IntPtr value, out int n_elements); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_message_iter_arguments_get(IntPtr iter, string signature, out IntPtr value); + +// [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool +// eldbus_message_iter_arguments_vget(IntPtr iter, string signature, va_list ap); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_message_iter_del(IntPtr iter); +} + + +public class Message : IDisposable +{ + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} = true; + + private void InitNew(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + CheckHandle(); + } + + private void CheckHandle() + { + if (Handle == IntPtr.Zero) + { + eldbus.Common.RaiseNullHandle(); + } + } + + public Message(IntPtr handle, bool own) + { + InitNew(handle, own); + } + + ~Message() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (Own) + eldbus_message_unref(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public static eldbus.Message NewMethodCall(string dest, string path, string iface, string method) + { + var ptr = eldbus_message_method_call_new(dest, path, iface, method); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Message' object from eldbus_message_method_call_new"); + } + return new eldbus.Message(ptr, true); + } + + public static eldbus.Message NewSignal(string path, string _interface, string name) + { + var ptr = eldbus_message_signal_new(path, _interface, name); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Message' object from eldbus_message_signal_new"); + } + return new eldbus.Message(ptr, true); + } + + public void Ref() + { + CheckHandle(); + eldbus_message_ref(Handle); + } + + public void Unref() + { + CheckHandle(); + eldbus_message_unref(Handle); + } + + public string GetPath() + { + CheckHandle(); + var ptr = eldbus_message_path_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetInterface() + { + CheckHandle(); + var ptr = eldbus_message_interface_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetMember() + { + CheckHandle(); + var ptr = eldbus_message_member_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetDestination() + { + CheckHandle(); + var ptr = eldbus_message_destination_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetSender() + { + CheckHandle(); + var ptr = eldbus_message_sender_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetSignature() + { + CheckHandle(); + var ptr = eldbus_message_signature_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public eldbus.Message NewError(string error_name, string error_msg) + { + CheckHandle(); + var ptr = eldbus_message_error_new(Handle, error_name, error_msg); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Message' object from eldbus_message_error_new"); + } + return new eldbus.Message(ptr, false); + } + + public eldbus.Message NewMethodReturn() + { + CheckHandle(); + var ptr = eldbus_message_method_return_new(Handle); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Message' object from eldbus_message_method_return_new"); + } + return new eldbus.Message(ptr, false); + } + + public bool GetError(out string name, out string text) + { + CheckHandle(); + IntPtr name_ptr; + IntPtr text_ptr; + bool r = eldbus_message_error_get(Handle, out name_ptr, out text_ptr); + name = Marshal.PtrToStringAuto(name_ptr); + text = Marshal.PtrToStringAuto(text_ptr); + return r; + } + + public bool Get(out byte val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.ByteType.Signature, out val); + } + + public bool Get(out bool val) + { + CheckHandle(); + Int32 aux; + var r = eldbus_message_arguments_get(Handle, Argument.BooleanType.Signature, out aux); + val = (aux != 0); + return r; + } + + public bool Get(out Int16 val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.Int16Type.Signature, out val); + } + + public bool Get(out UInt16 val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.UInt16Type.Signature, out val); + } + + public bool Get(out Int32 val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.Int32Type.Signature, out val); + } + + public bool Get(out UInt32 val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.UInt32Type.Signature, out val); + } + + public bool Get(out Int64 val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.Int64Type.Signature, out val); + } + + public bool Get(out UInt64 val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.UInt64Type.Signature, out val); + } + + public bool Get(out double val) + { + CheckHandle(); + return eldbus_message_arguments_get(Handle, Argument.DoubleType.Signature, out val); + } + + public bool Get(out string val) + { + CheckHandle(); + IntPtr aux; + var r = eldbus_message_arguments_get(Handle, Argument.StringType.Signature, out aux); + val = Marshal.PtrToStringAuto(aux); + return r; + } + + public bool Get(out eldbus.ObjectPath val) + { + CheckHandle(); + IntPtr aux; + var r = eldbus_message_arguments_get(Handle, Argument.ObjectPathType.Signature, out aux); + val = Marshal.PtrToStringAuto(aux); + return r; + } + + public bool Get(out eldbus.SignatureString val) + { + CheckHandle(); + IntPtr aux; + var r = eldbus_message_arguments_get(Handle, Argument.SignatureType.Signature, out aux); + val = Marshal.PtrToStringAuto(aux); + return r; + } + + public bool Get(out eldbus.UnixFd val) + { + CheckHandle(); + Int32 aux; + var r = eldbus_message_arguments_get(Handle, Argument.UnixFdType.Signature, out aux); + val = aux; + return r; + } + + public void Append(params BasicMessageArgument[] args) + { + CheckHandle(); + foreach (BasicMessageArgument arg in args) + { + arg.AppendTo(this); + } + } + + public eldbus.MessageIterator AppendOpenContainer(string signature) + { + var iter = GetMessageIterator(); + return iter.AppendOpenContainer(signature); + } + + public eldbus.MessageIterator GetMessageIterator() + { + CheckHandle(); + var ptr = eldbus_message_iter_get(Handle); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `MessageIterator' object from eldbus_message_iter_get"); + } + return new eldbus.MessageIterator(ptr, IntPtr.Zero); + } +} + +public class MessageIterator +{ + public IntPtr Handle {get;set;} = IntPtr.Zero; + public IntPtr Parent {get;set;} = IntPtr.Zero; + + private void InitNew(IntPtr handle, IntPtr parent) + { + Handle = handle; + Parent = parent; + CheckHandle(); + } + + private void CheckHandle() + { + if (Handle == IntPtr.Zero) + { + eldbus.Common.RaiseNullHandle(); + } + } + + public MessageIterator(IntPtr handle, IntPtr parent) + { + InitNew(handle, parent); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + Parent = IntPtr.Zero; + return h; + } + + public void Append(params BasicMessageArgument[] args) + { + CheckHandle(); + + foreach (BasicMessageArgument arg in args) + { + arg.AppendTo(this); + } + } + + public eldbus.MessageIterator AppendOpenContainer(string signature) + { + CheckHandle(); + + IntPtr new_iter = IntPtr.Zero; + + if (signature[0] == 'v') + { + new_iter = eldbus_message_iter_container_new(Handle, 'v', signature.Substring(1)); + } + else if (!eldbus_message_iter_arguments_append(Handle, signature, out new_iter)) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not append container type"); + } + + if (new_iter == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `MessageIterator' object from eldbus_message_iter_arguments_append"); + } + + return new eldbus.MessageIterator(new_iter, Handle); + } + + public eldbus.MessageIterator AppendOpenContainer(char type, string contained_signature) + { + CheckHandle(); + + IntPtr new_iter = eldbus_message_iter_container_new(Handle, type, contained_signature); + + if (new_iter == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `MessageIterator' object from eldbus_message_iter_container_new"); + } + + return new eldbus.MessageIterator(new_iter, Handle); + } + + public void CloseContainer() + { + CheckHandle(); + + if (Parent == IntPtr.Zero) + { + throw new SEHException("Eldbus: can not close MessageIterator open container without a parent"); + } + + if (!eldbus_message_iter_container_close(Parent, Handle)) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not close MessageIterator"); + } + + Handle = IntPtr.Zero; + Parent = IntPtr.Zero; + } + + public string GetSignature() + { + return eldbus_message_iter_signature_get(Handle); + } + + public bool GetAndNext(out byte val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.ByteType.Code, out val); + } + + public bool GetAndNext(out bool val) + { + CheckHandle(); + Int32 aux; + bool r = eldbus_message_iter_get_and_next(Handle, Argument.BooleanType.Code, out aux); + val = (aux != 0); + return r; + } + + public bool GetAndNext(out Int16 val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.Int16Type.Code, out val); + } + + public bool GetAndNext(out UInt16 val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.UInt16Type.Code, out val); + } + + public bool GetAndNext(out Int32 val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.Int32Type.Code, out val); + } + + public bool GetAndNext(out UInt32 val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.UInt32Type.Code, out val); + } + + public bool GetAndNext(out Int64 val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.Int64Type.Code, out val); + } + + public bool GetAndNext(out UInt64 val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.UInt64Type.Code, out val); + } + + public bool GetAndNext(out double val) + { + CheckHandle(); + return eldbus_message_iter_get_and_next(Handle, Argument.DoubleType.Code, out val); + } + + public bool GetAndNext(out string val) + { + CheckHandle(); + IntPtr aux; + bool r = eldbus_message_iter_get_and_next(Handle, Argument.StringType.Code, out aux); + val = Marshal.PtrToStringAuto(aux); + return r; + } + + public bool GetAndNext(out eldbus.ObjectPath val) + { + CheckHandle(); + IntPtr aux; + bool r = eldbus_message_iter_get_and_next(Handle, Argument.ObjectPathType.Code, out aux); + val = Marshal.PtrToStringAuto(aux); + return r; + } + + public bool GetAndNext(out eldbus.SignatureString val) + { + CheckHandle(); + IntPtr aux; + bool r = eldbus_message_iter_get_and_next(Handle, Argument.SignatureType.Code, out aux); + val = Marshal.PtrToStringAuto(aux); + return r; + } + + public bool GetAndNext(out eldbus.UnixFd val) + { + CheckHandle(); + Int32 aux; + bool r = eldbus_message_iter_get_and_next(Handle, Argument.UnixFdType.Code, out aux); + val = aux; + return r; + } + + public bool GetAndNext(out eldbus.MessageIterator iter, char typecode) + { + CheckHandle(); + IntPtr hdl = IntPtr.Zero; + bool r = eldbus_message_iter_get_and_next(Handle, typecode, out hdl); + if (hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get argument"); + } + iter = new eldbus.MessageIterator(hdl, Handle); + + return r; + } + + public bool GetAndNext(out eldbus.MessageIterator iter, string signatue) + { + CheckHandle(); + IntPtr hdl = IntPtr.Zero; + if (!eldbus_message_iter_arguments_get(Handle, signatue, out hdl) || hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get argument"); + } + iter = new eldbus.MessageIterator(hdl, Handle); + + return Next(); + } + + public void Get(out byte val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out bool val) + { + CheckHandle(); + Int32 aux; + eldbus_message_iter_basic_get(Handle, out aux); + val = (aux != 0); + } + + public void Get(out Int16 val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out UInt16 val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out Int32 val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out UInt32 val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out Int64 val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out UInt64 val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out double val) + { + CheckHandle(); + eldbus_message_iter_basic_get(Handle, out val); + } + + public void Get(out string val) + { + CheckHandle(); + IntPtr aux; + eldbus_message_iter_basic_get(Handle, out aux); + val = Marshal.PtrToStringAuto(aux); + } + + public void Get(out eldbus.ObjectPath val) + { + CheckHandle(); + IntPtr aux; + eldbus_message_iter_basic_get(Handle, out aux); + val = Marshal.PtrToStringAuto(aux); + } + + public void Get(out eldbus.SignatureString val) + { + CheckHandle(); + IntPtr aux; + eldbus_message_iter_basic_get(Handle, out aux); + val = Marshal.PtrToStringAuto(aux); + } + + public void Get(out eldbus.UnixFd val) + { + CheckHandle(); + Int32 aux; + eldbus_message_iter_basic_get(Handle, out aux); + val = aux; + } + + public void Get(out eldbus.MessageIterator iter, string signatue) + { + CheckHandle(); + IntPtr hdl = IntPtr.Zero; + if (!eldbus_message_iter_arguments_get(Handle, signatue, out hdl) || hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get argument"); + } + iter = new eldbus.MessageIterator(hdl, Handle); + } + + public bool Next() + { + CheckHandle(); + return eldbus_message_iter_next(Handle); + } + + public void Del() + { + CheckHandle(); + + eldbus_message_iter_del(Handle); + + Handle = IntPtr.Zero; + Parent = IntPtr.Zero; + } + + private void GetFixedArrayInternal(int type_code, out IntPtr value, out int n_elements) + { + CheckHandle(); + + if (!eldbus_message_iter_fixed_array_get(Handle, type_code, out value, out n_elements)) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get fixed array"); + } + } + + public void GetFixedArray(out byte[] array) + { + IntPtr value; + int n_elements; + GetFixedArrayInternal(Argument.ByteType.Code, out value, out n_elements); + array = new byte[n_elements]; + Marshal.Copy(value, array, 0, n_elements); + } + + public void GetFixedArray(out bool[] array) + { + IntPtr value; + int n_elements; + GetFixedArrayInternal(Argument.BooleanType.Code, out value, out n_elements); + var aux = new Int32[n_elements]; + Marshal.Copy(value, aux, 0, n_elements); + + // array = aux.Select(Convert.ToBoolean).ToArray(); + array = Array.ConvertAll(aux, Convert.ToBoolean); + } + + public void GetFixedArray(out Int16[] array) + { + IntPtr value; + int n_elements; + GetFixedArrayInternal(Argument.Int16Type.Code, out value, out n_elements); + array = new Int16[n_elements]; + Marshal.Copy(value, array, 0, n_elements); + } + +// public void GetFixedArray(out UInt16[] array) +// { +// IntPtr value; +// int n_elements; +// GetFixedArrayInternal(Argument.UInt16Type.Code, out value, out n_elements); +// array = new UInt16[n_elements]; +// Marshal.Copy(value, array, 0, n_elements); +// } + + public void GetFixedArray(out Int32[] array) + { + IntPtr value; + int n_elements; + GetFixedArrayInternal(Argument.Int32Type.Code, out value, out n_elements); + array = new Int32[n_elements]; + Marshal.Copy(value, array, 0, n_elements); + } + +// public void GetFixedArray(out UInt32[] array) +// { +// IntPtr value; +// int n_elements; +// GetFixedArrayInternal(Argument.UInt32Type.Code, out value, out n_elements); +// array = new UInt32[n_elements]; +// Marshal.Copy(value, array, 0, n_elements); +// } + + public void GetFixedArray(out Int64[] array) + { + IntPtr value; + int n_elements; + GetFixedArrayInternal(Argument.Int64Type.Code, out value, out n_elements); + array = new Int64[n_elements]; + Marshal.Copy(value, array, 0, n_elements); + } + +// public void GetFixedArray(out UInt64[] array) +// { +// IntPtr value; +// int n_elements; +// GetFixedArrayInternal(Argument.UInt64Type.Code, out value, out n_elements); +// array = new UInt64[n_elements]; +// Marshal.Copy(value, array, 0, n_elements); +// } + + public void GetFixedArray(out eldbus.UnixFd[] array) + { + IntPtr value; + int n_elements; + GetFixedArrayInternal(Argument.DoubleType.Code, out value, out n_elements); + var aux = new Int32[n_elements]; + Marshal.Copy(value, aux, 0, n_elements); + + array = Array.ConvertAll(aux, e => new UnixFd(e)); + } +} + +} + diff --git a/src/bindings/mono/eldbus_mono/eldbus_object.cs b/src/bindings/mono/eldbus_mono/eldbus_object.cs new file mode 100644 index 0000000000..1b0f4cb58f --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_object.cs @@ -0,0 +1,314 @@ +using System.Runtime.InteropServices; + +using static eldbus.EldbusObjectNativeFunctions; + +using IntPtr = System.IntPtr; + +namespace eldbus { + + +public static class EldbusObjectNativeFunctions +{ + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_get(IntPtr conn, string bus, string path); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_ref(IntPtr obj); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_object_unref(IntPtr obj); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_object_free_cb_add(IntPtr obj, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_object_free_cb_del(IntPtr obj, IntPtr cb, IntPtr data); + +// typedef enum +// { +// ELDBUS_OBJECT_EVENT_IFACE_ADDED = 0, /**< a parent path must have a ObjectManager interface */ +// ELDBUS_OBJECT_EVENT_IFACE_REMOVED, /**< a parent path must have a ObjectManager interface */ +// ELDBUS_OBJECT_EVENT_PROPERTY_CHANGED, /**< a property has changes */ +// ELDBUS_OBJECT_EVENT_PROPERTY_REMOVED, /**< a property was removed */ +// ELDBUS_OBJECT_EVENT_DEL, +// ELDBUS_OBJECT_EVENT_LAST /**< sentinel, not a real event type */ +// } Eldbus_Object_Event_Type; +// +// [DllImport(efl.Libs.Eldbus)] public static extern void +// eldbus_object_event_callback_add(IntPtr obj, Eldbus_Object_Event_Type type, IntPtr cb, IntPtr cb_data); +// +// [DllImport(efl.Libs.Eldbus)] public static extern void +// eldbus_object_event_callback_del(IntPtr obj, Eldbus_Object_Event_Type type, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_connection_get(IntPtr obj); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_bus_name_get(IntPtr obj); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_path_get(IntPtr obj); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_send(IntPtr obj, IntPtr msg, IntPtr cb, IntPtr cb_data, double timeout); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_signal_handler_add(IntPtr obj, string _interface, string member, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_method_call_new(IntPtr obj, string _interface, string member); + + // FreeDesktop.Org Methods + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_peer_ping(IntPtr obj, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_peer_machine_id_get(IntPtr obj, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_introspect(IntPtr obj, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_object_managed_objects_get(IntPtr obj, IntPtr cb, IntPtr data); + +// [DllImport(efl.Libs.Eldbus)] public static extern IntPtr +// eldbus_object_manager_interfaces_added(IntPtr obj, Eldbus_Signal_Cb cb, IntPtr cb_data); +// +// [DllImport(efl.Libs.Eldbus)] public static extern IntPtr +// eldbus_object_manager_interfaces_removed(IntPtr obj, Eldbus_Signal_Cb cb, IntPtr cb_data); +} + + +public class Object : System.IDisposable +{ + + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} = true; + + private void InitNew(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + CheckHandle(); + } + + private void CheckHandle() + { + if (Handle == IntPtr.Zero) + { + eldbus.Common.RaiseNullHandle(); + } + } + + public Object(IntPtr handle, bool own) + { + InitNew(handle, own); + } + + public Object(eldbus.Connection conn, string bus, string path) + { + if (conn == null) + throw new System.ArgumentNullException("conn"); + if (bus == null) + throw new System.ArgumentNullException("bus"); + if (path == null) + throw new System.ArgumentNullException("path"); + + var handle = eldbus_object_get(conn.Handle, bus, path); + + if (handle == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Object' object from eldbus_object_get"); + } + + InitNew(handle, true); + } + + ~Object() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (Own) + eldbus_object_unref(h); + } + + public void Dispose() + { + Dispose(true); + System.GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public eldbus.Connection GetConnection() + { + CheckHandle(); + var conn = eldbus_object_connection_get(Handle); + + if (conn == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Connection' object from eldbus_object_connection_get"); + } + + return new eldbus.Connection(conn, false); + } + + public string GetBusName() + { + CheckHandle(); + var ptr = eldbus_object_bus_name_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetPath() + { + CheckHandle(); + var ptr = eldbus_object_path_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public void Ref() + { + CheckHandle(); + eldbus_object_ref(Handle); + } + + public void Unref() + { + CheckHandle(); + eldbus_object_unref(Handle); + } + + public eldbus.Pending Send(eldbus.Message msg, eldbus.MessageDelegate dlgt = null, double timeout = -1) + { + CheckHandle(); + + if (msg == null) + throw new System.ArgumentNullException("msg"); + + IntPtr cb_wrapper = dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr(); + IntPtr cb_data = dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt); + + var pending_hdl = eldbus_object_send(Handle, msg.Handle, cb_wrapper, cb_data, timeout); + + if (pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_object_send"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Message NewMethodCall(string _interface, string member) + { + CheckHandle(); + + var hdl = eldbus_object_method_call_new(Handle, _interface, member); + + if (hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Message' object from eldbus_object_method_call_new"); + } + + return new eldbus.Message(hdl, false); + } + + public eldbus.Pending PeerPing(eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + IntPtr cb_wrapper = dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr(); + IntPtr cb_data = dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt); + + var pending_hdl = eldbus_object_peer_ping(Handle, cb_wrapper, cb_data); + + if (pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_object_peer_ping"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending GetPeerMachineId(eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + IntPtr cb_wrapper = dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr(); + IntPtr cb_data = dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt); + + var pending_hdl = eldbus_object_peer_machine_id_get(Handle, cb_wrapper, cb_data); + + if (pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_object_peer_machine_id_get"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending Introspect(eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + IntPtr cb_wrapper = dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr(); + IntPtr cb_data = dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt); + + var pending_hdl = eldbus_object_introspect(Handle, cb_wrapper, cb_data); + + if (pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_object_introspect"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + public eldbus.Pending GetManagedObjects(eldbus.MessageDelegate dlgt = null) + { + CheckHandle(); + + IntPtr cb_wrapper = dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr(); + IntPtr cb_data = dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt); + + var pending_hdl = eldbus_object_managed_objects_get(Handle, cb_wrapper, cb_data); + + if (pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_object_managed_objects_get"); + } + + return new eldbus.Pending(pending_hdl, false); + } + +} + + +} diff --git a/src/bindings/mono/eldbus_mono/eldbus_pending.cs b/src/bindings/mono/eldbus_mono/eldbus_pending.cs new file mode 100644 index 0000000000..9dff599619 --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_pending.cs @@ -0,0 +1,109 @@ +using System; +using System.Runtime.InteropServices; + +using static eldbus.EldbusPendingNativeFunctions; + +namespace eldbus { + +public static class EldbusPendingNativeFunctions +{ + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_pending_data_set(IntPtr pending, string key, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_pending_data_get(IntPtr pending, string key); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_pending_data_del(IntPtr pending, string key); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_pending_cancel(IntPtr pending); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_pending_destination_get(IntPtr pending); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_pending_path_get(IntPtr pending); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_pending_interface_get(IntPtr pending); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_pending_method_get(IntPtr pending); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_pending_free_cb_add(IntPtr pending, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_pending_free_cb_del(IntPtr pending, IntPtr cb, IntPtr data); +} + +public class Pending +{ + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} = true; + + private void InitNew(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + CheckHandle(); + } + + private void CheckHandle() + { + if (Handle == IntPtr.Zero) + { + eldbus.Common.RaiseNullHandle(); + } + } + + public Pending(IntPtr handle, bool own) + { + InitNew(handle, own); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + public void Cancel() + { + CheckHandle(); + eldbus_pending_cancel(Handle); + } + + public string GetDestination() + { + CheckHandle(); + var ptr = eldbus_pending_destination_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetPath() + { + CheckHandle(); + var ptr = eldbus_pending_path_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetInterface() + { + CheckHandle(); + var ptr = eldbus_pending_interface_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + public string GetMethod() + { + CheckHandle(); + var ptr = eldbus_pending_method_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } +} + +} + diff --git a/src/bindings/mono/eldbus_mono/eldbus_proxy.cs b/src/bindings/mono/eldbus_mono/eldbus_proxy.cs new file mode 100644 index 0000000000..1d07de71d8 --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_proxy.cs @@ -0,0 +1,218 @@ +using System; +using System.Runtime.InteropServices; + +using static eldbus.EldbusProxyNativeFunctions; + +namespace eldbus { + +public static class EldbusProxyNativeFunctions +{ + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_get(IntPtr obj, string _interface); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_ref(IntPtr proxy); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_proxy_unref(IntPtr proxy); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_object_get(IntPtr proxy); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_interface_get(IntPtr proxy); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_proxy_data_set(IntPtr proxy, string key, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_data_get(IntPtr proxy, string key); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_data_del(IntPtr proxy, string key); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_proxy_free_cb_add(IntPtr proxy, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_proxy_free_cb_del(IntPtr proxy, IntPtr cb, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_method_call_new(IntPtr proxy, string member); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_send(IntPtr proxy, IntPtr msg, IntPtr cb, IntPtr cb_data, double timeout); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_send_and_block(IntPtr proxy, IntPtr msg, double timeout); + +// [DllImport(efl.Libs.Eldbus)] public static extern IntPtr +// eldbus_proxy_call(IntPtr proxy, string member, IntPtr cb, IntPtr cb_data, double timeout, string signature, ...); +// +// [DllImport(efl.Libs.Eldbus)] public static extern IntPtr +// eldbus_proxy_vcall(IntPtr proxy, string member, IntPtr cb, IntPtr cb_data, double timeout, string signature, va_list ap); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_proxy_signal_handler_add(IntPtr proxy, string member, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_proxy_event_callback_add(IntPtr proxy, int type, IntPtr cb, IntPtr cb_data); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_proxy_event_callback_del(IntPtr proxy, int type, IntPtr cb, IntPtr cb_data); +} + +public class Proxy : IDisposable +{ + public IntPtr Handle {get;set;} = IntPtr.Zero; + public bool Own {get;set;} = true; + + private void InitNew(IntPtr handle, bool own) + { + Handle = handle; + Own = own; + CheckHandle(); + } + + private void CheckHandle() + { + if (Handle == IntPtr.Zero) + { + eldbus.Common.RaiseNullHandle(); + } + } + + public Proxy(IntPtr handle, bool own) + { + InitNew(handle, own); + } + + public Proxy(eldbus.Object obj, string _interface) + { + InitNew(eldbus_proxy_get(obj.Handle, _interface), true); + } + + ~Proxy() + { + Dispose(false); + } + + protected virtual void Dispose(bool disposing) + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + if (h == IntPtr.Zero) + return; + + if (Own) + eldbus_proxy_unref(h); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Free() + { + Dispose(); + } + + public IntPtr Release() + { + IntPtr h = Handle; + Handle = IntPtr.Zero; + return h; + } + + eldbus.Object GetObject() + { + CheckHandle(); + var ptr = eldbus_proxy_object_get(Handle); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Object' object from eldbus_proxy_object_get"); + } + return new eldbus.Object(ptr, false); + } + + string GetInterface() + { + CheckHandle(); + var ptr = eldbus_proxy_interface_get(Handle); + return Marshal.PtrToStringAuto(ptr); + } + + eldbus.Message NewMethodCall(string member) + { + CheckHandle(); + + if (member == null) + throw new ArgumentNullException("member"); + + var ptr = eldbus_proxy_method_call_new(Handle, member); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Message' object from eldbus_proxy_method_call_new"); + } + return new eldbus.Message(ptr, false); + } + + eldbus.Pending Send(eldbus.Message msg, eldbus.MessageDelegate dlgt = null, double timeout = -1) + { + CheckHandle(); + + if (msg == null) + throw new ArgumentNullException("msg"); + + IntPtr cb_wrapper = dlgt == null ? IntPtr.Zero : eldbus.Common.GetMessageCbWrapperPtr(); + IntPtr cb_data = dlgt == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(dlgt); + + var pending_hdl = eldbus_proxy_send(Handle, msg.Handle, cb_wrapper, cb_data, timeout); + + if (pending_hdl == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Pending' object from eldbus_proxy_send"); + } + + return new eldbus.Pending(pending_hdl, false); + } + + eldbus.Message SendAndBlock(eldbus.Message msg, double timeout = -1) + { + CheckHandle(); + var ptr = eldbus_proxy_send_and_block(Handle, msg.Handle, timeout); + if (ptr == IntPtr.Zero) + { + eina.Error.RaiseIfOccurred(); + throw new SEHException("Eldbus: could not get `Message' object from eldbus_proxy_send_and_block"); + } + return new eldbus.Message(ptr, true); + } + + eldbus.Pending Call(string member, eldbus.MessageDelegate dlgt, double timeout, params BasicMessageArgument[] args) + { + CheckHandle(); + + var msg = NewMethodCall(member); + + foreach (BasicMessageArgument arg in args) + { + arg.AppendTo(msg); + } + + return Send(msg, dlgt, timeout); + } + + eldbus.Pending Call(string member, params BasicMessageArgument[] args) + { + return Call(member, null, -1.0, args); + } +} + +} + diff --git a/src/bindings/mono/eldbus_mono/eldbus_service.cs b/src/bindings/mono/eldbus_mono/eldbus_service.cs new file mode 100644 index 0000000000..b3b5487733 --- /dev/null +++ b/src/bindings/mono/eldbus_mono/eldbus_service.cs @@ -0,0 +1,66 @@ +using System; +using System.Runtime.InteropServices; + +using static eldbus.EldbusServiceNativeFunctions; + +namespace eldbus { + +public static class EldbusServiceNativeFunctions +{ + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_interface_register(IntPtr conn, string path, IntPtr desc); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_interface_fallback_register(IntPtr conn, string path, IntPtr desc); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_interface_register2(IntPtr conn, string path, IntPtr desc); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_interface_fallback_register2(IntPtr conn, string path, IntPtr desc); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_service_interface_unregister(IntPtr iface); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_service_object_unregister(IntPtr iface); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_connection_get(IntPtr iface); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_object_path_get(IntPtr iface); + +// [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool +// eldbus_service_signal_emit(IntPtr iface, uint signal_id, ...); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_signal_new(IntPtr iface, uint signal_id); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_service_signal_send(IntPtr iface, IntPtr signal_msg); + + [DllImport(efl.Libs.Eldbus)] public static extern void + eldbus_service_object_data_set(IntPtr iface, string key, IntPtr data); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_object_data_get(IntPtr iface, string key); + + [DllImport(efl.Libs.Eldbus)] public static extern IntPtr + eldbus_service_object_data_del(IntPtr iface, string key); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_service_property_changed(IntPtr iface, string name); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_service_property_invalidate_set(IntPtr iface, string name, [MarshalAs(UnmanagedType.U1)] bool is_invalidate); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_service_object_manager_attach(IntPtr iface); + + [DllImport(efl.Libs.Eldbus)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool + eldbus_service_object_manager_detach(IntPtr iface); +} + +} + diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs new file mode 100644 index 0000000000..bd3ba50edf --- /dev/null +++ b/src/bindings/mono/eo_mono/iwrapper.cs @@ -0,0 +1,392 @@ + +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using static eina.NativeCustomExportFunctions; + +namespace efl { namespace eo { + +public class Globals { + [DllImport(efl.Libs.Eo)] public static extern void efl_object_init(); + [DllImport(efl.Libs.Eo)] public static extern void efl_object_shutdown(); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + _efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line, + IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + _efl_add_end(IntPtr eo, byte is_ref, byte is_fallback); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_ref(IntPtr eo); + [DllImport(efl.Libs.Eo)] public static extern void + efl_unref(IntPtr eo); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0, IntPtr base1); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0, IntPtr base1, IntPtr base2); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0, IntPtr base1, IntPtr base2, IntPtr base3); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0, IntPtr base1, IntPtr base2, IntPtr base3, IntPtr base4); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0, IntPtr base1, IntPtr base2, IntPtr base3, IntPtr base4, IntPtr base5); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0, IntPtr base1, IntPtr base2, IntPtr base3, IntPtr base4, IntPtr base5, IntPtr base6); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + efl_class_new(IntPtr class_description, IntPtr base0, IntPtr base1, IntPtr base2, IntPtr base3, IntPtr base4, IntPtr base5, IntPtr base6, IntPtr base7); + [DllImport(efl.Libs.Eo)] public static extern byte efl_class_functions_set(IntPtr klass_id, IntPtr object_ops, IntPtr class_ops); + [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_data_scope_get(IntPtr obj, IntPtr klass); + [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_super(IntPtr obj, IntPtr klass); + [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_class_get(IntPtr obj); +#if WIN32 + public static IntPtr RTLD_DEFAULT = new IntPtr(1); +#else + public static IntPtr RTLD_DEFAULT = new IntPtr(0); +#endif + [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror(); + [DllImport(efl.Libs.Evil)] public static extern IntPtr dlsym + (IntPtr handle, [MarshalAs(UnmanagedType.LPStr)] String name); + + [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_priority_add( + System.IntPtr obj, + // FIXME commented to allow passing null stuff during test + /* ref efl.kw_event.Description desc, */ + efl.kw_event.Description desc, + short priority, + efl.Event_Cb cb, + System.IntPtr data); + [DllImport(efl.Libs.Eo)] public static extern bool efl_event_callback_del( + System.IntPtr obj, + efl.kw_event.Description desc, + efl.Event_Cb cb, + System.IntPtr data); + + + public const int RTLD_NOW = 2; + + public delegate byte class_initializer(IntPtr klass); + + public static IntPtr register_class(class_initializer initializer, IntPtr base_klass) + { + ClassDescription description; + description.version = 2; // EO_VERSION + description.name = "BoxInherit"; + description.class_type = 0; // REGULAR + description.data_size = (UIntPtr)8; + description.class_initializer = IntPtr.Zero; + description.class_constructor = IntPtr.Zero; + description.class_destructor = IntPtr.Zero; + + if(initializer != null) + description.class_initializer = Marshal.GetFunctionPointerForDelegate(initializer); + + IntPtr description_ptr = eina.MemoryNative.Alloc(Marshal.SizeOf(description)); + Marshal.StructureToPtr(description, description_ptr, false); + + eina.Log.Debug("Going to register!"); + IntPtr klass = efl.eo.Globals.efl_class_new(description_ptr, base_klass, IntPtr.Zero); + if(klass == IntPtr.Zero) + eina.Log.Error("klass was not registered"); + eina.Log.Debug("Registered?"); + return klass; + } + public static IntPtr instantiate_start(IntPtr klass, efl.Object parent) + { + eina.Log.Debug("Instantiating"); + System.IntPtr parent_ptr = System.IntPtr.Zero; + if(parent != null) + parent_ptr = parent.raw_handle; + + System.IntPtr eo = efl.eo.Globals._efl_add_internal_start("file", 0, klass, parent_ptr, 0, 0); + return eo; + } + + public static IntPtr instantiate_end(IntPtr eo) { + eina.Log.Debug("efl_add_internal_start returned"); + eo = efl.eo.Globals._efl_add_end(eo, 0, 0); + eina.Log.Debug("efl_add_end returned"); + return eo; + } + public static void data_set(efl.eo.IWrapper obj) + { + IntPtr pd = efl.eo.Globals.efl_data_scope_get(obj.raw_handle, obj.raw_klass); + { + GCHandle gch = GCHandle.Alloc(obj); + EolianPD epd; + epd.pointer = GCHandle.ToIntPtr(gch); + Marshal.StructureToPtr(epd, pd, false); + } + } + public static efl.eo.IWrapper data_get(IntPtr pd) + { + EolianPD epd = (EolianPD)Marshal.PtrToStructure(pd, typeof(EolianPD)); + if(epd.pointer != IntPtr.Zero) + { + GCHandle gch = GCHandle.FromIntPtr(epd.pointer); + return (efl.eo.IWrapper)gch.Target; + } + else + return null; + } + + public static IntPtr cached_string_to_intptr(Dictionary dict, String str) + { + IntPtr ptr = IntPtr.Zero; + if (!dict.TryGetValue(str, out ptr)) + { + ptr = eina.StringConversion.ManagedStringToNativeUtf8Alloc(str); + dict[str] = ptr; + } + + return ptr; + } + + public static IntPtr cached_stringshare_to_intptr(Dictionary dict, String str) + { + IntPtr ptr = IntPtr.Zero; + if (!dict.TryGetValue(str, out ptr)) + { + ptr = eina.Stringshare.eina_stringshare_add(str); + dict[str] = ptr; + } + + return ptr; + } + + public static void free_dict_values(Dictionary dict) + { + foreach(IntPtr ptr in dict.Values) + { + eina.MemoryNative.Free(ptr); + } + } + + public static void free_stringshare_values(Dictionary dict) + { + foreach(IntPtr ptr in dict.Values) + { + eina.Stringshare.eina_stringshare_del(ptr); + } + } + + public static void free_gchandle(IntPtr ptr) + { + GCHandle handle = GCHandle.FromIntPtr(ptr); + handle.Free(); + } +} + +public static class Config +{ + public static void Init() + { + Globals.efl_object_init(); + } + + public static void Shutdown() + { + Globals.efl_object_shutdown(); + } +} + +public interface IWrapper +{ + IntPtr raw_handle + { + get; + } + IntPtr raw_klass + { + get; + } +} + +public interface IOwnershipTag +{ +} + +public class OwnTag : IOwnershipTag +{ +} + +public class NonOwnTag : IOwnershipTag +{ +} + +public class MarshalTest : ICustomMarshaler + where U : IOwnershipTag +{ + public static ICustomMarshaler GetInstance(string cookie) + { + eina.Log.Debug("MarshalTest.GetInstace cookie " + cookie); + return new MarshalTest(); + } + public void CleanUpManagedData(object ManagedObj) + { + //eina.Log.Warning("MarshalTest.CleanUpManagedData not implemented"); + //throw new NotImplementedException(); + } + + public void CleanUpNativeData(IntPtr pNativeData) + { + //eina.Log.Warning("MarshalTest.CleanUpNativeData not implemented"); + //throw new NotImplementedException(); + } + + public int GetNativeDataSize() + { + eina.Log.Debug("MarshalTest.GetNativeDataSize"); + return 0; + //return 8; + } + + public IntPtr MarshalManagedToNative(object ManagedObj) + { + eina.Log.Debug("MarshalTest.MarshallManagedToNative"); + var r = ((IWrapper)ManagedObj).raw_handle; + if (typeof(U) == typeof(OwnTag)) + efl.eo.Globals.efl_ref(r); + return r; + } + + public object MarshalNativeToManaged(IntPtr pNativeData) + { + eina.Log.Debug("MarshalTest.MarshalNativeToManaged"); + if (typeof(U) != typeof(OwnTag)) + efl.eo.Globals.efl_ref(pNativeData); + return Activator.CreateInstance(typeof(T), new System.Object[] {pNativeData}); +// return null; + } +} + +public class StringPassOwnershipMarshaler : ICustomMarshaler { + public object MarshalNativeToManaged(IntPtr pNativeData) { + var ret = eina.StringConversion.NativeUtf8ToManagedString(pNativeData); + eina.MemoryNative.Free(pNativeData); + return ret; + } + + public IntPtr MarshalManagedToNative(object managedObj) { + return eina.MemoryNative.StrDup((string)managedObj); + } + + public void CleanUpNativeData(IntPtr pNativeData) { + // No need to cleanup. C will take care of it. + } + + public void CleanUpManagedData(object managedObj) { + } + + public int GetNativeDataSize() { + return -1; + } + + public static ICustomMarshaler GetInstance(string cookie) { + if (marshaler == null) { + marshaler = new StringPassOwnershipMarshaler(); + } + return marshaler; + } + static private StringPassOwnershipMarshaler marshaler; +} + +public class StringKeepOwnershipMarshaler: ICustomMarshaler { + public object MarshalNativeToManaged(IntPtr pNativeData) { + return eina.StringConversion.NativeUtf8ToManagedString(pNativeData); + } + + public IntPtr MarshalManagedToNative(object managedObj) { + return eina.StringConversion.ManagedStringToNativeUtf8Alloc((string)managedObj); + } + + public void CleanUpNativeData(IntPtr pNativeData) { + // No need to free. The Native side will keep the ownership. + } + + public void CleanUpManagedData(object managedObj) { + } + + public int GetNativeDataSize() { + return -1; + } + + public static ICustomMarshaler GetInstance(string cookie) { + if (marshaler == null) { + marshaler = new StringKeepOwnershipMarshaler(); + } + return marshaler; + } + static private StringKeepOwnershipMarshaler marshaler; +} + +public class StringsharePassOwnershipMarshaler : ICustomMarshaler { + public object MarshalNativeToManaged(IntPtr pNativeData) { + var ret = eina.StringConversion.NativeUtf8ToManagedString(pNativeData); + eina.Stringshare.eina_stringshare_del(pNativeData); + return ret; + } + + public IntPtr MarshalManagedToNative(object managedObj) { + return eina.Stringshare.eina_stringshare_add((string)managedObj); + } + + public void CleanUpNativeData(IntPtr pNativeData) { + // No need to free as it's for own() parameters. + } + + public void CleanUpManagedData(object managedObj) { + } + + public int GetNativeDataSize() { + return -1; + } + + public static ICustomMarshaler GetInstance(string cookie) { + if (marshaler == null) { + marshaler = new StringsharePassOwnershipMarshaler(); + } + return marshaler; + } + static private StringsharePassOwnershipMarshaler marshaler; +} + +public class StringshareKeepOwnershipMarshaler : ICustomMarshaler { + public object MarshalNativeToManaged(IntPtr pNativeData) { + return eina.StringConversion.NativeUtf8ToManagedString(pNativeData); + } + + public IntPtr MarshalManagedToNative(object managedObj) { + return eina.Stringshare.eina_stringshare_add((string)managedObj); + } + + public void CleanUpNativeData(IntPtr pNativeData) { + // No need to free, as the native side will keep ownership. + } + + public void CleanUpManagedData(object managedObj) { + } + + public int GetNativeDataSize() { + return -1; + } + + public static ICustomMarshaler GetInstance(string cookie) { + if (marshaler == null) { + marshaler = new StringshareKeepOwnershipMarshaler(); + } + return marshaler; + } + static private StringshareKeepOwnershipMarshaler marshaler; +} + +} // namespace eo + +public class EflException : Exception +{ + public EflException(string message) : base(message) + { + } +} + +} // namespace efl diff --git a/src/bindings/mono/eo_mono/object.cs b/src/bindings/mono/eo_mono/object.cs new file mode 100644 index 0000000000..08e1e5f0ef --- /dev/null +++ b/src/bindings/mono/eo_mono/object.cs @@ -0,0 +1,10 @@ + +namespace efl { + +using System; + +// public interface Object : efl.eo.IWrapper +// { +// } + +} diff --git a/src/bindings/mono/eo_mono/workaround.cs b/src/bindings/mono/eo_mono/workaround.cs new file mode 100644 index 0000000000..7e338de8ef --- /dev/null +++ b/src/bindings/mono/eo_mono/workaround.cs @@ -0,0 +1,523 @@ + +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] +public struct ClassDescription +{ + public uint version; + [MarshalAs(UnmanagedType.LPStr)] public String name; + public int class_type; + public UIntPtr data_size; + public IntPtr class_initializer; + public IntPtr class_constructor; + public IntPtr class_destructor; +} + +[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] +public struct Efl_Op_Description +{ + public IntPtr api_func; + public IntPtr func; +} + +[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] +public struct Efl_Object_Ops +{ + public IntPtr descs; /**< The op descriptions array of size count. */ + public UIntPtr count; /**< Number of op descriptions. */ +}; + +[StructLayout(LayoutKind.Sequential)] +public struct EolianPD +{ + public IntPtr pointer; +} + +#pragma warning disable 0169 +public struct Evas_Object_Box_Layout +{ + IntPtr o; + IntPtr priv; + IntPtr user_data; +}; +[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] +public struct Evas_Object_Box_Data +{ +} +public delegate void Eina_Free_Cb(IntPtr data); +public struct Evas_Object_Box_Option { + IntPtr obj; + [MarshalAsAttribute(UnmanagedType.U1)] bool max_reached; + [MarshalAsAttribute(UnmanagedType.U1)] bool min_reached; + evas.Coord alloc_size; +}; +#pragma warning restore 0169 + +namespace efl { namespace kw_event { + +[StructLayout(LayoutKind.Sequential)] +public struct Description { + IntPtr pointer; // Opaque type, just pass the pointer. What about hot/freeze/etc? + + private static Dictionary descriptions = new Dictionary(); + + public Description(string name) + { + if (!descriptions.ContainsKey(name)) + { + IntPtr data = efl.eo.Globals.dlsym(efl.eo.Globals.RTLD_DEFAULT, name); + + if (data == IntPtr.Zero) { + string error = eina.StringConversion.NativeUtf8ToManagedString(efl.eo.Globals.dlerror()); + throw new Exception(error); + } + descriptions.Add(name, data); + } + + this.pointer = descriptions[name]; + } +}; + +} // namespace kw_event + + +public delegate void Event_Cb(System.IntPtr data, ref Event evt); +#pragma warning disable 0169 +public struct Callback_Array_Item { + IntPtr desc; + IntPtr func; +}; +public struct Dbg_Info { + IntPtr name; + IntPtr value; +}; +#pragma warning restore 0169 + +namespace text { + +namespace cursor { + +[StructLayout(LayoutKind.Sequential)] +public struct Cursor { + IntPtr obj; + UIntPtr pos; // UIntPtr to automatically change size_t between 32/64 + IntPtr node; + [MarshalAsAttribute(UnmanagedType.U1)]bool changed; +} + +} // namespace cursor + +namespace annotate { + +[StructLayout(LayoutKind.Sequential)] +public struct Annotation { + IntPtr list; + IntPtr obj; + IntPtr start_node; + IntPtr end_node; + [MarshalAsAttribute(UnmanagedType.U1)]bool is_item; +} + +} // namespace annotate + +} // namespace text + +public delegate void Signal_Cb(IntPtr data, IntPtr obj, IntPtr emission, IntPtr source); + + +namespace gfx { + +public interface Buffer {} + +namespace buffer { +public struct Access_Mode {} +} + +} // namespace gfx + +namespace access { + +public struct State_Set { + private ulong mask; + + public static implicit operator State_Set(ulong x) + { + return new State_Set{mask=x}; + } + public static implicit operator ulong(State_Set x) + { + return x.mask; + } +} + +public struct Relation_Set { + private IntPtr mask; + + public static implicit operator Relation_Set(IntPtr x) + { + return new Relation_Set{mask=x}; + } + public static implicit operator IntPtr(Relation_Set x) + { + return x.mask; + } +} + +public struct Action_Data { + public IntPtr name; + public IntPtr action; + public IntPtr param; + public IntPtr func; +} + +} // namespace access + +namespace font { + +public struct Size { + private int mask; + + public static implicit operator Size(int x) + { + return new Size{mask=x}; + } + public static implicit operator int(Size x) + { + return x.mask; + } +} + +} + +} // namespace efl + +namespace evas { namespace font { + +} + + +// C# does not allow typedefs, so we use these implicit conversions. +public struct Modifier_Mask { + private ulong mask; + + public static implicit operator Modifier_Mask(ulong x) + { + return new Modifier_Mask{mask=x}; + } + public static implicit operator ulong(Modifier_Mask x) + { + return x.mask; + } +} + +public struct Coord { + int val; + + public Coord(int value) { val = value; } + static public implicit operator Coord(int val) { + return new Coord(val); + } + static public implicit operator int(Coord coord) { + return coord.val; + } +} + + +} + +public struct Efl_Font_Size { + int val; + + public Efl_Font_Size(int value) { val = value; } + static public implicit operator Efl_Font_Size(int val) { + return new Efl_Font_Size(val); + } + static public implicit operator int(Efl_Font_Size coord) { + return coord.val; + } +} + +namespace eina { + +public struct Rectangle { + public int x; + public int y; + public int w; + public int h; +} + +} + +namespace eina { + +public interface File {} + +} + +namespace evas { + +/* Copied from Evas_Legacy.h */ +public enum Text_Style_Type +{ + Plain = 0, /**< plain, standard text */ + Shadow, /**< text with shadow underneath */ + Outline, /**< text with an outline */ + SoftOutline, /**< text with a soft outline */ + Glow, /**< text with a glow effect */ + OutlineShadow, /**< text with both outline and shadow effects */ + FarShadow, /**< text with (far) shadow underneath */ + OutlineSoftShadow, /**< text with outline and soft shadow effects combined */ + SoftShadow, /**< text with (soft) shadow underneath */ + FarSoftShadow, /**< text with (far soft) shadow underneath */ + + // Shadow direction modifiers + ShadowDirectionBottomRight = 0 /* 0 >> 4 */, /**< shadow growing to bottom right */ + ShadowDirectionBottom= 16 /* 1 >> 4 */, /**< shadow growing to the bottom */ + ShadowDirectionBottomLeft = 32 /* 2 >> 4 */, /**< shadow growing to bottom left */ + ShadowDirectionLeft = 48 /* 3 >> 4 */, /**< shadow growing to the left */ + ShadowDirectionTopLeft = 64 /* 4 >> 4 */, /**< shadow growing to top left */ + ShadowDirectionTop = 80 /* 5 >> 4 */, /**< shadow growing to the top */ + ShadowDirectionTopRight = 96 /* 6 >> 4 */, /**< shadow growing to top right */ + ShadowDirectionRight = 112 /* 7 >> 4 */ /**< shadow growing to the right */ +}; + + +// Copied from Evas_Common.h +// +// +// + +public enum Callback_Type +{ + EVAS_CALLBACK_MOUSE_IN = 0, /**< Mouse In Event */ + EVAS_CALLBACK_MOUSE_OUT, /**< Mouse Out Event */ + EVAS_CALLBACK_MOUSE_DOWN, /**< Mouse Button Down Event */ + EVAS_CALLBACK_MOUSE_UP, /**< Mouse Button Up Event */ + EVAS_CALLBACK_MOUSE_MOVE, /**< Mouse Move Event */ + EVAS_CALLBACK_MOUSE_WHEEL, /**< Mouse Wheel Event */ + EVAS_CALLBACK_MULTI_DOWN, /**< Multi-touch Down Event */ + EVAS_CALLBACK_MULTI_UP, /**< Multi-touch Up Event */ + EVAS_CALLBACK_MULTI_MOVE, /**< Multi-touch Move Event */ + EVAS_CALLBACK_FREE, /**< Object Being Freed (Called after Del) */ + EVAS_CALLBACK_KEY_DOWN, /**< Key Press Event */ + EVAS_CALLBACK_KEY_UP, /**< Key Release Event */ + EVAS_CALLBACK_FOCUS_IN, /**< Focus In Event */ + EVAS_CALLBACK_FOCUS_OUT, /**< Focus Out Event */ + EVAS_CALLBACK_SHOW, /**< Show Event */ + EVAS_CALLBACK_HIDE, /**< Hide Event */ + EVAS_CALLBACK_MOVE, /**< Move Event */ + EVAS_CALLBACK_RESIZE, /**< Resize Event */ + EVAS_CALLBACK_RESTACK, /**< Restack Event */ + EVAS_CALLBACK_DEL, /**< Object Being Deleted (called before Free) */ + EVAS_CALLBACK_HOLD, /**< Events go on/off hold */ + EVAS_CALLBACK_CHANGED_SIZE_HINTS, /**< Size hints changed event */ + EVAS_CALLBACK_IMAGE_PRELOADED, /**< Image has been preloaded */ + EVAS_CALLBACK_CANVAS_FOCUS_IN, /**< Canvas got focus as a whole */ + EVAS_CALLBACK_CANVAS_FOCUS_OUT, /**< Canvas lost focus as a whole */ + EVAS_CALLBACK_RENDER_FLUSH_PRE, /**< Called after render update regions have + * been calculated, but only if update regions exist */ + EVAS_CALLBACK_RENDER_FLUSH_POST, /**< Called after render update regions have + * been sent to the display server, but only + * if update regions existed for the most recent frame */ + EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN, /**< Canvas object got focus */ + EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_OUT, /**< Canvas object lost focus */ + EVAS_CALLBACK_IMAGE_UNLOADED, /**< Image data has been unloaded (by some mechanism in Evas that throw out original image data) */ + EVAS_CALLBACK_RENDER_PRE, /**< Called just before rendering starts on the canvas target. @since 1.2 */ + EVAS_CALLBACK_RENDER_POST, /**< Called just after rendering stops on the canvas target. @since 1.2 */ + EVAS_CALLBACK_IMAGE_RESIZE, /**< Image size is changed. @since 1.8 */ + EVAS_CALLBACK_DEVICE_CHANGED, /**< Devices added, removed or changed on canvas. @since 1.8 */ + EVAS_CALLBACK_AXIS_UPDATE, /**< Input device changed value on some axis. @since 1.13 */ + EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE, /**< Canvas viewport resized. @since 1.15 */ + EVAS_CALLBACK_LAST /**< Sentinel value to indicate last enum field during + * iteration */ +}; + +} + +namespace elm { + +namespace atspi { +public struct State_Set { + private ulong val; + + public static implicit operator State_Set(ulong x) + { + return new State_Set{val=x}; + } + public static implicit operator ulong(State_Set x) + { + return x.val; + } +} + +[StructLayout(LayoutKind.Sequential)] +public struct Relation_Set +{ + public IntPtr pointer; // list +} +} // namespace atspi + +namespace gengrid { namespace item { +[StructLayout(LayoutKind.Sequential)] +public struct Class +{ + int version; + uint refcount; + [MarshalAsAttribute(UnmanagedType.U1)]bool delete_me; + IntPtr item_style; + IntPtr decorate_item_style; + IntPtr decorate_all_item_style; + + // Delegates inside Elm_Gen_Item_Class_Functions + IntPtr text_get; + IntPtr content_get; + IntPtr state_get; + IntPtr del; + IntPtr filter_get; + IntPtr reusable_content_get; +} +} // namespace item +} // namespace gengrid + +namespace genlist { namespace item { +[StructLayout(LayoutKind.Sequential)] +public struct Class +{ + int version; + uint refcount; + [MarshalAsAttribute(UnmanagedType.U1)]bool delete_me; + IntPtr item_style; + IntPtr decorate_item_style; + IntPtr decorate_all_item_style; + + // Delegates inside Elm_Gen_Item_Class_Functions + IntPtr text_get; + IntPtr content_get; + IntPtr state_get; + IntPtr del; + IntPtr filter_get; + IntPtr reusable_content_get; +} +} // namespace item +} // namespace genlist + +} // namespace elm + +// Global delegates +public delegate IntPtr list_data_get_func_type(IntPtr l); +public delegate void region_hook_func_type(IntPtr data, IntPtr obj); +public delegate void slider_freefunc_type(IntPtr data); +public delegate void slider_func_type(double val); + +public delegate int Eina_Compare_Cb(IntPtr a, IntPtr b); +public delegate void Elm_Interface_Scrollable_Cb(IntPtr obj, IntPtr data); +public delegate void Elm_Interface_Scrollable_Min_Limit_Cb(IntPtr obj, + [MarshalAsAttribute(UnmanagedType.U1)]bool w, + [MarshalAsAttribute(UnmanagedType.U1)]bool h); +public delegate void Elm_Interface_Scrollable_Resize_Cb(IntPtr obj, evas.Coord w, evas.Coord h); +public delegate void Elm_Entry_Item_Provider_Cb(IntPtr data, IntPtr obj, IntPtr item); +public delegate void Elm_Entry_Filter_Cb(IntPtr data, IntPtr obj, IntPtr text); +[return: MarshalAsAttribute(UnmanagedType.U1)] +public delegate bool Elm_Multibuttonentry_Item_Filter_Cb(IntPtr obj, IntPtr item_label, IntPtr item_data, IntPtr data); +public delegate IntPtr Elm_Multibuttonentry_Format_Cb(int count, IntPtr data); +[return: MarshalAsAttribute(UnmanagedType.U1)] +public delegate bool Elm_Fileselector_Filter_Func(IntPtr path, [MarshalAsAttribute(UnmanagedType.U1)]bool dir, IntPtr data); +public delegate void Evas_Smart_Cb(IntPtr data, IntPtr obj, IntPtr event_info); +public delegate void Elm_Gesture_Event_Cb(IntPtr data, IntPtr event_info); +public delegate void Elm_Object_Item_Signal_Cb(IntPtr data, IntPtr item, IntPtr emission, IntPtr source); +public delegate void Elm_Tooltip_Item_Content_Cb(IntPtr data, IntPtr obj, IntPtr tooltip, IntPtr item); +public delegate void Elm_Sys_Notify_Send_Cb(IntPtr data, uint id); +public delegate IntPtr Elm_Calendar_Format_Cb(IntPtr format); + +namespace edje { + +public delegate void Signal_Cb(IntPtr data, IntPtr obj, IntPtr emission, IntPtr source); +public delegate void Markup_Filter_Cb(IntPtr data, IntPtr obj, IntPtr part, IntPtr text ); +public delegate void Item_Provider_Cb(IntPtr data, IntPtr obj, IntPtr part, IntPtr item); +// Message_Handler_Cb is now legacy + +namespace text { +public delegate void Filter_Cb(IntPtr data, IntPtr obj, IntPtr part, int _type, IntPtr text); +public delegate void Change_Cb(IntPtr data, IntPtr obj, IntPtr part); +} + + +} // namespace edje + +[StructLayout(LayoutKind.Sequential)] +public struct Elm_Code +{ + IntPtr file; + IntPtr widgets; + IntPtr parsers; + + // Below is inside _Elm_Code_Config + [MarshalAsAttribute(UnmanagedType.U1)]bool config; +} + +[StructLayout(LayoutKind.Sequential)] +public struct Elm_Code_Line +{ + IntPtr file; + IntPtr content; + uint length; + uint number; + IntPtr modified; + + Elm_Code_Status_Type status; + IntPtr tokens; + + IntPtr data; + IntPtr status_text; +} + +public enum Elm_Code_Status_Type { + ELM_CODE_STATUS_TYPE_DEFAULT = 0, + ELM_CODE_STATUS_TYPE_CURRENT, + ELM_CODE_STATUS_TYPE_IGNORED, + ELM_CODE_STATUS_TYPE_NOTE, + ELM_CODE_STATUS_TYPE_WARNING, + ELM_CODE_STATUS_TYPE_ERROR, + ELM_CODE_STATUS_TYPE_FATAL, + + ELM_CODE_STATUS_TYPE_ADDED, + ELM_CODE_STATUS_TYPE_REMOVED, + ELM_CODE_STATUS_TYPE_CHANGED, + + ELM_CODE_STATUS_TYPE_PASSED, + ELM_CODE_STATUS_TYPE_FAILED, + + ELM_CODE_STATUS_TYPE_TODO, + + ELM_CODE_STATUS_TYPE_COUNT +}; + + +[StructLayout(LayoutKind.Sequential)] +public struct Elm_Atspi_Action +{ + IntPtr name; + IntPtr action; + IntPtr param; + IntPtr func; +} + +// Some places stil use the non-namespaced Efl_Event_Cb +public delegate void Efl_Event_Cb(System.IntPtr data, ref efl.Event evt); + +[StructLayout(LayoutKind.Sequential)] +public struct Tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +} + +public delegate IntPtr Efl_Ui_Calendar_Format_Cb(Tm stime); // struct tm as argument