Signal.cs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace Avalonia.Gtk3.Interop
  8. {
  9. class Signal
  10. {
  11. class ConnectedSignal : IDisposable
  12. {
  13. private readonly GObject _instance;
  14. private GCHandle _handle;
  15. private readonly ulong _id;
  16. public ConnectedSignal(GObject instance, GCHandle handle, ulong id)
  17. {
  18. _instance = instance;
  19. Native.GObjectRef(instance);
  20. _handle = handle;
  21. _id = id;
  22. }
  23. public void Dispose()
  24. {
  25. if (_handle.IsAllocated)
  26. {
  27. Native.GObjectUnref(_instance.DangerousGetHandle());
  28. Native.GSignalHandlerDisconnect(_instance, _id);
  29. _handle.Free();
  30. }
  31. }
  32. }
  33. public static IDisposable Connect<T>(GObject obj, string name, T handler)
  34. {
  35. var handle = GCHandle.Alloc(handler);
  36. var ptr = Marshal.GetFunctionPointerForDelegate((Delegate)(object)handler);
  37. using (var utf = new Utf8Buffer(name))
  38. {
  39. var id = Native.GSignalConnectObject(obj, utf, ptr, IntPtr.Zero, 0);
  40. if (id == 0)
  41. throw new ArgumentException("Unable to connect to signal " + name);
  42. return new ConnectedSignal(obj, handle, id);
  43. }
  44. }
  45. }
  46. }