using System; using System.Runtime.InteropServices; namespace Avalonia.LinuxFramebuffer.Input.LibInput { unsafe class LibInputNativeUnsafeMethods { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate int OpenRestrictedCallbackDelegate(IntPtr path, int flags, IntPtr userData); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void CloseRestrictedCallbackDelegate(int fd, IntPtr userData); static int OpenRestricted(IntPtr path, int flags, IntPtr userData) { var fd = NativeUnsafeMethods.open(Marshal.PtrToStringAnsi(path), flags, 0); if (fd == -1) return -Marshal.GetLastWin32Error(); return fd; } static void CloseRestricted(int fd, IntPtr userData) { NativeUnsafeMethods.close(fd); } private static readonly IntPtr* s_Interface; static LibInputNativeUnsafeMethods() { s_Interface = (IntPtr*)Marshal.AllocHGlobal(IntPtr.Size * 2); IntPtr Convert(TDelegate del) { GCHandle.Alloc(del); return Marshal.GetFunctionPointerForDelegate(del); } s_Interface[0] = Convert(OpenRestricted); s_Interface[1] = Convert(CloseRestricted); } private const string LibInput = "libinput.so.10"; [DllImport(LibInput)] public extern static IntPtr libinput_path_create_context(IntPtr* iface, IntPtr userData); public static IntPtr libinput_path_create_context() => libinput_path_create_context(s_Interface, IntPtr.Zero); [DllImport(LibInput)] public extern static IntPtr libinput_path_add_device(IntPtr ctx, [MarshalAs(UnmanagedType.LPStr)] string path); [DllImport(LibInput)] public extern static IntPtr libinput_path_remove_device(IntPtr device); [DllImport(LibInput)] public extern static int libinput_get_fd(IntPtr ctx); [DllImport(LibInput)] public extern static void libinput_dispatch(IntPtr ctx); [DllImport(LibInput)] public extern static IntPtr libinput_get_event(IntPtr ctx); [DllImport(LibInput)] public extern static LibInputEventType libinput_event_get_type(IntPtr ev); public enum LibInputEventType { LIBINPUT_EVENT_NONE = 0, LIBINPUT_EVENT_DEVICE_ADDED, LIBINPUT_EVENT_DEVICE_REMOVED, LIBINPUT_EVENT_KEYBOARD_KEY = 300, LIBINPUT_EVENT_POINTER_MOTION = 400, LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE, LIBINPUT_EVENT_POINTER_BUTTON, LIBINPUT_EVENT_POINTER_AXIS, LIBINPUT_EVENT_TOUCH_DOWN = 500, LIBINPUT_EVENT_TOUCH_UP, LIBINPUT_EVENT_TOUCH_MOTION, LIBINPUT_EVENT_TOUCH_CANCEL, LIBINPUT_EVENT_TOUCH_FRAME, LIBINPUT_EVENT_TABLET_TOOL_AXIS = 600, LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY, LIBINPUT_EVENT_TABLET_TOOL_TIP, LIBINPUT_EVENT_TABLET_TOOL_BUTTON, LIBINPUT_EVENT_TABLET_PAD_BUTTON = 700, LIBINPUT_EVENT_TABLET_PAD_RING, LIBINPUT_EVENT_TABLET_PAD_STRIP, LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN = 800, LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE, LIBINPUT_EVENT_GESTURE_SWIPE_END, LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, LIBINPUT_EVENT_GESTURE_PINCH_END, LIBINPUT_EVENT_SWITCH_TOGGLE = 900, } [DllImport(LibInput)] public extern static void libinput_event_destroy(IntPtr ev); [DllImport(LibInput)] public extern static IntPtr libinput_event_get_touch_event(IntPtr ev); [DllImport(LibInput)] public extern static int libinput_event_touch_get_slot(IntPtr ev); [DllImport(LibInput)] public extern static ulong libinput_event_touch_get_time_usec(IntPtr ev); [DllImport(LibInput)] public extern static double libinput_event_touch_get_x_transformed(IntPtr ev, int width); [DllImport(LibInput)] public extern static double libinput_event_touch_get_y_transformed(IntPtr ev, int height); [DllImport(LibInput)] public extern static IntPtr libinput_event_get_pointer_event(IntPtr ev); [DllImport(LibInput)] public extern static ulong libinput_event_pointer_get_time_usec(IntPtr ev); [DllImport(LibInput)] public extern static double libinput_event_pointer_get_absolute_x_transformed(IntPtr ev, int width); [DllImport(LibInput)] public extern static double libinput_event_pointer_get_absolute_y_transformed(IntPtr ev, int height); [DllImport(LibInput)] public extern static int libinput_event_pointer_get_button(IntPtr ev); [DllImport(LibInput)] public extern static int libinput_event_pointer_get_button_state(IntPtr ev); } }