From 785d7c645e7104b456bd0a9453ba6c4de9d16393 Mon Sep 17 00:00:00 2001 From: Dillon Nys Date: Wed, 6 Mar 2024 15:53:04 -0800 Subject: [PATCH] Add Linux bindings --- packages/celest_core/ffigen.glib.yaml | 16 +- packages/celest_core/ffigen.libsecret.yaml | 7 +- .../lib/src/native/linux/glib.ffi.dart | 169 +++++++++++++++ .../lib/src/native/linux/libsecret.ffi.dart | 194 ++++++++++++++++++ packages/celest_core/tool/ffigen.sh | 12 +- 5 files changed, 380 insertions(+), 18 deletions(-) create mode 100644 packages/celest_core/lib/src/native/linux/glib.ffi.dart create mode 100644 packages/celest_core/lib/src/native/linux/libsecret.ffi.dart diff --git a/packages/celest_core/ffigen.glib.yaml b/packages/celest_core/ffigen.glib.yaml index d9440768..308d2f37 100644 --- a/packages/celest_core/ffigen.glib.yaml +++ b/packages/celest_core/ffigen.glib.yaml @@ -5,14 +5,11 @@ description: | Regenerate bindings with `dart run ffigen --config=ffigen.glib.yaml`. language: c output: lib/src/native/linux/glib.ffi.dart -compiler-opts: - - -I./third_party/glib/ - - -I./third_party/glib/glib/ headers: entry-points: - - third_party/glib/glib/glib.h - - third_party/glib/glib/glib-object.h - - third_party/glib/gio/gio.h + - /usr/include/glib-2.0/glib.h + - /usr/include/glib-2.0/glib-object.h + - /usr/include/glib-2.0/gio/gio.h preamble: | // ignore_for_file: type=lint // ignore_for_file: return_of_invalid_type @@ -22,6 +19,11 @@ comments: length: full exclude-all-by-default: true +typedefs: + include: + - gboolean + - gint + - gpointer functions: include: - g_hash_table_new @@ -30,9 +32,11 @@ functions: structs: include: - _GError + - _GHashTable - _GCancellable - _GObject rename: "_GError": GError + "_GHashTable": GHashTable "_GCancellable": GCancellable "_GObject": GObject diff --git a/packages/celest_core/ffigen.libsecret.yaml b/packages/celest_core/ffigen.libsecret.yaml index a26a60cb..d3ebea78 100644 --- a/packages/celest_core/ffigen.libsecret.yaml +++ b/packages/celest_core/ffigen.libsecret.yaml @@ -5,14 +5,9 @@ description: | Regenerate bindings with `dart run ffigen --config=ffigen.libsecret.yaml`. language: c output: lib/src/native/linux/libsecret.ffi.dart -compiler-opts: - - -I./third_party/glib/ - - -I./third_party/glib/glib/ headers: entry-points: - - third_party/libsecret/libsecret/secret.h - - third_party/libsecret/libsecret/secret-schema.h - - third_party/libsecret/libsecret/secret-password.h + - /usr/include/libsecret-1/libsecret/secret.h preamble: | // ignore_for_file: type=lint // ignore_for_file: return_of_invalid_type diff --git a/packages/celest_core/lib/src/native/linux/glib.ffi.dart b/packages/celest_core/lib/src/native/linux/glib.ffi.dart new file mode 100644 index 00000000..f7a39af7 --- /dev/null +++ b/packages/celest_core/lib/src/native/linux/glib.ffi.dart @@ -0,0 +1,169 @@ +// ignore_for_file: type=lint +// ignore_for_file: return_of_invalid_type +// ignore_for_file: unnecessary_non_null_assertion + +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +import 'dart:ffi' as ffi; + +/// Bindings for glib on Linux. +/// +/// Regenerate bindings with `dart run ffigen --config=ffigen.glib.yaml`. +/// +class Glib { + /// Holds the symbol lookup function. + final ffi.Pointer Function(String symbolName) + _lookup; + + /// The symbols are looked up in [dynamicLibrary]. + Glib(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup; + + /// The symbols are looked up with [lookup]. + Glib.fromLookup( + ffi.Pointer Function(String symbolName) + lookup) + : _lookup = lookup; + + ffi.Pointer g_hash_table_new( + ffi.Pointer< + ffi.NativeFunction)>> + hash_func, + ffi.Pointer< + ffi.NativeFunction< + gboolean Function( + ffi.Pointer, ffi.Pointer)>> + key_equal_func, + ) { + return _g_hash_table_new( + hash_func, + key_equal_func, + ); + } + + late final _g_hash_table_newPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer< + ffi.NativeFunction< + ffi.UnsignedInt Function(ffi.Pointer)>>, + ffi.Pointer< + ffi.NativeFunction< + gboolean Function(ffi.Pointer, + ffi.Pointer)>>)>>('g_hash_table_new'); + late final _g_hash_table_new = _g_hash_table_newPtr.asFunction< + ffi.Pointer Function( + ffi.Pointer< + ffi + .NativeFunction)>>, + ffi.Pointer< + ffi.NativeFunction< + gboolean Function( + ffi.Pointer, ffi.Pointer)>>)>(); + + void g_hash_table_destroy( + ffi.Pointer hash_table, + ) { + return _g_hash_table_destroy( + hash_table, + ); + } + + late final _g_hash_table_destroyPtr = + _lookup)>>( + 'g_hash_table_destroy'); + late final _g_hash_table_destroy = _g_hash_table_destroyPtr + .asFunction)>(); + + int g_hash_table_insert( + ffi.Pointer hash_table, + gpointer key, + gpointer value, + ) { + return _g_hash_table_insert( + hash_table, + key, + value, + ); + } + + late final _g_hash_table_insertPtr = _lookup< + ffi.NativeFunction< + gboolean Function(ffi.Pointer, gpointer, + gpointer)>>('g_hash_table_insert'); + late final _g_hash_table_insert = _g_hash_table_insertPtr + .asFunction, gpointer, gpointer)>(); +} + +final class GError extends ffi.Struct { + @ffi.UnsignedInt() + external int domain; + + @gint() + external int code; + + external ffi.Pointer message; +} + +typedef gint = ffi.Int; +typedef Dartgint = int; + +final class GHashTable extends ffi.Opaque {} + +typedef gboolean = gint; +typedef gpointer = ffi.Pointer; + +/// GObject: +/// +/// The base object type. +/// +/// All the fields in the `GObject` structure are private to the implementation +/// and should never be accessed directly. +/// +/// Since GLib 2.72, all #GObjects are guaranteed to be aligned to at least the +/// alignment of the largest basic GLib type (typically this is #guint64 or +/// #gdouble). If you need larger alignment for an element in a #GObject, you +/// should allocate it on the heap (aligned), or arrange for your #GObject to be +/// appropriately padded. This guarantee applies to the #GObject (or derived) +/// struct, the #GObjectClass (or derived) struct, and any private data allocated +/// by G_ADD_PRIVATE(). +final class GObject extends ffi.Struct { + external _GTypeInstance g_type_instance; + + /// (atomic) + @ffi.UnsignedInt() + external int ref_count; + + external ffi.Pointer<_GData> qdata; +} + +/// GTypeInstance: +/// +/// An opaque structure used as the base of all type instances. +final class _GTypeInstance extends ffi.Struct { + /// < private > + external ffi.Pointer<_GTypeClass> g_class; +} + +/// Basic Type Structures +/// / +/// /** +/// GTypeClass: +/// +/// An opaque structure used as the base of all classes. +final class _GTypeClass extends ffi.Struct { + /// < private > + @ffi.UnsignedLong() + external int g_type; +} + +final class _GData extends ffi.Opaque {} + +final class GCancellable extends ffi.Struct { + external GObject parent_instance; + + /// < private > + external ffi.Pointer<_GCancellablePrivate> priv; +} + +final class _GCancellablePrivate extends ffi.Opaque {} diff --git a/packages/celest_core/lib/src/native/linux/libsecret.ffi.dart b/packages/celest_core/lib/src/native/linux/libsecret.ffi.dart new file mode 100644 index 00000000..a585cb67 --- /dev/null +++ b/packages/celest_core/lib/src/native/linux/libsecret.ffi.dart @@ -0,0 +1,194 @@ +// ignore_for_file: type=lint +// ignore_for_file: return_of_invalid_type +// ignore_for_file: unnecessary_non_null_assertion + +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +import 'dart:ffi' as ffi; +import 'package:celest_core/src/native/linux/glib.ffi.dart' as glib; +import 'package:ffi/ffi.dart' as pkg_ffi; + +/// Bindings for Libsecret on Linux. +/// +/// Regenerate bindings with `dart run ffigen --config=ffigen.libsecret.yaml`. +/// +class Libsecret { + /// Holds the symbol lookup function. + final ffi.Pointer Function(String symbolName) + _lookup; + + /// The symbols are looked up in [dynamicLibrary]. + Libsecret(ffi.DynamicLibrary dynamicLibrary) + : _lookup = dynamicLibrary.lookup; + + /// The symbols are looked up with [lookup]. + Libsecret.fromLookup( + ffi.Pointer Function(String symbolName) + lookup) + : _lookup = lookup; + + int secret_password_storev_sync( + ffi.Pointer schema, + ffi.Pointer attributes, + ffi.Pointer collection, + ffi.Pointer label, + ffi.Pointer password, + ffi.Pointer cancellable, + ffi.Pointer> error, + ) { + return _secret_password_storev_sync( + schema, + attributes, + collection, + label, + password, + cancellable, + error, + ); + } + + late final _secret_password_storev_syncPtr = _lookup< + ffi.NativeFunction< + glib.gboolean Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer>)>>( + 'secret_password_storev_sync'); + late final _secret_password_storev_sync = + _secret_password_storev_syncPtr.asFunction< + int Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer>)>(); + + ffi.Pointer secret_password_lookupv_sync( + ffi.Pointer schema, + ffi.Pointer attributes, + ffi.Pointer cancellable, + ffi.Pointer> error, + ) { + return _secret_password_lookupv_sync( + schema, + attributes, + cancellable, + error, + ); + } + + late final _secret_password_lookupv_syncPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer>)>>( + 'secret_password_lookupv_sync'); + late final _secret_password_lookupv_sync = + _secret_password_lookupv_syncPtr.asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer>)>(); + + int secret_password_clearv_sync( + ffi.Pointer schema, + ffi.Pointer attributes, + ffi.Pointer cancellable, + ffi.Pointer> error, + ) { + return _secret_password_clearv_sync( + schema, + attributes, + cancellable, + error, + ); + } + + late final _secret_password_clearv_syncPtr = _lookup< + ffi.NativeFunction< + glib.gboolean Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer>)>>( + 'secret_password_clearv_sync'); + late final _secret_password_clearv_sync = + _secret_password_clearv_syncPtr.asFunction< + int Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer>)>(); + + void secret_password_free( + ffi.Pointer password, + ) { + return _secret_password_free( + password, + ); + } + + late final _secret_password_freePtr = + _lookup)>>( + 'secret_password_free'); + late final _secret_password_free = _secret_password_freePtr + .asFunction)>(); +} + +abstract class SecretSchemaAttributeType { + static const int SECRET_SCHEMA_ATTRIBUTE_STRING = 0; + static const int SECRET_SCHEMA_ATTRIBUTE_INTEGER = 1; + static const int SECRET_SCHEMA_ATTRIBUTE_BOOLEAN = 2; +} + +final class SecretSchemaAttribute extends ffi.Struct { + external ffi.Pointer name; + + @ffi.Int32() + external int type; +} + +abstract class SecretSchemaFlags { + static const int SECRET_SCHEMA_NONE = 0; + static const int SECRET_SCHEMA_DONT_MATCH_NAME = 2; +} + +final class SecretSchema extends ffi.Struct { + external ffi.Pointer name; + + @ffi.Int32() + external int flags; + + @ffi.Array.multi([32]) + external ffi.Array attributes; + + /// + @glib.gint() + external int reserved; + + external glib.gpointer reserved1; + + external glib.gpointer reserved2; + + external glib.gpointer reserved3; + + external glib.gpointer reserved4; + + external glib.gpointer reserved5; + + external glib.gpointer reserved6; + + external glib.gpointer reserved7; +} + +const String SECRET_COLLECTION_DEFAULT = 'default'; diff --git a/packages/celest_core/tool/ffigen.sh b/packages/celest_core/tool/ffigen.sh index c3169fba..dee1ce1a 100755 --- a/packages/celest_core/tool/ffigen.sh +++ b/packages/celest_core/tool/ffigen.sh @@ -8,17 +8,17 @@ flutter pub get flutter build apk popd -echo "Checking out submodules..." -git submodule update --init - echo "Generating FFI bindings..." dart run ffigen --config=ffigen.core_foundation.yaml dart run ffigen --config=ffigen.security.yaml -if "$(uname)" == "Darwin"; then +if !command -v pkg-config >&/dev/null; then echo "Skipping Linux bindings." >&2 else - dart run ffigen --config=ffigen.glib.yaml - dart run ffigen --config=ffigen.libsecret.yaml + GLIB_OPTS=$(pkg-config --cflags-only-I glib-2.0) + dart run ffigen --config=ffigen.glib.yaml --compiler-opts="$GLIB_OPTS" + + LIBSECRET_OPTS=$(pkg-config --cflags-only-I libsecret-1) + dart run ffigen --config=ffigen.libsecret.yaml --compiler-opts="$LIBSECRET_OPTS" fi echo "Generating JNI bindings..."