From ae0063f941b3542e5df502f29f1f18f0d17243db Mon Sep 17 00:00:00 2001 From: sds100 Date: Mon, 3 Nov 2025 17:39:44 +0100 Subject: [PATCH 01/65] create BaseSystemBridge --- .../keymapper/sysbridge/service/SystemBridge.kt | 16 ++++++++++++++++ sysbridge/src/main/cpp/libevdev_jni.cpp | 12 ++++++------ .../{SystemBridge.kt => BaseSystemBridge.kt} | 10 +--------- 3 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/io/github/sds100/keymapper/sysbridge/service/SystemBridge.kt rename sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/{SystemBridge.kt => BaseSystemBridge.kt} (98%) diff --git a/app/src/main/java/io/github/sds100/keymapper/sysbridge/service/SystemBridge.kt b/app/src/main/java/io/github/sds100/keymapper/sysbridge/service/SystemBridge.kt new file mode 100644 index 0000000000..da2cc1854c --- /dev/null +++ b/app/src/main/java/io/github/sds100/keymapper/sysbridge/service/SystemBridge.kt @@ -0,0 +1,16 @@ +package io.github.sds100.keymapper.sysbridge.service + +import android.os.Looper + +class SystemBridge : BaseSystemBridge() { + + companion object { + @JvmStatic + fun main(args: Array) { + @Suppress("DEPRECATION") + Looper.prepareMainLooper() + SystemBridge() + Looper.loop() + } + } +} diff --git a/sysbridge/src/main/cpp/libevdev_jni.cpp b/sysbridge/src/main/cpp/libevdev_jni.cpp index 829d5df81a..276a3d10fd 100644 --- a/sysbridge/src/main/cpp/libevdev_jni.cpp +++ b/sysbridge/src/main/cpp/libevdev_jni.cpp @@ -58,7 +58,7 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) { extern "C" JNIEXPORT jboolean JNICALL -Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_grabEvdevDeviceNative(JNIEnv *env, +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_grabEvdevDeviceNative(JNIEnv *env, jobject thiz, jstring jDevicePath) { @@ -284,7 +284,7 @@ static int MAX_EPOLL_EVENTS = 100; extern "C" JNIEXPORT void JNICALL -Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_startEvdevEventLoop(JNIEnv *env, +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_startEvdevEventLoop(JNIEnv *env, jobject thiz, jobject jCallbackBinder) { std::unique_lock epollLock(epollMutex); @@ -469,7 +469,7 @@ Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_ungrabEvdevDevice extern "C" JNIEXPORT void JNICALL -Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_stopEvdevEventLoop(JNIEnv *env, +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_stopEvdevEventLoop(JNIEnv *env, jobject thiz) { if (commandEventFd == -1) { return; @@ -490,7 +490,7 @@ Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_stopEvdevEventLoo extern "C" JNIEXPORT jboolean JNICALL -Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_writeEvdevEventNative(JNIEnv *env, +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_writeEvdevEventNative(JNIEnv *env, jobject thiz, jstring jDevicePath, jint type, @@ -518,7 +518,7 @@ Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_writeEvdevEventNa } extern "C" JNIEXPORT jboolean JNICALL -Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_ungrabAllEvdevDevicesNative( +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_ungrabAllEvdevDevicesNative( JNIEnv *env, jobject thiz) { @@ -600,7 +600,7 @@ createEvdevDeviceHandle(JNIEnv *env, const char *path, const char *name, int bus extern "C" JNIEXPORT jobjectArray JNICALL -Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_getEvdevDevicesNative(JNIEnv *env, +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_getEvdevDevicesNative(JNIEnv *env, jobject thiz) { DIR *dir = opendir("/dev/input"); diff --git a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/SystemBridge.kt b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt similarity index 98% rename from sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/SystemBridge.kt rename to sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt index fdb9d4cc66..1245e10a9c 100644 --- a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/SystemBridge.kt +++ b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt @@ -52,7 +52,7 @@ import rikka.hidden.compat.UserManagerApis import rikka.hidden.compat.adapter.ProcessObserverAdapter @SuppressLint("LogNotTimber") -internal class SystemBridge : ISystemBridge.Stub() { +abstract class BaseSystemBridge : ISystemBridge.Stub() { external fun grabEvdevDeviceNative(devicePath: String): Boolean @@ -83,14 +83,6 @@ internal class SystemBridge : ISystemBridge.Stub() { private const val KEYMAPPER_CHECK_INTERVAL_MS = 60 * 1000L // 1 minute private const val DATA_ENABLED_REASON_USER: Int = 0 - @JvmStatic - fun main(args: Array) { - @Suppress("DEPRECATION") - Looper.prepareMainLooper() - SystemBridge() - Looper.loop() - } - private fun waitSystemService(name: String?) { var count = 0 From 9e7589d3ea781e218c3b152c1bada7c3fae5b5ff Mon Sep 17 00:00:00 2001 From: sds100 Date: Mon, 3 Nov 2025 18:26:49 +0100 Subject: [PATCH 02/65] create separate evdev module --- app/build.gradle.kts | 1 + app/proguard-rules.pro | 2 +- app/src/main/AndroidManifest.xml | 2 +- .../keymapper/base/input/InputEventHub.kt | 2 +- evdev/.gitignore | 4 + evdev/build.gradle.kts | 175 ++++++++++++++++++ evdev/consumer-rules.pro | 0 evdev/proguard-rules.pro | 21 +++ .../keymapper/evdev}/IEvdevCallback.aidl | 2 +- evdev/src/main/cpp/CMakeLists.txt | 91 +++++++++ .../src/main/cpp/android/ftl/algorithm.h | 0 .../src/main/cpp/android/ftl/cast.h | 0 .../src/main/cpp/android/ftl/concat.h | 0 .../cpp/android/ftl/details/array_traits.h | 0 .../src/main/cpp/android/ftl/details/cast.h | 0 .../src/main/cpp/android/ftl/details/concat.h | 0 .../main/cpp/android/ftl/details/function.h | 0 .../src/main/cpp/android/ftl/details/future.h | 0 .../src/main/cpp/android/ftl/details/hash.h | 0 .../src/main/cpp/android/ftl/details/match.h | 0 .../src/main/cpp/android/ftl/details/mixins.h | 0 .../main/cpp/android/ftl/details/optional.h | 0 .../cpp/android/ftl/details/type_traits.h | 0 .../src/main/cpp/android/ftl/enum.h | 0 .../src/main/cpp/android/ftl/expected.h | 0 .../src/main/cpp/android/ftl/fake_guard.h | 0 .../src/main/cpp/android/ftl/finalizer.h | 0 .../src/main/cpp/android/ftl/flags.h | 0 .../src/main/cpp/android/ftl/function.h | 0 .../src/main/cpp/android/ftl/future.h | 0 .../src/main/cpp/android/ftl/hash.h | 0 .../src/main/cpp/android/ftl/ignore.h | 0 .../main/cpp/android/ftl/initializer_list.h | 0 .../src/main/cpp/android/ftl/match.h | 0 .../src/main/cpp/android/ftl/mixins.h | 0 .../src/main/cpp/android/ftl/non_null.h | 0 .../src/main/cpp/android/ftl/optional.h | 0 .../src/main/cpp/android/ftl/shared_mutex.h | 0 .../src/main/cpp/android/ftl/small_map.h | 0 .../src/main/cpp/android/ftl/small_vector.h | 0 .../src/main/cpp/android/ftl/static_vector.h | 0 .../src/main/cpp/android/ftl/string.h | 0 .../src/main/cpp/android/ftl/unit.h | 0 .../src/main/cpp/android/input/Input.cpp | 0 .../src/main/cpp/android/input/Input.h | 0 .../main/cpp/android/input/InputDevice.cpp | 0 .../src/main/cpp/android/input/InputDevice.h | 0 .../cpp/android/input/InputEventLabels.cpp | 0 .../main/cpp/android/input/InputEventLabels.h | 0 .../main/cpp/android/input/KeyLayoutMap.cpp | 0 .../src/main/cpp/android/input/KeyLayoutMap.h | 0 .../src/main/cpp/android/libbase/errors.h | 0 .../src/main/cpp/android/libbase/expected.h | 0 .../src/main/cpp/android/libbase/result.cpp | 0 .../src/main/cpp/android/libbase/result.h | 0 .../main/cpp/android/libbase/stringprintf.cpp | 0 .../main/cpp/android/libbase/stringprintf.h | 0 .../src/main/cpp/android/liblog/log_main.h | 0 .../main/cpp/android/ui/LogicalDisplayId.h | 0 .../src/main/cpp/android/utils/Errors.h | 0 .../src/main/cpp/android/utils/FileMap.cpp | 0 .../src/main/cpp/android/utils/FileMap.h | 0 .../main/cpp/android/utils/SharedBuffer.cpp | 0 .../src/main/cpp/android/utils/SharedBuffer.h | 0 .../src/main/cpp/android/utils/String16.cpp | 0 .../src/main/cpp/android/utils/String16.h | 0 .../src/main/cpp/android/utils/String8.cpp | 0 .../src/main/cpp/android/utils/String8.h | 0 .../src/main/cpp/android/utils/Tokenizer.cpp | 0 .../src/main/cpp/android/utils/Tokenizer.h | 0 .../src/main/cpp/android/utils/TypeHelpers.h | 0 .../src/main/cpp/android/utils/Unicode.cpp | 0 .../src/main/cpp/android/utils/Unicode.h | 0 .../src/main/cpp/libevdev/Makefile.am | 0 .../src/main/cpp/libevdev/libevdev-int.h | 0 .../src/main/cpp/libevdev/libevdev-names.c | 0 .../main/cpp/libevdev/libevdev-uinput-int.h | 0 .../src/main/cpp/libevdev/libevdev-uinput.c | 0 .../src/main/cpp/libevdev/libevdev-uinput.h | 0 .../src/main/cpp/libevdev/libevdev-util.h | 0 .../src/main/cpp/libevdev/libevdev.c | 0 .../src/main/cpp/libevdev/libevdev.h | 0 .../src/main/cpp/libevdev/libevdev.sym | 0 .../src/main/cpp/libevdev/make-event-names.py | 0 .../src/main/cpp/libevdev_jni.cpp | 6 +- evdev/src/main/cpp/logging.h | 30 +++ settings.gradle.kts | 1 + sysbridge/NDK_VERSION | 1 - sysbridge/build.gradle.kts | 115 +----------- .../keymapper/evdev/IEvdevCallback.aidl | 7 + .../keymapper/sysbridge/ISystemBridge.aidl | 2 +- sysbridge/src/main/cpp/CMakeLists.txt | 66 +------ .../sysbridge/service/BaseSystemBridge.kt | 2 +- 93 files changed, 341 insertions(+), 189 deletions(-) create mode 100644 evdev/.gitignore create mode 100644 evdev/build.gradle.kts create mode 100644 evdev/consumer-rules.pro create mode 100644 evdev/proguard-rules.pro rename {sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge => evdev/src/main/aidl/io/github/sds100/keymapper/evdev}/IEvdevCallback.aidl (83%) create mode 100644 evdev/src/main/cpp/CMakeLists.txt rename {sysbridge => evdev}/src/main/cpp/android/ftl/algorithm.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/cast.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/concat.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/array_traits.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/cast.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/concat.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/function.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/future.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/hash.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/match.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/mixins.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/optional.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/details/type_traits.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/enum.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/expected.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/fake_guard.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/finalizer.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/flags.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/function.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/future.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/hash.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/ignore.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/initializer_list.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/match.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/mixins.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/non_null.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/optional.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/shared_mutex.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/small_map.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/small_vector.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/static_vector.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/string.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ftl/unit.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/Input.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/Input.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/InputDevice.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/InputDevice.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/InputEventLabels.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/InputEventLabels.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/KeyLayoutMap.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/input/KeyLayoutMap.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/libbase/errors.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/libbase/expected.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/libbase/result.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/libbase/result.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/libbase/stringprintf.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/libbase/stringprintf.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/liblog/log_main.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/ui/LogicalDisplayId.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/Errors.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/FileMap.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/FileMap.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/SharedBuffer.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/SharedBuffer.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/String16.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/String16.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/String8.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/String8.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/Tokenizer.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/Tokenizer.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/TypeHelpers.h (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/Unicode.cpp (100%) rename {sysbridge => evdev}/src/main/cpp/android/utils/Unicode.h (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/Makefile.am (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev-int.h (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev-names.c (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev-uinput-int.h (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev-uinput.c (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev-uinput.h (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev-util.h (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev.c (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev.h (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/libevdev.sym (100%) rename {sysbridge => evdev}/src/main/cpp/libevdev/make-event-names.py (100%) mode change 100755 => 100644 rename {sysbridge => evdev}/src/main/cpp/libevdev_jni.cpp (99%) create mode 100644 evdev/src/main/cpp/logging.h delete mode 100644 sysbridge/NDK_VERSION create mode 100644 sysbridge/src/main/aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.aidl diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2b0504c7a9..7d234f10e3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -152,6 +152,7 @@ dependencies { implementation(project(":data")) implementation(project(":sysbridge")) implementation(project(":system")) + implementation(project(":evdev")) compileOnly(project(":systemstubs")) coreLibraryDesugaring(libs.desugar.jdk.libs) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 032e987d4b..c9ac9e7d76 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -109,7 +109,7 @@ # Keep all AIDL interface classes and their methods -keep class io.github.sds100.keymapper.sysbridge.ISystemBridge** { *; } --keep class io.github.sds100.keymapper.sysbridge.IEvdevCallback** { *; } +-keep class io.github.sds100.keymapper.evdev.IEvdevCallback** { *; } -keep class io.github.sds100.keymapper.sysbridge.IShizukuStarterService** { *; } -keepclassmembers class io.github.sds100.keymapper.sysbridge.shizuku.ShizukuStarterService { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c4e87ba265..d74d55e0eb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ - + file.isDirectory } + ?: throw GradleException("No prebuilt toolchain directories found in $prebuiltDir") + + if (hostDirs.size != 1) { + throw GradleException( + "Expected exactly one prebuilt toolchain directory in $prebuiltDir, found ${hostDirs.size}", + ) + } + val toolchainDir = hostDirs[0].absolutePath + + val inputHeader = "$toolchainDir/sysroot/usr/include/linux/input.h" + val inputEventCodesHeader = "$toolchainDir/sysroot/usr/include/linux/input-event-codes.h" + val outputHeader = "$projectDir/src/main/cpp/libevdev/event-names.h" + val pythonScript = "$projectDir/src/main/cpp/libevdev/make-event-names.py" + + commandLine("python3", pythonScript, inputHeader, inputEventCodesHeader) + + standardOutput = File(outputHeader).outputStream() + + inputs.file(pythonScript) + inputs.file(inputHeader) + inputs.file(inputEventCodesHeader) + outputs.file(outputHeader) +} + +// Task to compile AIDL files for NDK. +// Taken from https://github.com/lakinduboteju/AndroidNdkBinderExamples +val compileAidlNdk by tasks.registering(Exec::class) { + group = "build" + description = "Compiles AIDL files in src/main/aidl to NDK C++ headers and sources." + + val aidlSrcDir = project.file("src/main/aidl") + // Find all .aidl files. Using fileTree ensures it's dynamic. + val aidlFiles = project.fileTree(aidlSrcDir) { + include("**/IEvdevCallback.aidl") + } + + inputs.files(aidlFiles) + .withPathSensitivity(PathSensitivity.RELATIVE) + .withPropertyName("aidlInputFiles") + + val cppOutDir = project.file("src/main/cpp/aidl") + val cppHeaderOutDir = project.file("src/main/cpp") + + outputs.dir(cppOutDir).withPropertyName("cppOutputDir") + outputs.dir(cppHeaderOutDir).withPropertyName("cppHeaderOutputDir") + + // Path to the aidl executable in the Android SDK + val aidlToolPath = + android.sdkDirectory.toPath() + .resolve("build-tools") + .resolve(android.buildToolsVersion) + .resolve("aidl") + .absolutePathString() + val importSearchPath = aidlSrcDir.absolutePath + + // Ensure output directories exist before trying to write to them + cppOutDir.mkdirs() + cppHeaderOutDir.mkdirs() + + if (aidlFiles.isEmpty) { + logger.info("No AIDL files found in $aidlSrcDir. Skipping compileAidlNdk task.") + return@registering // Exit doLast if no files to process + } + + for (aidlFile in aidlFiles) { + logger.lifecycle("Compiling AIDL file (NDK): ${aidlFile.path}") + + commandLine( + aidlToolPath, + "--lang=ndk", + "-o", cppOutDir.absolutePath, + "-h", cppHeaderOutDir.absolutePath, + "-I", importSearchPath, + aidlFile.absolutePath, + ) + } + + logger.lifecycle( + "AIDL NDK compilation finished. Check outputs in $cppOutDir and $cppHeaderOutDir", + ) +} diff --git a/evdev/consumer-rules.pro b/evdev/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/evdev/proguard-rules.pro b/evdev/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/evdev/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge/IEvdevCallback.aidl b/evdev/src/main/aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.aidl similarity index 83% rename from sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge/IEvdevCallback.aidl rename to evdev/src/main/aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.aidl index f6b4039a6d..a304c78dab 100644 --- a/sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge/IEvdevCallback.aidl +++ b/evdev/src/main/aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.aidl @@ -1,4 +1,4 @@ -package io.github.sds100.keymapper.sysbridge; +package io.github.sds100.keymapper.evdev; interface IEvdevCallback { oneway void onEvdevEventLoopStarted(); diff --git a/evdev/src/main/cpp/CMakeLists.txt b/evdev/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000..6fbc7bbdbb --- /dev/null +++ b/evdev/src/main/cpp/CMakeLists.txt @@ -0,0 +1,91 @@ +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html. +# For more examples on how to use CMake, see https://github.com/android/ndk-samples. + +# Sets the minimum CMake version required for this project. +cmake_minimum_required(VERSION 3.22.1) + +# Declares the project name. The project name can be accessed via ${ PROJECT_NAME}, +# Since this is the top level CMakeLists.txt, the project name is also accessible +# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level +# build script scope). +project("evdev") + +set(CMAKE_CXX_STANDARD 20) + +set(C_FLAGS "-Werror=format -fdata-sections -ffunction-sections -fno-exceptions -fno-rtti -fno-threadsafe-statics") +set(LINKER_FLAGS "-Wl,--hash-style=both") + +if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + message("Building Release...") + + set(C_FLAGS "${C_FLAGS} -O2 -fvisibility=hidden -fvisibility-inlines-hidden") + set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,-exclude-libs,ALL -Wl,--gc-sections") +else () + message("Building Debug...") + + add_definitions(-DDEBUG) +endif () + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_FLAGS}") + +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}") +set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}") + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. +# +# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define +# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME} +# is preferred for the same purpose. +# +# In order to load a library into your app from Java/Kotlin, you must call +# System.loadLibrary() and pass the name of the library defined here; +# for GameActivity/NativeActivity derived applications, the same library name must be +# used in the AndroidManifest.xml file. +add_library(evdev SHARED + # List C/C++ source files with relative paths to this CMakeLists.txt. + libevdev_jni.cpp + libevdev/libevdev.c + libevdev/libevdev-names.c + libevdev/libevdev-uinput.c + android/input/KeyLayoutMap.cpp + android/input/InputEventLabels.cpp + android/libbase/result.cpp + android/utils/Tokenizer.cpp + android/utils/String16.cpp + android/utils/String8.cpp + android/utils/SharedBuffer.cpp + android/utils/FileMap.cpp + android/utils/Unicode.cpp + android/input/InputDevice.cpp + android/input/Input.cpp + android/libbase/stringprintf.cpp + ${aidl_src_dir}/io/github/sds100/keymapper/evdev/IEvdevCallback.cpp) + +find_library( + binder_ndk-lib + binder_ndk +) + +# Specifies libraries CMake should link to your target library. You +# can link libraries from various origins, such as libraries defined in this +# build script, prebuilt third-party libraries, or Android system libraries. +target_link_libraries(evdev + # List libraries link to the target library + android + log + ${binder_ndk-lib}) + +# Add include directories for header files +target_include_directories(evdev PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/android + ${CMAKE_CURRENT_SOURCE_DIR}/android/input + ${CMAKE_CURRENT_SOURCE_DIR}/android/libbase + ${CMAKE_CURRENT_SOURCE_DIR}/android/utils + ${CMAKE_CURRENT_SOURCE_DIR}/libevdev) + diff --git a/sysbridge/src/main/cpp/android/ftl/algorithm.h b/evdev/src/main/cpp/android/ftl/algorithm.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/algorithm.h rename to evdev/src/main/cpp/android/ftl/algorithm.h diff --git a/sysbridge/src/main/cpp/android/ftl/cast.h b/evdev/src/main/cpp/android/ftl/cast.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/cast.h rename to evdev/src/main/cpp/android/ftl/cast.h diff --git a/sysbridge/src/main/cpp/android/ftl/concat.h b/evdev/src/main/cpp/android/ftl/concat.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/concat.h rename to evdev/src/main/cpp/android/ftl/concat.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/array_traits.h b/evdev/src/main/cpp/android/ftl/details/array_traits.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/array_traits.h rename to evdev/src/main/cpp/android/ftl/details/array_traits.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/cast.h b/evdev/src/main/cpp/android/ftl/details/cast.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/cast.h rename to evdev/src/main/cpp/android/ftl/details/cast.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/concat.h b/evdev/src/main/cpp/android/ftl/details/concat.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/concat.h rename to evdev/src/main/cpp/android/ftl/details/concat.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/function.h b/evdev/src/main/cpp/android/ftl/details/function.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/function.h rename to evdev/src/main/cpp/android/ftl/details/function.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/future.h b/evdev/src/main/cpp/android/ftl/details/future.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/future.h rename to evdev/src/main/cpp/android/ftl/details/future.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/hash.h b/evdev/src/main/cpp/android/ftl/details/hash.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/hash.h rename to evdev/src/main/cpp/android/ftl/details/hash.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/match.h b/evdev/src/main/cpp/android/ftl/details/match.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/match.h rename to evdev/src/main/cpp/android/ftl/details/match.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/mixins.h b/evdev/src/main/cpp/android/ftl/details/mixins.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/mixins.h rename to evdev/src/main/cpp/android/ftl/details/mixins.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/optional.h b/evdev/src/main/cpp/android/ftl/details/optional.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/optional.h rename to evdev/src/main/cpp/android/ftl/details/optional.h diff --git a/sysbridge/src/main/cpp/android/ftl/details/type_traits.h b/evdev/src/main/cpp/android/ftl/details/type_traits.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/details/type_traits.h rename to evdev/src/main/cpp/android/ftl/details/type_traits.h diff --git a/sysbridge/src/main/cpp/android/ftl/enum.h b/evdev/src/main/cpp/android/ftl/enum.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/enum.h rename to evdev/src/main/cpp/android/ftl/enum.h diff --git a/sysbridge/src/main/cpp/android/ftl/expected.h b/evdev/src/main/cpp/android/ftl/expected.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/expected.h rename to evdev/src/main/cpp/android/ftl/expected.h diff --git a/sysbridge/src/main/cpp/android/ftl/fake_guard.h b/evdev/src/main/cpp/android/ftl/fake_guard.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/fake_guard.h rename to evdev/src/main/cpp/android/ftl/fake_guard.h diff --git a/sysbridge/src/main/cpp/android/ftl/finalizer.h b/evdev/src/main/cpp/android/ftl/finalizer.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/finalizer.h rename to evdev/src/main/cpp/android/ftl/finalizer.h diff --git a/sysbridge/src/main/cpp/android/ftl/flags.h b/evdev/src/main/cpp/android/ftl/flags.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/flags.h rename to evdev/src/main/cpp/android/ftl/flags.h diff --git a/sysbridge/src/main/cpp/android/ftl/function.h b/evdev/src/main/cpp/android/ftl/function.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/function.h rename to evdev/src/main/cpp/android/ftl/function.h diff --git a/sysbridge/src/main/cpp/android/ftl/future.h b/evdev/src/main/cpp/android/ftl/future.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/future.h rename to evdev/src/main/cpp/android/ftl/future.h diff --git a/sysbridge/src/main/cpp/android/ftl/hash.h b/evdev/src/main/cpp/android/ftl/hash.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/hash.h rename to evdev/src/main/cpp/android/ftl/hash.h diff --git a/sysbridge/src/main/cpp/android/ftl/ignore.h b/evdev/src/main/cpp/android/ftl/ignore.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/ignore.h rename to evdev/src/main/cpp/android/ftl/ignore.h diff --git a/sysbridge/src/main/cpp/android/ftl/initializer_list.h b/evdev/src/main/cpp/android/ftl/initializer_list.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/initializer_list.h rename to evdev/src/main/cpp/android/ftl/initializer_list.h diff --git a/sysbridge/src/main/cpp/android/ftl/match.h b/evdev/src/main/cpp/android/ftl/match.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/match.h rename to evdev/src/main/cpp/android/ftl/match.h diff --git a/sysbridge/src/main/cpp/android/ftl/mixins.h b/evdev/src/main/cpp/android/ftl/mixins.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/mixins.h rename to evdev/src/main/cpp/android/ftl/mixins.h diff --git a/sysbridge/src/main/cpp/android/ftl/non_null.h b/evdev/src/main/cpp/android/ftl/non_null.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/non_null.h rename to evdev/src/main/cpp/android/ftl/non_null.h diff --git a/sysbridge/src/main/cpp/android/ftl/optional.h b/evdev/src/main/cpp/android/ftl/optional.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/optional.h rename to evdev/src/main/cpp/android/ftl/optional.h diff --git a/sysbridge/src/main/cpp/android/ftl/shared_mutex.h b/evdev/src/main/cpp/android/ftl/shared_mutex.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/shared_mutex.h rename to evdev/src/main/cpp/android/ftl/shared_mutex.h diff --git a/sysbridge/src/main/cpp/android/ftl/small_map.h b/evdev/src/main/cpp/android/ftl/small_map.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/small_map.h rename to evdev/src/main/cpp/android/ftl/small_map.h diff --git a/sysbridge/src/main/cpp/android/ftl/small_vector.h b/evdev/src/main/cpp/android/ftl/small_vector.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/small_vector.h rename to evdev/src/main/cpp/android/ftl/small_vector.h diff --git a/sysbridge/src/main/cpp/android/ftl/static_vector.h b/evdev/src/main/cpp/android/ftl/static_vector.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/static_vector.h rename to evdev/src/main/cpp/android/ftl/static_vector.h diff --git a/sysbridge/src/main/cpp/android/ftl/string.h b/evdev/src/main/cpp/android/ftl/string.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/string.h rename to evdev/src/main/cpp/android/ftl/string.h diff --git a/sysbridge/src/main/cpp/android/ftl/unit.h b/evdev/src/main/cpp/android/ftl/unit.h similarity index 100% rename from sysbridge/src/main/cpp/android/ftl/unit.h rename to evdev/src/main/cpp/android/ftl/unit.h diff --git a/sysbridge/src/main/cpp/android/input/Input.cpp b/evdev/src/main/cpp/android/input/Input.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/input/Input.cpp rename to evdev/src/main/cpp/android/input/Input.cpp diff --git a/sysbridge/src/main/cpp/android/input/Input.h b/evdev/src/main/cpp/android/input/Input.h similarity index 100% rename from sysbridge/src/main/cpp/android/input/Input.h rename to evdev/src/main/cpp/android/input/Input.h diff --git a/sysbridge/src/main/cpp/android/input/InputDevice.cpp b/evdev/src/main/cpp/android/input/InputDevice.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/input/InputDevice.cpp rename to evdev/src/main/cpp/android/input/InputDevice.cpp diff --git a/sysbridge/src/main/cpp/android/input/InputDevice.h b/evdev/src/main/cpp/android/input/InputDevice.h similarity index 100% rename from sysbridge/src/main/cpp/android/input/InputDevice.h rename to evdev/src/main/cpp/android/input/InputDevice.h diff --git a/sysbridge/src/main/cpp/android/input/InputEventLabels.cpp b/evdev/src/main/cpp/android/input/InputEventLabels.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/input/InputEventLabels.cpp rename to evdev/src/main/cpp/android/input/InputEventLabels.cpp diff --git a/sysbridge/src/main/cpp/android/input/InputEventLabels.h b/evdev/src/main/cpp/android/input/InputEventLabels.h similarity index 100% rename from sysbridge/src/main/cpp/android/input/InputEventLabels.h rename to evdev/src/main/cpp/android/input/InputEventLabels.h diff --git a/sysbridge/src/main/cpp/android/input/KeyLayoutMap.cpp b/evdev/src/main/cpp/android/input/KeyLayoutMap.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/input/KeyLayoutMap.cpp rename to evdev/src/main/cpp/android/input/KeyLayoutMap.cpp diff --git a/sysbridge/src/main/cpp/android/input/KeyLayoutMap.h b/evdev/src/main/cpp/android/input/KeyLayoutMap.h similarity index 100% rename from sysbridge/src/main/cpp/android/input/KeyLayoutMap.h rename to evdev/src/main/cpp/android/input/KeyLayoutMap.h diff --git a/sysbridge/src/main/cpp/android/libbase/errors.h b/evdev/src/main/cpp/android/libbase/errors.h similarity index 100% rename from sysbridge/src/main/cpp/android/libbase/errors.h rename to evdev/src/main/cpp/android/libbase/errors.h diff --git a/sysbridge/src/main/cpp/android/libbase/expected.h b/evdev/src/main/cpp/android/libbase/expected.h similarity index 100% rename from sysbridge/src/main/cpp/android/libbase/expected.h rename to evdev/src/main/cpp/android/libbase/expected.h diff --git a/sysbridge/src/main/cpp/android/libbase/result.cpp b/evdev/src/main/cpp/android/libbase/result.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/libbase/result.cpp rename to evdev/src/main/cpp/android/libbase/result.cpp diff --git a/sysbridge/src/main/cpp/android/libbase/result.h b/evdev/src/main/cpp/android/libbase/result.h similarity index 100% rename from sysbridge/src/main/cpp/android/libbase/result.h rename to evdev/src/main/cpp/android/libbase/result.h diff --git a/sysbridge/src/main/cpp/android/libbase/stringprintf.cpp b/evdev/src/main/cpp/android/libbase/stringprintf.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/libbase/stringprintf.cpp rename to evdev/src/main/cpp/android/libbase/stringprintf.cpp diff --git a/sysbridge/src/main/cpp/android/libbase/stringprintf.h b/evdev/src/main/cpp/android/libbase/stringprintf.h similarity index 100% rename from sysbridge/src/main/cpp/android/libbase/stringprintf.h rename to evdev/src/main/cpp/android/libbase/stringprintf.h diff --git a/sysbridge/src/main/cpp/android/liblog/log_main.h b/evdev/src/main/cpp/android/liblog/log_main.h similarity index 100% rename from sysbridge/src/main/cpp/android/liblog/log_main.h rename to evdev/src/main/cpp/android/liblog/log_main.h diff --git a/sysbridge/src/main/cpp/android/ui/LogicalDisplayId.h b/evdev/src/main/cpp/android/ui/LogicalDisplayId.h similarity index 100% rename from sysbridge/src/main/cpp/android/ui/LogicalDisplayId.h rename to evdev/src/main/cpp/android/ui/LogicalDisplayId.h diff --git a/sysbridge/src/main/cpp/android/utils/Errors.h b/evdev/src/main/cpp/android/utils/Errors.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/Errors.h rename to evdev/src/main/cpp/android/utils/Errors.h diff --git a/sysbridge/src/main/cpp/android/utils/FileMap.cpp b/evdev/src/main/cpp/android/utils/FileMap.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/utils/FileMap.cpp rename to evdev/src/main/cpp/android/utils/FileMap.cpp diff --git a/sysbridge/src/main/cpp/android/utils/FileMap.h b/evdev/src/main/cpp/android/utils/FileMap.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/FileMap.h rename to evdev/src/main/cpp/android/utils/FileMap.h diff --git a/sysbridge/src/main/cpp/android/utils/SharedBuffer.cpp b/evdev/src/main/cpp/android/utils/SharedBuffer.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/utils/SharedBuffer.cpp rename to evdev/src/main/cpp/android/utils/SharedBuffer.cpp diff --git a/sysbridge/src/main/cpp/android/utils/SharedBuffer.h b/evdev/src/main/cpp/android/utils/SharedBuffer.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/SharedBuffer.h rename to evdev/src/main/cpp/android/utils/SharedBuffer.h diff --git a/sysbridge/src/main/cpp/android/utils/String16.cpp b/evdev/src/main/cpp/android/utils/String16.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/utils/String16.cpp rename to evdev/src/main/cpp/android/utils/String16.cpp diff --git a/sysbridge/src/main/cpp/android/utils/String16.h b/evdev/src/main/cpp/android/utils/String16.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/String16.h rename to evdev/src/main/cpp/android/utils/String16.h diff --git a/sysbridge/src/main/cpp/android/utils/String8.cpp b/evdev/src/main/cpp/android/utils/String8.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/utils/String8.cpp rename to evdev/src/main/cpp/android/utils/String8.cpp diff --git a/sysbridge/src/main/cpp/android/utils/String8.h b/evdev/src/main/cpp/android/utils/String8.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/String8.h rename to evdev/src/main/cpp/android/utils/String8.h diff --git a/sysbridge/src/main/cpp/android/utils/Tokenizer.cpp b/evdev/src/main/cpp/android/utils/Tokenizer.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/utils/Tokenizer.cpp rename to evdev/src/main/cpp/android/utils/Tokenizer.cpp diff --git a/sysbridge/src/main/cpp/android/utils/Tokenizer.h b/evdev/src/main/cpp/android/utils/Tokenizer.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/Tokenizer.h rename to evdev/src/main/cpp/android/utils/Tokenizer.h diff --git a/sysbridge/src/main/cpp/android/utils/TypeHelpers.h b/evdev/src/main/cpp/android/utils/TypeHelpers.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/TypeHelpers.h rename to evdev/src/main/cpp/android/utils/TypeHelpers.h diff --git a/sysbridge/src/main/cpp/android/utils/Unicode.cpp b/evdev/src/main/cpp/android/utils/Unicode.cpp similarity index 100% rename from sysbridge/src/main/cpp/android/utils/Unicode.cpp rename to evdev/src/main/cpp/android/utils/Unicode.cpp diff --git a/sysbridge/src/main/cpp/android/utils/Unicode.h b/evdev/src/main/cpp/android/utils/Unicode.h similarity index 100% rename from sysbridge/src/main/cpp/android/utils/Unicode.h rename to evdev/src/main/cpp/android/utils/Unicode.h diff --git a/sysbridge/src/main/cpp/libevdev/Makefile.am b/evdev/src/main/cpp/libevdev/Makefile.am similarity index 100% rename from sysbridge/src/main/cpp/libevdev/Makefile.am rename to evdev/src/main/cpp/libevdev/Makefile.am diff --git a/sysbridge/src/main/cpp/libevdev/libevdev-int.h b/evdev/src/main/cpp/libevdev/libevdev-int.h similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev-int.h rename to evdev/src/main/cpp/libevdev/libevdev-int.h diff --git a/sysbridge/src/main/cpp/libevdev/libevdev-names.c b/evdev/src/main/cpp/libevdev/libevdev-names.c similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev-names.c rename to evdev/src/main/cpp/libevdev/libevdev-names.c diff --git a/sysbridge/src/main/cpp/libevdev/libevdev-uinput-int.h b/evdev/src/main/cpp/libevdev/libevdev-uinput-int.h similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev-uinput-int.h rename to evdev/src/main/cpp/libevdev/libevdev-uinput-int.h diff --git a/sysbridge/src/main/cpp/libevdev/libevdev-uinput.c b/evdev/src/main/cpp/libevdev/libevdev-uinput.c similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev-uinput.c rename to evdev/src/main/cpp/libevdev/libevdev-uinput.c diff --git a/sysbridge/src/main/cpp/libevdev/libevdev-uinput.h b/evdev/src/main/cpp/libevdev/libevdev-uinput.h similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev-uinput.h rename to evdev/src/main/cpp/libevdev/libevdev-uinput.h diff --git a/sysbridge/src/main/cpp/libevdev/libevdev-util.h b/evdev/src/main/cpp/libevdev/libevdev-util.h similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev-util.h rename to evdev/src/main/cpp/libevdev/libevdev-util.h diff --git a/sysbridge/src/main/cpp/libevdev/libevdev.c b/evdev/src/main/cpp/libevdev/libevdev.c similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev.c rename to evdev/src/main/cpp/libevdev/libevdev.c diff --git a/sysbridge/src/main/cpp/libevdev/libevdev.h b/evdev/src/main/cpp/libevdev/libevdev.h similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev.h rename to evdev/src/main/cpp/libevdev/libevdev.h diff --git a/sysbridge/src/main/cpp/libevdev/libevdev.sym b/evdev/src/main/cpp/libevdev/libevdev.sym similarity index 100% rename from sysbridge/src/main/cpp/libevdev/libevdev.sym rename to evdev/src/main/cpp/libevdev/libevdev.sym diff --git a/sysbridge/src/main/cpp/libevdev/make-event-names.py b/evdev/src/main/cpp/libevdev/make-event-names.py old mode 100755 new mode 100644 similarity index 100% rename from sysbridge/src/main/cpp/libevdev/make-event-names.py rename to evdev/src/main/cpp/libevdev/make-event-names.py diff --git a/sysbridge/src/main/cpp/libevdev_jni.cpp b/evdev/src/main/cpp/libevdev_jni.cpp similarity index 99% rename from sysbridge/src/main/cpp/libevdev_jni.cpp rename to evdev/src/main/cpp/libevdev_jni.cpp index 276a3d10fd..7aa338dd31 100644 --- a/sysbridge/src/main/cpp/libevdev_jni.cpp +++ b/evdev/src/main/cpp/libevdev_jni.cpp @@ -10,7 +10,7 @@ #include "android/input/KeyLayoutMap.h" #include "android/libbase/result.h" #include "android/input/InputDevice.h" -#include "aidl/io/github/sds100/keymapper/sysbridge/IEvdevCallback.h" +#include "aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.h" #include #include #include @@ -19,7 +19,7 @@ #include #include -using aidl::io::github::sds100::keymapper::sysbridge::IEvdevCallback; +using aidl::io::github::sds100::keymapper::evdev::IEvdevCallback; enum CommandType { STOP @@ -416,7 +416,7 @@ Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_startEvdevEve extern "C" JNIEXPORT jboolean JNICALL -Java_io_github_sds100_keymapper_sysbridge_service_SystemBridge_ungrabEvdevDeviceNative(JNIEnv *env, +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_ungrabEvdevDeviceNative(JNIEnv *env, jobject thiz, jstring jDevicePath) { const char *devicePath = env->GetStringUTFChars(jDevicePath, nullptr); diff --git a/evdev/src/main/cpp/logging.h b/evdev/src/main/cpp/logging.h new file mode 100644 index 0000000000..0bc5310dc8 --- /dev/null +++ b/evdev/src/main/cpp/logging.h @@ -0,0 +1,30 @@ +#ifndef _LOGGING_H +#define _LOGGING_H + +#include +#include "android/log.h" + +#ifndef LOG_TAG +#define LOG_TAG "KeyMapperSystemBridge" +#endif + +#ifndef NO_LOG +#ifndef NO_DEBUG_LOG +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#else +#define LOGD(...) +#endif +#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)) +#else +#define LOGD(...) +#define LOGV(...) +#define LOGI(...) +#define LOGW(...) +#define LOGE(...) +#define PLOGE(fmt, args...) +#endif +#endif // _LOGGING_H diff --git a/settings.gradle.kts b/settings.gradle.kts index f035ff415c..81636c377b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -31,3 +31,4 @@ include(":system") include(":common") include(":data") include(":sysbridge") +include(":evdev") diff --git a/sysbridge/NDK_VERSION b/sysbridge/NDK_VERSION deleted file mode 100644 index b48e72d6d9..0000000000 --- a/sysbridge/NDK_VERSION +++ /dev/null @@ -1 +0,0 @@ -27.2.12479018 \ No newline at end of file diff --git a/sysbridge/build.gradle.kts b/sysbridge/build.gradle.kts index c1bf2d10a2..911d9933c3 100644 --- a/sysbridge/build.gradle.kts +++ b/sysbridge/build.gradle.kts @@ -1,5 +1,3 @@ -import kotlin.io.path.absolutePathString - plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) @@ -13,15 +11,7 @@ android { namespace = "io.github.sds100.keymapper.sysbridge" compileSdk = libs.versions.compile.sdk.get().toInt() - // Read NDK version from NDK_VERSION file, with fallback to gradle.properties - // The NDK version is stored in a file so the same value can be used across multiple modules. - val ndkVersionFile = project.file("NDK_VERSION") - val ndkVersionFromFile = if (ndkVersionFile.exists()) { - ndkVersionFile.readText().trim() - } else { - null - } - ndkVersion = ndkVersionFromFile!! + ndkVersion = "27.2.12479018" defaultConfig { // Must be API 29 so that the binder-ndk library can be found. @@ -114,106 +104,3 @@ dependencies { implementation(libs.zhanghai.appiconloader) implementation(libs.rikka.rikkax.core) } - -tasks.named("preBuild") { - dependsOn(generateLibEvDevEventNames) - dependsOn(compileAidlNdk) -} - -// The list of event names needs to be parsed from the input.h file in the NDK. -// input.h can be found in the Android/sdk/ndk/27.0.12077973/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/linux/input.h -// folder on macOS. -val generateLibEvDevEventNames by tasks.registering(Exec::class) { - dependsOn(compileAidlNdk) - - group = "build" - description = "Generates event names header from input.h" - - val prebuiltDir = File(android.ndkDirectory, "toolchains/llvm/prebuilt") - - // The "darwin-x86_64" part of the path is different on each operating system but it seems like - // the SDK Manager only downloads the NDK specific to the local operating system. So, just - // go into the only directory that the "prebuilt" directory contains. - val hostDirs = prebuiltDir.listFiles { file -> file.isDirectory } - ?: throw GradleException("No prebuilt toolchain directories found in $prebuiltDir") - - if (hostDirs.size != 1) { - throw GradleException( - "Expected exactly one prebuilt toolchain directory in $prebuiltDir, found ${hostDirs.size}", - ) - } - val toolchainDir = hostDirs[0].absolutePath - - val inputHeader = "$toolchainDir/sysroot/usr/include/linux/input.h" - val inputEventCodesHeader = "$toolchainDir/sysroot/usr/include/linux/input-event-codes.h" - val outputHeader = "$projectDir/src/main/cpp/libevdev/event-names.h" - val pythonScript = "$projectDir/src/main/cpp/libevdev/make-event-names.py" - - commandLine("python3", pythonScript, inputHeader, inputEventCodesHeader) - - standardOutput = File(outputHeader).outputStream() - - inputs.file(pythonScript) - inputs.file(inputHeader) - inputs.file(inputEventCodesHeader) - outputs.file(outputHeader) -} - -// Task to compile AIDL files for NDK. -// Taken from https://github.com/lakinduboteju/AndroidNdkBinderExamples -val compileAidlNdk by tasks.registering(Exec::class) { - group = "build" - description = "Compiles AIDL files in src/main/aidl to NDK C++ headers and sources." - - val aidlSrcDir = project.file("src/main/aidl") - // Find all .aidl files. Using fileTree ensures it's dynamic. - val aidlFiles = project.fileTree(aidlSrcDir) { - include("**/IEvdevCallback.aidl") - include("**/InputDeviceIdentifier.aidl") - } - - inputs.files(aidlFiles) - .withPathSensitivity(PathSensitivity.RELATIVE) - .withPropertyName("aidlInputFiles") - - val cppOutDir = project.file("src/main/cpp/aidl") - val cppHeaderOutDir = project.file("src/main/cpp") - - outputs.dir(cppOutDir).withPropertyName("cppOutputDir") - outputs.dir(cppHeaderOutDir).withPropertyName("cppHeaderOutputDir") - - // Path to the aidl executable in the Android SDK - val aidlToolPath = - android.sdkDirectory.toPath() - .resolve("build-tools") - .resolve(android.buildToolsVersion) - .resolve("aidl") - .absolutePathString() - val importSearchPath = aidlSrcDir.absolutePath - - // Ensure output directories exist before trying to write to them - cppOutDir.mkdirs() - cppHeaderOutDir.mkdirs() - - if (aidlFiles.isEmpty) { - logger.info("No AIDL files found in $aidlSrcDir. Skipping compileAidlNdk task.") - return@registering // Exit doLast if no files to process - } - - for (aidlFile in aidlFiles) { - logger.lifecycle("Compiling AIDL file (NDK): ${aidlFile.path}") - - commandLine( - aidlToolPath, - "--lang=ndk", - "-o", cppOutDir.absolutePath, - "-h", cppHeaderOutDir.absolutePath, - "-I", importSearchPath, - aidlFile.absolutePath, - ) - } - - logger.lifecycle( - "AIDL NDK compilation finished. Check outputs in $cppOutDir and $cppHeaderOutDir", - ) -} diff --git a/sysbridge/src/main/aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.aidl b/sysbridge/src/main/aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.aidl new file mode 100644 index 0000000000..a304c78dab --- /dev/null +++ b/sysbridge/src/main/aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.aidl @@ -0,0 +1,7 @@ +package io.github.sds100.keymapper.evdev; + +interface IEvdevCallback { + oneway void onEvdevEventLoopStarted(); + boolean onEvdevEvent(String devicePath, long timeSec, long timeUsec, int type, int code, int value, int androidCode); + void onEmergencyKillSystemBridge(); +} \ No newline at end of file diff --git a/sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge/ISystemBridge.aidl b/sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge/ISystemBridge.aidl index 602310a084..345eebc998 100644 --- a/sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge/ISystemBridge.aidl +++ b/sysbridge/src/main/aidl/io/github/sds100/keymapper/sysbridge/ISystemBridge.aidl @@ -1,6 +1,6 @@ package io.github.sds100.keymapper.sysbridge; -import io.github.sds100.keymapper.sysbridge.IEvdevCallback; +import io.github.sds100.keymapper.evdev.IEvdevCallback; import io.github.sds100.keymapper.common.models.EvdevDeviceHandle; import io.github.sds100.keymapper.common.models.ShellResult; import android.view.InputEvent; diff --git a/sysbridge/src/main/cpp/CMakeLists.txt b/sysbridge/src/main/cpp/CMakeLists.txt index 5781ee5879..b7eef6b73f 100644 --- a/sysbridge/src/main/cpp/CMakeLists.txt +++ b/sysbridge/src/main/cpp/CMakeLists.txt @@ -59,68 +59,4 @@ target_link_libraries(adb ${log-lib} boringssl::crypto_static) if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") add_custom_command(TARGET adb POST_BUILD COMMAND ${CMAKE_STRIP} --remove-section=.comment "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libadb.so") -endif () - -# Creates and names a library, sets it as either STATIC -# or SHARED, and provides the relative paths to its source code. -# You can define multiple libraries, and CMake builds them for you. -# Gradle automatically packages shared libraries with your APK. -# -# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define -# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME} -# is preferred for the same purpose. -# -# In order to load a library into your app from Java/Kotlin, you must call -# System.loadLibrary() and pass the name of the library defined here; -# for GameActivity/NativeActivity derived applications, the same library name must be -# used in the AndroidManifest.xml file. -add_library(evdev SHARED - # List C/C++ source files with relative paths to this CMakeLists.txt. - libevdev_jni.cpp - libevdev/libevdev.c - libevdev/libevdev-names.c - libevdev/libevdev-uinput.c - android/input/KeyLayoutMap.cpp - android/input/InputEventLabels.cpp - android/libbase/result.cpp - android/utils/Tokenizer.cpp - android/utils/String16.cpp - android/utils/String8.cpp - android/utils/SharedBuffer.cpp - android/utils/FileMap.cpp - android/utils/Unicode.cpp - android/input/InputDevice.cpp - android/input/Input.cpp - android/libbase/stringprintf.cpp - ${aidl_src_dir}/io/github/sds100/keymapper/sysbridge/IEvdevCallback.cpp) - -# Set a stable custom output directory for libevdev.so so it can be linked to in other modules -# Outputs to custom "libs" directory in the sysbridge module build directory -set_target_properties(evdev PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../../build/libs/${ANDROID_ABI}" - LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../../../build/libs/${ANDROID_ABI}" - LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../../../build/libs/${ANDROID_ABI}") - -find_library( - binder_ndk-lib - binder_ndk -) - -# Specifies libraries CMake should link to your target library. You -# can link libraries from various origins, such as libraries defined in this -# build script, prebuilt third-party libraries, or Android system libraries. -target_link_libraries(evdev - # List libraries link to the target library - android - log - ${binder_ndk-lib}) - -# Add include directories for header files -target_include_directories(evdev PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/android - ${CMAKE_CURRENT_SOURCE_DIR}/android/input - ${CMAKE_CURRENT_SOURCE_DIR}/android/libbase - ${CMAKE_CURRENT_SOURCE_DIR}/android/utils - ${CMAKE_CURRENT_SOURCE_DIR}/libevdev) - +endif () \ No newline at end of file diff --git a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt index 1245e10a9c..7ac59046f4 100644 --- a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt +++ b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt @@ -32,7 +32,7 @@ import com.android.internal.telephony.ITelephony import io.github.sds100.keymapper.common.models.EvdevDeviceHandle import io.github.sds100.keymapper.common.models.ShellResult import io.github.sds100.keymapper.common.utils.UserHandleUtils -import io.github.sds100.keymapper.sysbridge.IEvdevCallback +import io.github.sds100.keymapper.evdev.IEvdevCallback import io.github.sds100.keymapper.sysbridge.ISystemBridge import io.github.sds100.keymapper.sysbridge.provider.BinderContainer import io.github.sds100.keymapper.sysbridge.provider.SystemBridgeBinderProvider From 34f5a2d76e411c0706074012d04f2f9921e398a2 Mon Sep 17 00:00:00 2001 From: sds100 Date: Mon, 3 Nov 2025 23:49:13 +0100 Subject: [PATCH 03/65] setup Rust project for evdev_manager --- build.gradle.kts | 4 +- evdev/.gitignore | 3 +- evdev/.idea/.gitignore | 8 + evdev/.idea/gradle.xml | 11 + .../inspectionProfiles/Project_Default.xml | 6 + evdev/.idea/misc.xml | 14 + evdev/.idea/vcs.xml | 6 + evdev/build.gradle.kts | 40 ++- evdev/src/main/rust/evdev_manager/Cargo.lock | 272 ++++++++++++++++++ evdev/src/main/rust/evdev_manager/Cargo.toml | 14 + evdev/src/main/rust/evdev_manager/src/lib.rs | 57 ++++ gradle/libs.versions.toml | 3 + .../sysbridge/service/BaseSystemBridge.kt | 5 + 13 files changed, 435 insertions(+), 8 deletions(-) create mode 100644 evdev/.idea/.gitignore create mode 100644 evdev/.idea/gradle.xml create mode 100644 evdev/.idea/inspectionProfiles/Project_Default.xml create mode 100644 evdev/.idea/misc.xml create mode 100644 evdev/.idea/vcs.xml create mode 100644 evdev/src/main/rust/evdev_manager/Cargo.lock create mode 100644 evdev/src/main/rust/evdev_manager/Cargo.toml create mode 100644 evdev/src/main/rust/evdev_manager/src/lib.rs diff --git a/build.gradle.kts b/build.gradle.kts index 9e070cd106..78ed67584b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,9 @@ - // Top-level build file where you can add configuration options common to all sub-projects/modules. +// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false + // Must come before the others for the jnilibs folder to be automatically detected + alias(libs.plugins.mozilla.rust.android) apply false alias(libs.plugins.kotlin.compose) apply false alias(libs.plugins.kotlin.kapt) apply false alias(libs.plugins.kotlin.serialization) apply false diff --git a/evdev/.gitignore b/evdev/.gitignore index a20eae71c6..48b4c6e25e 100644 --- a/evdev/.gitignore +++ b/evdev/.gitignore @@ -1,4 +1,5 @@ /build .cxx /src/main/cpp/libevdev/event-names.h -/src/main/cpp/aidl/* \ No newline at end of file +/src/main/cpp/aidl/* +/src/main/rust/**/target/ diff --git a/evdev/.idea/.gitignore b/evdev/.idea/.gitignore new file mode 100644 index 0000000000..13566b81b0 --- /dev/null +++ b/evdev/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/evdev/.idea/gradle.xml b/evdev/.idea/gradle.xml new file mode 100644 index 0000000000..1b387c73e6 --- /dev/null +++ b/evdev/.idea/gradle.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/evdev/.idea/inspectionProfiles/Project_Default.xml b/evdev/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000..c5e1cad975 --- /dev/null +++ b/evdev/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/evdev/.idea/misc.xml b/evdev/.idea/misc.xml new file mode 100644 index 0000000000..e8e8dad566 --- /dev/null +++ b/evdev/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + \ No newline at end of file diff --git a/evdev/.idea/vcs.xml b/evdev/.idea/vcs.xml new file mode 100644 index 0000000000..6c0b863585 --- /dev/null +++ b/evdev/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/evdev/build.gradle.kts b/evdev/build.gradle.kts index ad38f3774f..eec0227ac1 100644 --- a/evdev/build.gradle.kts +++ b/evdev/build.gradle.kts @@ -2,6 +2,7 @@ import kotlin.io.path.absolutePathString plugins { alias(libs.plugins.android.library) + alias(libs.plugins.mozilla.rust.android) } android { @@ -52,8 +53,6 @@ android { buildFeatures { // Disable because a Java implementation of IEvdevCallback is not required in this module aidl = false - prefab = true - buildConfig = true } packaging { @@ -69,12 +68,24 @@ android { } } -dependencies { +cargo { + module = "src/main/rust/evdev_manager" + libname = "evdev_manager" + targets = listOf("arm", "arm64", "x86", "x86_64") + + // Can not do this with buildType configurations. + // See https://github.com/mozilla/rust-android-gradle/issues/38 + profile = + if (gradle.startParameter.taskNames + .any { it.lowercase().contains("debug") } + ) { + "debug" + } else { + "release" + } } -tasks.named("preBuild") { - dependsOn(generateLibEvDevEventNames) - dependsOn(compileAidlNdk) +dependencies { } // The list of event names needs to be parsed from the input.h file in the NDK. @@ -173,3 +184,20 @@ val compileAidlNdk by tasks.registering(Exec::class) { "AIDL NDK compilation finished. Check outputs in $cppOutDir and $cppHeaderOutDir", ) } + +tasks.named("preBuild") { + dependsOn(generateLibEvDevEventNames) + dependsOn(compileAidlNdk) +} + +// Must come after all tasks above, otherwise gradle syncing fails. +// +// Run cargo build when the files change. +// See https://github.com/mozilla/rust-android-gradle/issues/166 +tasks.whenTaskAdded { + if (name == "mergeDebugJniLibFolders" || name == "mergeReleaseJniLibFolders") { + outputs.upToDateWhen { false } + + dependsOn("cargoBuild") + } +} diff --git a/evdev/src/main/rust/evdev_manager/Cargo.lock b/evdev/src/main/rust/evdev_manager/Cargo.lock new file mode 100644 index 0000000000..4cef43c5a2 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/Cargo.lock @@ -0,0 +1,272 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "android_liblog-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf82c031178ca72b38595a54d16df8a257df9deea7d97a8992870e5c6a738e7" +dependencies = [ + "libc", +] + +[[package]] +name = "android_log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc00e0d3a060cce3fa338f9644ce9a93901c79f5405330891aeca69c9957009a" +dependencies = [ + "android_liblog-sys", + "log 0.3.9", +] + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "evdev_manager" +version = "0.1.0" +dependencies = [ + "android_log", + "jni", + "log 0.4.28", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log 0.4.28", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "log" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +dependencies = [ + "log 0.4.28", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "syn" +version = "2.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/evdev/src/main/rust/evdev_manager/Cargo.toml b/evdev/src/main/rust/evdev_manager/Cargo.toml new file mode 100644 index 0000000000..c450603f19 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "evdev_manager" +version = "0.1.0" +edition = "2021" + +[lib] +name = "evdev_manager" +# "cdylib" is necessary to produce a C-style dynamic library that can be loaded by Android's JNI. +crate-type = ["cdylib"] + +[dependencies] +jni = "0.21.1" +log = "0.4.28" +android_log = "0.1.3" \ No newline at end of file diff --git a/evdev/src/main/rust/evdev_manager/src/lib.rs b/evdev/src/main/rust/evdev_manager/src/lib.rs new file mode 100644 index 0000000000..f3c3dc3679 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/src/lib.rs @@ -0,0 +1,57 @@ +#[macro_use] +extern crate log; +extern crate android_log; + +use jni::objects::{JClass, JString}; +use jni::sys::jstring; +use jni::JNIEnv; + +#[no_mangle] +pub extern "system" fn Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_helloEvdevManager( + mut env: JNIEnv, + _class: JClass, + input: JString, +) -> jstring { + let input: String = env + .get_string(&input) + .expect("Couldn't get java string!") + .into(); + + let output = env + .new_string(format!("Hello from evdev Rust: {}", input)) + .expect("Couldn't create java string!"); + + // Initialize Android logger + android_log::init("KeyMapperSystemBridge").unwrap(); + + set_log_panic_hook(); + + info!("Hello from evdev Rust"); + + output.into_raw() +} + +fn set_log_panic_hook() { + std::panic::set_hook(Box::new(|panic_info| { + error!("PANIC in Rust code!"); + + if let Some(location) = panic_info.location() { + error!( + "Panic at {}:{}:{}", + location.file(), + location.line(), + location.column() + ); + } else { + error!("Panic at unknown location"); + } + + if let Some(payload) = panic_info.payload().downcast_ref::<&str>() { + error!("Panic message: {}", payload); + } else if let Some(payload) = panic_info.payload().downcast_ref::() { + error!("Panic message: {}", payload); + } else { + error!("Panic with unknown payload"); + } + })); +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 67a55b1535..c6670598b3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -79,6 +79,8 @@ ui-tooling = "1.8.1" # android.arch.persistence.room:testing libsu-core = "6.0.0" rikka-hidden = "4.4.0" +rust-android-gradle = "0.9.6" + [libraries] # Kotlin androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hilt-navigation-compose" } @@ -218,6 +220,7 @@ kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } android-library = { id = "com.android.library", version.ref = "android-gradle-plugin" } dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "dagger-hilt-android" } +mozilla-rust-android = { id = "org.mozilla.rust-android-gradle.rust-android", version.ref = "rust-android-gradle" } [bundles] splitties = [ diff --git a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt index 7ac59046f4..7d0be398d2 100644 --- a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt +++ b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt @@ -70,6 +70,8 @@ abstract class BaseSystemBridge : ISystemBridge.Stub() { external fun startEvdevEventLoop(callback: IBinder) external fun stopEvdevEventLoop() + external fun helloEvdevManager(input: String) + companion object { private const val TAG: String = "KeyMapperSystemBridge" private val systemBridgePackageName: String? by lazy { @@ -185,6 +187,9 @@ abstract class BaseSystemBridge : ISystemBridge.Stub() { val libraryPath = System.getProperty("keymapper_sysbridge.library.path") @SuppressLint("UnsafeDynamicallyLoadedCode") System.load("$libraryPath/libevdev.so") + System.load("$libraryPath/libevdev_manager.so") + + helloEvdevManager("test input") Log.i(TAG, "SystemBridge starting... Version code $versionCode") From d882b94c0ab8c546cf33a6fedf72afbd50f541e0 Mon Sep 17 00:00:00 2001 From: sds100 Date: Wed, 12 Nov 2025 12:09:14 +0100 Subject: [PATCH 04/65] #1897 create boilerplate code for Rust evdev manager --- evdev/build.gradle.kts | 30 +- evdev/src/main/cpp/CMakeLists.txt | 91 - evdev/src/main/rust/evdev_manager/Cargo.lock | 171 + evdev/src/main/rust/evdev_manager/Cargo.toml | 10 +- evdev/src/main/rust/evdev_manager/build.rs | 252 + .../src/main/rust/evdev_manager/rustfmt.toml | 4 + .../main/rust/evdev_manager/src/bindings.rs | 7629 +++++++++++++++++ .../src/main/rust/evdev_manager/src/enums.rs | 385 + .../src/main/rust/evdev_manager/src/evdev.rs | 416 + evdev/src/main/rust/evdev_manager/src/lib.rs | 4 + .../sysbridge/service/BaseSystemBridge.kt | 1 - 11 files changed, 8878 insertions(+), 115 deletions(-) delete mode 100644 evdev/src/main/cpp/CMakeLists.txt create mode 100644 evdev/src/main/rust/evdev_manager/build.rs create mode 100644 evdev/src/main/rust/evdev_manager/rustfmt.toml create mode 100644 evdev/src/main/rust/evdev_manager/src/bindings.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/enums.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/evdev.rs diff --git a/evdev/build.gradle.kts b/evdev/build.gradle.kts index eec0227ac1..11826a0fcf 100644 --- a/evdev/build.gradle.kts +++ b/evdev/build.gradle.kts @@ -17,21 +17,6 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") - - externalNativeBuild { - cmake { - val aidlSrcDir = project.file("src/main/cpp/aidl") - - // -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON is required to get the app running on the Android 15. This is related to the new 16kB page size support. - // -DANDROID_WEAK_API_DEFS=ON is required so the libevdev_jni file can run code depending on the SDK. https://developer.android.com/ndk/guides/using-newer-apis - arguments( - "-DANDROID_STL=c++_static", - "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", - "-DANDROID_WEAK_API_DEFS=ON", - "-Daidl_src_dir=${aidlSrcDir.absolutePath}", - ) - } - } } buildTypes { @@ -43,13 +28,6 @@ android { } } - externalNativeBuild { - cmake { - path("src/main/cpp/CMakeLists.txt") - version = "3.22.1" - } - } - buildFeatures { // Disable because a Java implementation of IEvdevCallback is not required in this module aidl = false @@ -190,6 +168,14 @@ tasks.named("preBuild") { dependsOn(compileAidlNdk) } +// Ensure AIDL files are compiled before cargo build runs +afterEvaluate { + tasks.matching { it.name.contains("cargoBuild") }.configureEach { + dependsOn(compileAidlNdk) + dependsOn(generateLibEvDevEventNames) + } +} + // Must come after all tasks above, otherwise gradle syncing fails. // // Run cargo build when the files change. diff --git a/evdev/src/main/cpp/CMakeLists.txt b/evdev/src/main/cpp/CMakeLists.txt deleted file mode 100644 index 6fbc7bbdbb..0000000000 --- a/evdev/src/main/cpp/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -# For more information about using CMake with Android Studio, read the -# documentation: https://d.android.com/studio/projects/add-native-code.html. -# For more examples on how to use CMake, see https://github.com/android/ndk-samples. - -# Sets the minimum CMake version required for this project. -cmake_minimum_required(VERSION 3.22.1) - -# Declares the project name. The project name can be accessed via ${ PROJECT_NAME}, -# Since this is the top level CMakeLists.txt, the project name is also accessible -# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level -# build script scope). -project("evdev") - -set(CMAKE_CXX_STANDARD 20) - -set(C_FLAGS "-Werror=format -fdata-sections -ffunction-sections -fno-exceptions -fno-rtti -fno-threadsafe-statics") -set(LINKER_FLAGS "-Wl,--hash-style=both") - -if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug") - message("Building Release...") - - set(C_FLAGS "${C_FLAGS} -O2 -fvisibility=hidden -fvisibility-inlines-hidden") - set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,-exclude-libs,ALL -Wl,--gc-sections") -else () - message("Building Debug...") - - add_definitions(-DDEBUG) -endif () - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_FLAGS}") - -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}") -set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}") - -# Creates and names a library, sets it as either STATIC -# or SHARED, and provides the relative paths to its source code. -# You can define multiple libraries, and CMake builds them for you. -# Gradle automatically packages shared libraries with your APK. -# -# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define -# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME} -# is preferred for the same purpose. -# -# In order to load a library into your app from Java/Kotlin, you must call -# System.loadLibrary() and pass the name of the library defined here; -# for GameActivity/NativeActivity derived applications, the same library name must be -# used in the AndroidManifest.xml file. -add_library(evdev SHARED - # List C/C++ source files with relative paths to this CMakeLists.txt. - libevdev_jni.cpp - libevdev/libevdev.c - libevdev/libevdev-names.c - libevdev/libevdev-uinput.c - android/input/KeyLayoutMap.cpp - android/input/InputEventLabels.cpp - android/libbase/result.cpp - android/utils/Tokenizer.cpp - android/utils/String16.cpp - android/utils/String8.cpp - android/utils/SharedBuffer.cpp - android/utils/FileMap.cpp - android/utils/Unicode.cpp - android/input/InputDevice.cpp - android/input/Input.cpp - android/libbase/stringprintf.cpp - ${aidl_src_dir}/io/github/sds100/keymapper/evdev/IEvdevCallback.cpp) - -find_library( - binder_ndk-lib - binder_ndk -) - -# Specifies libraries CMake should link to your target library. You -# can link libraries from various origins, such as libraries defined in this -# build script, prebuilt third-party libraries, or Android system libraries. -target_link_libraries(evdev - # List libraries link to the target library - android - log - ${binder_ndk-lib}) - -# Add include directories for header files -target_include_directories(evdev PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/android - ${CMAKE_CURRENT_SOURCE_DIR}/android/input - ${CMAKE_CURRENT_SOURCE_DIR}/android/libbase - ${CMAKE_CURRENT_SOURCE_DIR}/android/utils - ${CMAKE_CURRENT_SOURCE_DIR}/libevdev) - diff --git a/evdev/src/main/rust/evdev_manager/Cargo.lock b/evdev/src/main/rust/evdev_manager/Cargo.lock index 4cef43c5a2..7596290a40 100644 --- a/evdev/src/main/rust/evdev_manager/Cargo.lock +++ b/evdev/src/main/rust/evdev_manager/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + [[package]] name = "android_liblog-sys" version = "0.1.4" @@ -21,24 +30,80 @@ dependencies = [ "log 0.3.9", ] +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "log 0.4.28", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + [[package]] name = "bytes" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "cc" +version = "1.2.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cesu8" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "combine" version = "4.6.7" @@ -49,15 +114,44 @@ dependencies = [ "memchr", ] +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "evdev_manager" version = "0.1.0" dependencies = [ "android_log", + "bindgen", + "cc", "jni", "log 0.4.28", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "jni" version = "0.21.1" @@ -86,6 +180,16 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + [[package]] name = "log" version = "0.3.9" @@ -107,6 +211,32 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.103" @@ -125,6 +255,41 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "same-file" version = "1.0.6" @@ -134,6 +299,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "syn" version = "2.0.108" diff --git a/evdev/src/main/rust/evdev_manager/Cargo.toml b/evdev/src/main/rust/evdev_manager/Cargo.toml index c450603f19..dd94c0f1a2 100644 --- a/evdev/src/main/rust/evdev_manager/Cargo.toml +++ b/evdev/src/main/rust/evdev_manager/Cargo.toml @@ -8,7 +8,15 @@ name = "evdev_manager" # "cdylib" is necessary to produce a C-style dynamic library that can be loaded by Android's JNI. crate-type = ["cdylib"] +[profile.dev] +debug = true +strip = false # Don't strip symbols, keeps them in the .so file + [dependencies] jni = "0.21.1" log = "0.4.28" -android_log = "0.1.3" \ No newline at end of file +android_log = "0.1.3" + +[build-dependencies] +cc = "1.2.45" +bindgen = "0.72.1" \ No newline at end of file diff --git a/evdev/src/main/rust/evdev_manager/build.rs b/evdev/src/main/rust/evdev_manager/build.rs new file mode 100644 index 0000000000..2851b27740 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/build.rs @@ -0,0 +1,252 @@ +use std::env; +use std::path::{Path, PathBuf}; + +fn main() { + let manifest_dir: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + // Map Rust target architecture to Android ABI directory + let target = env::var("TARGET").expect("TARGET environment variable not set"); + + // This crate only supports Android targets for actual builds. + // For cargo check on host systems, we'll skip C/C++ compilation but still + // generate bindings to allow type checking. + let is_android = target.contains("android"); + + if !is_android { + eprintln!("Warning: Building for non-Android target '{}'. Skipping C/C++ compilation.", target); + eprintln!("This crate is designed for Android. Use Gradle for actual builds."); + // Skip all compilation but succeed to allow cargo check to work + return; + } + + // Path to C/C++ source files + let cpp_dir = manifest_dir.join("../../cpp"); + + println!("cargo:rerun-if-changed={}", cpp_dir.to_str().unwrap()); + + // Find Android NDK sysroot for bindgen + let ndk_sysroot = find_ndk_sysroot(&manifest_dir); + let sysroot_include = ndk_sysroot.join("usr/include"); + + let libevdev_dir = cpp_dir.join("libevdev"); + let android_dir = cpp_dir.join("android"); + let aidl_dir = cpp_dir.join("aidl"); + + // Build C files from libevdev + let mut c_builder = cc::Build::new(); + c_builder + .file(libevdev_dir.join("libevdev.c")) + .file(libevdev_dir.join("libevdev-names.c")) + .file(libevdev_dir.join("libevdev-uinput.c")) + .include(&cpp_dir) + .include(&libevdev_dir) + .flag("-Werror=format") + .flag("-fdata-sections") + .flag("-ffunction-sections"); + + if env::var("PROFILE").unwrap() == "release" { + c_builder.flag("-O2").flag("-fvisibility=hidden"); + } + + c_builder.compile("evdev_c"); + + // Build C++ files + let mut cpp_builder = cc::Build::new(); + cpp_builder + .cpp(true) + .std("c++20") + // libevdev JNI wrapper + .file(cpp_dir.join("libevdev_jni.cpp")) + // Android input framework files + .file(android_dir.join("input/KeyLayoutMap.cpp")) + .file(android_dir.join("input/InputEventLabels.cpp")) + .file(android_dir.join("input/InputDevice.cpp")) + .file(android_dir.join("input/Input.cpp")) + // Android base library files + .file(android_dir.join("libbase/result.cpp")) + .file(android_dir.join("libbase/stringprintf.cpp")) + // Android utils files + .file(android_dir.join("utils/Tokenizer.cpp")) + .file(android_dir.join("utils/String16.cpp")) + .file(android_dir.join("utils/String8.cpp")) + .file(android_dir.join("utils/SharedBuffer.cpp")) + .file(android_dir.join("utils/FileMap.cpp")) + .file(android_dir.join("utils/Unicode.cpp")) + // AIDL generated file + .file(aidl_dir.join("io/github/sds100/keymapper/evdev/IEvdevCallback.cpp")) + // Include directories + .include(&cpp_dir) + .include(&android_dir) + .include(&android_dir.join("input")) + .include(&android_dir.join("libbase")) + .include(&android_dir.join("utils")) + .include(&libevdev_dir) + // Compiler flags matching CMakeLists.txt + .flag("-Werror=format") + .flag("-fdata-sections") + .flag("-ffunction-sections") + .flag("-fno-exceptions") + .flag("-fno-rtti") + .flag("-fno-threadsafe-statics"); + + if env::var("PROFILE").unwrap() == "release" { + cpp_builder + .flag("-O2") + .flag("-fvisibility=hidden") + .flag("-fvisibility-inlines-hidden"); + } + + cpp_builder.compile("evdev_cpp"); + + // Link against Android libraries + println!("cargo:rustc-link-lib=android"); + println!("cargo:rustc-link-lib=log"); + println!("cargo:rustc-link-lib=binder_ndk"); + + // Generate Rust bindings from libevdev headers + let evdev_headers_path = libevdev_dir.clone(); + + // Configure bindgen with Android NDK sysroot and include paths + let mut bindgen_builder = bindgen::Builder::default() + .formatter(bindgen::Formatter::Prettyplease) + // Disable all format/style warnings for generated code + .raw_line("#![allow(clippy::all)]") + .raw_line("#![allow(non_camel_case_types)]") + .raw_line("#![allow(non_snake_case)]") + .raw_line("#![allow(non_upper_case_globals)]") + .raw_line("#![allow(dead_code)]") + .raw_line("#![allow(rustdoc::broken_intra_doc_links)]") + .raw_line("#![allow(rustdoc::private_intra_doc_links)]") + .header(evdev_headers_path.join("libevdev.h").display().to_string()) + .header( + evdev_headers_path + .join("libevdev-int.h") + .display() + .to_string(), + ) + .header( + evdev_headers_path + .join("libevdev-uinput.h") + .display() + .to_string(), + ) + .header( + evdev_headers_path + .join("libevdev-uinput-int.h") + .display() + .to_string(), + ) + .clang_arg(format!("--sysroot={}", ndk_sysroot.display())) + .clang_arg(format!("-I{}", sysroot_include.display())); + + // Add architecture-specific includes if needed + let arch_include = get_arch_include_path(&target, &ndk_sysroot); + if arch_include.exists() { + bindgen_builder = bindgen_builder.clang_arg(format!("-I{}", arch_include.display())); + } + + let bindings = bindgen_builder + .generate() + .expect("Unable to generate bindings"); + + let out_path = manifest_dir.join("src"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} + +fn find_ndk_sysroot(manifest_dir: &Path) -> PathBuf { + let sdk_dir = get_sdk_dir(manifest_dir).expect("SDK directory not available"); + let ndk_version = "27.2.12479018"; + + get_sysroot_for_version(&sdk_dir, &ndk_version) +} + +fn get_sdk_dir(manifest_dir: &Path) -> Option { + // 1. Read from local.properties file + // Navigate from evdev crate to project root + let local_properties = manifest_dir.join("../../../../../local.properties"); + + if let Ok(contents) = std::fs::read_to_string(&local_properties) { + for line in contents.lines() { + // Skip comments and empty lines + let line = line.trim(); + if line.is_empty() || line.starts_with('#') { + continue; + } + + // Look for sdk.dir=value or android.sdk.dir=value + if let Some(stripped) = line.strip_prefix("sdk.dir=") { + let sdk_path = stripped.trim(); + if !sdk_path.is_empty() { + return Some(sdk_path.to_string()); + } + } + if let Some(stripped) = line.strip_prefix("android.sdk.dir=") { + let sdk_path = stripped.trim(); + if !sdk_path.is_empty() { + return Some(sdk_path.to_string()); + } + } + } + } + + // 2. Check environment variables + if let Ok(sdk_dir) = env::var("ANDROID_SDK_ROOT") { + return Some(sdk_dir); + } + + if let Ok(sdk_dir) = env::var("ANDROID_HOME") { + return Some(sdk_dir); + } + + None +} + +fn get_sysroot_for_version(sdk_dir: &str, version: &str) -> PathBuf { + // Detect host platform + let host = if cfg!(target_os = "macos") { + "darwin-x86_64" + } else if cfg!(target_os = "linux") { + "linux-x86_64" + } else if cfg!(target_os = "windows") { + "windows-x86_64" + } else { + panic!("Unsupported host platform for NDK") + }; + + let sysroot = PathBuf::from(sdk_dir) + .join("ndk") + .join(version) + .join("toolchains") + .join("llvm") + .join("prebuilt") + .join(host) + .join("sysroot"); + + if !sysroot.exists() { + panic!( + "Could not find Android NDK sysroot for version {} at {}. Please ensure NDK {} is installed in {}/ndk/", + version, sysroot.display(), version, sdk_dir + ); + } + + sysroot +} + +fn get_arch_include_path(target: &str, sysroot: &Path) -> PathBuf { + let arch = if target.contains("aarch64") { + "aarch64-linux-android" + } else if target.contains("armv7") { + "arm-linux-androideabi" + } else if target.contains("i686") { + "i686-linux-android" + } else if target.contains("x86_64") { + "x86_64-linux-android" + } else { + return sysroot.join("usr").join("include").join("nonexistent"); + }; + + sysroot.join("usr").join("include").join(arch) +} diff --git a/evdev/src/main/rust/evdev_manager/rustfmt.toml b/evdev/src/main/rust/evdev_manager/rustfmt.toml new file mode 100644 index 0000000000..dc22519282 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/rustfmt.toml @@ -0,0 +1,4 @@ +# Workspace-wide rustfmt configuration +# Exclude generated bindings.rs from formatting +ignore = ["src/bindings.rs"] + diff --git a/evdev/src/main/rust/evdev_manager/src/bindings.rs b/evdev/src/main/rust/evdev_manager/src/bindings.rs new file mode 100644 index 0000000000..1acd99bfe1 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/src/bindings.rs @@ -0,0 +1,7629 @@ +/* automatically generated by rust-bindgen 0.72.1 */ + +#![allow(clippy::all)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(dead_code)] +#![allow(rustdoc::broken_intra_doc_links)] +#![allow(rustdoc::private_intra_doc_links)] + +/// If Bindgen could only determine the size and alignment of a +/// type, it is represented like this. +#[derive(PartialEq, Copy, Clone, Debug, Hash)] +#[repr(C)] +pub struct __BindgenOpaqueArray(pub [T; N]); +impl Default for __BindgenOpaqueArray { + fn default() -> Self { + Self([::default(); N]) + } +} +pub const __BIONIC__: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __bos_level: u32 = 0; +pub const __ANDROID_API_FUTURE__: u32 = 10000; +pub const __ANDROID_API__: u32 = 10000; +pub const __ANDROID_API_G__: u32 = 9; +pub const __ANDROID_API_I__: u32 = 14; +pub const __ANDROID_API_J__: u32 = 16; +pub const __ANDROID_API_J_MR1__: u32 = 17; +pub const __ANDROID_API_J_MR2__: u32 = 18; +pub const __ANDROID_API_K__: u32 = 19; +pub const __ANDROID_API_L__: u32 = 21; +pub const __ANDROID_API_L_MR1__: u32 = 22; +pub const __ANDROID_API_M__: u32 = 23; +pub const __ANDROID_API_N__: u32 = 24; +pub const __ANDROID_API_N_MR1__: u32 = 25; +pub const __ANDROID_API_O__: u32 = 26; +pub const __ANDROID_API_O_MR1__: u32 = 27; +pub const __ANDROID_API_P__: u32 = 28; +pub const __ANDROID_API_Q__: u32 = 29; +pub const __ANDROID_API_R__: u32 = 30; +pub const __ANDROID_API_S__: u32 = 31; +pub const __ANDROID_API_T__: u32 = 33; +pub const __ANDROID_API_U__: u32 = 34; +pub const __ANDROID_API_V__: u32 = 35; +pub const __ANDROID_NDK__: u32 = 1; +pub const __NDK_MAJOR__: u32 = 27; +pub const __NDK_MINOR__: u32 = 2; +pub const __NDK_BETA__: u32 = 0; +pub const __NDK_BUILD__: u32 = 12479018; +pub const __NDK_CANARY__: u32 = 0; +pub const WCHAR_MIN: u8 = 0u8; +pub const INT8_MIN: i32 = -128; +pub const INT8_MAX: u32 = 127; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST8_MAX: u32 = 127; +pub const UINT8_MAX: u32 = 255; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_FAST8_MAX: u32 = 255; +pub const INT16_MIN: i32 = -32768; +pub const INT16_MAX: u32 = 32767; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const UINT16_MAX: u32 = 65535; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const INT32_MIN: i32 = -2147483648; +pub const INT32_MAX: u32 = 2147483647; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const INT_FAST32_MIN: i32 = -2147483648; +pub const INT_FAST32_MAX: u32 = 2147483647; +pub const UINT32_MAX: u32 = 4294967295; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const UINT_FAST32_MAX: u32 = 4294967295; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const WINT_MAX: u32 = 4294967295; +pub const WINT_MIN: u32 = 0; +pub const __BITS_PER_LONG: u32 = 64; +pub const __FD_SETSIZE: u32 = 1024; +pub const ITIMER_REAL: u32 = 0; +pub const ITIMER_VIRTUAL: u32 = 1; +pub const ITIMER_PROF: u32 = 2; +pub const CLOCK_REALTIME: u32 = 0; +pub const CLOCK_MONOTONIC: u32 = 1; +pub const CLOCK_PROCESS_CPUTIME_ID: u32 = 2; +pub const CLOCK_THREAD_CPUTIME_ID: u32 = 3; +pub const CLOCK_MONOTONIC_RAW: u32 = 4; +pub const CLOCK_REALTIME_COARSE: u32 = 5; +pub const CLOCK_MONOTONIC_COARSE: u32 = 6; +pub const CLOCK_BOOTTIME: u32 = 7; +pub const CLOCK_REALTIME_ALARM: u32 = 8; +pub const CLOCK_BOOTTIME_ALARM: u32 = 9; +pub const CLOCK_SGI_CYCLE: u32 = 10; +pub const CLOCK_TAI: u32 = 11; +pub const MAX_CLOCKS: u32 = 16; +pub const CLOCKS_MASK: u32 = 1; +pub const CLOCKS_MONO: u32 = 1; +pub const TIMER_ABSTIME: u32 = 1; +pub const FPSIMD_MAGIC: u32 = 1179680769; +pub const ESR_MAGIC: u32 = 1163088385; +pub const EXTRA_MAGIC: u32 = 1163416577; +pub const SVE_MAGIC: u32 = 1398162689; +pub const SVE_SIG_FLAG_SM: u32 = 1; +pub const TPIDR2_MAGIC: u32 = 1414547714; +pub const ZA_MAGIC: u32 = 1412850501; +pub const ZT_MAGIC: u32 = 1515474433; +pub const __SVE_VQ_BYTES: u32 = 16; +pub const __SVE_VQ_MIN: u32 = 1; +pub const __SVE_VQ_MAX: u32 = 512; +pub const __SVE_VL_MIN: u32 = 16; +pub const __SVE_VL_MAX: u32 = 8192; +pub const __SVE_NUM_ZREGS: u32 = 32; +pub const __SVE_NUM_PREGS: u32 = 16; +pub const __SVE_ZREGS_OFFSET: u32 = 0; +pub const SVE_VQ_BYTES: u32 = 16; +pub const SVE_VQ_MIN: u32 = 1; +pub const SVE_VQ_MAX: u32 = 512; +pub const SVE_VL_MIN: u32 = 16; +pub const SVE_VL_MAX: u32 = 8192; +pub const SVE_NUM_ZREGS: u32 = 32; +pub const SVE_NUM_PREGS: u32 = 16; +pub const ZT_SIG_REG_SIZE: u32 = 512; +pub const ZT_SIG_REG_BYTES: u32 = 64; +pub const NR_OPEN: u32 = 1024; +pub const NGROUPS_MAX: u32 = 65536; +pub const ARG_MAX: u32 = 131072; +pub const LINK_MAX: u32 = 127; +pub const MAX_CANON: u32 = 255; +pub const MAX_INPUT: u32 = 255; +pub const NAME_MAX: u32 = 255; +pub const PATH_MAX: u32 = 4096; +pub const PIPE_BUF: u32 = 4096; +pub const XATTR_NAME_MAX: u32 = 255; +pub const XATTR_SIZE_MAX: u32 = 65536; +pub const XATTR_LIST_MAX: u32 = 65536; +pub const RTSIG_MAX: u32 = 32; +pub const PASS_MAX: u32 = 128; +pub const NL_ARGMAX: u32 = 9; +pub const NL_LANGMAX: u32 = 14; +pub const NL_MSGMAX: u32 = 32767; +pub const NL_NMAX: u32 = 1; +pub const NL_SETMAX: u32 = 255; +pub const NL_TEXTMAX: u32 = 255; +pub const TMP_MAX: u32 = 308915776; +pub const CHAR_BIT: u32 = 8; +pub const LONG_BIT: u32 = 64; +pub const WORD_BIT: u32 = 32; +pub const SCHAR_MAX: u32 = 127; +pub const SCHAR_MIN: i32 = -128; +pub const UCHAR_MAX: u32 = 255; +pub const CHAR_MIN: u32 = 0; +pub const CHAR_MAX: u32 = 255; +pub const USHRT_MAX: u32 = 65535; +pub const SHRT_MAX: u32 = 32767; +pub const SHRT_MIN: i32 = -32768; +pub const UINT_MAX: u32 = 4294967295; +pub const INT_MAX: u32 = 2147483647; +pub const INT_MIN: i32 = -2147483648; +pub const ULONG_MAX: i32 = -1; +pub const LONG_MAX: u64 = 9223372036854775807; +pub const LONG_MIN: i64 = -9223372036854775808; +pub const ULLONG_MAX: i32 = -1; +pub const LLONG_MAX: u64 = 9223372036854775807; +pub const LLONG_MIN: i64 = -9223372036854775808; +pub const LONG_LONG_MIN: i64 = -9223372036854775808; +pub const LONG_LONG_MAX: u64 = 9223372036854775807; +pub const ULONG_LONG_MAX: i32 = -1; +pub const UID_MAX: u32 = 4294967295; +pub const GID_MAX: u32 = 4294967295; +pub const SIZE_T_MAX: i32 = -1; +pub const SSIZE_MAX: u64 = 9223372036854775807; +pub const MB_LEN_MAX: u32 = 4; +pub const NZERO: u32 = 20; +pub const IOV_MAX: u32 = 1024; +pub const SEM_VALUE_MAX: u32 = 1073741823; +pub const _POSIX_VERSION: u32 = 200809; +pub const _POSIX2_VERSION: u32 = 200809; +pub const _XOPEN_VERSION: u32 = 700; +pub const __BIONIC_POSIX_FEATURE_MISSING: i32 = -1; +pub const _POSIX_ASYNCHRONOUS_IO: i32 = -1; +pub const _POSIX_CHOWN_RESTRICTED: u32 = 1; +pub const _POSIX_CPUTIME: u32 = 200809; +pub const _POSIX_FSYNC: u32 = 200809; +pub const _POSIX_IPV6: u32 = 200809; +pub const _POSIX_MAPPED_FILES: u32 = 200809; +pub const _POSIX_MEMLOCK_RANGE: u32 = 200809; +pub const _POSIX_MEMORY_PROTECTION: u32 = 200809; +pub const _POSIX_MESSAGE_PASSING: i32 = -1; +pub const _POSIX_MONOTONIC_CLOCK: u32 = 200809; +pub const _POSIX_NO_TRUNC: u32 = 1; +pub const _POSIX_PRIORITIZED_IO: i32 = -1; +pub const _POSIX_PRIORITY_SCHEDULING: u32 = 200809; +pub const _POSIX_RAW_SOCKETS: u32 = 200809; +pub const _POSIX_READER_WRITER_LOCKS: u32 = 200809; +pub const _POSIX_REGEXP: u32 = 1; +pub const _POSIX_SAVED_IDS: u32 = 1; +pub const _POSIX_SEMAPHORES: u32 = 200809; +pub const _POSIX_SHARED_MEMORY_OBJECTS: i32 = -1; +pub const _POSIX_SHELL: u32 = 1; +pub const _POSIX_SPORADIC_SERVER: i32 = -1; +pub const _POSIX_SYNCHRONIZED_IO: u32 = 200809; +pub const _POSIX_THREAD_ATTR_STACKADDR: u32 = 200809; +pub const _POSIX_THREAD_ATTR_STACKSIZE: u32 = 200809; +pub const _POSIX_THREAD_CPUTIME: u32 = 200809; +pub const _POSIX_THREAD_PRIO_INHERIT: i32 = -1; +pub const _POSIX_THREAD_PRIO_PROTECT: i32 = -1; +pub const _POSIX_THREAD_PRIORITY_SCHEDULING: u32 = 200809; +pub const _POSIX_THREAD_PROCESS_SHARED: u32 = 200809; +pub const _POSIX_THREAD_ROBUST_PRIO_INHERIT: i32 = -1; +pub const _POSIX_THREAD_ROBUST_PRIO_PROTECT: i32 = -1; +pub const _POSIX_THREAD_SAFE_FUNCTIONS: u32 = 200809; +pub const _POSIX_THREAD_SPORADIC_SERVER: i32 = -1; +pub const _POSIX_THREADS: u32 = 200809; +pub const _POSIX_TIMERS: u32 = 200809; +pub const _POSIX_TRACE: i32 = -1; +pub const _POSIX_TRACE_EVENT_FILTER: i32 = -1; +pub const _POSIX_TRACE_INHERIT: i32 = -1; +pub const _POSIX_TRACE_LOG: i32 = -1; +pub const _POSIX_TYPED_MEMORY_OBJECTS: i32 = -1; +pub const _POSIX_VDISABLE: u8 = 0u8; +pub const _POSIX2_C_BIND: u32 = 200809; +pub const _POSIX2_C_DEV: i32 = -1; +pub const _POSIX2_CHAR_TERM: u32 = 200809; +pub const _POSIX2_FORT_DEV: i32 = -1; +pub const _POSIX2_FORT_RUN: i32 = -1; +pub const _POSIX2_LOCALEDEF: i32 = -1; +pub const _POSIX2_SW_DEV: i32 = -1; +pub const _POSIX2_UPE: i32 = -1; +pub const _POSIX_V7_ILP32_OFF32: i32 = -1; +pub const _POSIX_V7_ILP32_OFFBIG: i32 = -1; +pub const _POSIX_V7_LP64_OFF64: u32 = 1; +pub const _POSIX_V7_LPBIG_OFFBIG: u32 = 1; +pub const _XOPEN_CRYPT: i32 = -1; +pub const _XOPEN_ENH_I18N: u32 = 1; +pub const _XOPEN_LEGACY: i32 = -1; +pub const _XOPEN_REALTIME: u32 = 1; +pub const _XOPEN_REALTIME_THREADS: u32 = 1; +pub const _XOPEN_SHM: u32 = 1; +pub const _XOPEN_STREAMS: i32 = -1; +pub const _XOPEN_UNIX: u32 = 1; +pub const _POSIX_AIO_LISTIO_MAX: u32 = 2; +pub const _POSIX_AIO_MAX: u32 = 1; +pub const _POSIX_ARG_MAX: u32 = 4096; +pub const _POSIX_CHILD_MAX: u32 = 25; +pub const _POSIX_CLOCKRES_MIN: u32 = 20000000; +pub const _POSIX_DELAYTIMER_MAX: u32 = 32; +pub const _POSIX_HOST_NAME_MAX: u32 = 255; +pub const _POSIX_LINK_MAX: u32 = 8; +pub const _POSIX_LOGIN_NAME_MAX: u32 = 9; +pub const _POSIX_MAX_CANON: u32 = 255; +pub const _POSIX_MAX_INPUT: u32 = 255; +pub const _POSIX_MQ_OPEN_MAX: u32 = 8; +pub const _POSIX_MQ_PRIO_MAX: u32 = 32; +pub const _POSIX_NAME_MAX: u32 = 14; +pub const _POSIX_NGROUPS_MAX: u32 = 8; +pub const _POSIX_OPEN_MAX: u32 = 20; +pub const _POSIX_PATH_MAX: u32 = 256; +pub const _POSIX_PIPE_BUF: u32 = 512; +pub const _POSIX_RE_DUP_MAX: u32 = 255; +pub const _POSIX_RTSIG_MAX: u32 = 8; +pub const _POSIX_SEM_NSEMS_MAX: u32 = 256; +pub const _POSIX_SEM_VALUE_MAX: u32 = 32767; +pub const _POSIX_SIGQUEUE_MAX: u32 = 32; +pub const _POSIX_SSIZE_MAX: u32 = 32767; +pub const _POSIX_STREAM_MAX: u32 = 8; +pub const _POSIX_SS_REPL_MAX: u32 = 4; +pub const _POSIX_SYMLINK_MAX: u32 = 255; +pub const _POSIX_SYMLOOP_MAX: u32 = 8; +pub const _POSIX_THREAD_DESTRUCTOR_ITERATIONS: u32 = 4; +pub const _POSIX_THREAD_KEYS_MAX: u32 = 128; +pub const _POSIX_THREAD_THREADS_MAX: u32 = 64; +pub const _POSIX_TIMER_MAX: u32 = 32; +pub const _POSIX_TRACE_EVENT_NAME_MAX: u32 = 30; +pub const _POSIX_TRACE_NAME_MAX: u32 = 8; +pub const _POSIX_TRACE_SYS_MAX: u32 = 8; +pub const _POSIX_TRACE_USER_EVENT_MAX: u32 = 32; +pub const _POSIX_TTY_NAME_MAX: u32 = 9; +pub const _POSIX_TZNAME_MAX: u32 = 6; +pub const _POSIX2_BC_BASE_MAX: u32 = 99; +pub const _POSIX2_BC_DIM_MAX: u32 = 2048; +pub const _POSIX2_BC_SCALE_MAX: u32 = 99; +pub const _POSIX2_BC_STRING_MAX: u32 = 1000; +pub const _POSIX2_CHARCLASS_NAME_MAX: u32 = 14; +pub const _POSIX2_COLL_WEIGHTS_MAX: u32 = 2; +pub const _POSIX2_EXPR_NEST_MAX: u32 = 32; +pub const _POSIX2_LINE_MAX: u32 = 2048; +pub const _POSIX2_RE_DUP_MAX: u32 = 255; +pub const _XOPEN_IOV_MAX: u32 = 16; +pub const _XOPEN_NAME_MAX: u32 = 255; +pub const _XOPEN_PATH_MAX: u32 = 1024; +pub const HOST_NAME_MAX: u32 = 255; +pub const LOGIN_NAME_MAX: u32 = 256; +pub const TTY_NAME_MAX: u32 = 32; +pub const PTHREAD_DESTRUCTOR_ITERATIONS: u32 = 4; +pub const PTHREAD_KEYS_MAX: u32 = 128; +pub const SA_RESTORER: u32 = 67108864; +pub const MINSIGSTKSZ: u32 = 5120; +pub const SIGSTKSZ: u32 = 16384; +pub const _KERNEL__NSIG: u32 = 64; +pub const _NSIG_BPW: u32 = 64; +pub const _NSIG_WORDS: u32 = 1; +pub const SIGHUP: u32 = 1; +pub const SIGINT: u32 = 2; +pub const SIGQUIT: u32 = 3; +pub const SIGILL: u32 = 4; +pub const SIGTRAP: u32 = 5; +pub const SIGABRT: u32 = 6; +pub const SIGIOT: u32 = 6; +pub const SIGBUS: u32 = 7; +pub const SIGFPE: u32 = 8; +pub const SIGKILL: u32 = 9; +pub const SIGUSR1: u32 = 10; +pub const SIGSEGV: u32 = 11; +pub const SIGUSR2: u32 = 12; +pub const SIGPIPE: u32 = 13; +pub const SIGALRM: u32 = 14; +pub const SIGTERM: u32 = 15; +pub const SIGSTKFLT: u32 = 16; +pub const SIGCHLD: u32 = 17; +pub const SIGCONT: u32 = 18; +pub const SIGSTOP: u32 = 19; +pub const SIGTSTP: u32 = 20; +pub const SIGTTIN: u32 = 21; +pub const SIGTTOU: u32 = 22; +pub const SIGURG: u32 = 23; +pub const SIGXCPU: u32 = 24; +pub const SIGXFSZ: u32 = 25; +pub const SIGVTALRM: u32 = 26; +pub const SIGPROF: u32 = 27; +pub const SIGWINCH: u32 = 28; +pub const SIGIO: u32 = 29; +pub const SIGPOLL: u32 = 29; +pub const SIGPWR: u32 = 30; +pub const SIGSYS: u32 = 31; +pub const SIGUNUSED: u32 = 31; +pub const __SIGRTMIN: u32 = 32; +pub const __SIGRTMAX: u32 = 64; +pub const SA_NOCLDSTOP: u32 = 1; +pub const SA_NOCLDWAIT: u32 = 2; +pub const SA_SIGINFO: u32 = 4; +pub const SA_UNSUPPORTED: u32 = 1024; +pub const SA_EXPOSE_TAGBITS: u32 = 2048; +pub const SA_ONSTACK: u32 = 134217728; +pub const SA_RESTART: u32 = 268435456; +pub const SA_NODEFER: u32 = 1073741824; +pub const SA_RESETHAND: u32 = 2147483648; +pub const SA_NOMASK: u32 = 1073741824; +pub const SA_ONESHOT: u32 = 2147483648; +pub const SIG_BLOCK: u32 = 0; +pub const SIG_UNBLOCK: u32 = 1; +pub const SIG_SETMASK: u32 = 2; +pub const SI_MAX_SIZE: u32 = 128; +pub const SI_USER: u32 = 0; +pub const SI_KERNEL: u32 = 128; +pub const SI_QUEUE: i32 = -1; +pub const SI_TIMER: i32 = -2; +pub const SI_MESGQ: i32 = -3; +pub const SI_ASYNCIO: i32 = -4; +pub const SI_SIGIO: i32 = -5; +pub const SI_TKILL: i32 = -6; +pub const SI_DETHREAD: i32 = -7; +pub const SI_ASYNCNL: i32 = -60; +pub const ILL_ILLOPC: u32 = 1; +pub const ILL_ILLOPN: u32 = 2; +pub const ILL_ILLADR: u32 = 3; +pub const ILL_ILLTRP: u32 = 4; +pub const ILL_PRVOPC: u32 = 5; +pub const ILL_PRVREG: u32 = 6; +pub const ILL_COPROC: u32 = 7; +pub const ILL_BADSTK: u32 = 8; +pub const ILL_BADIADDR: u32 = 9; +pub const __ILL_BREAK: u32 = 10; +pub const __ILL_BNDMOD: u32 = 11; +pub const NSIGILL: u32 = 11; +pub const FPE_INTDIV: u32 = 1; +pub const FPE_INTOVF: u32 = 2; +pub const FPE_FLTDIV: u32 = 3; +pub const FPE_FLTOVF: u32 = 4; +pub const FPE_FLTUND: u32 = 5; +pub const FPE_FLTRES: u32 = 6; +pub const FPE_FLTINV: u32 = 7; +pub const FPE_FLTSUB: u32 = 8; +pub const __FPE_DECOVF: u32 = 9; +pub const __FPE_DECDIV: u32 = 10; +pub const __FPE_DECERR: u32 = 11; +pub const __FPE_INVASC: u32 = 12; +pub const __FPE_INVDEC: u32 = 13; +pub const FPE_FLTUNK: u32 = 14; +pub const FPE_CONDTRAP: u32 = 15; +pub const NSIGFPE: u32 = 15; +pub const SEGV_MAPERR: u32 = 1; +pub const SEGV_ACCERR: u32 = 2; +pub const SEGV_BNDERR: u32 = 3; +pub const SEGV_PKUERR: u32 = 4; +pub const SEGV_ACCADI: u32 = 5; +pub const SEGV_ADIDERR: u32 = 6; +pub const SEGV_ADIPERR: u32 = 7; +pub const SEGV_MTEAERR: u32 = 8; +pub const SEGV_MTESERR: u32 = 9; +pub const SEGV_CPERR: u32 = 10; +pub const NSIGSEGV: u32 = 10; +pub const BUS_ADRALN: u32 = 1; +pub const BUS_ADRERR: u32 = 2; +pub const BUS_OBJERR: u32 = 3; +pub const BUS_MCEERR_AR: u32 = 4; +pub const BUS_MCEERR_AO: u32 = 5; +pub const NSIGBUS: u32 = 5; +pub const TRAP_BRKPT: u32 = 1; +pub const TRAP_TRACE: u32 = 2; +pub const TRAP_BRANCH: u32 = 3; +pub const TRAP_HWBKPT: u32 = 4; +pub const TRAP_UNK: u32 = 5; +pub const TRAP_PERF: u32 = 6; +pub const NSIGTRAP: u32 = 6; +pub const TRAP_PERF_FLAG_ASYNC: u32 = 1; +pub const CLD_EXITED: u32 = 1; +pub const CLD_KILLED: u32 = 2; +pub const CLD_DUMPED: u32 = 3; +pub const CLD_TRAPPED: u32 = 4; +pub const CLD_STOPPED: u32 = 5; +pub const CLD_CONTINUED: u32 = 6; +pub const NSIGCHLD: u32 = 6; +pub const POLL_IN: u32 = 1; +pub const POLL_OUT: u32 = 2; +pub const POLL_MSG: u32 = 3; +pub const POLL_ERR: u32 = 4; +pub const POLL_PRI: u32 = 5; +pub const POLL_HUP: u32 = 6; +pub const NSIGPOLL: u32 = 6; +pub const SYS_SECCOMP: u32 = 1; +pub const SYS_USER_DISPATCH: u32 = 2; +pub const NSIGSYS: u32 = 2; +pub const EMT_TAGOVF: u32 = 1; +pub const NSIGEMT: u32 = 1; +pub const SIGEV_SIGNAL: u32 = 0; +pub const SIGEV_NONE: u32 = 1; +pub const SIGEV_THREAD: u32 = 2; +pub const SIGEV_THREAD_ID: u32 = 4; +pub const SIGEV_MAX_SIZE: u32 = 64; +pub const SS_ONSTACK: u32 = 1; +pub const SS_DISABLE: u32 = 2; +pub const SS_AUTODISARM: u32 = 2147483648; +pub const SS_FLAG_BITS: u32 = 2147483648; +pub const _NSIG: u32 = 65; +pub const NSIG: u32 = 65; +pub const PAGE_SIZE: u32 = 4096; +pub const PAGE_MASK: i32 = -4096; +pub const NGREG: u32 = 34; +pub const FD_SETSIZE: u32 = 1024; +pub const _IOC_NRBITS: u32 = 8; +pub const _IOC_TYPEBITS: u32 = 8; +pub const _IOC_SIZEBITS: u32 = 14; +pub const _IOC_DIRBITS: u32 = 2; +pub const _IOC_NRMASK: u32 = 255; +pub const _IOC_TYPEMASK: u32 = 255; +pub const _IOC_SIZEMASK: u32 = 16383; +pub const _IOC_DIRMASK: u32 = 3; +pub const _IOC_NRSHIFT: u32 = 0; +pub const _IOC_TYPESHIFT: u32 = 8; +pub const _IOC_SIZESHIFT: u32 = 16; +pub const _IOC_DIRSHIFT: u32 = 30; +pub const _IOC_NONE: u32 = 0; +pub const _IOC_WRITE: u32 = 1; +pub const _IOC_READ: u32 = 2; +pub const IOC_IN: u32 = 1073741824; +pub const IOC_OUT: u32 = 2147483648; +pub const IOC_INOUT: u32 = 3221225472; +pub const IOCSIZE_MASK: u32 = 1073676288; +pub const IOCSIZE_SHIFT: u32 = 16; +pub const IGNBRK: u32 = 1; +pub const BRKINT: u32 = 2; +pub const IGNPAR: u32 = 4; +pub const PARMRK: u32 = 8; +pub const INPCK: u32 = 16; +pub const ISTRIP: u32 = 32; +pub const INLCR: u32 = 64; +pub const IGNCR: u32 = 128; +pub const ICRNL: u32 = 256; +pub const IXANY: u32 = 2048; +pub const OPOST: u32 = 1; +pub const OCRNL: u32 = 8; +pub const ONOCR: u32 = 16; +pub const ONLRET: u32 = 32; +pub const OFILL: u32 = 64; +pub const OFDEL: u32 = 128; +pub const B0: u32 = 0; +pub const B50: u32 = 1; +pub const B75: u32 = 2; +pub const B110: u32 = 3; +pub const B134: u32 = 4; +pub const B150: u32 = 5; +pub const B200: u32 = 6; +pub const B300: u32 = 7; +pub const B600: u32 = 8; +pub const B1200: u32 = 9; +pub const B1800: u32 = 10; +pub const B2400: u32 = 11; +pub const B4800: u32 = 12; +pub const B9600: u32 = 13; +pub const B19200: u32 = 14; +pub const B38400: u32 = 15; +pub const EXTA: u32 = 14; +pub const EXTB: u32 = 15; +pub const ADDRB: u32 = 536870912; +pub const CMSPAR: u32 = 1073741824; +pub const CRTSCTS: u32 = 2147483648; +pub const IBSHIFT: u32 = 16; +pub const TCOOFF: u32 = 0; +pub const TCOON: u32 = 1; +pub const TCIOFF: u32 = 2; +pub const TCION: u32 = 3; +pub const TCIFLUSH: u32 = 0; +pub const TCOFLUSH: u32 = 1; +pub const TCIOFLUSH: u32 = 2; +pub const NCCS: u32 = 19; +pub const VINTR: u32 = 0; +pub const VQUIT: u32 = 1; +pub const VERASE: u32 = 2; +pub const VKILL: u32 = 3; +pub const VEOF: u32 = 4; +pub const VTIME: u32 = 5; +pub const VMIN: u32 = 6; +pub const VSWTC: u32 = 7; +pub const VSTART: u32 = 8; +pub const VSTOP: u32 = 9; +pub const VSUSP: u32 = 10; +pub const VEOL: u32 = 11; +pub const VREPRINT: u32 = 12; +pub const VDISCARD: u32 = 13; +pub const VWERASE: u32 = 14; +pub const VLNEXT: u32 = 15; +pub const VEOL2: u32 = 16; +pub const IUCLC: u32 = 512; +pub const IXON: u32 = 1024; +pub const IXOFF: u32 = 4096; +pub const IMAXBEL: u32 = 8192; +pub const IUTF8: u32 = 16384; +pub const OLCUC: u32 = 2; +pub const ONLCR: u32 = 4; +pub const NLDLY: u32 = 256; +pub const NL0: u32 = 0; +pub const NL1: u32 = 256; +pub const CRDLY: u32 = 1536; +pub const CR0: u32 = 0; +pub const CR1: u32 = 512; +pub const CR2: u32 = 1024; +pub const CR3: u32 = 1536; +pub const TABDLY: u32 = 6144; +pub const TAB0: u32 = 0; +pub const TAB1: u32 = 2048; +pub const TAB2: u32 = 4096; +pub const TAB3: u32 = 6144; +pub const XTABS: u32 = 6144; +pub const BSDLY: u32 = 8192; +pub const BS0: u32 = 0; +pub const BS1: u32 = 8192; +pub const VTDLY: u32 = 16384; +pub const VT0: u32 = 0; +pub const VT1: u32 = 16384; +pub const FFDLY: u32 = 32768; +pub const FF0: u32 = 0; +pub const FF1: u32 = 32768; +pub const CBAUD: u32 = 4111; +pub const CSIZE: u32 = 48; +pub const CS5: u32 = 0; +pub const CS6: u32 = 16; +pub const CS7: u32 = 32; +pub const CS8: u32 = 48; +pub const CSTOPB: u32 = 64; +pub const CREAD: u32 = 128; +pub const PARENB: u32 = 256; +pub const PARODD: u32 = 512; +pub const HUPCL: u32 = 1024; +pub const CLOCAL: u32 = 2048; +pub const CBAUDEX: u32 = 4096; +pub const BOTHER: u32 = 4096; +pub const B57600: u32 = 4097; +pub const B115200: u32 = 4098; +pub const B230400: u32 = 4099; +pub const B460800: u32 = 4100; +pub const B500000: u32 = 4101; +pub const B576000: u32 = 4102; +pub const B921600: u32 = 4103; +pub const B1000000: u32 = 4104; +pub const B1152000: u32 = 4105; +pub const B1500000: u32 = 4106; +pub const B2000000: u32 = 4107; +pub const B2500000: u32 = 4108; +pub const B3000000: u32 = 4109; +pub const B3500000: u32 = 4110; +pub const B4000000: u32 = 4111; +pub const CIBAUD: u32 = 269418496; +pub const ISIG: u32 = 1; +pub const ICANON: u32 = 2; +pub const XCASE: u32 = 4; +pub const ECHO: u32 = 8; +pub const ECHOE: u32 = 16; +pub const ECHOK: u32 = 32; +pub const ECHONL: u32 = 64; +pub const NOFLSH: u32 = 128; +pub const TOSTOP: u32 = 256; +pub const ECHOCTL: u32 = 512; +pub const ECHOPRT: u32 = 1024; +pub const ECHOKE: u32 = 2048; +pub const FLUSHO: u32 = 4096; +pub const PENDIN: u32 = 16384; +pub const IEXTEN: u32 = 32768; +pub const EXTPROC: u32 = 65536; +pub const TCSANOW: u32 = 0; +pub const TCSADRAIN: u32 = 1; +pub const TCSAFLUSH: u32 = 2; +pub const TCGETS: u32 = 21505; +pub const TCSETS: u32 = 21506; +pub const TCSETSW: u32 = 21507; +pub const TCSETSF: u32 = 21508; +pub const TCGETA: u32 = 21509; +pub const TCSETA: u32 = 21510; +pub const TCSETAW: u32 = 21511; +pub const TCSETAF: u32 = 21512; +pub const TCSBRK: u32 = 21513; +pub const TCXONC: u32 = 21514; +pub const TCFLSH: u32 = 21515; +pub const TIOCEXCL: u32 = 21516; +pub const TIOCNXCL: u32 = 21517; +pub const TIOCSCTTY: u32 = 21518; +pub const TIOCGPGRP: u32 = 21519; +pub const TIOCSPGRP: u32 = 21520; +pub const TIOCOUTQ: u32 = 21521; +pub const TIOCSTI: u32 = 21522; +pub const TIOCGWINSZ: u32 = 21523; +pub const TIOCSWINSZ: u32 = 21524; +pub const TIOCMGET: u32 = 21525; +pub const TIOCMBIS: u32 = 21526; +pub const TIOCMBIC: u32 = 21527; +pub const TIOCMSET: u32 = 21528; +pub const TIOCGSOFTCAR: u32 = 21529; +pub const TIOCSSOFTCAR: u32 = 21530; +pub const FIONREAD: u32 = 21531; +pub const TIOCINQ: u32 = 21531; +pub const TIOCLINUX: u32 = 21532; +pub const TIOCCONS: u32 = 21533; +pub const TIOCGSERIAL: u32 = 21534; +pub const TIOCSSERIAL: u32 = 21535; +pub const TIOCPKT: u32 = 21536; +pub const FIONBIO: u32 = 21537; +pub const TIOCNOTTY: u32 = 21538; +pub const TIOCSETD: u32 = 21539; +pub const TIOCGETD: u32 = 21540; +pub const TCSBRKP: u32 = 21541; +pub const TIOCSBRK: u32 = 21543; +pub const TIOCCBRK: u32 = 21544; +pub const TIOCGSID: u32 = 21545; +pub const TIOCGRS485: u32 = 21550; +pub const TIOCSRS485: u32 = 21551; +pub const TCGETX: u32 = 21554; +pub const TCSETX: u32 = 21555; +pub const TCSETXF: u32 = 21556; +pub const TCSETXW: u32 = 21557; +pub const TIOCVHANGUP: u32 = 21559; +pub const FIONCLEX: u32 = 21584; +pub const FIOCLEX: u32 = 21585; +pub const FIOASYNC: u32 = 21586; +pub const TIOCSERCONFIG: u32 = 21587; +pub const TIOCSERGWILD: u32 = 21588; +pub const TIOCSERSWILD: u32 = 21589; +pub const TIOCGLCKTRMIOS: u32 = 21590; +pub const TIOCSLCKTRMIOS: u32 = 21591; +pub const TIOCSERGSTRUCT: u32 = 21592; +pub const TIOCSERGETLSR: u32 = 21593; +pub const TIOCSERGETMULTI: u32 = 21594; +pub const TIOCSERSETMULTI: u32 = 21595; +pub const TIOCMIWAIT: u32 = 21596; +pub const TIOCGICOUNT: u32 = 21597; +pub const FIOQSIZE: u32 = 21600; +pub const TIOCPKT_DATA: u32 = 0; +pub const TIOCPKT_FLUSHREAD: u32 = 1; +pub const TIOCPKT_FLUSHWRITE: u32 = 2; +pub const TIOCPKT_STOP: u32 = 4; +pub const TIOCPKT_START: u32 = 8; +pub const TIOCPKT_NOSTOP: u32 = 16; +pub const TIOCPKT_DOSTOP: u32 = 32; +pub const TIOCPKT_IOCTL: u32 = 64; +pub const TIOCSER_TEMT: u32 = 1; +pub const NCC: u32 = 8; +pub const TIOCM_LE: u32 = 1; +pub const TIOCM_DTR: u32 = 2; +pub const TIOCM_RTS: u32 = 4; +pub const TIOCM_ST: u32 = 8; +pub const TIOCM_SR: u32 = 16; +pub const TIOCM_CTS: u32 = 32; +pub const TIOCM_CAR: u32 = 64; +pub const TIOCM_RNG: u32 = 128; +pub const TIOCM_DSR: u32 = 256; +pub const TIOCM_CD: u32 = 64; +pub const TIOCM_RI: u32 = 128; +pub const TIOCM_OUT1: u32 = 8192; +pub const TIOCM_OUT2: u32 = 16384; +pub const TIOCM_LOOP: u32 = 32768; +pub const N_TTY: u32 = 0; +pub const N_SLIP: u32 = 1; +pub const N_MOUSE: u32 = 2; +pub const N_PPP: u32 = 3; +pub const N_STRIP: u32 = 4; +pub const N_AX25: u32 = 5; +pub const N_X25: u32 = 6; +pub const N_6PACK: u32 = 7; +pub const N_MASC: u32 = 8; +pub const N_R3964: u32 = 9; +pub const N_PROFIBUS_FDL: u32 = 10; +pub const N_IRDA: u32 = 11; +pub const N_SMSBLOCK: u32 = 12; +pub const N_HDLC: u32 = 13; +pub const N_SYNC_PPP: u32 = 14; +pub const N_HCI: u32 = 15; +pub const N_GIGASET_M101: u32 = 16; +pub const N_SLCAN: u32 = 17; +pub const N_PPS: u32 = 18; +pub const N_V253: u32 = 19; +pub const N_CAIF: u32 = 20; +pub const N_GSM0710: u32 = 21; +pub const N_TI_WL: u32 = 22; +pub const N_TRACESINK: u32 = 23; +pub const N_TRACEROUTER: u32 = 24; +pub const N_NCI: u32 = 25; +pub const N_SPEAKUP: u32 = 26; +pub const N_NULL: u32 = 27; +pub const N_MCTP: u32 = 28; +pub const N_DEVELOPMENT: u32 = 29; +pub const N_CAN327: u32 = 30; +pub const NR_LDISCS: u32 = 31; +pub const INPUT_PROP_POINTER: u32 = 0; +pub const INPUT_PROP_DIRECT: u32 = 1; +pub const INPUT_PROP_BUTTONPAD: u32 = 2; +pub const INPUT_PROP_SEMI_MT: u32 = 3; +pub const INPUT_PROP_TOPBUTTONPAD: u32 = 4; +pub const INPUT_PROP_POINTING_STICK: u32 = 5; +pub const INPUT_PROP_ACCELEROMETER: u32 = 6; +pub const INPUT_PROP_MAX: u32 = 31; +pub const INPUT_PROP_CNT: u32 = 32; +pub const EV_SYN: u32 = 0; +pub const EV_KEY: u32 = 1; +pub const EV_REL: u32 = 2; +pub const EV_ABS: u32 = 3; +pub const EV_MSC: u32 = 4; +pub const EV_SW: u32 = 5; +pub const EV_LED: u32 = 17; +pub const EV_SND: u32 = 18; +pub const EV_REP: u32 = 20; +pub const EV_FF: u32 = 21; +pub const EV_PWR: u32 = 22; +pub const EV_FF_STATUS: u32 = 23; +pub const EV_MAX: u32 = 31; +pub const EV_CNT: u32 = 32; +pub const SYN_REPORT: u32 = 0; +pub const SYN_CONFIG: u32 = 1; +pub const SYN_MT_REPORT: u32 = 2; +pub const SYN_DROPPED: u32 = 3; +pub const SYN_MAX: u32 = 15; +pub const SYN_CNT: u32 = 16; +pub const KEY_RESERVED: u32 = 0; +pub const KEY_ESC: u32 = 1; +pub const KEY_1: u32 = 2; +pub const KEY_2: u32 = 3; +pub const KEY_3: u32 = 4; +pub const KEY_4: u32 = 5; +pub const KEY_5: u32 = 6; +pub const KEY_6: u32 = 7; +pub const KEY_7: u32 = 8; +pub const KEY_8: u32 = 9; +pub const KEY_9: u32 = 10; +pub const KEY_0: u32 = 11; +pub const KEY_MINUS: u32 = 12; +pub const KEY_EQUAL: u32 = 13; +pub const KEY_BACKSPACE: u32 = 14; +pub const KEY_TAB: u32 = 15; +pub const KEY_Q: u32 = 16; +pub const KEY_W: u32 = 17; +pub const KEY_E: u32 = 18; +pub const KEY_R: u32 = 19; +pub const KEY_T: u32 = 20; +pub const KEY_Y: u32 = 21; +pub const KEY_U: u32 = 22; +pub const KEY_I: u32 = 23; +pub const KEY_O: u32 = 24; +pub const KEY_P: u32 = 25; +pub const KEY_LEFTBRACE: u32 = 26; +pub const KEY_RIGHTBRACE: u32 = 27; +pub const KEY_ENTER: u32 = 28; +pub const KEY_LEFTCTRL: u32 = 29; +pub const KEY_A: u32 = 30; +pub const KEY_S: u32 = 31; +pub const KEY_D: u32 = 32; +pub const KEY_F: u32 = 33; +pub const KEY_G: u32 = 34; +pub const KEY_H: u32 = 35; +pub const KEY_J: u32 = 36; +pub const KEY_K: u32 = 37; +pub const KEY_L: u32 = 38; +pub const KEY_SEMICOLON: u32 = 39; +pub const KEY_APOSTROPHE: u32 = 40; +pub const KEY_GRAVE: u32 = 41; +pub const KEY_LEFTSHIFT: u32 = 42; +pub const KEY_BACKSLASH: u32 = 43; +pub const KEY_Z: u32 = 44; +pub const KEY_X: u32 = 45; +pub const KEY_C: u32 = 46; +pub const KEY_V: u32 = 47; +pub const KEY_B: u32 = 48; +pub const KEY_N: u32 = 49; +pub const KEY_M: u32 = 50; +pub const KEY_COMMA: u32 = 51; +pub const KEY_DOT: u32 = 52; +pub const KEY_SLASH: u32 = 53; +pub const KEY_RIGHTSHIFT: u32 = 54; +pub const KEY_KPASTERISK: u32 = 55; +pub const KEY_LEFTALT: u32 = 56; +pub const KEY_SPACE: u32 = 57; +pub const KEY_CAPSLOCK: u32 = 58; +pub const KEY_F1: u32 = 59; +pub const KEY_F2: u32 = 60; +pub const KEY_F3: u32 = 61; +pub const KEY_F4: u32 = 62; +pub const KEY_F5: u32 = 63; +pub const KEY_F6: u32 = 64; +pub const KEY_F7: u32 = 65; +pub const KEY_F8: u32 = 66; +pub const KEY_F9: u32 = 67; +pub const KEY_F10: u32 = 68; +pub const KEY_NUMLOCK: u32 = 69; +pub const KEY_SCROLLLOCK: u32 = 70; +pub const KEY_KP7: u32 = 71; +pub const KEY_KP8: u32 = 72; +pub const KEY_KP9: u32 = 73; +pub const KEY_KPMINUS: u32 = 74; +pub const KEY_KP4: u32 = 75; +pub const KEY_KP5: u32 = 76; +pub const KEY_KP6: u32 = 77; +pub const KEY_KPPLUS: u32 = 78; +pub const KEY_KP1: u32 = 79; +pub const KEY_KP2: u32 = 80; +pub const KEY_KP3: u32 = 81; +pub const KEY_KP0: u32 = 82; +pub const KEY_KPDOT: u32 = 83; +pub const KEY_ZENKAKUHANKAKU: u32 = 85; +pub const KEY_102ND: u32 = 86; +pub const KEY_F11: u32 = 87; +pub const KEY_F12: u32 = 88; +pub const KEY_RO: u32 = 89; +pub const KEY_KATAKANA: u32 = 90; +pub const KEY_HIRAGANA: u32 = 91; +pub const KEY_HENKAN: u32 = 92; +pub const KEY_KATAKANAHIRAGANA: u32 = 93; +pub const KEY_MUHENKAN: u32 = 94; +pub const KEY_KPJPCOMMA: u32 = 95; +pub const KEY_KPENTER: u32 = 96; +pub const KEY_RIGHTCTRL: u32 = 97; +pub const KEY_KPSLASH: u32 = 98; +pub const KEY_SYSRQ: u32 = 99; +pub const KEY_RIGHTALT: u32 = 100; +pub const KEY_LINEFEED: u32 = 101; +pub const KEY_HOME: u32 = 102; +pub const KEY_UP: u32 = 103; +pub const KEY_PAGEUP: u32 = 104; +pub const KEY_LEFT: u32 = 105; +pub const KEY_RIGHT: u32 = 106; +pub const KEY_END: u32 = 107; +pub const KEY_DOWN: u32 = 108; +pub const KEY_PAGEDOWN: u32 = 109; +pub const KEY_INSERT: u32 = 110; +pub const KEY_DELETE: u32 = 111; +pub const KEY_MACRO: u32 = 112; +pub const KEY_MUTE: u32 = 113; +pub const KEY_VOLUMEDOWN: u32 = 114; +pub const KEY_VOLUMEUP: u32 = 115; +pub const KEY_POWER: u32 = 116; +pub const KEY_KPEQUAL: u32 = 117; +pub const KEY_KPPLUSMINUS: u32 = 118; +pub const KEY_PAUSE: u32 = 119; +pub const KEY_SCALE: u32 = 120; +pub const KEY_KPCOMMA: u32 = 121; +pub const KEY_HANGEUL: u32 = 122; +pub const KEY_HANGUEL: u32 = 122; +pub const KEY_HANJA: u32 = 123; +pub const KEY_YEN: u32 = 124; +pub const KEY_LEFTMETA: u32 = 125; +pub const KEY_RIGHTMETA: u32 = 126; +pub const KEY_COMPOSE: u32 = 127; +pub const KEY_STOP: u32 = 128; +pub const KEY_AGAIN: u32 = 129; +pub const KEY_PROPS: u32 = 130; +pub const KEY_UNDO: u32 = 131; +pub const KEY_FRONT: u32 = 132; +pub const KEY_COPY: u32 = 133; +pub const KEY_OPEN: u32 = 134; +pub const KEY_PASTE: u32 = 135; +pub const KEY_FIND: u32 = 136; +pub const KEY_CUT: u32 = 137; +pub const KEY_HELP: u32 = 138; +pub const KEY_MENU: u32 = 139; +pub const KEY_CALC: u32 = 140; +pub const KEY_SETUP: u32 = 141; +pub const KEY_SLEEP: u32 = 142; +pub const KEY_WAKEUP: u32 = 143; +pub const KEY_FILE: u32 = 144; +pub const KEY_SENDFILE: u32 = 145; +pub const KEY_DELETEFILE: u32 = 146; +pub const KEY_XFER: u32 = 147; +pub const KEY_PROG1: u32 = 148; +pub const KEY_PROG2: u32 = 149; +pub const KEY_WWW: u32 = 150; +pub const KEY_MSDOS: u32 = 151; +pub const KEY_COFFEE: u32 = 152; +pub const KEY_SCREENLOCK: u32 = 152; +pub const KEY_ROTATE_DISPLAY: u32 = 153; +pub const KEY_DIRECTION: u32 = 153; +pub const KEY_CYCLEWINDOWS: u32 = 154; +pub const KEY_MAIL: u32 = 155; +pub const KEY_BOOKMARKS: u32 = 156; +pub const KEY_COMPUTER: u32 = 157; +pub const KEY_BACK: u32 = 158; +pub const KEY_FORWARD: u32 = 159; +pub const KEY_CLOSECD: u32 = 160; +pub const KEY_EJECTCD: u32 = 161; +pub const KEY_EJECTCLOSECD: u32 = 162; +pub const KEY_NEXTSONG: u32 = 163; +pub const KEY_PLAYPAUSE: u32 = 164; +pub const KEY_PREVIOUSSONG: u32 = 165; +pub const KEY_STOPCD: u32 = 166; +pub const KEY_RECORD: u32 = 167; +pub const KEY_REWIND: u32 = 168; +pub const KEY_PHONE: u32 = 169; +pub const KEY_ISO: u32 = 170; +pub const KEY_CONFIG: u32 = 171; +pub const KEY_HOMEPAGE: u32 = 172; +pub const KEY_REFRESH: u32 = 173; +pub const KEY_EXIT: u32 = 174; +pub const KEY_MOVE: u32 = 175; +pub const KEY_EDIT: u32 = 176; +pub const KEY_SCROLLUP: u32 = 177; +pub const KEY_SCROLLDOWN: u32 = 178; +pub const KEY_KPLEFTPAREN: u32 = 179; +pub const KEY_KPRIGHTPAREN: u32 = 180; +pub const KEY_NEW: u32 = 181; +pub const KEY_REDO: u32 = 182; +pub const KEY_F13: u32 = 183; +pub const KEY_F14: u32 = 184; +pub const KEY_F15: u32 = 185; +pub const KEY_F16: u32 = 186; +pub const KEY_F17: u32 = 187; +pub const KEY_F18: u32 = 188; +pub const KEY_F19: u32 = 189; +pub const KEY_F20: u32 = 190; +pub const KEY_F21: u32 = 191; +pub const KEY_F22: u32 = 192; +pub const KEY_F23: u32 = 193; +pub const KEY_F24: u32 = 194; +pub const KEY_PLAYCD: u32 = 200; +pub const KEY_PAUSECD: u32 = 201; +pub const KEY_PROG3: u32 = 202; +pub const KEY_PROG4: u32 = 203; +pub const KEY_ALL_APPLICATIONS: u32 = 204; +pub const KEY_DASHBOARD: u32 = 204; +pub const KEY_SUSPEND: u32 = 205; +pub const KEY_CLOSE: u32 = 206; +pub const KEY_PLAY: u32 = 207; +pub const KEY_FASTFORWARD: u32 = 208; +pub const KEY_BASSBOOST: u32 = 209; +pub const KEY_PRINT: u32 = 210; +pub const KEY_HP: u32 = 211; +pub const KEY_CAMERA: u32 = 212; +pub const KEY_SOUND: u32 = 213; +pub const KEY_QUESTION: u32 = 214; +pub const KEY_EMAIL: u32 = 215; +pub const KEY_CHAT: u32 = 216; +pub const KEY_SEARCH: u32 = 217; +pub const KEY_CONNECT: u32 = 218; +pub const KEY_FINANCE: u32 = 219; +pub const KEY_SPORT: u32 = 220; +pub const KEY_SHOP: u32 = 221; +pub const KEY_ALTERASE: u32 = 222; +pub const KEY_CANCEL: u32 = 223; +pub const KEY_BRIGHTNESSDOWN: u32 = 224; +pub const KEY_BRIGHTNESSUP: u32 = 225; +pub const KEY_MEDIA: u32 = 226; +pub const KEY_SWITCHVIDEOMODE: u32 = 227; +pub const KEY_KBDILLUMTOGGLE: u32 = 228; +pub const KEY_KBDILLUMDOWN: u32 = 229; +pub const KEY_KBDILLUMUP: u32 = 230; +pub const KEY_SEND: u32 = 231; +pub const KEY_REPLY: u32 = 232; +pub const KEY_FORWARDMAIL: u32 = 233; +pub const KEY_SAVE: u32 = 234; +pub const KEY_DOCUMENTS: u32 = 235; +pub const KEY_BATTERY: u32 = 236; +pub const KEY_BLUETOOTH: u32 = 237; +pub const KEY_WLAN: u32 = 238; +pub const KEY_UWB: u32 = 239; +pub const KEY_UNKNOWN: u32 = 240; +pub const KEY_VIDEO_NEXT: u32 = 241; +pub const KEY_VIDEO_PREV: u32 = 242; +pub const KEY_BRIGHTNESS_CYCLE: u32 = 243; +pub const KEY_BRIGHTNESS_AUTO: u32 = 244; +pub const KEY_BRIGHTNESS_ZERO: u32 = 244; +pub const KEY_DISPLAY_OFF: u32 = 245; +pub const KEY_WWAN: u32 = 246; +pub const KEY_WIMAX: u32 = 246; +pub const KEY_RFKILL: u32 = 247; +pub const KEY_MICMUTE: u32 = 248; +pub const BTN_MISC: u32 = 256; +pub const BTN_0: u32 = 256; +pub const BTN_1: u32 = 257; +pub const BTN_2: u32 = 258; +pub const BTN_3: u32 = 259; +pub const BTN_4: u32 = 260; +pub const BTN_5: u32 = 261; +pub const BTN_6: u32 = 262; +pub const BTN_7: u32 = 263; +pub const BTN_8: u32 = 264; +pub const BTN_9: u32 = 265; +pub const BTN_MOUSE: u32 = 272; +pub const BTN_LEFT: u32 = 272; +pub const BTN_RIGHT: u32 = 273; +pub const BTN_MIDDLE: u32 = 274; +pub const BTN_SIDE: u32 = 275; +pub const BTN_EXTRA: u32 = 276; +pub const BTN_FORWARD: u32 = 277; +pub const BTN_BACK: u32 = 278; +pub const BTN_TASK: u32 = 279; +pub const BTN_JOYSTICK: u32 = 288; +pub const BTN_TRIGGER: u32 = 288; +pub const BTN_THUMB: u32 = 289; +pub const BTN_THUMB2: u32 = 290; +pub const BTN_TOP: u32 = 291; +pub const BTN_TOP2: u32 = 292; +pub const BTN_PINKIE: u32 = 293; +pub const BTN_BASE: u32 = 294; +pub const BTN_BASE2: u32 = 295; +pub const BTN_BASE3: u32 = 296; +pub const BTN_BASE4: u32 = 297; +pub const BTN_BASE5: u32 = 298; +pub const BTN_BASE6: u32 = 299; +pub const BTN_DEAD: u32 = 303; +pub const BTN_GAMEPAD: u32 = 304; +pub const BTN_SOUTH: u32 = 304; +pub const BTN_A: u32 = 304; +pub const BTN_EAST: u32 = 305; +pub const BTN_B: u32 = 305; +pub const BTN_C: u32 = 306; +pub const BTN_NORTH: u32 = 307; +pub const BTN_X: u32 = 307; +pub const BTN_WEST: u32 = 308; +pub const BTN_Y: u32 = 308; +pub const BTN_Z: u32 = 309; +pub const BTN_TL: u32 = 310; +pub const BTN_TR: u32 = 311; +pub const BTN_TL2: u32 = 312; +pub const BTN_TR2: u32 = 313; +pub const BTN_SELECT: u32 = 314; +pub const BTN_START: u32 = 315; +pub const BTN_MODE: u32 = 316; +pub const BTN_THUMBL: u32 = 317; +pub const BTN_THUMBR: u32 = 318; +pub const BTN_DIGI: u32 = 320; +pub const BTN_TOOL_PEN: u32 = 320; +pub const BTN_TOOL_RUBBER: u32 = 321; +pub const BTN_TOOL_BRUSH: u32 = 322; +pub const BTN_TOOL_PENCIL: u32 = 323; +pub const BTN_TOOL_AIRBRUSH: u32 = 324; +pub const BTN_TOOL_FINGER: u32 = 325; +pub const BTN_TOOL_MOUSE: u32 = 326; +pub const BTN_TOOL_LENS: u32 = 327; +pub const BTN_TOOL_QUINTTAP: u32 = 328; +pub const BTN_STYLUS3: u32 = 329; +pub const BTN_TOUCH: u32 = 330; +pub const BTN_STYLUS: u32 = 331; +pub const BTN_STYLUS2: u32 = 332; +pub const BTN_TOOL_DOUBLETAP: u32 = 333; +pub const BTN_TOOL_TRIPLETAP: u32 = 334; +pub const BTN_TOOL_QUADTAP: u32 = 335; +pub const BTN_WHEEL: u32 = 336; +pub const BTN_GEAR_DOWN: u32 = 336; +pub const BTN_GEAR_UP: u32 = 337; +pub const KEY_OK: u32 = 352; +pub const KEY_SELECT: u32 = 353; +pub const KEY_GOTO: u32 = 354; +pub const KEY_CLEAR: u32 = 355; +pub const KEY_POWER2: u32 = 356; +pub const KEY_OPTION: u32 = 357; +pub const KEY_INFO: u32 = 358; +pub const KEY_TIME: u32 = 359; +pub const KEY_VENDOR: u32 = 360; +pub const KEY_ARCHIVE: u32 = 361; +pub const KEY_PROGRAM: u32 = 362; +pub const KEY_CHANNEL: u32 = 363; +pub const KEY_FAVORITES: u32 = 364; +pub const KEY_EPG: u32 = 365; +pub const KEY_PVR: u32 = 366; +pub const KEY_MHP: u32 = 367; +pub const KEY_LANGUAGE: u32 = 368; +pub const KEY_TITLE: u32 = 369; +pub const KEY_SUBTITLE: u32 = 370; +pub const KEY_ANGLE: u32 = 371; +pub const KEY_FULL_SCREEN: u32 = 372; +pub const KEY_ZOOM: u32 = 372; +pub const KEY_MODE: u32 = 373; +pub const KEY_KEYBOARD: u32 = 374; +pub const KEY_ASPECT_RATIO: u32 = 375; +pub const KEY_SCREEN: u32 = 375; +pub const KEY_PC: u32 = 376; +pub const KEY_TV: u32 = 377; +pub const KEY_TV2: u32 = 378; +pub const KEY_VCR: u32 = 379; +pub const KEY_VCR2: u32 = 380; +pub const KEY_SAT: u32 = 381; +pub const KEY_SAT2: u32 = 382; +pub const KEY_CD: u32 = 383; +pub const KEY_TAPE: u32 = 384; +pub const KEY_RADIO: u32 = 385; +pub const KEY_TUNER: u32 = 386; +pub const KEY_PLAYER: u32 = 387; +pub const KEY_TEXT: u32 = 388; +pub const KEY_DVD: u32 = 389; +pub const KEY_AUX: u32 = 390; +pub const KEY_MP3: u32 = 391; +pub const KEY_AUDIO: u32 = 392; +pub const KEY_VIDEO: u32 = 393; +pub const KEY_DIRECTORY: u32 = 394; +pub const KEY_LIST: u32 = 395; +pub const KEY_MEMO: u32 = 396; +pub const KEY_CALENDAR: u32 = 397; +pub const KEY_RED: u32 = 398; +pub const KEY_GREEN: u32 = 399; +pub const KEY_YELLOW: u32 = 400; +pub const KEY_BLUE: u32 = 401; +pub const KEY_CHANNELUP: u32 = 402; +pub const KEY_CHANNELDOWN: u32 = 403; +pub const KEY_FIRST: u32 = 404; +pub const KEY_LAST: u32 = 405; +pub const KEY_AB: u32 = 406; +pub const KEY_NEXT: u32 = 407; +pub const KEY_RESTART: u32 = 408; +pub const KEY_SLOW: u32 = 409; +pub const KEY_SHUFFLE: u32 = 410; +pub const KEY_BREAK: u32 = 411; +pub const KEY_PREVIOUS: u32 = 412; +pub const KEY_DIGITS: u32 = 413; +pub const KEY_TEEN: u32 = 414; +pub const KEY_TWEN: u32 = 415; +pub const KEY_VIDEOPHONE: u32 = 416; +pub const KEY_GAMES: u32 = 417; +pub const KEY_ZOOMIN: u32 = 418; +pub const KEY_ZOOMOUT: u32 = 419; +pub const KEY_ZOOMRESET: u32 = 420; +pub const KEY_WORDPROCESSOR: u32 = 421; +pub const KEY_EDITOR: u32 = 422; +pub const KEY_SPREADSHEET: u32 = 423; +pub const KEY_GRAPHICSEDITOR: u32 = 424; +pub const KEY_PRESENTATION: u32 = 425; +pub const KEY_DATABASE: u32 = 426; +pub const KEY_NEWS: u32 = 427; +pub const KEY_VOICEMAIL: u32 = 428; +pub const KEY_ADDRESSBOOK: u32 = 429; +pub const KEY_MESSENGER: u32 = 430; +pub const KEY_DISPLAYTOGGLE: u32 = 431; +pub const KEY_BRIGHTNESS_TOGGLE: u32 = 431; +pub const KEY_SPELLCHECK: u32 = 432; +pub const KEY_LOGOFF: u32 = 433; +pub const KEY_DOLLAR: u32 = 434; +pub const KEY_EURO: u32 = 435; +pub const KEY_FRAMEBACK: u32 = 436; +pub const KEY_FRAMEFORWARD: u32 = 437; +pub const KEY_CONTEXT_MENU: u32 = 438; +pub const KEY_MEDIA_REPEAT: u32 = 439; +pub const KEY_10CHANNELSUP: u32 = 440; +pub const KEY_10CHANNELSDOWN: u32 = 441; +pub const KEY_IMAGES: u32 = 442; +pub const KEY_NOTIFICATION_CENTER: u32 = 444; +pub const KEY_PICKUP_PHONE: u32 = 445; +pub const KEY_HANGUP_PHONE: u32 = 446; +pub const KEY_DEL_EOL: u32 = 448; +pub const KEY_DEL_EOS: u32 = 449; +pub const KEY_INS_LINE: u32 = 450; +pub const KEY_DEL_LINE: u32 = 451; +pub const KEY_FN: u32 = 464; +pub const KEY_FN_ESC: u32 = 465; +pub const KEY_FN_F1: u32 = 466; +pub const KEY_FN_F2: u32 = 467; +pub const KEY_FN_F3: u32 = 468; +pub const KEY_FN_F4: u32 = 469; +pub const KEY_FN_F5: u32 = 470; +pub const KEY_FN_F6: u32 = 471; +pub const KEY_FN_F7: u32 = 472; +pub const KEY_FN_F8: u32 = 473; +pub const KEY_FN_F9: u32 = 474; +pub const KEY_FN_F10: u32 = 475; +pub const KEY_FN_F11: u32 = 476; +pub const KEY_FN_F12: u32 = 477; +pub const KEY_FN_1: u32 = 478; +pub const KEY_FN_2: u32 = 479; +pub const KEY_FN_D: u32 = 480; +pub const KEY_FN_E: u32 = 481; +pub const KEY_FN_F: u32 = 482; +pub const KEY_FN_S: u32 = 483; +pub const KEY_FN_B: u32 = 484; +pub const KEY_FN_RIGHT_SHIFT: u32 = 485; +pub const KEY_BRL_DOT1: u32 = 497; +pub const KEY_BRL_DOT2: u32 = 498; +pub const KEY_BRL_DOT3: u32 = 499; +pub const KEY_BRL_DOT4: u32 = 500; +pub const KEY_BRL_DOT5: u32 = 501; +pub const KEY_BRL_DOT6: u32 = 502; +pub const KEY_BRL_DOT7: u32 = 503; +pub const KEY_BRL_DOT8: u32 = 504; +pub const KEY_BRL_DOT9: u32 = 505; +pub const KEY_BRL_DOT10: u32 = 506; +pub const KEY_NUMERIC_0: u32 = 512; +pub const KEY_NUMERIC_1: u32 = 513; +pub const KEY_NUMERIC_2: u32 = 514; +pub const KEY_NUMERIC_3: u32 = 515; +pub const KEY_NUMERIC_4: u32 = 516; +pub const KEY_NUMERIC_5: u32 = 517; +pub const KEY_NUMERIC_6: u32 = 518; +pub const KEY_NUMERIC_7: u32 = 519; +pub const KEY_NUMERIC_8: u32 = 520; +pub const KEY_NUMERIC_9: u32 = 521; +pub const KEY_NUMERIC_STAR: u32 = 522; +pub const KEY_NUMERIC_POUND: u32 = 523; +pub const KEY_NUMERIC_A: u32 = 524; +pub const KEY_NUMERIC_B: u32 = 525; +pub const KEY_NUMERIC_C: u32 = 526; +pub const KEY_NUMERIC_D: u32 = 527; +pub const KEY_CAMERA_FOCUS: u32 = 528; +pub const KEY_WPS_BUTTON: u32 = 529; +pub const KEY_TOUCHPAD_TOGGLE: u32 = 530; +pub const KEY_TOUCHPAD_ON: u32 = 531; +pub const KEY_TOUCHPAD_OFF: u32 = 532; +pub const KEY_CAMERA_ZOOMIN: u32 = 533; +pub const KEY_CAMERA_ZOOMOUT: u32 = 534; +pub const KEY_CAMERA_UP: u32 = 535; +pub const KEY_CAMERA_DOWN: u32 = 536; +pub const KEY_CAMERA_LEFT: u32 = 537; +pub const KEY_CAMERA_RIGHT: u32 = 538; +pub const KEY_ATTENDANT_ON: u32 = 539; +pub const KEY_ATTENDANT_OFF: u32 = 540; +pub const KEY_ATTENDANT_TOGGLE: u32 = 541; +pub const KEY_LIGHTS_TOGGLE: u32 = 542; +pub const BTN_DPAD_UP: u32 = 544; +pub const BTN_DPAD_DOWN: u32 = 545; +pub const BTN_DPAD_LEFT: u32 = 546; +pub const BTN_DPAD_RIGHT: u32 = 547; +pub const KEY_ALS_TOGGLE: u32 = 560; +pub const KEY_ROTATE_LOCK_TOGGLE: u32 = 561; +pub const KEY_BUTTONCONFIG: u32 = 576; +pub const KEY_TASKMANAGER: u32 = 577; +pub const KEY_JOURNAL: u32 = 578; +pub const KEY_CONTROLPANEL: u32 = 579; +pub const KEY_APPSELECT: u32 = 580; +pub const KEY_SCREENSAVER: u32 = 581; +pub const KEY_VOICECOMMAND: u32 = 582; +pub const KEY_ASSISTANT: u32 = 583; +pub const KEY_KBD_LAYOUT_NEXT: u32 = 584; +pub const KEY_EMOJI_PICKER: u32 = 585; +pub const KEY_DICTATE: u32 = 586; +pub const KEY_CAMERA_ACCESS_ENABLE: u32 = 587; +pub const KEY_CAMERA_ACCESS_DISABLE: u32 = 588; +pub const KEY_CAMERA_ACCESS_TOGGLE: u32 = 589; +pub const KEY_BRIGHTNESS_MIN: u32 = 592; +pub const KEY_BRIGHTNESS_MAX: u32 = 593; +pub const KEY_KBDINPUTASSIST_PREV: u32 = 608; +pub const KEY_KBDINPUTASSIST_NEXT: u32 = 609; +pub const KEY_KBDINPUTASSIST_PREVGROUP: u32 = 610; +pub const KEY_KBDINPUTASSIST_NEXTGROUP: u32 = 611; +pub const KEY_KBDINPUTASSIST_ACCEPT: u32 = 612; +pub const KEY_KBDINPUTASSIST_CANCEL: u32 = 613; +pub const KEY_RIGHT_UP: u32 = 614; +pub const KEY_RIGHT_DOWN: u32 = 615; +pub const KEY_LEFT_UP: u32 = 616; +pub const KEY_LEFT_DOWN: u32 = 617; +pub const KEY_ROOT_MENU: u32 = 618; +pub const KEY_MEDIA_TOP_MENU: u32 = 619; +pub const KEY_NUMERIC_11: u32 = 620; +pub const KEY_NUMERIC_12: u32 = 621; +pub const KEY_AUDIO_DESC: u32 = 622; +pub const KEY_3D_MODE: u32 = 623; +pub const KEY_NEXT_FAVORITE: u32 = 624; +pub const KEY_STOP_RECORD: u32 = 625; +pub const KEY_PAUSE_RECORD: u32 = 626; +pub const KEY_VOD: u32 = 627; +pub const KEY_UNMUTE: u32 = 628; +pub const KEY_FASTREVERSE: u32 = 629; +pub const KEY_SLOWREVERSE: u32 = 630; +pub const KEY_DATA: u32 = 631; +pub const KEY_ONSCREEN_KEYBOARD: u32 = 632; +pub const KEY_PRIVACY_SCREEN_TOGGLE: u32 = 633; +pub const KEY_SELECTIVE_SCREENSHOT: u32 = 634; +pub const KEY_NEXT_ELEMENT: u32 = 635; +pub const KEY_PREVIOUS_ELEMENT: u32 = 636; +pub const KEY_AUTOPILOT_ENGAGE_TOGGLE: u32 = 637; +pub const KEY_MARK_WAYPOINT: u32 = 638; +pub const KEY_SOS: u32 = 639; +pub const KEY_NAV_CHART: u32 = 640; +pub const KEY_FISHING_CHART: u32 = 641; +pub const KEY_SINGLE_RANGE_RADAR: u32 = 642; +pub const KEY_DUAL_RANGE_RADAR: u32 = 643; +pub const KEY_RADAR_OVERLAY: u32 = 644; +pub const KEY_TRADITIONAL_SONAR: u32 = 645; +pub const KEY_CLEARVU_SONAR: u32 = 646; +pub const KEY_SIDEVU_SONAR: u32 = 647; +pub const KEY_NAV_INFO: u32 = 648; +pub const KEY_BRIGHTNESS_MENU: u32 = 649; +pub const KEY_MACRO1: u32 = 656; +pub const KEY_MACRO2: u32 = 657; +pub const KEY_MACRO3: u32 = 658; +pub const KEY_MACRO4: u32 = 659; +pub const KEY_MACRO5: u32 = 660; +pub const KEY_MACRO6: u32 = 661; +pub const KEY_MACRO7: u32 = 662; +pub const KEY_MACRO8: u32 = 663; +pub const KEY_MACRO9: u32 = 664; +pub const KEY_MACRO10: u32 = 665; +pub const KEY_MACRO11: u32 = 666; +pub const KEY_MACRO12: u32 = 667; +pub const KEY_MACRO13: u32 = 668; +pub const KEY_MACRO14: u32 = 669; +pub const KEY_MACRO15: u32 = 670; +pub const KEY_MACRO16: u32 = 671; +pub const KEY_MACRO17: u32 = 672; +pub const KEY_MACRO18: u32 = 673; +pub const KEY_MACRO19: u32 = 674; +pub const KEY_MACRO20: u32 = 675; +pub const KEY_MACRO21: u32 = 676; +pub const KEY_MACRO22: u32 = 677; +pub const KEY_MACRO23: u32 = 678; +pub const KEY_MACRO24: u32 = 679; +pub const KEY_MACRO25: u32 = 680; +pub const KEY_MACRO26: u32 = 681; +pub const KEY_MACRO27: u32 = 682; +pub const KEY_MACRO28: u32 = 683; +pub const KEY_MACRO29: u32 = 684; +pub const KEY_MACRO30: u32 = 685; +pub const KEY_MACRO_RECORD_START: u32 = 688; +pub const KEY_MACRO_RECORD_STOP: u32 = 689; +pub const KEY_MACRO_PRESET_CYCLE: u32 = 690; +pub const KEY_MACRO_PRESET1: u32 = 691; +pub const KEY_MACRO_PRESET2: u32 = 692; +pub const KEY_MACRO_PRESET3: u32 = 693; +pub const KEY_KBD_LCD_MENU1: u32 = 696; +pub const KEY_KBD_LCD_MENU2: u32 = 697; +pub const KEY_KBD_LCD_MENU3: u32 = 698; +pub const KEY_KBD_LCD_MENU4: u32 = 699; +pub const KEY_KBD_LCD_MENU5: u32 = 700; +pub const BTN_TRIGGER_HAPPY: u32 = 704; +pub const BTN_TRIGGER_HAPPY1: u32 = 704; +pub const BTN_TRIGGER_HAPPY2: u32 = 705; +pub const BTN_TRIGGER_HAPPY3: u32 = 706; +pub const BTN_TRIGGER_HAPPY4: u32 = 707; +pub const BTN_TRIGGER_HAPPY5: u32 = 708; +pub const BTN_TRIGGER_HAPPY6: u32 = 709; +pub const BTN_TRIGGER_HAPPY7: u32 = 710; +pub const BTN_TRIGGER_HAPPY8: u32 = 711; +pub const BTN_TRIGGER_HAPPY9: u32 = 712; +pub const BTN_TRIGGER_HAPPY10: u32 = 713; +pub const BTN_TRIGGER_HAPPY11: u32 = 714; +pub const BTN_TRIGGER_HAPPY12: u32 = 715; +pub const BTN_TRIGGER_HAPPY13: u32 = 716; +pub const BTN_TRIGGER_HAPPY14: u32 = 717; +pub const BTN_TRIGGER_HAPPY15: u32 = 718; +pub const BTN_TRIGGER_HAPPY16: u32 = 719; +pub const BTN_TRIGGER_HAPPY17: u32 = 720; +pub const BTN_TRIGGER_HAPPY18: u32 = 721; +pub const BTN_TRIGGER_HAPPY19: u32 = 722; +pub const BTN_TRIGGER_HAPPY20: u32 = 723; +pub const BTN_TRIGGER_HAPPY21: u32 = 724; +pub const BTN_TRIGGER_HAPPY22: u32 = 725; +pub const BTN_TRIGGER_HAPPY23: u32 = 726; +pub const BTN_TRIGGER_HAPPY24: u32 = 727; +pub const BTN_TRIGGER_HAPPY25: u32 = 728; +pub const BTN_TRIGGER_HAPPY26: u32 = 729; +pub const BTN_TRIGGER_HAPPY27: u32 = 730; +pub const BTN_TRIGGER_HAPPY28: u32 = 731; +pub const BTN_TRIGGER_HAPPY29: u32 = 732; +pub const BTN_TRIGGER_HAPPY30: u32 = 733; +pub const BTN_TRIGGER_HAPPY31: u32 = 734; +pub const BTN_TRIGGER_HAPPY32: u32 = 735; +pub const BTN_TRIGGER_HAPPY33: u32 = 736; +pub const BTN_TRIGGER_HAPPY34: u32 = 737; +pub const BTN_TRIGGER_HAPPY35: u32 = 738; +pub const BTN_TRIGGER_HAPPY36: u32 = 739; +pub const BTN_TRIGGER_HAPPY37: u32 = 740; +pub const BTN_TRIGGER_HAPPY38: u32 = 741; +pub const BTN_TRIGGER_HAPPY39: u32 = 742; +pub const BTN_TRIGGER_HAPPY40: u32 = 743; +pub const KEY_MIN_INTERESTING: u32 = 113; +pub const KEY_MAX: u32 = 767; +pub const KEY_CNT: u32 = 768; +pub const REL_X: u32 = 0; +pub const REL_Y: u32 = 1; +pub const REL_Z: u32 = 2; +pub const REL_RX: u32 = 3; +pub const REL_RY: u32 = 4; +pub const REL_RZ: u32 = 5; +pub const REL_HWHEEL: u32 = 6; +pub const REL_DIAL: u32 = 7; +pub const REL_WHEEL: u32 = 8; +pub const REL_MISC: u32 = 9; +pub const REL_RESERVED: u32 = 10; +pub const REL_WHEEL_HI_RES: u32 = 11; +pub const REL_HWHEEL_HI_RES: u32 = 12; +pub const REL_MAX: u32 = 15; +pub const REL_CNT: u32 = 16; +pub const ABS_X: u32 = 0; +pub const ABS_Y: u32 = 1; +pub const ABS_Z: u32 = 2; +pub const ABS_RX: u32 = 3; +pub const ABS_RY: u32 = 4; +pub const ABS_RZ: u32 = 5; +pub const ABS_THROTTLE: u32 = 6; +pub const ABS_RUDDER: u32 = 7; +pub const ABS_WHEEL: u32 = 8; +pub const ABS_GAS: u32 = 9; +pub const ABS_BRAKE: u32 = 10; +pub const ABS_HAT0X: u32 = 16; +pub const ABS_HAT0Y: u32 = 17; +pub const ABS_HAT1X: u32 = 18; +pub const ABS_HAT1Y: u32 = 19; +pub const ABS_HAT2X: u32 = 20; +pub const ABS_HAT2Y: u32 = 21; +pub const ABS_HAT3X: u32 = 22; +pub const ABS_HAT3Y: u32 = 23; +pub const ABS_PRESSURE: u32 = 24; +pub const ABS_DISTANCE: u32 = 25; +pub const ABS_TILT_X: u32 = 26; +pub const ABS_TILT_Y: u32 = 27; +pub const ABS_TOOL_WIDTH: u32 = 28; +pub const ABS_VOLUME: u32 = 32; +pub const ABS_PROFILE: u32 = 33; +pub const ABS_MISC: u32 = 40; +pub const ABS_RESERVED: u32 = 46; +pub const ABS_MT_SLOT: u32 = 47; +pub const ABS_MT_TOUCH_MAJOR: u32 = 48; +pub const ABS_MT_TOUCH_MINOR: u32 = 49; +pub const ABS_MT_WIDTH_MAJOR: u32 = 50; +pub const ABS_MT_WIDTH_MINOR: u32 = 51; +pub const ABS_MT_ORIENTATION: u32 = 52; +pub const ABS_MT_POSITION_X: u32 = 53; +pub const ABS_MT_POSITION_Y: u32 = 54; +pub const ABS_MT_TOOL_TYPE: u32 = 55; +pub const ABS_MT_BLOB_ID: u32 = 56; +pub const ABS_MT_TRACKING_ID: u32 = 57; +pub const ABS_MT_PRESSURE: u32 = 58; +pub const ABS_MT_DISTANCE: u32 = 59; +pub const ABS_MT_TOOL_X: u32 = 60; +pub const ABS_MT_TOOL_Y: u32 = 61; +pub const ABS_MAX: u32 = 63; +pub const ABS_CNT: u32 = 64; +pub const SW_LID: u32 = 0; +pub const SW_TABLET_MODE: u32 = 1; +pub const SW_HEADPHONE_INSERT: u32 = 2; +pub const SW_RFKILL_ALL: u32 = 3; +pub const SW_RADIO: u32 = 3; +pub const SW_MICROPHONE_INSERT: u32 = 4; +pub const SW_DOCK: u32 = 5; +pub const SW_LINEOUT_INSERT: u32 = 6; +pub const SW_JACK_PHYSICAL_INSERT: u32 = 7; +pub const SW_VIDEOOUT_INSERT: u32 = 8; +pub const SW_CAMERA_LENS_COVER: u32 = 9; +pub const SW_KEYPAD_SLIDE: u32 = 10; +pub const SW_FRONT_PROXIMITY: u32 = 11; +pub const SW_ROTATE_LOCK: u32 = 12; +pub const SW_LINEIN_INSERT: u32 = 13; +pub const SW_MUTE_DEVICE: u32 = 14; +pub const SW_PEN_INSERTED: u32 = 15; +pub const SW_MACHINE_COVER: u32 = 16; +pub const SW_MAX: u32 = 16; +pub const SW_CNT: u32 = 17; +pub const MSC_SERIAL: u32 = 0; +pub const MSC_PULSELED: u32 = 1; +pub const MSC_GESTURE: u32 = 2; +pub const MSC_RAW: u32 = 3; +pub const MSC_SCAN: u32 = 4; +pub const MSC_TIMESTAMP: u32 = 5; +pub const MSC_MAX: u32 = 7; +pub const MSC_CNT: u32 = 8; +pub const LED_NUML: u32 = 0; +pub const LED_CAPSL: u32 = 1; +pub const LED_SCROLLL: u32 = 2; +pub const LED_COMPOSE: u32 = 3; +pub const LED_KANA: u32 = 4; +pub const LED_SLEEP: u32 = 5; +pub const LED_SUSPEND: u32 = 6; +pub const LED_MUTE: u32 = 7; +pub const LED_MISC: u32 = 8; +pub const LED_MAIL: u32 = 9; +pub const LED_CHARGING: u32 = 10; +pub const LED_MAX: u32 = 15; +pub const LED_CNT: u32 = 16; +pub const REP_DELAY: u32 = 0; +pub const REP_PERIOD: u32 = 1; +pub const REP_MAX: u32 = 1; +pub const REP_CNT: u32 = 2; +pub const SND_CLICK: u32 = 0; +pub const SND_BELL: u32 = 1; +pub const SND_TONE: u32 = 2; +pub const SND_MAX: u32 = 7; +pub const SND_CNT: u32 = 8; +pub const EV_VERSION: u32 = 65537; +pub const INPUT_KEYMAP_BY_INDEX: u32 = 1; +pub const ID_BUS: u32 = 0; +pub const ID_VENDOR: u32 = 1; +pub const ID_PRODUCT: u32 = 2; +pub const ID_VERSION: u32 = 3; +pub const BUS_PCI: u32 = 1; +pub const BUS_ISAPNP: u32 = 2; +pub const BUS_USB: u32 = 3; +pub const BUS_HIL: u32 = 4; +pub const BUS_BLUETOOTH: u32 = 5; +pub const BUS_VIRTUAL: u32 = 6; +pub const BUS_ISA: u32 = 16; +pub const BUS_I8042: u32 = 17; +pub const BUS_XTKBD: u32 = 18; +pub const BUS_RS232: u32 = 19; +pub const BUS_GAMEPORT: u32 = 20; +pub const BUS_PARPORT: u32 = 21; +pub const BUS_AMIGA: u32 = 22; +pub const BUS_ADB: u32 = 23; +pub const BUS_I2C: u32 = 24; +pub const BUS_HOST: u32 = 25; +pub const BUS_GSC: u32 = 26; +pub const BUS_ATARI: u32 = 27; +pub const BUS_SPI: u32 = 28; +pub const BUS_RMI: u32 = 29; +pub const BUS_CEC: u32 = 30; +pub const BUS_INTEL_ISHTP: u32 = 31; +pub const BUS_AMD_SFH: u32 = 32; +pub const MT_TOOL_FINGER: u32 = 0; +pub const MT_TOOL_PEN: u32 = 1; +pub const MT_TOOL_PALM: u32 = 2; +pub const MT_TOOL_DIAL: u32 = 10; +pub const MT_TOOL_MAX: u32 = 15; +pub const FF_STATUS_STOPPED: u32 = 0; +pub const FF_STATUS_PLAYING: u32 = 1; +pub const FF_STATUS_MAX: u32 = 1; +pub const FF_RUMBLE: u32 = 80; +pub const FF_PERIODIC: u32 = 81; +pub const FF_CONSTANT: u32 = 82; +pub const FF_SPRING: u32 = 83; +pub const FF_FRICTION: u32 = 84; +pub const FF_DAMPER: u32 = 85; +pub const FF_INERTIA: u32 = 86; +pub const FF_RAMP: u32 = 87; +pub const FF_EFFECT_MIN: u32 = 80; +pub const FF_EFFECT_MAX: u32 = 87; +pub const FF_SQUARE: u32 = 88; +pub const FF_TRIANGLE: u32 = 89; +pub const FF_SINE: u32 = 90; +pub const FF_SAW_UP: u32 = 91; +pub const FF_SAW_DOWN: u32 = 92; +pub const FF_CUSTOM: u32 = 93; +pub const FF_WAVEFORM_MIN: u32 = 88; +pub const FF_WAVEFORM_MAX: u32 = 93; +pub const FF_GAIN: u32 = 96; +pub const FF_AUTOCENTER: u32 = 97; +pub const FF_MAX_EFFECTS: u32 = 96; +pub const FF_MAX: u32 = 127; +pub const FF_CNT: u32 = 128; +pub const SEEK_SET: u32 = 0; +pub const SEEK_CUR: u32 = 1; +pub const SEEK_END: u32 = 2; +pub const _IOFBF: u32 = 0; +pub const _IOLBF: u32 = 1; +pub const _IONBF: u32 = 2; +pub const BUFSIZ: u32 = 1024; +pub const EOF: i32 = -1; +pub const FOPEN_MAX: u32 = 20; +pub const FILENAME_MAX: u32 = 4096; +pub const L_tmpnam: u32 = 4096; +pub const P_tmpdir: &[u8; 6] = b"/tmp/\0"; +pub const L_ctermid: u32 = 1024; +pub const WNOHANG: u32 = 1; +pub const WUNTRACED: u32 = 2; +pub const WSTOPPED: u32 = 2; +pub const WEXITED: u32 = 4; +pub const WCONTINUED: u32 = 8; +pub const WNOWAIT: u32 = 16777216; +pub const __WNOTHREAD: u32 = 536870912; +pub const __WALL: u32 = 1073741824; +pub const __WCLONE: u32 = 2147483648; +pub const P_ALL: u32 = 0; +pub const P_PID: u32 = 1; +pub const P_PGID: u32 = 2; +pub const P_PIDFD: u32 = 3; +pub const STRUCT_MALLINFO_DECLARED: u32 = 1; +pub const M_DECAY_TIME: i32 = -100; +pub const M_PURGE: i32 = -101; +pub const M_PURGE_ALL: i32 = -104; +pub const M_MEMTAG_TUNING: i32 = -102; +pub const M_MEMTAG_TUNING_BUFFER_OVERFLOW: u32 = 0; +pub const M_MEMTAG_TUNING_UAF: u32 = 1; +pub const M_THREAD_DISABLE_MEM_INIT: i32 = -103; +pub const M_CACHE_COUNT_MAX: i32 = -200; +pub const M_CACHE_SIZE_MAX: i32 = -201; +pub const M_TSDS_COUNT_MAX: i32 = -202; +pub const M_BIONIC_ZERO_INIT: i32 = -203; +pub const M_BIONIC_SET_HEAP_TAGGING_LEVEL: i32 = -204; +pub const M_LOG_STATS: i32 = -205; +pub const EXIT_FAILURE: u32 = 1; +pub const EXIT_SUCCESS: u32 = 0; +pub const RAND_MAX: u32 = 2147483647; +pub const __bool_true_false_are_defined: u32 = 1; +pub const true_: u32 = 1; +pub const false_: u32 = 0; +pub const EPERM: u32 = 1; +pub const ENOENT: u32 = 2; +pub const ESRCH: u32 = 3; +pub const EINTR: u32 = 4; +pub const EIO: u32 = 5; +pub const ENXIO: u32 = 6; +pub const E2BIG: u32 = 7; +pub const ENOEXEC: u32 = 8; +pub const EBADF: u32 = 9; +pub const ECHILD: u32 = 10; +pub const EAGAIN: u32 = 11; +pub const ENOMEM: u32 = 12; +pub const EACCES: u32 = 13; +pub const EFAULT: u32 = 14; +pub const ENOTBLK: u32 = 15; +pub const EBUSY: u32 = 16; +pub const EEXIST: u32 = 17; +pub const EXDEV: u32 = 18; +pub const ENODEV: u32 = 19; +pub const ENOTDIR: u32 = 20; +pub const EISDIR: u32 = 21; +pub const EINVAL: u32 = 22; +pub const ENFILE: u32 = 23; +pub const EMFILE: u32 = 24; +pub const ENOTTY: u32 = 25; +pub const ETXTBSY: u32 = 26; +pub const EFBIG: u32 = 27; +pub const ENOSPC: u32 = 28; +pub const ESPIPE: u32 = 29; +pub const EROFS: u32 = 30; +pub const EMLINK: u32 = 31; +pub const EPIPE: u32 = 32; +pub const EDOM: u32 = 33; +pub const ERANGE: u32 = 34; +pub const EDEADLK: u32 = 35; +pub const ENAMETOOLONG: u32 = 36; +pub const ENOLCK: u32 = 37; +pub const ENOSYS: u32 = 38; +pub const ENOTEMPTY: u32 = 39; +pub const ELOOP: u32 = 40; +pub const EWOULDBLOCK: u32 = 11; +pub const ENOMSG: u32 = 42; +pub const EIDRM: u32 = 43; +pub const ECHRNG: u32 = 44; +pub const EL2NSYNC: u32 = 45; +pub const EL3HLT: u32 = 46; +pub const EL3RST: u32 = 47; +pub const ELNRNG: u32 = 48; +pub const EUNATCH: u32 = 49; +pub const ENOCSI: u32 = 50; +pub const EL2HLT: u32 = 51; +pub const EBADE: u32 = 52; +pub const EBADR: u32 = 53; +pub const EXFULL: u32 = 54; +pub const ENOANO: u32 = 55; +pub const EBADRQC: u32 = 56; +pub const EBADSLT: u32 = 57; +pub const EDEADLOCK: u32 = 35; +pub const EBFONT: u32 = 59; +pub const ENOSTR: u32 = 60; +pub const ENODATA: u32 = 61; +pub const ETIME: u32 = 62; +pub const ENOSR: u32 = 63; +pub const ENONET: u32 = 64; +pub const ENOPKG: u32 = 65; +pub const EREMOTE: u32 = 66; +pub const ENOLINK: u32 = 67; +pub const EADV: u32 = 68; +pub const ESRMNT: u32 = 69; +pub const ECOMM: u32 = 70; +pub const EPROTO: u32 = 71; +pub const EMULTIHOP: u32 = 72; +pub const EDOTDOT: u32 = 73; +pub const EBADMSG: u32 = 74; +pub const EOVERFLOW: u32 = 75; +pub const ENOTUNIQ: u32 = 76; +pub const EBADFD: u32 = 77; +pub const EREMCHG: u32 = 78; +pub const ELIBACC: u32 = 79; +pub const ELIBBAD: u32 = 80; +pub const ELIBSCN: u32 = 81; +pub const ELIBMAX: u32 = 82; +pub const ELIBEXEC: u32 = 83; +pub const EILSEQ: u32 = 84; +pub const ERESTART: u32 = 85; +pub const ESTRPIPE: u32 = 86; +pub const EUSERS: u32 = 87; +pub const ENOTSOCK: u32 = 88; +pub const EDESTADDRREQ: u32 = 89; +pub const EMSGSIZE: u32 = 90; +pub const EPROTOTYPE: u32 = 91; +pub const ENOPROTOOPT: u32 = 92; +pub const EPROTONOSUPPORT: u32 = 93; +pub const ESOCKTNOSUPPORT: u32 = 94; +pub const EOPNOTSUPP: u32 = 95; +pub const EPFNOSUPPORT: u32 = 96; +pub const EAFNOSUPPORT: u32 = 97; +pub const EADDRINUSE: u32 = 98; +pub const EADDRNOTAVAIL: u32 = 99; +pub const ENETDOWN: u32 = 100; +pub const ENETUNREACH: u32 = 101; +pub const ENETRESET: u32 = 102; +pub const ECONNABORTED: u32 = 103; +pub const ECONNRESET: u32 = 104; +pub const ENOBUFS: u32 = 105; +pub const EISCONN: u32 = 106; +pub const ENOTCONN: u32 = 107; +pub const ESHUTDOWN: u32 = 108; +pub const ETOOMANYREFS: u32 = 109; +pub const ETIMEDOUT: u32 = 110; +pub const ECONNREFUSED: u32 = 111; +pub const EHOSTDOWN: u32 = 112; +pub const EHOSTUNREACH: u32 = 113; +pub const EALREADY: u32 = 114; +pub const EINPROGRESS: u32 = 115; +pub const ESTALE: u32 = 116; +pub const EUCLEAN: u32 = 117; +pub const ENOTNAM: u32 = 118; +pub const ENAVAIL: u32 = 119; +pub const EISNAM: u32 = 120; +pub const EREMOTEIO: u32 = 121; +pub const EDQUOT: u32 = 122; +pub const ENOMEDIUM: u32 = 123; +pub const EMEDIUMTYPE: u32 = 124; +pub const ECANCELED: u32 = 125; +pub const ENOKEY: u32 = 126; +pub const EKEYEXPIRED: u32 = 127; +pub const EKEYREVOKED: u32 = 128; +pub const EKEYREJECTED: u32 = 129; +pub const EOWNERDEAD: u32 = 130; +pub const ENOTRECOVERABLE: u32 = 131; +pub const ERFKILL: u32 = 132; +pub const EHWPOISON: u32 = 133; +pub const ENOTSUP: u32 = 95; +pub const MAX_NAME: u32 = 256; +pub const ABS_MT_MIN: u32 = 47; +pub const ABS_MT_MAX: u32 = 61; +pub const ABS_MT_CNT: u32 = 15; +unsafe extern "C" { + pub fn android_get_application_target_sdk_version() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn android_get_device_api_level() -> ::std::os::raw::c_int; +} +pub type wchar_t = ::std::os::raw::c_uint; +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone)] +pub struct max_align_t { + pub __clang_max_align_nonce1: ::std::os::raw::c_longlong, + pub __bindgen_padding_0: u64, + pub __clang_max_align_nonce2: u128, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of max_align_t"][::std::mem::size_of::() - 32usize]; + ["Alignment of max_align_t"][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: max_align_t::__clang_max_align_nonce1", + ][::std::mem::offset_of!(max_align_t, __clang_max_align_nonce1) - 0usize]; + [ + "Offset of field: max_align_t::__clang_max_align_nonce2", + ][::std::mem::offset_of!(max_align_t, __clang_max_align_nonce2) - 16usize]; +}; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __uintptr_t = ::std::os::raw::c_ulong; +pub type int_least8_t = i8; +pub type uint_least8_t = u8; +pub type int_least16_t = i16; +pub type uint_least16_t = u16; +pub type int_least32_t = i32; +pub type uint_least32_t = u32; +pub type int_least64_t = i64; +pub type uint_least64_t = u64; +pub type int_fast8_t = i8; +pub type uint_fast8_t = u8; +pub type int_fast64_t = i64; +pub type uint_fast64_t = u64; +pub type int_fast16_t = i64; +pub type uint_fast16_t = u64; +pub type int_fast32_t = i64; +pub type uint_fast32_t = u64; +pub type uintmax_t = u64; +pub type intmax_t = i64; +pub type __s8 = ::std::os::raw::c_schar; +pub type __u8 = ::std::os::raw::c_uchar; +pub type __s16 = ::std::os::raw::c_short; +pub type __u16 = ::std::os::raw::c_ushort; +pub type __s32 = ::std::os::raw::c_int; +pub type __u32 = ::std::os::raw::c_uint; +pub type __s64 = ::std::os::raw::c_longlong; +pub type __u64 = ::std::os::raw::c_ulonglong; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fd_set { + pub fds_bits: [::std::os::raw::c_ulong; 16usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of __kernel_fd_set"][::std::mem::size_of::<__kernel_fd_set>() - 128usize]; + ["Alignment of __kernel_fd_set"][::std::mem::align_of::<__kernel_fd_set>() - 8usize]; + [ + "Offset of field: __kernel_fd_set::fds_bits", + ][::std::mem::offset_of!(__kernel_fd_set, fds_bits) - 0usize]; +}; +pub type __kernel_sighandler_t = ::std::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int), +>; +pub type __kernel_key_t = ::std::os::raw::c_int; +pub type __kernel_mqd_t = ::std::os::raw::c_int; +pub type __kernel_old_uid_t = ::std::os::raw::c_ushort; +pub type __kernel_old_gid_t = ::std::os::raw::c_ushort; +pub type __kernel_long_t = ::std::os::raw::c_long; +pub type __kernel_ulong_t = ::std::os::raw::c_ulong; +pub type __kernel_ino_t = __kernel_ulong_t; +pub type __kernel_mode_t = ::std::os::raw::c_uint; +pub type __kernel_pid_t = ::std::os::raw::c_int; +pub type __kernel_ipc_pid_t = ::std::os::raw::c_int; +pub type __kernel_uid_t = ::std::os::raw::c_uint; +pub type __kernel_gid_t = ::std::os::raw::c_uint; +pub type __kernel_suseconds_t = __kernel_long_t; +pub type __kernel_daddr_t = ::std::os::raw::c_int; +pub type __kernel_uid32_t = ::std::os::raw::c_uint; +pub type __kernel_gid32_t = ::std::os::raw::c_uint; +pub type __kernel_old_dev_t = ::std::os::raw::c_uint; +pub type __kernel_size_t = __kernel_ulong_t; +pub type __kernel_ssize_t = __kernel_long_t; +pub type __kernel_ptrdiff_t = __kernel_long_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_fsid_t { + pub val: [::std::os::raw::c_int; 2usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of __kernel_fsid_t"][::std::mem::size_of::<__kernel_fsid_t>() - 8usize]; + ["Alignment of __kernel_fsid_t"][::std::mem::align_of::<__kernel_fsid_t>() - 4usize]; + [ + "Offset of field: __kernel_fsid_t::val", + ][::std::mem::offset_of!(__kernel_fsid_t, val) - 0usize]; +}; +pub type __kernel_off_t = __kernel_long_t; +pub type __kernel_loff_t = ::std::os::raw::c_longlong; +pub type __kernel_old_time_t = __kernel_long_t; +pub type __kernel_time_t = __kernel_long_t; +pub type __kernel_time64_t = ::std::os::raw::c_longlong; +pub type __kernel_clock_t = __kernel_long_t; +pub type __kernel_timer_t = ::std::os::raw::c_int; +pub type __kernel_clockid_t = ::std::os::raw::c_int; +pub type __kernel_caddr_t = *mut ::std::os::raw::c_char; +pub type __kernel_uid16_t = ::std::os::raw::c_ushort; +pub type __kernel_gid16_t = ::std::os::raw::c_ushort; +pub type __s128 = i128; +pub type __u128 = u128; +pub type __le16 = __u16; +pub type __be16 = __u16; +pub type __le32 = __u32; +pub type __be32 = __u32; +pub type __le64 = __u64; +pub type __be64 = __u64; +pub type __sum16 = __u16; +pub type __wsum = __u32; +pub type __poll_t = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_attr_t { + pub flags: u32, + pub stack_base: *mut ::std::os::raw::c_void, + pub stack_size: usize, + pub guard_size: usize, + pub sched_policy: i32, + pub sched_priority: i32, + pub __reserved: [::std::os::raw::c_char; 16usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pthread_attr_t"][::std::mem::size_of::() - 56usize]; + ["Alignment of pthread_attr_t"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: pthread_attr_t::flags", + ][::std::mem::offset_of!(pthread_attr_t, flags) - 0usize]; + [ + "Offset of field: pthread_attr_t::stack_base", + ][::std::mem::offset_of!(pthread_attr_t, stack_base) - 8usize]; + [ + "Offset of field: pthread_attr_t::stack_size", + ][::std::mem::offset_of!(pthread_attr_t, stack_size) - 16usize]; + [ + "Offset of field: pthread_attr_t::guard_size", + ][::std::mem::offset_of!(pthread_attr_t, guard_size) - 24usize]; + [ + "Offset of field: pthread_attr_t::sched_policy", + ][::std::mem::offset_of!(pthread_attr_t, sched_policy) - 32usize]; + [ + "Offset of field: pthread_attr_t::sched_priority", + ][::std::mem::offset_of!(pthread_attr_t, sched_priority) - 36usize]; + [ + "Offset of field: pthread_attr_t::__reserved", + ][::std::mem::offset_of!(pthread_attr_t, __reserved) - 40usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_barrier_t { + pub __private: [i64; 4usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pthread_barrier_t"][::std::mem::size_of::() - 32usize]; + [ + "Alignment of pthread_barrier_t", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: pthread_barrier_t::__private", + ][::std::mem::offset_of!(pthread_barrier_t, __private) - 0usize]; +}; +pub type pthread_barrierattr_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_cond_t { + pub __private: [i32; 12usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pthread_cond_t"][::std::mem::size_of::() - 48usize]; + ["Alignment of pthread_cond_t"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: pthread_cond_t::__private", + ][::std::mem::offset_of!(pthread_cond_t, __private) - 0usize]; +}; +pub type pthread_condattr_t = ::std::os::raw::c_long; +pub type pthread_key_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_mutex_t { + pub __private: [i32; 10usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pthread_mutex_t"][::std::mem::size_of::() - 40usize]; + ["Alignment of pthread_mutex_t"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: pthread_mutex_t::__private", + ][::std::mem::offset_of!(pthread_mutex_t, __private) - 0usize]; +}; +pub type pthread_mutexattr_t = ::std::os::raw::c_long; +pub type pthread_once_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_rwlock_t { + pub __private: [i32; 14usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pthread_rwlock_t"][::std::mem::size_of::() - 56usize]; + [ + "Alignment of pthread_rwlock_t", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: pthread_rwlock_t::__private", + ][::std::mem::offset_of!(pthread_rwlock_t, __private) - 0usize]; +}; +pub type pthread_rwlockattr_t = ::std::os::raw::c_long; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct pthread_spinlock_t { + pub __private: i64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of pthread_spinlock_t"][::std::mem::size_of::() - 8usize]; + [ + "Alignment of pthread_spinlock_t", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: pthread_spinlock_t::__private", + ][::std::mem::offset_of!(pthread_spinlock_t, __private) - 0usize]; +}; +pub type pthread_t = ::std::os::raw::c_long; +pub type __gid_t = __kernel_gid32_t; +pub type gid_t = __gid_t; +pub type __uid_t = __kernel_uid32_t; +pub type uid_t = __uid_t; +pub type __pid_t = __kernel_pid_t; +pub type pid_t = __pid_t; +pub type __id_t = u32; +pub type id_t = __id_t; +pub type blkcnt_t = ::std::os::raw::c_ulong; +pub type blksize_t = ::std::os::raw::c_ulong; +pub type caddr_t = __kernel_caddr_t; +pub type clock_t = __kernel_clock_t; +pub type __clockid_t = __kernel_clockid_t; +pub type clockid_t = __clockid_t; +pub type daddr_t = __kernel_daddr_t; +pub type fsblkcnt_t = ::std::os::raw::c_ulong; +pub type fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __mode_t = __kernel_mode_t; +pub type mode_t = __mode_t; +pub type __key_t = __kernel_key_t; +pub type key_t = __key_t; +pub type __ino_t = __kernel_ino_t; +pub type ino_t = __ino_t; +pub type ino64_t = u64; +pub type __nlink_t = u32; +pub type nlink_t = __nlink_t; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type timer_t = __timer_t; +pub type __suseconds_t = __kernel_suseconds_t; +pub type suseconds_t = __suseconds_t; +pub type __useconds_t = u32; +pub type useconds_t = __useconds_t; +pub type dev_t = u64; +pub type __time_t = __kernel_time_t; +pub type time_t = __time_t; +pub type off_t = i64; +pub type loff_t = off_t; +pub type off64_t = loff_t; +pub type __socklen_t = u32; +pub type socklen_t = __socklen_t; +pub type __va_list = __BindgenOpaqueArray; +pub type uint_t = ::std::os::raw::c_uint; +pub type uint = ::std::os::raw::c_uint; +pub type u_char = ::std::os::raw::c_uchar; +pub type u_short = ::std::os::raw::c_ushort; +pub type u_int = ::std::os::raw::c_uint; +pub type u_long = ::std::os::raw::c_ulong; +pub type u_int32_t = u32; +pub type u_int16_t = u16; +pub type u_int8_t = u8; +pub type u_int64_t = u64; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timespec { + pub tv_sec: time_t, + pub tv_nsec: ::std::os::raw::c_long, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of timespec"][::std::mem::size_of::() - 16usize]; + ["Alignment of timespec"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: timespec::tv_sec", + ][::std::mem::offset_of!(timespec, tv_sec) - 0usize]; + [ + "Offset of field: timespec::tv_nsec", + ][::std::mem::offset_of!(timespec, tv_nsec) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_timespec { + pub tv_sec: __kernel_time64_t, + pub tv_nsec: ::std::os::raw::c_longlong, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of __kernel_timespec"][::std::mem::size_of::<__kernel_timespec>() - 16usize]; + [ + "Alignment of __kernel_timespec", + ][::std::mem::align_of::<__kernel_timespec>() - 8usize]; + [ + "Offset of field: __kernel_timespec::tv_sec", + ][::std::mem::offset_of!(__kernel_timespec, tv_sec) - 0usize]; + [ + "Offset of field: __kernel_timespec::tv_nsec", + ][::std::mem::offset_of!(__kernel_timespec, tv_nsec) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_itimerspec { + pub it_interval: __kernel_timespec, + pub it_value: __kernel_timespec, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __kernel_itimerspec", + ][::std::mem::size_of::<__kernel_itimerspec>() - 32usize]; + [ + "Alignment of __kernel_itimerspec", + ][::std::mem::align_of::<__kernel_itimerspec>() - 8usize]; + [ + "Offset of field: __kernel_itimerspec::it_interval", + ][::std::mem::offset_of!(__kernel_itimerspec, it_interval) - 0usize]; + [ + "Offset of field: __kernel_itimerspec::it_value", + ][::std::mem::offset_of!(__kernel_itimerspec, it_value) - 16usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_old_timespec { + pub tv_sec: __kernel_old_time_t, + pub tv_nsec: ::std::os::raw::c_long, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __kernel_old_timespec", + ][::std::mem::size_of::<__kernel_old_timespec>() - 16usize]; + [ + "Alignment of __kernel_old_timespec", + ][::std::mem::align_of::<__kernel_old_timespec>() - 8usize]; + [ + "Offset of field: __kernel_old_timespec::tv_sec", + ][::std::mem::offset_of!(__kernel_old_timespec, tv_sec) - 0usize]; + [ + "Offset of field: __kernel_old_timespec::tv_nsec", + ][::std::mem::offset_of!(__kernel_old_timespec, tv_nsec) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_sock_timeval { + pub tv_sec: __s64, + pub tv_usec: __s64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __kernel_sock_timeval", + ][::std::mem::size_of::<__kernel_sock_timeval>() - 16usize]; + [ + "Alignment of __kernel_sock_timeval", + ][::std::mem::align_of::<__kernel_sock_timeval>() - 8usize]; + [ + "Offset of field: __kernel_sock_timeval::tv_sec", + ][::std::mem::offset_of!(__kernel_sock_timeval, tv_sec) - 0usize]; + [ + "Offset of field: __kernel_sock_timeval::tv_usec", + ][::std::mem::offset_of!(__kernel_sock_timeval, tv_usec) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timeval { + pub tv_sec: __kernel_old_time_t, + pub tv_usec: __kernel_suseconds_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of timeval"][::std::mem::size_of::() - 16usize]; + ["Alignment of timeval"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: timeval::tv_sec", + ][::std::mem::offset_of!(timeval, tv_sec) - 0usize]; + [ + "Offset of field: timeval::tv_usec", + ][::std::mem::offset_of!(timeval, tv_usec) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct itimerspec { + pub it_interval: timespec, + pub it_value: timespec, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of itimerspec"][::std::mem::size_of::() - 32usize]; + ["Alignment of itimerspec"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: itimerspec::it_interval", + ][::std::mem::offset_of!(itimerspec, it_interval) - 0usize]; + [ + "Offset of field: itimerspec::it_value", + ][::std::mem::offset_of!(itimerspec, it_value) - 16usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct itimerval { + pub it_interval: timeval, + pub it_value: timeval, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of itimerval"][::std::mem::size_of::() - 32usize]; + ["Alignment of itimerval"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: itimerval::it_interval", + ][::std::mem::offset_of!(itimerval, it_interval) - 0usize]; + [ + "Offset of field: itimerval::it_value", + ][::std::mem::offset_of!(itimerval, it_value) - 16usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct timezone { + pub tz_minuteswest: ::std::os::raw::c_int, + pub tz_dsttime: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of timezone"][::std::mem::size_of::() - 8usize]; + ["Alignment of timezone"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: timezone::tz_minuteswest", + ][::std::mem::offset_of!(timezone, tz_minuteswest) - 0usize]; + [ + "Offset of field: timezone::tz_dsttime", + ][::std::mem::offset_of!(timezone, tz_dsttime) - 4usize]; +}; +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone)] +pub struct sigcontext { + pub fault_address: __u64, + pub regs: [__u64; 31usize], + pub sp: __u64, + pub pc: __u64, + pub pstate: __u64, + pub __bindgen_padding_0: [u8; 8usize], + pub __reserved: [__u8; 4096usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sigcontext"][::std::mem::size_of::() - 4384usize]; + ["Alignment of sigcontext"][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: sigcontext::fault_address", + ][::std::mem::offset_of!(sigcontext, fault_address) - 0usize]; + [ + "Offset of field: sigcontext::regs", + ][::std::mem::offset_of!(sigcontext, regs) - 8usize]; + [ + "Offset of field: sigcontext::sp", + ][::std::mem::offset_of!(sigcontext, sp) - 256usize]; + [ + "Offset of field: sigcontext::pc", + ][::std::mem::offset_of!(sigcontext, pc) - 264usize]; + [ + "Offset of field: sigcontext::pstate", + ][::std::mem::offset_of!(sigcontext, pstate) - 272usize]; + [ + "Offset of field: sigcontext::__reserved", + ][::std::mem::offset_of!(sigcontext, __reserved) - 288usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _aarch64_ctx { + pub magic: __u32, + pub size: __u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of _aarch64_ctx"][::std::mem::size_of::<_aarch64_ctx>() - 8usize]; + ["Alignment of _aarch64_ctx"][::std::mem::align_of::<_aarch64_ctx>() - 4usize]; + [ + "Offset of field: _aarch64_ctx::magic", + ][::std::mem::offset_of!(_aarch64_ctx, magic) - 0usize]; + [ + "Offset of field: _aarch64_ctx::size", + ][::std::mem::offset_of!(_aarch64_ctx, size) - 4usize]; +}; +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone)] +pub struct fpsimd_context { + pub head: _aarch64_ctx, + pub fpsr: __u32, + pub fpcr: __u32, + pub vregs: [__uint128_t; 32usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of fpsimd_context"][::std::mem::size_of::() - 528usize]; + ["Alignment of fpsimd_context"][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: fpsimd_context::head", + ][::std::mem::offset_of!(fpsimd_context, head) - 0usize]; + [ + "Offset of field: fpsimd_context::fpsr", + ][::std::mem::offset_of!(fpsimd_context, fpsr) - 8usize]; + [ + "Offset of field: fpsimd_context::fpcr", + ][::std::mem::offset_of!(fpsimd_context, fpcr) - 12usize]; + [ + "Offset of field: fpsimd_context::vregs", + ][::std::mem::offset_of!(fpsimd_context, vregs) - 16usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct esr_context { + pub head: _aarch64_ctx, + pub esr: __u64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of esr_context"][::std::mem::size_of::() - 16usize]; + ["Alignment of esr_context"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: esr_context::head", + ][::std::mem::offset_of!(esr_context, head) - 0usize]; + [ + "Offset of field: esr_context::esr", + ][::std::mem::offset_of!(esr_context, esr) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct extra_context { + pub head: _aarch64_ctx, + pub datap: __u64, + pub size: __u32, + pub __reserved: [__u32; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of extra_context"][::std::mem::size_of::() - 32usize]; + ["Alignment of extra_context"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: extra_context::head", + ][::std::mem::offset_of!(extra_context, head) - 0usize]; + [ + "Offset of field: extra_context::datap", + ][::std::mem::offset_of!(extra_context, datap) - 8usize]; + [ + "Offset of field: extra_context::size", + ][::std::mem::offset_of!(extra_context, size) - 16usize]; + [ + "Offset of field: extra_context::__reserved", + ][::std::mem::offset_of!(extra_context, __reserved) - 20usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sve_context { + pub head: _aarch64_ctx, + pub vl: __u16, + pub flags: __u16, + pub __reserved: [__u16; 2usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sve_context"][::std::mem::size_of::() - 16usize]; + ["Alignment of sve_context"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: sve_context::head", + ][::std::mem::offset_of!(sve_context, head) - 0usize]; + [ + "Offset of field: sve_context::vl", + ][::std::mem::offset_of!(sve_context, vl) - 8usize]; + [ + "Offset of field: sve_context::flags", + ][::std::mem::offset_of!(sve_context, flags) - 10usize]; + [ + "Offset of field: sve_context::__reserved", + ][::std::mem::offset_of!(sve_context, __reserved) - 12usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct tpidr2_context { + pub head: _aarch64_ctx, + pub tpidr2: __u64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of tpidr2_context"][::std::mem::size_of::() - 16usize]; + ["Alignment of tpidr2_context"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: tpidr2_context::head", + ][::std::mem::offset_of!(tpidr2_context, head) - 0usize]; + [ + "Offset of field: tpidr2_context::tpidr2", + ][::std::mem::offset_of!(tpidr2_context, tpidr2) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct za_context { + pub head: _aarch64_ctx, + pub vl: __u16, + pub __reserved: [__u16; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of za_context"][::std::mem::size_of::() - 16usize]; + ["Alignment of za_context"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: za_context::head", + ][::std::mem::offset_of!(za_context, head) - 0usize]; + ["Offset of field: za_context::vl"][::std::mem::offset_of!(za_context, vl) - 8usize]; + [ + "Offset of field: za_context::__reserved", + ][::std::mem::offset_of!(za_context, __reserved) - 10usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct zt_context { + pub head: _aarch64_ctx, + pub nregs: __u16, + pub __reserved: [__u16; 3usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of zt_context"][::std::mem::size_of::() - 16usize]; + ["Alignment of zt_context"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: zt_context::head", + ][::std::mem::offset_of!(zt_context, head) - 0usize]; + [ + "Offset of field: zt_context::nregs", + ][::std::mem::offset_of!(zt_context, nregs) - 8usize]; + [ + "Offset of field: zt_context::__reserved", + ][::std::mem::offset_of!(zt_context, __reserved) - 10usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigset_t { + pub sig: [::std::os::raw::c_ulong; 1usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sigset_t"][::std::mem::size_of::() - 8usize]; + ["Alignment of sigset_t"][::std::mem::align_of::() - 8usize]; + ["Offset of field: sigset_t::sig"][::std::mem::offset_of!(sigset_t, sig) - 0usize]; +}; +pub type old_sigset_t = ::std::os::raw::c_ulong; +pub type __signalfn_t = ::std::option::Option< + unsafe extern "C" fn(arg1: ::std::os::raw::c_int), +>; +pub type __sighandler_t = __signalfn_t; +pub type __restorefn_t = ::std::option::Option; +pub type __sigrestore_t = __restorefn_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __kernel_sigaction { + pub sa_handler: __sighandler_t, + pub sa_flags: ::std::os::raw::c_ulong, + pub sa_restorer: __sigrestore_t, + pub sa_mask: sigset_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __kernel_sigaction", + ][::std::mem::size_of::<__kernel_sigaction>() - 32usize]; + [ + "Alignment of __kernel_sigaction", + ][::std::mem::align_of::<__kernel_sigaction>() - 8usize]; + [ + "Offset of field: __kernel_sigaction::sa_handler", + ][::std::mem::offset_of!(__kernel_sigaction, sa_handler) - 0usize]; + [ + "Offset of field: __kernel_sigaction::sa_flags", + ][::std::mem::offset_of!(__kernel_sigaction, sa_flags) - 8usize]; + [ + "Offset of field: __kernel_sigaction::sa_restorer", + ][::std::mem::offset_of!(__kernel_sigaction, sa_restorer) - 16usize]; + [ + "Offset of field: __kernel_sigaction::sa_mask", + ][::std::mem::offset_of!(__kernel_sigaction, sa_mask) - 24usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigaltstack { + pub ss_sp: *mut ::std::os::raw::c_void, + pub ss_flags: ::std::os::raw::c_int, + pub ss_size: __kernel_size_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sigaltstack"][::std::mem::size_of::() - 24usize]; + ["Alignment of sigaltstack"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigaltstack::ss_sp", + ][::std::mem::offset_of!(sigaltstack, ss_sp) - 0usize]; + [ + "Offset of field: sigaltstack::ss_flags", + ][::std::mem::offset_of!(sigaltstack, ss_flags) - 8usize]; + [ + "Offset of field: sigaltstack::ss_size", + ][::std::mem::offset_of!(sigaltstack, ss_size) - 16usize]; +}; +pub type stack_t = sigaltstack; +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigval { + pub sival_int: ::std::os::raw::c_int, + pub sival_ptr: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sigval"][::std::mem::size_of::() - 8usize]; + ["Alignment of sigval"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigval::sival_int", + ][::std::mem::offset_of!(sigval, sival_int) - 0usize]; + [ + "Offset of field: sigval::sival_ptr", + ][::std::mem::offset_of!(sigval, sival_ptr) - 0usize]; +}; +pub type sigval_t = sigval; +#[repr(C)] +#[derive(Copy, Clone)] +pub union __sifields { + pub _kill: __sifields__bindgen_ty_1, + pub _timer: __sifields__bindgen_ty_2, + pub _rt: __sifields__bindgen_ty_3, + pub _sigchld: __sifields__bindgen_ty_4, + pub _sigfault: __sifields__bindgen_ty_5, + pub _sigpoll: __sifields__bindgen_ty_6, + pub _sigsys: __sifields__bindgen_ty_7, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sifields__bindgen_ty_1 { + pub _pid: __kernel_pid_t, + pub _uid: __kernel_uid32_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_1", + ][::std::mem::size_of::<__sifields__bindgen_ty_1>() - 8usize]; + [ + "Alignment of __sifields__bindgen_ty_1", + ][::std::mem::align_of::<__sifields__bindgen_ty_1>() - 4usize]; + [ + "Offset of field: __sifields__bindgen_ty_1::_pid", + ][::std::mem::offset_of!(__sifields__bindgen_ty_1, _pid) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_1::_uid", + ][::std::mem::offset_of!(__sifields__bindgen_ty_1, _uid) - 4usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __sifields__bindgen_ty_2 { + pub _tid: __kernel_timer_t, + pub _overrun: ::std::os::raw::c_int, + pub _sigval: sigval_t, + pub _sys_private: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_2", + ][::std::mem::size_of::<__sifields__bindgen_ty_2>() - 24usize]; + [ + "Alignment of __sifields__bindgen_ty_2", + ][::std::mem::align_of::<__sifields__bindgen_ty_2>() - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_2::_tid", + ][::std::mem::offset_of!(__sifields__bindgen_ty_2, _tid) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_2::_overrun", + ][::std::mem::offset_of!(__sifields__bindgen_ty_2, _overrun) - 4usize]; + [ + "Offset of field: __sifields__bindgen_ty_2::_sigval", + ][::std::mem::offset_of!(__sifields__bindgen_ty_2, _sigval) - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_2::_sys_private", + ][::std::mem::offset_of!(__sifields__bindgen_ty_2, _sys_private) - 16usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __sifields__bindgen_ty_3 { + pub _pid: __kernel_pid_t, + pub _uid: __kernel_uid32_t, + pub _sigval: sigval_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_3", + ][::std::mem::size_of::<__sifields__bindgen_ty_3>() - 16usize]; + [ + "Alignment of __sifields__bindgen_ty_3", + ][::std::mem::align_of::<__sifields__bindgen_ty_3>() - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_3::_pid", + ][::std::mem::offset_of!(__sifields__bindgen_ty_3, _pid) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_3::_uid", + ][::std::mem::offset_of!(__sifields__bindgen_ty_3, _uid) - 4usize]; + [ + "Offset of field: __sifields__bindgen_ty_3::_sigval", + ][::std::mem::offset_of!(__sifields__bindgen_ty_3, _sigval) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sifields__bindgen_ty_4 { + pub _pid: __kernel_pid_t, + pub _uid: __kernel_uid32_t, + pub _status: ::std::os::raw::c_int, + pub _utime: __kernel_clock_t, + pub _stime: __kernel_clock_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_4", + ][::std::mem::size_of::<__sifields__bindgen_ty_4>() - 32usize]; + [ + "Alignment of __sifields__bindgen_ty_4", + ][::std::mem::align_of::<__sifields__bindgen_ty_4>() - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_4::_pid", + ][::std::mem::offset_of!(__sifields__bindgen_ty_4, _pid) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_4::_uid", + ][::std::mem::offset_of!(__sifields__bindgen_ty_4, _uid) - 4usize]; + [ + "Offset of field: __sifields__bindgen_ty_4::_status", + ][::std::mem::offset_of!(__sifields__bindgen_ty_4, _status) - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_4::_utime", + ][::std::mem::offset_of!(__sifields__bindgen_ty_4, _utime) - 16usize]; + [ + "Offset of field: __sifields__bindgen_ty_4::_stime", + ][::std::mem::offset_of!(__sifields__bindgen_ty_4, _stime) - 24usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct __sifields__bindgen_ty_5 { + pub _addr: *mut ::std::os::raw::c_void, + pub __bindgen_anon_1: __sifields__bindgen_ty_5__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union __sifields__bindgen_ty_5__bindgen_ty_1 { + pub _trapno: ::std::os::raw::c_int, + pub _addr_lsb: ::std::os::raw::c_short, + pub _addr_bnd: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, + pub _addr_pkey: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2, + pub _perf: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1 { + pub _dummy_bnd: [::std::os::raw::c_char; 8usize], + pub _lower: *mut ::std::os::raw::c_void, + pub _upper: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1>() + - 24usize]; + [ + "Alignment of __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1>() + - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1::_dummy_bnd", + ][::std::mem::offset_of!( + __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, _dummy_bnd + ) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1::_lower", + ][::std::mem::offset_of!( + __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, _lower + ) - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1::_upper", + ][::std::mem::offset_of!( + __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_1, _upper + ) - 16usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2 { + pub _dummy_pkey: [::std::os::raw::c_char; 8usize], + pub _pkey: __u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2>() + - 12usize]; + [ + "Alignment of __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2", + ][::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2>() + - 4usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2::_dummy_pkey", + ][::std::mem::offset_of!( + __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2, _dummy_pkey + ) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2::_pkey", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_2, _pkey) + - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3 { + pub _data: ::std::os::raw::c_ulong, + pub _type: __u32, + pub _flags: __u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3", + ][::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>() + - 16usize]; + [ + "Alignment of __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3", + ][::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3>() + - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3::_data", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3, _data) + - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3::_type", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3, _type) + - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3::_flags", + ][::std::mem::offset_of!( + __sifields__bindgen_ty_5__bindgen_ty_1__bindgen_ty_3, _flags + ) - 12usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_5__bindgen_ty_1", + ][::std::mem::size_of::<__sifields__bindgen_ty_5__bindgen_ty_1>() - 24usize]; + [ + "Alignment of __sifields__bindgen_ty_5__bindgen_ty_1", + ][::std::mem::align_of::<__sifields__bindgen_ty_5__bindgen_ty_1>() - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1::_trapno", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1, _trapno) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1::_addr_lsb", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1, _addr_lsb) + - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1::_addr_bnd", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1, _addr_bnd) + - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1::_addr_pkey", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1, _addr_pkey) + - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_5__bindgen_ty_1::_perf", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5__bindgen_ty_1, _perf) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_5", + ][::std::mem::size_of::<__sifields__bindgen_ty_5>() - 32usize]; + [ + "Alignment of __sifields__bindgen_ty_5", + ][::std::mem::align_of::<__sifields__bindgen_ty_5>() - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_5::_addr", + ][::std::mem::offset_of!(__sifields__bindgen_ty_5, _addr) - 0usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sifields__bindgen_ty_6 { + pub _band: ::std::os::raw::c_long, + pub _fd: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_6", + ][::std::mem::size_of::<__sifields__bindgen_ty_6>() - 16usize]; + [ + "Alignment of __sifields__bindgen_ty_6", + ][::std::mem::align_of::<__sifields__bindgen_ty_6>() - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_6::_band", + ][::std::mem::offset_of!(__sifields__bindgen_ty_6, _band) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_6::_fd", + ][::std::mem::offset_of!(__sifields__bindgen_ty_6, _fd) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sifields__bindgen_ty_7 { + pub _call_addr: *mut ::std::os::raw::c_void, + pub _syscall: ::std::os::raw::c_int, + pub _arch: ::std::os::raw::c_uint, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of __sifields__bindgen_ty_7", + ][::std::mem::size_of::<__sifields__bindgen_ty_7>() - 16usize]; + [ + "Alignment of __sifields__bindgen_ty_7", + ][::std::mem::align_of::<__sifields__bindgen_ty_7>() - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_7::_call_addr", + ][::std::mem::offset_of!(__sifields__bindgen_ty_7, _call_addr) - 0usize]; + [ + "Offset of field: __sifields__bindgen_ty_7::_syscall", + ][::std::mem::offset_of!(__sifields__bindgen_ty_7, _syscall) - 8usize]; + [ + "Offset of field: __sifields__bindgen_ty_7::_arch", + ][::std::mem::offset_of!(__sifields__bindgen_ty_7, _arch) - 12usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of __sifields"][::std::mem::size_of::<__sifields>() - 32usize]; + ["Alignment of __sifields"][::std::mem::align_of::<__sifields>() - 8usize]; + [ + "Offset of field: __sifields::_kill", + ][::std::mem::offset_of!(__sifields, _kill) - 0usize]; + [ + "Offset of field: __sifields::_timer", + ][::std::mem::offset_of!(__sifields, _timer) - 0usize]; + [ + "Offset of field: __sifields::_rt", + ][::std::mem::offset_of!(__sifields, _rt) - 0usize]; + [ + "Offset of field: __sifields::_sigchld", + ][::std::mem::offset_of!(__sifields, _sigchld) - 0usize]; + [ + "Offset of field: __sifields::_sigfault", + ][::std::mem::offset_of!(__sifields, _sigfault) - 0usize]; + [ + "Offset of field: __sifields::_sigpoll", + ][::std::mem::offset_of!(__sifields, _sigpoll) - 0usize]; + [ + "Offset of field: __sifields::_sigsys", + ][::std::mem::offset_of!(__sifields, _sigsys) - 0usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo { + pub __bindgen_anon_1: siginfo__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union siginfo__bindgen_ty_1 { + pub __bindgen_anon_1: siginfo__bindgen_ty_1__bindgen_ty_1, + pub _si_pad: [::std::os::raw::c_int; 32usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct siginfo__bindgen_ty_1__bindgen_ty_1 { + pub si_signo: ::std::os::raw::c_int, + pub si_errno: ::std::os::raw::c_int, + pub si_code: ::std::os::raw::c_int, + pub _sifields: __sifields, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of siginfo__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 48usize]; + [ + "Alignment of siginfo__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: siginfo__bindgen_ty_1__bindgen_ty_1::si_signo", + ][::std::mem::offset_of!(siginfo__bindgen_ty_1__bindgen_ty_1, si_signo) - 0usize]; + [ + "Offset of field: siginfo__bindgen_ty_1__bindgen_ty_1::si_errno", + ][::std::mem::offset_of!(siginfo__bindgen_ty_1__bindgen_ty_1, si_errno) - 4usize]; + [ + "Offset of field: siginfo__bindgen_ty_1__bindgen_ty_1::si_code", + ][::std::mem::offset_of!(siginfo__bindgen_ty_1__bindgen_ty_1, si_code) - 8usize]; + [ + "Offset of field: siginfo__bindgen_ty_1__bindgen_ty_1::_sifields", + ][::std::mem::offset_of!(siginfo__bindgen_ty_1__bindgen_ty_1, _sifields) - 16usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of siginfo__bindgen_ty_1", + ][::std::mem::size_of::() - 128usize]; + [ + "Alignment of siginfo__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: siginfo__bindgen_ty_1::_si_pad", + ][::std::mem::offset_of!(siginfo__bindgen_ty_1, _si_pad) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of siginfo"][::std::mem::size_of::() - 128usize]; + ["Alignment of siginfo"][::std::mem::align_of::() - 8usize]; +}; +pub type siginfo_t = siginfo; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigevent { + pub sigev_value: sigval_t, + pub sigev_signo: ::std::os::raw::c_int, + pub sigev_notify: ::std::os::raw::c_int, + pub _sigev_un: sigevent__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigevent__bindgen_ty_1 { + pub _pad: [::std::os::raw::c_int; 12usize], + pub _tid: ::std::os::raw::c_int, + pub _sigev_thread: sigevent__bindgen_ty_1__bindgen_ty_1, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct sigevent__bindgen_ty_1__bindgen_ty_1 { + pub _function: ::std::option::Option, + pub _attribute: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of sigevent__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::size_of::() - 16usize]; + [ + "Alignment of sigevent__bindgen_ty_1__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigevent__bindgen_ty_1__bindgen_ty_1::_function", + ][::std::mem::offset_of!(sigevent__bindgen_ty_1__bindgen_ty_1, _function) - 0usize]; + [ + "Offset of field: sigevent__bindgen_ty_1__bindgen_ty_1::_attribute", + ][::std::mem::offset_of!(sigevent__bindgen_ty_1__bindgen_ty_1, _attribute) - 8usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of sigevent__bindgen_ty_1", + ][::std::mem::size_of::() - 48usize]; + [ + "Alignment of sigevent__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigevent__bindgen_ty_1::_pad", + ][::std::mem::offset_of!(sigevent__bindgen_ty_1, _pad) - 0usize]; + [ + "Offset of field: sigevent__bindgen_ty_1::_tid", + ][::std::mem::offset_of!(sigevent__bindgen_ty_1, _tid) - 0usize]; + [ + "Offset of field: sigevent__bindgen_ty_1::_sigev_thread", + ][::std::mem::offset_of!(sigevent__bindgen_ty_1, _sigev_thread) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sigevent"][::std::mem::size_of::() - 64usize]; + ["Alignment of sigevent"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigevent::sigev_value", + ][::std::mem::offset_of!(sigevent, sigev_value) - 0usize]; + [ + "Offset of field: sigevent::sigev_signo", + ][::std::mem::offset_of!(sigevent, sigev_signo) - 8usize]; + [ + "Offset of field: sigevent::sigev_notify", + ][::std::mem::offset_of!(sigevent, sigev_notify) - 12usize]; + [ + "Offset of field: sigevent::_sigev_un", + ][::std::mem::offset_of!(sigevent, _sigev_un) - 16usize]; +}; +pub type sigevent_t = sigevent; +pub type sig_atomic_t = ::std::os::raw::c_int; +pub type sig_t = __sighandler_t; +pub type sighandler_t = __sighandler_t; +pub type sigset64_t = sigset_t; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigaction { + pub sa_flags: ::std::os::raw::c_int, + pub __bindgen_anon_1: sigaction__bindgen_ty_1, + pub sa_mask: sigset_t, + pub sa_restorer: ::std::option::Option, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigaction__bindgen_ty_1 { + pub sa_handler: sighandler_t, + pub sa_sigaction: ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: *mut siginfo, + arg3: *mut ::std::os::raw::c_void, + ), + >, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of sigaction__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of sigaction__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigaction__bindgen_ty_1::sa_handler", + ][::std::mem::offset_of!(sigaction__bindgen_ty_1, sa_handler) - 0usize]; + [ + "Offset of field: sigaction__bindgen_ty_1::sa_sigaction", + ][::std::mem::offset_of!(sigaction__bindgen_ty_1, sa_sigaction) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sigaction"][::std::mem::size_of::() - 32usize]; + ["Alignment of sigaction"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigaction::sa_flags", + ][::std::mem::offset_of!(sigaction, sa_flags) - 0usize]; + [ + "Offset of field: sigaction::sa_mask", + ][::std::mem::offset_of!(sigaction, sa_mask) - 16usize]; + [ + "Offset of field: sigaction::sa_restorer", + ][::std::mem::offset_of!(sigaction, sa_restorer) - 24usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct sigaction64 { + pub sa_flags: ::std::os::raw::c_int, + pub __bindgen_anon_1: sigaction64__bindgen_ty_1, + pub sa_mask: sigset_t, + pub sa_restorer: ::std::option::Option, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union sigaction64__bindgen_ty_1 { + pub sa_handler: sighandler_t, + pub sa_sigaction: ::std::option::Option< + unsafe extern "C" fn( + arg1: ::std::os::raw::c_int, + arg2: *mut siginfo, + arg3: *mut ::std::os::raw::c_void, + ), + >, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of sigaction64__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of sigaction64__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigaction64__bindgen_ty_1::sa_handler", + ][::std::mem::offset_of!(sigaction64__bindgen_ty_1, sa_handler) - 0usize]; + [ + "Offset of field: sigaction64__bindgen_ty_1::sa_sigaction", + ][::std::mem::offset_of!(sigaction64__bindgen_ty_1, sa_sigaction) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of sigaction64"][::std::mem::size_of::() - 32usize]; + ["Alignment of sigaction64"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: sigaction64::sa_flags", + ][::std::mem::offset_of!(sigaction64, sa_flags) - 0usize]; + [ + "Offset of field: sigaction64::sa_mask", + ][::std::mem::offset_of!(sigaction64, sa_mask) - 16usize]; + [ + "Offset of field: sigaction64::sa_restorer", + ][::std::mem::offset_of!(sigaction64, sa_restorer) - 24usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct user_regs_struct { + pub regs: [u64; 31usize], + pub sp: u64, + pub pc: u64, + pub pstate: u64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of user_regs_struct"][::std::mem::size_of::() - 272usize]; + [ + "Alignment of user_regs_struct", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: user_regs_struct::regs", + ][::std::mem::offset_of!(user_regs_struct, regs) - 0usize]; + [ + "Offset of field: user_regs_struct::sp", + ][::std::mem::offset_of!(user_regs_struct, sp) - 248usize]; + [ + "Offset of field: user_regs_struct::pc", + ][::std::mem::offset_of!(user_regs_struct, pc) - 256usize]; + [ + "Offset of field: user_regs_struct::pstate", + ][::std::mem::offset_of!(user_regs_struct, pstate) - 264usize]; +}; +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone)] +pub struct user_fpsimd_struct { + pub vregs: [__uint128_t; 32usize], + pub fpsr: u32, + pub fpcr: u32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of user_fpsimd_struct", + ][::std::mem::size_of::() - 528usize]; + [ + "Alignment of user_fpsimd_struct", + ][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: user_fpsimd_struct::vregs", + ][::std::mem::offset_of!(user_fpsimd_struct, vregs) - 0usize]; + [ + "Offset of field: user_fpsimd_struct::fpsr", + ][::std::mem::offset_of!(user_fpsimd_struct, fpsr) - 512usize]; + [ + "Offset of field: user_fpsimd_struct::fpcr", + ][::std::mem::offset_of!(user_fpsimd_struct, fpcr) - 516usize]; +}; +pub type greg_t = ::std::os::raw::c_ulong; +pub type gregset_t = [greg_t; 34usize]; +pub type fpregset_t = user_fpsimd_struct; +pub type mcontext_t = sigcontext; +#[repr(C)] +#[repr(align(16))] +#[derive(Copy, Clone)] +pub struct ucontext { + pub uc_flags: ::std::os::raw::c_ulong, + pub uc_link: *mut ucontext, + pub uc_stack: stack_t, + pub __bindgen_anon_1: ucontext__bindgen_ty_1, + pub __padding: [::std::os::raw::c_char; 120usize], + pub __bindgen_padding_0: u64, + pub uc_mcontext: mcontext_t, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ucontext__bindgen_ty_1 { + pub uc_sigmask: sigset_t, + pub uc_sigmask64: sigset64_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ucontext__bindgen_ty_1", + ][::std::mem::size_of::() - 8usize]; + [ + "Alignment of ucontext__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ucontext__bindgen_ty_1::uc_sigmask", + ][::std::mem::offset_of!(ucontext__bindgen_ty_1, uc_sigmask) - 0usize]; + [ + "Offset of field: ucontext__bindgen_ty_1::uc_sigmask64", + ][::std::mem::offset_of!(ucontext__bindgen_ty_1, uc_sigmask64) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ucontext"][::std::mem::size_of::() - 4560usize]; + ["Alignment of ucontext"][::std::mem::align_of::() - 16usize]; + [ + "Offset of field: ucontext::uc_flags", + ][::std::mem::offset_of!(ucontext, uc_flags) - 0usize]; + [ + "Offset of field: ucontext::uc_link", + ][::std::mem::offset_of!(ucontext, uc_link) - 8usize]; + [ + "Offset of field: ucontext::uc_stack", + ][::std::mem::offset_of!(ucontext, uc_stack) - 16usize]; + [ + "Offset of field: ucontext::__padding", + ][::std::mem::offset_of!(ucontext, __padding) - 48usize]; + [ + "Offset of field: ucontext::uc_mcontext", + ][::std::mem::offset_of!(ucontext, uc_mcontext) - 176usize]; +}; +pub type ucontext_t = ucontext; +unsafe extern "C" { + pub fn __libc_current_sigrtmin() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn __libc_current_sigrtmax() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub static sys_siglist: [*const ::std::os::raw::c_char; 65usize]; +} +unsafe extern "C" { + pub static sys_signame: [*const ::std::os::raw::c_char; 65usize]; +} +unsafe extern "C" { + pub fn sigaction( + __signal: ::std::os::raw::c_int, + __new_action: *const sigaction, + __old_action: *mut sigaction, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigaction64( + __signal: ::std::os::raw::c_int, + __new_action: *const sigaction64, + __old_action: *mut sigaction64, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn siginterrupt( + __signal: ::std::os::raw::c_int, + __flag: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn signal( + __signal: ::std::os::raw::c_int, + __handler: sighandler_t, + ) -> sighandler_t; +} +unsafe extern "C" { + pub fn sigaddset( + __set: *mut sigset_t, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigaddset64( + __set: *mut sigset64_t, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigdelset( + __set: *mut sigset_t, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigdelset64( + __set: *mut sigset64_t, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigemptyset(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigemptyset64(__set: *mut sigset64_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigfillset(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigfillset64(__set: *mut sigset64_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigismember( + __set: *const sigset_t, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigismember64( + __set: *const sigset64_t, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigpending(__set: *mut sigset_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigpending64(__set: *mut sigset64_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigprocmask( + __how: ::std::os::raw::c_int, + __new_set: *const sigset_t, + __old_set: *mut sigset_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigprocmask64( + __how: ::std::os::raw::c_int, + __new_set: *const sigset64_t, + __old_set: *mut sigset64_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigsuspend(__mask: *const sigset_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigsuspend64(__mask: *const sigset64_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigwait( + __set: *const sigset_t, + __signal: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigwait64( + __set: *const sigset64_t, + __signal: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sighold(__signal: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigignore(__signal: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigpause(__signal: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigrelse(__signal: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigset( + __signal: ::std::os::raw::c_int, + __handler: sighandler_t, + ) -> sighandler_t; +} +unsafe extern "C" { + pub fn raise(__signal: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn kill(__pid: pid_t, __signal: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn killpg( + __pgrp: ::std::os::raw::c_int, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn tgkill( + __tgid: ::std::os::raw::c_int, + __tid: ::std::os::raw::c_int, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigaltstack( + __new_signal_stack: *const stack_t, + __old_signal_stack: *mut stack_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn psiginfo(__info: *const siginfo_t, __msg: *const ::std::os::raw::c_char); +} +unsafe extern "C" { + pub fn psignal( + __signal: ::std::os::raw::c_int, + __msg: *const ::std::os::raw::c_char, + ); +} +unsafe extern "C" { + pub fn pthread_kill( + __pthread: pthread_t, + __signal: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn pthread_sigmask( + __how: ::std::os::raw::c_int, + __new_set: *const sigset_t, + __old_set: *mut sigset_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn pthread_sigmask64( + __how: ::std::os::raw::c_int, + __new_set: *const sigset64_t, + __old_set: *mut sigset64_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigqueue( + __pid: pid_t, + __signal: ::std::os::raw::c_int, + __value: sigval, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigtimedwait( + __set: *const sigset_t, + __info: *mut siginfo_t, + __timeout: *const timespec, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigtimedwait64( + __set: *const sigset64_t, + __info: *mut siginfo_t, + __timeout: *const timespec, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigwaitinfo( + __set: *const sigset_t, + __info: *mut siginfo_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sigwaitinfo64( + __set: *const sigset64_t, + __info: *mut siginfo_t, + ) -> ::std::os::raw::c_int; +} +pub type fd_mask = ::std::os::raw::c_ulong; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct fd_set { + pub fds_bits: [fd_mask; 16usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of fd_set"][::std::mem::size_of::() - 128usize]; + ["Alignment of fd_set"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: fd_set::fds_bits", + ][::std::mem::offset_of!(fd_set, fds_bits) - 0usize]; +}; +unsafe extern "C" { + pub fn __FD_CLR_chk(arg1: ::std::os::raw::c_int, arg2: *mut fd_set, arg3: usize); +} +unsafe extern "C" { + pub fn __FD_SET_chk(arg1: ::std::os::raw::c_int, arg2: *mut fd_set, arg3: usize); +} +unsafe extern "C" { + pub fn __FD_ISSET_chk( + arg1: ::std::os::raw::c_int, + arg2: *const fd_set, + arg3: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn select( + __max_fd_plus_one: ::std::os::raw::c_int, + __read_fds: *mut fd_set, + __write_fds: *mut fd_set, + __exception_fds: *mut fd_set, + __timeout: *mut timeval, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn pselect( + __max_fd_plus_one: ::std::os::raw::c_int, + __read_fds: *mut fd_set, + __write_fds: *mut fd_set, + __exception_fds: *mut fd_set, + __timeout: *const timespec, + __mask: *const sigset_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn pselect64( + __max_fd_plus_one: ::std::os::raw::c_int, + __read_fds: *mut fd_set, + __write_fds: *mut fd_set, + __exception_fds: *mut fd_set, + __timeout: *const timespec, + __mask: *const sigset64_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn gettimeofday( + __tv: *mut timeval, + __tz: *mut timezone, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn settimeofday( + __tv: *const timeval, + __tz: *const timezone, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getitimer( + __which: ::std::os::raw::c_int, + __current_value: *mut itimerval, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn setitimer( + __which: ::std::os::raw::c_int, + __new_value: *const itimerval, + __old_value: *mut itimerval, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn utimes( + __path: *const ::std::os::raw::c_char, + __times: *const timeval, + ) -> ::std::os::raw::c_int; +} +pub type cc_t = ::std::os::raw::c_uchar; +pub type speed_t = ::std::os::raw::c_uint; +pub type tcflag_t = ::std::os::raw::c_uint; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct termios { + pub c_iflag: tcflag_t, + pub c_oflag: tcflag_t, + pub c_cflag: tcflag_t, + pub c_lflag: tcflag_t, + pub c_line: cc_t, + pub c_cc: [cc_t; 19usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of termios"][::std::mem::size_of::() - 36usize]; + ["Alignment of termios"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: termios::c_iflag", + ][::std::mem::offset_of!(termios, c_iflag) - 0usize]; + [ + "Offset of field: termios::c_oflag", + ][::std::mem::offset_of!(termios, c_oflag) - 4usize]; + [ + "Offset of field: termios::c_cflag", + ][::std::mem::offset_of!(termios, c_cflag) - 8usize]; + [ + "Offset of field: termios::c_lflag", + ][::std::mem::offset_of!(termios, c_lflag) - 12usize]; + [ + "Offset of field: termios::c_line", + ][::std::mem::offset_of!(termios, c_line) - 16usize]; + ["Offset of field: termios::c_cc"][::std::mem::offset_of!(termios, c_cc) - 17usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct termios2 { + pub c_iflag: tcflag_t, + pub c_oflag: tcflag_t, + pub c_cflag: tcflag_t, + pub c_lflag: tcflag_t, + pub c_line: cc_t, + pub c_cc: [cc_t; 19usize], + pub c_ispeed: speed_t, + pub c_ospeed: speed_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of termios2"][::std::mem::size_of::() - 44usize]; + ["Alignment of termios2"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: termios2::c_iflag", + ][::std::mem::offset_of!(termios2, c_iflag) - 0usize]; + [ + "Offset of field: termios2::c_oflag", + ][::std::mem::offset_of!(termios2, c_oflag) - 4usize]; + [ + "Offset of field: termios2::c_cflag", + ][::std::mem::offset_of!(termios2, c_cflag) - 8usize]; + [ + "Offset of field: termios2::c_lflag", + ][::std::mem::offset_of!(termios2, c_lflag) - 12usize]; + [ + "Offset of field: termios2::c_line", + ][::std::mem::offset_of!(termios2, c_line) - 16usize]; + [ + "Offset of field: termios2::c_cc", + ][::std::mem::offset_of!(termios2, c_cc) - 17usize]; + [ + "Offset of field: termios2::c_ispeed", + ][::std::mem::offset_of!(termios2, c_ispeed) - 36usize]; + [ + "Offset of field: termios2::c_ospeed", + ][::std::mem::offset_of!(termios2, c_ospeed) - 40usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ktermios { + pub c_iflag: tcflag_t, + pub c_oflag: tcflag_t, + pub c_cflag: tcflag_t, + pub c_lflag: tcflag_t, + pub c_line: cc_t, + pub c_cc: [cc_t; 19usize], + pub c_ispeed: speed_t, + pub c_ospeed: speed_t, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ktermios"][::std::mem::size_of::() - 44usize]; + ["Alignment of ktermios"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: ktermios::c_iflag", + ][::std::mem::offset_of!(ktermios, c_iflag) - 0usize]; + [ + "Offset of field: ktermios::c_oflag", + ][::std::mem::offset_of!(ktermios, c_oflag) - 4usize]; + [ + "Offset of field: ktermios::c_cflag", + ][::std::mem::offset_of!(ktermios, c_cflag) - 8usize]; + [ + "Offset of field: ktermios::c_lflag", + ][::std::mem::offset_of!(ktermios, c_lflag) - 12usize]; + [ + "Offset of field: ktermios::c_line", + ][::std::mem::offset_of!(ktermios, c_line) - 16usize]; + [ + "Offset of field: ktermios::c_cc", + ][::std::mem::offset_of!(ktermios, c_cc) - 17usize]; + [ + "Offset of field: ktermios::c_ispeed", + ][::std::mem::offset_of!(ktermios, c_ispeed) - 36usize]; + [ + "Offset of field: ktermios::c_ospeed", + ][::std::mem::offset_of!(ktermios, c_ospeed) - 40usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct winsize { + pub ws_row: ::std::os::raw::c_ushort, + pub ws_col: ::std::os::raw::c_ushort, + pub ws_xpixel: ::std::os::raw::c_ushort, + pub ws_ypixel: ::std::os::raw::c_ushort, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of winsize"][::std::mem::size_of::() - 8usize]; + ["Alignment of winsize"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: winsize::ws_row", + ][::std::mem::offset_of!(winsize, ws_row) - 0usize]; + [ + "Offset of field: winsize::ws_col", + ][::std::mem::offset_of!(winsize, ws_col) - 2usize]; + [ + "Offset of field: winsize::ws_xpixel", + ][::std::mem::offset_of!(winsize, ws_xpixel) - 4usize]; + [ + "Offset of field: winsize::ws_ypixel", + ][::std::mem::offset_of!(winsize, ws_ypixel) - 6usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct termio { + pub c_iflag: ::std::os::raw::c_ushort, + pub c_oflag: ::std::os::raw::c_ushort, + pub c_cflag: ::std::os::raw::c_ushort, + pub c_lflag: ::std::os::raw::c_ushort, + pub c_line: ::std::os::raw::c_uchar, + pub c_cc: [::std::os::raw::c_uchar; 8usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of termio"][::std::mem::size_of::() - 18usize]; + ["Alignment of termio"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: termio::c_iflag", + ][::std::mem::offset_of!(termio, c_iflag) - 0usize]; + [ + "Offset of field: termio::c_oflag", + ][::std::mem::offset_of!(termio, c_oflag) - 2usize]; + [ + "Offset of field: termio::c_cflag", + ][::std::mem::offset_of!(termio, c_cflag) - 4usize]; + [ + "Offset of field: termio::c_lflag", + ][::std::mem::offset_of!(termio, c_lflag) - 6usize]; + ["Offset of field: termio::c_line"][::std::mem::offset_of!(termio, c_line) - 8usize]; + ["Offset of field: termio::c_cc"][::std::mem::offset_of!(termio, c_cc) - 9usize]; +}; +unsafe extern "C" { + pub fn ioctl( + __fd: ::std::os::raw::c_int, + __op: ::std::os::raw::c_int, + ... + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct input_event { + pub time: timeval, + pub type_: __u16, + pub code: __u16, + pub value: __s32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of input_event"][::std::mem::size_of::() - 24usize]; + ["Alignment of input_event"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: input_event::time", + ][::std::mem::offset_of!(input_event, time) - 0usize]; + [ + "Offset of field: input_event::type_", + ][::std::mem::offset_of!(input_event, type_) - 16usize]; + [ + "Offset of field: input_event::code", + ][::std::mem::offset_of!(input_event, code) - 18usize]; + [ + "Offset of field: input_event::value", + ][::std::mem::offset_of!(input_event, value) - 20usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct input_id { + pub bustype: __u16, + pub vendor: __u16, + pub product: __u16, + pub version: __u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of input_id"][::std::mem::size_of::() - 8usize]; + ["Alignment of input_id"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: input_id::bustype", + ][::std::mem::offset_of!(input_id, bustype) - 0usize]; + [ + "Offset of field: input_id::vendor", + ][::std::mem::offset_of!(input_id, vendor) - 2usize]; + [ + "Offset of field: input_id::product", + ][::std::mem::offset_of!(input_id, product) - 4usize]; + [ + "Offset of field: input_id::version", + ][::std::mem::offset_of!(input_id, version) - 6usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct input_absinfo { + pub value: __s32, + pub minimum: __s32, + pub maximum: __s32, + pub fuzz: __s32, + pub flat: __s32, + pub resolution: __s32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of input_absinfo"][::std::mem::size_of::() - 24usize]; + ["Alignment of input_absinfo"][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: input_absinfo::value", + ][::std::mem::offset_of!(input_absinfo, value) - 0usize]; + [ + "Offset of field: input_absinfo::minimum", + ][::std::mem::offset_of!(input_absinfo, minimum) - 4usize]; + [ + "Offset of field: input_absinfo::maximum", + ][::std::mem::offset_of!(input_absinfo, maximum) - 8usize]; + [ + "Offset of field: input_absinfo::fuzz", + ][::std::mem::offset_of!(input_absinfo, fuzz) - 12usize]; + [ + "Offset of field: input_absinfo::flat", + ][::std::mem::offset_of!(input_absinfo, flat) - 16usize]; + [ + "Offset of field: input_absinfo::resolution", + ][::std::mem::offset_of!(input_absinfo, resolution) - 20usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct input_keymap_entry { + pub flags: __u8, + pub len: __u8, + pub index: __u16, + pub keycode: __u32, + pub scancode: [__u8; 32usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of input_keymap_entry", + ][::std::mem::size_of::() - 40usize]; + [ + "Alignment of input_keymap_entry", + ][::std::mem::align_of::() - 4usize]; + [ + "Offset of field: input_keymap_entry::flags", + ][::std::mem::offset_of!(input_keymap_entry, flags) - 0usize]; + [ + "Offset of field: input_keymap_entry::len", + ][::std::mem::offset_of!(input_keymap_entry, len) - 1usize]; + [ + "Offset of field: input_keymap_entry::index", + ][::std::mem::offset_of!(input_keymap_entry, index) - 2usize]; + [ + "Offset of field: input_keymap_entry::keycode", + ][::std::mem::offset_of!(input_keymap_entry, keycode) - 4usize]; + [ + "Offset of field: input_keymap_entry::scancode", + ][::std::mem::offset_of!(input_keymap_entry, scancode) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct input_mask { + pub type_: __u32, + pub codes_size: __u32, + pub codes_ptr: __u64, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of input_mask"][::std::mem::size_of::() - 16usize]; + ["Alignment of input_mask"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: input_mask::type_", + ][::std::mem::offset_of!(input_mask, type_) - 0usize]; + [ + "Offset of field: input_mask::codes_size", + ][::std::mem::offset_of!(input_mask, codes_size) - 4usize]; + [ + "Offset of field: input_mask::codes_ptr", + ][::std::mem::offset_of!(input_mask, codes_ptr) - 8usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_replay { + pub length: __u16, + pub delay: __u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ff_replay"][::std::mem::size_of::() - 4usize]; + ["Alignment of ff_replay"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: ff_replay::length", + ][::std::mem::offset_of!(ff_replay, length) - 0usize]; + [ + "Offset of field: ff_replay::delay", + ][::std::mem::offset_of!(ff_replay, delay) - 2usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_trigger { + pub button: __u16, + pub interval: __u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ff_trigger"][::std::mem::size_of::() - 4usize]; + ["Alignment of ff_trigger"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: ff_trigger::button", + ][::std::mem::offset_of!(ff_trigger, button) - 0usize]; + [ + "Offset of field: ff_trigger::interval", + ][::std::mem::offset_of!(ff_trigger, interval) - 2usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_envelope { + pub attack_length: __u16, + pub attack_level: __u16, + pub fade_length: __u16, + pub fade_level: __u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ff_envelope"][::std::mem::size_of::() - 8usize]; + ["Alignment of ff_envelope"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: ff_envelope::attack_length", + ][::std::mem::offset_of!(ff_envelope, attack_length) - 0usize]; + [ + "Offset of field: ff_envelope::attack_level", + ][::std::mem::offset_of!(ff_envelope, attack_level) - 2usize]; + [ + "Offset of field: ff_envelope::fade_length", + ][::std::mem::offset_of!(ff_envelope, fade_length) - 4usize]; + [ + "Offset of field: ff_envelope::fade_level", + ][::std::mem::offset_of!(ff_envelope, fade_level) - 6usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_constant_effect { + pub level: __s16, + pub envelope: ff_envelope, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ff_constant_effect", + ][::std::mem::size_of::() - 10usize]; + [ + "Alignment of ff_constant_effect", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: ff_constant_effect::level", + ][::std::mem::offset_of!(ff_constant_effect, level) - 0usize]; + [ + "Offset of field: ff_constant_effect::envelope", + ][::std::mem::offset_of!(ff_constant_effect, envelope) - 2usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_ramp_effect { + pub start_level: __s16, + pub end_level: __s16, + pub envelope: ff_envelope, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ff_ramp_effect"][::std::mem::size_of::() - 12usize]; + ["Alignment of ff_ramp_effect"][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: ff_ramp_effect::start_level", + ][::std::mem::offset_of!(ff_ramp_effect, start_level) - 0usize]; + [ + "Offset of field: ff_ramp_effect::end_level", + ][::std::mem::offset_of!(ff_ramp_effect, end_level) - 2usize]; + [ + "Offset of field: ff_ramp_effect::envelope", + ][::std::mem::offset_of!(ff_ramp_effect, envelope) - 4usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_condition_effect { + pub right_saturation: __u16, + pub left_saturation: __u16, + pub right_coeff: __s16, + pub left_coeff: __s16, + pub deadband: __u16, + pub center: __s16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ff_condition_effect", + ][::std::mem::size_of::() - 12usize]; + [ + "Alignment of ff_condition_effect", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: ff_condition_effect::right_saturation", + ][::std::mem::offset_of!(ff_condition_effect, right_saturation) - 0usize]; + [ + "Offset of field: ff_condition_effect::left_saturation", + ][::std::mem::offset_of!(ff_condition_effect, left_saturation) - 2usize]; + [ + "Offset of field: ff_condition_effect::right_coeff", + ][::std::mem::offset_of!(ff_condition_effect, right_coeff) - 4usize]; + [ + "Offset of field: ff_condition_effect::left_coeff", + ][::std::mem::offset_of!(ff_condition_effect, left_coeff) - 6usize]; + [ + "Offset of field: ff_condition_effect::deadband", + ][::std::mem::offset_of!(ff_condition_effect, deadband) - 8usize]; + [ + "Offset of field: ff_condition_effect::center", + ][::std::mem::offset_of!(ff_condition_effect, center) - 10usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_periodic_effect { + pub waveform: __u16, + pub period: __u16, + pub magnitude: __s16, + pub offset: __s16, + pub phase: __u16, + pub envelope: ff_envelope, + pub custom_len: __u32, + pub custom_data: *mut __s16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ff_periodic_effect", + ][::std::mem::size_of::() - 32usize]; + [ + "Alignment of ff_periodic_effect", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ff_periodic_effect::waveform", + ][::std::mem::offset_of!(ff_periodic_effect, waveform) - 0usize]; + [ + "Offset of field: ff_periodic_effect::period", + ][::std::mem::offset_of!(ff_periodic_effect, period) - 2usize]; + [ + "Offset of field: ff_periodic_effect::magnitude", + ][::std::mem::offset_of!(ff_periodic_effect, magnitude) - 4usize]; + [ + "Offset of field: ff_periodic_effect::offset", + ][::std::mem::offset_of!(ff_periodic_effect, offset) - 6usize]; + [ + "Offset of field: ff_periodic_effect::phase", + ][::std::mem::offset_of!(ff_periodic_effect, phase) - 8usize]; + [ + "Offset of field: ff_periodic_effect::envelope", + ][::std::mem::offset_of!(ff_periodic_effect, envelope) - 10usize]; + [ + "Offset of field: ff_periodic_effect::custom_len", + ][::std::mem::offset_of!(ff_periodic_effect, custom_len) - 20usize]; + [ + "Offset of field: ff_periodic_effect::custom_data", + ][::std::mem::offset_of!(ff_periodic_effect, custom_data) - 24usize]; +}; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ff_rumble_effect { + pub strong_magnitude: __u16, + pub weak_magnitude: __u16, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ff_rumble_effect"][::std::mem::size_of::() - 4usize]; + [ + "Alignment of ff_rumble_effect", + ][::std::mem::align_of::() - 2usize]; + [ + "Offset of field: ff_rumble_effect::strong_magnitude", + ][::std::mem::offset_of!(ff_rumble_effect, strong_magnitude) - 0usize]; + [ + "Offset of field: ff_rumble_effect::weak_magnitude", + ][::std::mem::offset_of!(ff_rumble_effect, weak_magnitude) - 2usize]; +}; +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ff_effect { + pub type_: __u16, + pub id: __s16, + pub direction: __u16, + pub trigger: ff_trigger, + pub replay: ff_replay, + pub u: ff_effect__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union ff_effect__bindgen_ty_1 { + pub constant: ff_constant_effect, + pub ramp: ff_ramp_effect, + pub periodic: ff_periodic_effect, + pub condition: [ff_condition_effect; 2usize], + pub rumble: ff_rumble_effect, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + [ + "Size of ff_effect__bindgen_ty_1", + ][::std::mem::size_of::() - 32usize]; + [ + "Alignment of ff_effect__bindgen_ty_1", + ][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ff_effect__bindgen_ty_1::constant", + ][::std::mem::offset_of!(ff_effect__bindgen_ty_1, constant) - 0usize]; + [ + "Offset of field: ff_effect__bindgen_ty_1::ramp", + ][::std::mem::offset_of!(ff_effect__bindgen_ty_1, ramp) - 0usize]; + [ + "Offset of field: ff_effect__bindgen_ty_1::periodic", + ][::std::mem::offset_of!(ff_effect__bindgen_ty_1, periodic) - 0usize]; + [ + "Offset of field: ff_effect__bindgen_ty_1::condition", + ][::std::mem::offset_of!(ff_effect__bindgen_ty_1, condition) - 0usize]; + [ + "Offset of field: ff_effect__bindgen_ty_1::rumble", + ][::std::mem::offset_of!(ff_effect__bindgen_ty_1, rumble) - 0usize]; +}; +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ff_effect"][::std::mem::size_of::() - 48usize]; + ["Alignment of ff_effect"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: ff_effect::type_", + ][::std::mem::offset_of!(ff_effect, type_) - 0usize]; + ["Offset of field: ff_effect::id"][::std::mem::offset_of!(ff_effect, id) - 2usize]; + [ + "Offset of field: ff_effect::direction", + ][::std::mem::offset_of!(ff_effect, direction) - 4usize]; + [ + "Offset of field: ff_effect::trigger", + ][::std::mem::offset_of!(ff_effect, trigger) - 6usize]; + [ + "Offset of field: ff_effect::replay", + ][::std::mem::offset_of!(ff_effect, replay) - 10usize]; + ["Offset of field: ff_effect::u"][::std::mem::offset_of!(ff_effect, u) - 16usize]; +}; +pub type __gnuc_va_list = __BindgenOpaqueArray; +pub type va_list = __BindgenOpaqueArray; +///< Process data in sync mode +pub const libevdev_read_flag_LIBEVDEV_READ_FLAG_SYNC: libevdev_read_flag = 1; +///< Process data in normal mode +pub const libevdev_read_flag_LIBEVDEV_READ_FLAG_NORMAL: libevdev_read_flag = 2; +/**< Pretend the next event is a SYN_DROPPED and +require the caller to sync*/ +pub const libevdev_read_flag_LIBEVDEV_READ_FLAG_FORCE_SYNC: libevdev_read_flag = 4; +///< The fd is not in O_NONBLOCK and a read may block +pub const libevdev_read_flag_LIBEVDEV_READ_FLAG_BLOCKING: libevdev_read_flag = 8; +/// @ingroup events +pub type libevdev_read_flag = ::std::os::raw::c_uint; +unsafe extern "C" { + /** @ingroup init + + Initialize a new libevdev device. This function only allocates the + required memory and initializes the struct to sane default values. + To actually hook up the device to a kernel device, use + libevdev_set_fd(). + + Memory allocated through libevdev_new() must be released by the + caller with libevdev_free(). + + @see libevdev_set_fd + @see libevdev_free*/ + pub fn libevdev_new() -> *mut libevdev; +} +unsafe extern "C" { + /** @ingroup init + + Initialize a new libevdev device from the given fd. + + This is a shortcut for + + @code + int err; + struct libevdev *dev = libevdev_new(); + err = libevdev_set_fd(dev, fd); + @endcode + + @param fd A file descriptor to the device in O_RDWR or O_RDONLY mode. + @param[out] dev The newly initialized evdev device. + + @return On success, 0 is returned and dev is set to the newly + allocated struct. On failure, a negative errno is returned and the value + of dev is undefined. + + @see libevdev_free*/ + pub fn libevdev_new_from_fd( + fd: ::std::os::raw::c_int, + dev: *mut *mut libevdev, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup init + + Clean up and free the libevdev struct. After completion, the struct + libevdev is invalid and must not be used. + + Note that calling libevdev_free() does not close the file descriptor + currently associated with this instance. + + @param dev The evdev device + + @note This function may be called before libevdev_set_fd().*/ + pub fn libevdev_free(dev: *mut libevdev); +} +///< critical errors and application bugs +pub const libevdev_log_priority_LIBEVDEV_LOG_ERROR: libevdev_log_priority = 10; +///< informational messages +pub const libevdev_log_priority_LIBEVDEV_LOG_INFO: libevdev_log_priority = 20; +///< debug information +pub const libevdev_log_priority_LIBEVDEV_LOG_DEBUG: libevdev_log_priority = 30; +/// @ingroup logging +pub type libevdev_log_priority = ::std::os::raw::c_uint; +/** @ingroup logging + + Logging function called by library-internal logging. + This function is expected to treat its input like printf would. + + @param priority Log priority of this message + @param data User-supplied data pointer (see libevdev_set_log_function()) + @param file libevdev source code file generating this message + @param line libevdev source code line generating this message + @param func libevdev source code function generating this message + @param format printf-style format string + @param args List of arguments + + @see libevdev_set_log_function*/ +pub type libevdev_log_func_t = ::std::option::Option< + unsafe extern "C" fn( + priority: libevdev_log_priority, + data: *mut ::std::os::raw::c_void, + file: *const ::std::os::raw::c_char, + line: ::std::os::raw::c_int, + func: *const ::std::os::raw::c_char, + format: *const ::std::os::raw::c_char, + args: va_list, + ), +>; +unsafe extern "C" { + /** @ingroup logging + + Set a printf-style logging handler for library-internal logging. The default + logging function is to stdout. + + @note The global log handler is only called if no context-specific log + handler has been set with libevdev_set_device_log_function(). + + @param logfunc The logging function for this device. If NULL, the current + logging function is unset and no logging is performed. + @param data User-specific data passed to the log handler. + + @note This function may be called before libevdev_set_fd(). + + @deprecated Use per-context logging instead, see + libevdev_set_device_log_function().*/ + pub fn libevdev_set_log_function( + logfunc: libevdev_log_func_t, + data: *mut ::std::os::raw::c_void, + ); +} +unsafe extern "C" { + /** @ingroup logging + + Define the minimum level to be printed to the log handler. + Messages higher than this level are printed, others are discarded. This + is a global setting and applies to any future logging messages. + + @param priority Minimum priority to be printed to the log. + + @deprecated Use per-context logging instead, see + libevdev_set_device_log_function().*/ + pub fn libevdev_set_log_priority(priority: libevdev_log_priority); +} +unsafe extern "C" { + /** @ingroup logging + + Return the current log priority level. Messages higher than this level + are printed, others are discarded. This is a global setting. + + @return the current log level + + @deprecated Use per-context logging instead, see + libevdev_set_device_log_function().*/ + pub fn libevdev_get_log_priority() -> libevdev_log_priority; +} +/** @ingroup logging + + Logging function called by library-internal logging for a specific + libevdev context. This function is expected to treat its input like + printf would. + + @param dev The evdev device + @param priority Log priority of this message + @param data User-supplied data pointer (see libevdev_set_log_function()) + @param file libevdev source code file generating this message + @param line libevdev source code line generating this message + @param func libevdev source code function generating this message + @param format printf-style format string + @param args List of arguments + + @see libevdev_set_log_function + @since 1.3*/ +pub type libevdev_device_log_func_t = ::std::option::Option< + unsafe extern "C" fn( + dev: *const libevdev, + priority: libevdev_log_priority, + data: *mut ::std::os::raw::c_void, + file: *const ::std::os::raw::c_char, + line: ::std::os::raw::c_int, + func: *const ::std::os::raw::c_char, + format: *const ::std::os::raw::c_char, + args: va_list, + ), +>; +unsafe extern "C" { + /** @ingroup logging + + Set a printf-style logging handler for library-internal logging for this + device context. The default logging function is NULL, i.e. the global log + handler is invoked. If a context-specific log handler is set, the global + log handler is not invoked for this device. + + @note This log function applies for this device context only, even if + another context exists for the same fd. + + @param dev The evdev device + @param logfunc The logging function for this device. If NULL, the current + logging function is unset and logging falls back to the global log + handler, if any. + @param priority Minimum priority to be printed to the log. + @param data User-specific data passed to the log handler. + + @note This function may be called before libevdev_set_fd(). + @since 1.3*/ + pub fn libevdev_set_device_log_function( + dev: *mut libevdev, + logfunc: libevdev_device_log_func_t, + priority: libevdev_log_priority, + data: *mut ::std::os::raw::c_void, + ); +} +///< Grab the device if not currently grabbed +pub const libevdev_grab_mode_LIBEVDEV_GRAB: libevdev_grab_mode = 3; +///< Ungrab the device if currently grabbed +pub const libevdev_grab_mode_LIBEVDEV_UNGRAB: libevdev_grab_mode = 4; +/// @ingroup init +pub type libevdev_grab_mode = ::std::os::raw::c_uint; +unsafe extern "C" { + /** @ingroup init + + Grab or ungrab the device through a kernel EVIOCGRAB. This prevents other + clients (including kernel-internal ones such as rfkill) from receiving + events from this device. + + This is generally a bad idea. Don't do this. + + Grabbing an already grabbed device, or ungrabbing an ungrabbed device is + a noop and always succeeds. + + A grab is an operation tied to a file descriptor, not a device. If a + client changes the file descriptor with libevdev_change_fd(), it must + also re-issue a grab with libevdev_grab(). + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param grab If true, grab the device. Otherwise ungrab the device. + + @return 0 if the device was successfully grabbed or ungrabbed, or a + negative errno in case of failure.*/ + pub fn libevdev_grab( + dev: *mut libevdev, + grab: libevdev_grab_mode, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup init + + Set the fd for this struct and initialize internal data. + The fd must be in O_RDONLY or O_RDWR mode. + + This function may only be called once per device. If the device changed and + you need to re-read a device, use libevdev_free() and libevdev_new(). If + you need to change the fd after closing and re-opening the same device, use + libevdev_change_fd(). + + A caller should ensure that any events currently pending on the fd are + drained before the file descriptor is passed to libevdev for + initialization. Due to how the kernel's ioctl handling works, the initial + device state will reflect the current device state *after* applying all + events currently pending on the fd. Thus, if the fd is not drained, the + state visible to the caller will be inconsistent with the events + immediately available on the device. This does not affect state-less + events like EV_REL. + + Unless otherwise specified, libevdev function behavior is undefined until + a successful call to libevdev_set_fd(). + + @param dev The evdev device + @param fd The file descriptor for the device + + @return 0 on success, or a negative errno on failure + + @see libevdev_change_fd + @see libevdev_new + @see libevdev_free*/ + pub fn libevdev_set_fd( + dev: *mut libevdev, + fd: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup init + + Change the fd for this device, without re-reading the actual device. If the fd + changes after initializing the device, for example after a VT-switch in the + X.org X server, this function updates the internal fd to the newly opened. + No check is made that new fd points to the same device. If the device has + changed, libevdev's behavior is undefined. + + libevdev does not sync itself after changing the fd and keeps the current + device state. Use libevdev_next_event with the + @ref LIBEVDEV_READ_FLAG_FORCE_SYNC flag to force a re-sync. + + The example code below illustrates how to force a re-sync of the + library-internal state. Note that this code doesn't handle the events in + the caller, it merely forces an update of the internal library state. + @code + struct input_event ev; + libevdev_change_fd(dev, new_fd); + libevdev_next_event(dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev); + while (libevdev_next_event(dev, LIBEVDEV_READ_FLAG_SYNC, &ev) == LIBEVDEV_READ_STATUS_SYNC) + ; // noop + @endcode + + The fd may be open in O_RDONLY or O_RDWR. + + After changing the fd, the device is assumed ungrabbed and a caller must + call libevdev_grab() again. + + It is an error to call this function before calling libevdev_set_fd(). + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param fd The new fd + + @return 0 on success, or -1 on failure. + + @see libevdev_set_fd*/ + pub fn libevdev_change_fd( + dev: *mut libevdev, + fd: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup init + + @param dev The evdev device + + @return The previously set fd, or -1 if none had been set previously. + @note This function may be called before libevdev_set_fd().*/ + pub fn libevdev_get_fd(dev: *const libevdev) -> ::std::os::raw::c_int; +} +/** libevdev_next_event() has finished without an error + and an event is available for processing. + + @see libevdev_next_event*/ +pub const libevdev_read_status_LIBEVDEV_READ_STATUS_SUCCESS: libevdev_read_status = 0; +/** Depending on the libevdev_next_event() read flag: + * libevdev received a SYN_DROPPED from the device, and the caller should + now resync the device, or, + * an event has been read in sync mode. + + @see libevdev_next_event*/ +pub const libevdev_read_status_LIBEVDEV_READ_STATUS_SYNC: libevdev_read_status = 1; +/// @ingroup events +pub type libevdev_read_status = ::std::os::raw::c_uint; +unsafe extern "C" { + /** @ingroup events + + Get the next event from the device. This function operates in two different + modes: normal mode or sync mode. + + In normal mode (when flags has @ref LIBEVDEV_READ_FLAG_NORMAL set), this + function returns @ref LIBEVDEV_READ_STATUS_SUCCESS and returns the event + in the argument @p ev. If no events are available at this + time, it returns -EAGAIN and ev is undefined. + + If the current event is an EV_SYN SYN_DROPPED event, this function returns + @ref LIBEVDEV_READ_STATUS_SYNC and ev is set to the EV_SYN event. + The caller should now call this function with the + @ref LIBEVDEV_READ_FLAG_SYNC flag set, to get the set of events that make up the + device state delta. This function returns @ref LIBEVDEV_READ_STATUS_SYNC for + each event part of that delta, until it returns -EAGAIN once all events + have been synced. For more details on what libevdev does to sync after a + SYN_DROPPED event, see @ref syn_dropped. + + If a device needs to be synced by the caller but the caller does not call + with the @ref LIBEVDEV_READ_FLAG_SYNC flag set, all events from the diff are + dropped after libevdev updates its internal state and event processing + continues as normal. Note that the current slot and the state of touch + points may have updated during the SYN_DROPPED event, it is strongly + recommended that a caller ignoring all sync events calls + libevdev_get_current_slot() and checks the ABS_MT_TRACKING_ID values for + all slots. + + If a device has changed state without events being enqueued in libevdev, + e.g. after changing the file descriptor, use the @ref + LIBEVDEV_READ_FLAG_FORCE_SYNC flag. This triggers an internal sync of the + device and libevdev_next_event() returns @ref LIBEVDEV_READ_STATUS_SYNC. + Any state changes are available as events as described above. If + @ref LIBEVDEV_READ_FLAG_FORCE_SYNC is set, the value of ev is undefined. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param flags Set of flags to determine behaviour. If @ref LIBEVDEV_READ_FLAG_NORMAL + is set, the next event is read in normal mode. If @ref LIBEVDEV_READ_FLAG_SYNC is + set, the next event is read in sync mode. + @param ev On success, set to the current event. + @return On failure, a negative errno is returned. + @retval LIBEVDEV_READ_STATUS_SUCCESS One or more events were read of the + device and ev points to the next event in the queue + @retval -EAGAIN No events are currently available on the device + @retval LIBEVDEV_READ_STATUS_SYNC A SYN_DROPPED event was received, or a + synced event was returned and ev points to the SYN_DROPPED event + + @note This function is signal-safe.*/ + pub fn libevdev_next_event( + dev: *mut libevdev, + flags: ::std::os::raw::c_uint, + ev: *mut input_event, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup events + + Check if there are events waiting for us. This function does not read an + event off the fd and may not access the fd at all. If there are events + queued internally this function will return non-zero. If the internal + queue is empty, this function will poll the file descriptor for data. + + This is a convenience function for simple processes, most complex programs + are expected to use select(2) or poll(2) on the file descriptor. The kernel + guarantees that if data is available, it is a multiple of sizeof(struct + input_event), and thus calling libevdev_next_event() when select(2) or + poll(2) return is safe. You do not need libevdev_has_event_pending() if + you're using select(2) or poll(2). + + @param dev The evdev device, already initialized with libevdev_set_fd() + @return On failure, a negative errno is returned. + @retval 0 No event is currently available + @retval 1 One or more events are available on the fd + + @note This function is signal-safe.*/ + pub fn libevdev_has_event_pending(dev: *mut libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Retrieve the device's name, either as set by the caller or as read from + the kernel. The string returned is valid until libevdev_free() or until + libevdev_set_name(), whichever comes earlier. + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The device name as read off the kernel device. The name is never + NULL but it may be the empty string. + + @note This function is signal-safe.*/ + pub fn libevdev_get_name(dev: *const libevdev) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup kernel + + Change the device's name as returned by libevdev_get_name(). This + function destroys the string previously returned by libevdev_get_name(), + a caller must take care that no references are kept. + + @param dev The evdev device + @param name The new, non-NULL, name to assign to this device. + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value.*/ + pub fn libevdev_set_name(dev: *mut libevdev, name: *const ::std::os::raw::c_char); +} +unsafe extern "C" { + /** @ingroup bits + + Retrieve the device's physical location, either as set by the caller or + as read from the kernel. The string returned is valid until + libevdev_free() or until libevdev_set_phys(), whichever comes earlier. + + Virtual devices such as uinput devices have no phys location. + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The physical location of this device, or NULL if there is none + + @note This function is signal safe.*/ + pub fn libevdev_get_phys(dev: *const libevdev) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup kernel + + Change the device's physical location as returned by libevdev_get_phys(). + This function destroys the string previously returned by + libevdev_get_phys(), a caller must take care that no references are kept. + + @param dev The evdev device + @param phys The new phys to assign to this device. + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value.*/ + pub fn libevdev_set_phys(dev: *mut libevdev, phys: *const ::std::os::raw::c_char); +} +unsafe extern "C" { + /** @ingroup bits + + Retrieve the device's unique identifier, either as set by the caller or + as read from the kernel. The string returned is valid until + libevdev_free() or until libevdev_set_uniq(), whichever comes earlier. + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The unique identifier for this device, or NULL if there is none + + @note This function is signal safe.*/ + pub fn libevdev_get_uniq(dev: *const libevdev) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup kernel + + Change the device's unique identifier as returned by libevdev_get_uniq(). + This function destroys the string previously returned by + libevdev_get_uniq(), a caller must take care that no references are kept. + + @param dev The evdev device + @param uniq The new uniq to assign to this device. + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value.*/ + pub fn libevdev_set_uniq(dev: *mut libevdev, uniq: *const ::std::os::raw::c_char); +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The device's product ID + + @note This function is signal-safe.*/ + pub fn libevdev_get_id_product(dev: *const libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + @param dev The evdev device + @param product_id The product ID to assign to this device + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value. Even though + the function accepts an int for product_id the value is truncated at 16 + bits.*/ + pub fn libevdev_set_id_product( + dev: *mut libevdev, + product_id: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The device's vendor ID + + @note This function is signal-safe.*/ + pub fn libevdev_get_id_vendor(dev: *const libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + @param dev The evdev device + @param vendor_id The vendor ID to assign to this device + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value. Even though + the function accepts an int for vendor_id the value is truncated at 16 + bits.*/ + pub fn libevdev_set_id_vendor(dev: *mut libevdev, vendor_id: ::std::os::raw::c_int); +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The device's bus type + + @note This function is signal-safe.*/ + pub fn libevdev_get_id_bustype(dev: *const libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + @param dev The evdev device + @param bustype The bustype to assign to this device + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value. Even though + the function accepts an int for bustype the value is truncated at 16 + bits.*/ + pub fn libevdev_set_id_bustype(dev: *mut libevdev, bustype: ::std::os::raw::c_int); +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The device's firmware version + + @note This function is signal-safe.*/ + pub fn libevdev_get_id_version(dev: *const libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + @param dev The evdev device + @param version The version to assign to this device + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value. Even though + the function accepts an int for version the value is truncated at 16 + bits.*/ + pub fn libevdev_set_id_version(dev: *mut libevdev, version: ::std::os::raw::c_int); +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The driver version for this device + + @note This function is signal-safe.*/ + pub fn libevdev_get_driver_version(dev: *const libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param prop The input property to query for, one of INPUT_PROP_... + + @return 1 if the device provides this input property, or 0 otherwise. + + @note This function is signal-safe*/ + pub fn libevdev_has_property( + dev: *const libevdev, + prop: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + @param dev The evdev device + @param prop The input property to enable, one of INPUT_PROP_... + + @return 0 on success or -1 on failure + + @note This function may be called before libevdev_set_fd(). A call to + libevdev_set_fd() will overwrite any previously set value.*/ + pub fn libevdev_enable_property( + dev: *mut libevdev, + prop: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + @param dev The evdev device + @param prop The input property to disable, one of INPUT_PROP_... + + @return 0 on success or -1 on failure*/ + pub fn libevdev_disable_property( + dev: *mut libevdev, + prop: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type to query for, one of EV_SYN, EV_REL, etc. + + @return 1 if the device supports this event type, or 0 otherwise. + + @note This function is signal-safe.*/ + pub fn libevdev_has_event_type( + dev: *const libevdev, + type_: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type for the code to query (EV_SYN, EV_REL, etc.) + @param code The event code to query for, one of ABS_X, REL_X, etc. + + @return 1 if the device supports this event type and code, or 0 otherwise. + + @note This function is signal-safe.*/ + pub fn libevdev_has_event_code( + dev: *const libevdev, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Get the minimum axis value for the given axis, as advertised by the kernel. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_ABS event code to query for, one of ABS_X, ABS_Y, etc. + + @return axis minimum for the given axis or 0 if the axis is invalid + + @note This function is signal-safe.*/ + pub fn libevdev_get_abs_minimum( + dev: *const libevdev, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Get the maximum axis value for the given axis, as advertised by the kernel. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_ABS event code to query for, one of ABS_X, ABS_Y, etc. + + @return axis maximum for the given axis or 0 if the axis is invalid + + @note This function is signal-safe.*/ + pub fn libevdev_get_abs_maximum( + dev: *const libevdev, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Get the axis fuzz for the given axis, as advertised by the kernel. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_ABS event code to query for, one of ABS_X, ABS_Y, etc. + + @return axis fuzz for the given axis or 0 if the axis is invalid + + @note This function is signal-safe.*/ + pub fn libevdev_get_abs_fuzz( + dev: *const libevdev, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Get the axis flat for the given axis, as advertised by the kernel. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_ABS event code to query for, one of ABS_X, ABS_Y, etc. + + @return axis flat for the given axis or 0 if the axis is invalid + + @note This function is signal-safe.*/ + pub fn libevdev_get_abs_flat( + dev: *const libevdev, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Get the axis resolution for the given axis, as advertised by the kernel. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_ABS event code to query for, one of ABS_X, ABS_Y, etc. + + @return axis resolution for the given axis or 0 if the axis is invalid + + @note This function is signal-safe.*/ + pub fn libevdev_get_abs_resolution( + dev: *const libevdev, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Get the axis info for the given axis, as advertised by the kernel. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_ABS event code to query for, one of ABS_X, ABS_Y, etc. + + @return The input_absinfo for the given code, or NULL if the device does + not support this event code. + + @note This function is signal-safe.*/ + pub fn libevdev_get_abs_info( + dev: *const libevdev, + code: ::std::os::raw::c_uint, + ) -> *const input_absinfo; +} +unsafe extern "C" { + /** @ingroup bits + + Behaviour of this function is undefined if the device does not provide + the event. + + If the device supports ABS_MT_SLOT, the value returned for any ABS_MT_* + event code is undefined. Use libevdev_get_slot_value() instead. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type for the code to query (EV_SYN, EV_REL, etc.) + @param code The event code to query for, one of ABS_X, REL_X, etc. + + @return The current value of the event. + + @note This function is signal-safe. + @note The value for ABS_MT_ events is undefined, use + libevdev_get_slot_value() instead + + @see libevdev_get_slot_value*/ + pub fn libevdev_get_event_value( + dev: *const libevdev, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Set the value for a given event type and code. This only makes sense for + some event types, e.g. setting the value for EV_REL is pointless. + + This is a local modification only affecting only this representation of + this device. A future call to libevdev_get_event_value() will return this + value, unless the value was overwritten by an event. + + If the device supports ABS_MT_SLOT, the value set for any ABS_MT_* + event code is the value of the currently active slot. You should use + libevdev_set_slot_value() instead. + + If the device supports ABS_MT_SLOT and the type is EV_ABS and the code is + ABS_MT_SLOT, the value must be a positive number less then the number of + slots on the device. Otherwise, libevdev_set_event_value() returns -1. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type for the code to query (EV_SYN, EV_REL, etc.) + @param code The event code to set the value for, one of ABS_X, LED_NUML, etc. + @param value The new value to set + + @return 0 on success, or -1 on failure. + @retval -1 + - the device does not have the event type or + - code enabled, or the code is outside the, or + - the code is outside the allowed limits for the given type, or + - the type cannot be set, or + - the value is not permitted for the given code. + + @see libevdev_set_slot_value + @see libevdev_get_event_value*/ + pub fn libevdev_set_event_value( + dev: *mut libevdev, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + value: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Fetch the current value of the event type. This is a shortcut for + + @code + if (libevdev_has_event_type(dev, t) && libevdev_has_event_code(dev, t, c)) + val = libevdev_get_event_value(dev, t, c); + @endcode + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type for the code to query (EV_SYN, EV_REL, etc.) + @param code The event code to query for, one of ABS_X, REL_X, etc. + @param[out] value The current value of this axis returned. + + @return If the device supports this event type and code, the return value is + non-zero and value is set to the current value of this axis. Otherwise, + 0 is returned and value is unmodified. + + @note This function is signal-safe. + @note The value for ABS_MT_ events is undefined, use + libevdev_fetch_slot_value() instead + + @see libevdev_fetch_slot_value*/ + pub fn libevdev_fetch_event_value( + dev: *const libevdev, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + value: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup mt + + Return the current value of the code for the given slot. + + The return value is undefined for a slot exceeding the available slots on + the device, for a code that is not in the permitted ABS_MT range or for a + device that does not have slots. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param slot The numerical slot number, must be smaller than the total number + of slots on this device + @param code The event code to query for, one of ABS_MT_POSITION_X, etc. + + @note This function is signal-safe. + @note The value for events other than ABS_MT_ is undefined, use + libevdev_fetch_value() instead + + @see libevdev_get_event_value*/ + pub fn libevdev_get_slot_value( + dev: *const libevdev, + slot: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Set the value for a given code for the given slot. + + This is a local modification only affecting only this representation of + this device. A future call to libevdev_get_slot_value() will return this + value, unless the value was overwritten by an event. + + This function does not set event values for axes outside the ABS_MT range, + use libevdev_set_event_value() instead. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param slot The numerical slot number, must be smaller than the total number + of slots on this device + @param code The event code to set the value for, one of ABS_MT_POSITION_X, etc. + @param value The new value to set + + @return 0 on success, or -1 on failure. + @retval -1 + - the device does not have the event code enabled, or + - the code is outside the allowed limits for multitouch events, or + - the slot number is outside the limits for this device, or + - the device does not support multitouch events. + + @see libevdev_set_event_value + @see libevdev_get_slot_value*/ + pub fn libevdev_set_slot_value( + dev: *mut libevdev, + slot: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + value: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup mt + + Fetch the current value of the code for the given slot. This is a shortcut for + + @code + if (libevdev_has_event_type(dev, EV_ABS) && + libevdev_has_event_code(dev, EV_ABS, c) && + slot < device->number_of_slots) + val = libevdev_get_slot_value(dev, slot, c); + @endcode + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param slot The numerical slot number, must be smaller than the total number + of slots on this * device + @param[out] value The current value of this axis returned. + + @param code The event code to query for, one of ABS_MT_POSITION_X, etc. + @return If the device supports this event code, the return value is + non-zero and value is set to the current value of this axis. Otherwise, or + if the event code is not an ABS_MT_* event code, 0 is returned and value + is unmodified. + + @note This function is signal-safe.*/ + pub fn libevdev_fetch_slot_value( + dev: *const libevdev, + slot: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + value: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup mt + + Get the number of slots supported by this device. + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return The number of slots supported, or -1 if the device does not provide + any slots + + @note A device may provide ABS_MT_SLOT but a total number of 0 slots. Hence + the return value of -1 for "device does not provide slots at all"*/ + pub fn libevdev_get_num_slots(dev: *const libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup mt + + Get the currently active slot. This may differ from the value + an ioctl may return at this time as events may have been read off the fd + since changing the slot value but those events are still in the buffer + waiting to be processed. The returned value is the value a caller would + see if it were to process events manually one-by-one. + + @param dev The evdev device, already initialized with libevdev_set_fd() + + @return the currently active slot (logically) + + @note This function is signal-safe.*/ + pub fn libevdev_get_current_slot(dev: *const libevdev) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Change the minimum for the given EV_ABS event code, if the code exists. + This function has no effect if libevdev_has_event_code() returns false for + this code. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code One of ABS_X, ABS_Y, ... + @param val The new minimum for this axis*/ + pub fn libevdev_set_abs_minimum( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + val: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + /** @ingroup kernel + + Change the maximum for the given EV_ABS event code, if the code exists. + This function has no effect if libevdev_has_event_code() returns false for + this code. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code One of ABS_X, ABS_Y, ... + @param val The new maxium for this axis*/ + pub fn libevdev_set_abs_maximum( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + val: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + /** @ingroup kernel + + Change the fuzz for the given EV_ABS event code, if the code exists. + This function has no effect if libevdev_has_event_code() returns false for + this code. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code One of ABS_X, ABS_Y, ... + @param val The new fuzz for this axis*/ + pub fn libevdev_set_abs_fuzz( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + val: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + /** @ingroup kernel + + Change the flat for the given EV_ABS event code, if the code exists. + This function has no effect if libevdev_has_event_code() returns false for + this code. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code One of ABS_X, ABS_Y, ... + @param val The new flat for this axis*/ + pub fn libevdev_set_abs_flat( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + val: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + /** @ingroup kernel + + Change the resolution for the given EV_ABS event code, if the code exists. + This function has no effect if libevdev_has_event_code() returns false for + this code. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code One of ABS_X, ABS_Y, ... + @param val The new axis resolution*/ + pub fn libevdev_set_abs_resolution( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + val: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + /** @ingroup kernel + + Change the abs info for the given EV_ABS event code, if the code exists. + This function has no effect if libevdev_has_event_code() returns false for + this code. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code One of ABS_X, ABS_Y, ... + @param abs The new absolute axis data (min, max, fuzz, flat, resolution)*/ + pub fn libevdev_set_abs_info( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + abs: *const input_absinfo, + ); +} +unsafe extern "C" { + /** @ingroup kernel + + Forcibly enable an event type on this device, even if the underlying + device does not support it. While this cannot make the device actually + report such events, it will now return true for libevdev_has_event_type(). + + This is a local modification only affecting only this representation of + this device. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type to enable (EV_ABS, EV_KEY, ...) + + @return 0 on success or -1 otherwise + + @see libevdev_has_event_type*/ + pub fn libevdev_enable_event_type( + dev: *mut libevdev, + type_: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Forcibly disable an event type on this device, even if the underlying + device provides it. This effectively mutes the respective set of + events. libevdev will filter any events matching this type and none will + reach the caller. libevdev_has_event_type() will return false for this + type. + + In most cases, a caller likely only wants to disable a single code, not + the whole type. Use libevdev_disable_event_code() for that. + + Disabling EV_SYN will not work. Don't shoot yourself in the foot. + It hurts. + + This is a local modification only affecting only this representation of + this device. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type to disable (EV_ABS, EV_KEY, ...) + + @return 0 on success or -1 otherwise + + @see libevdev_has_event_type + @see libevdev_disable_event_type*/ + pub fn libevdev_disable_event_type( + dev: *mut libevdev, + type_: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Forcibly enable an event code on this device, even if the underlying + device does not support it. While this cannot make the device actually + report such events, it will now return true for libevdev_has_event_code(). + + The last argument depends on the type and code: + - If type is EV_ABS, data must be a pointer to a struct input_absinfo + containing the data for this axis. + - If type is EV_REP, data must be a pointer to a int containing the data + for this axis + - For all other types, the argument must be NULL. + + This function calls libevdev_enable_event_type() if necessary. + + This is a local modification only affecting only this representation of + this device. + + If this function is called with a type of EV_ABS and EV_REP on a device + that already has the given event code enabled, the values in data + overwrite the previous values. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type to enable (EV_ABS, EV_KEY, ...) + @param code The event code to enable (ABS_X, REL_X, etc.) + @param data If type is EV_ABS, data points to a struct input_absinfo. If type is EV_REP, data + points to an integer. Otherwise, data must be NULL. + + @return 0 on success or -1 otherwise + + @see libevdev_enable_event_type*/ + pub fn libevdev_enable_event_code( + dev: *mut libevdev, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + data: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Forcibly disable an event code on this device, even if the underlying + device provides it. This effectively mutes the respective set of + events. libevdev will filter any events matching this type and code and + none will reach the caller. libevdev_has_event_code() will return false for + this code. + + Disabling all event codes for a given type will not disable the event + type. Use libevdev_disable_event_type() for that. + + This is a local modification only affecting only this representation of + this device. + + Disabling codes of type EV_SYN will not work. Don't shoot yourself in the + foot. It hurts. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param type The event type to disable (EV_ABS, EV_KEY, ...) + @param code The event code to disable (ABS_X, REL_X, etc.) + + @return 0 on success or -1 otherwise + + @see libevdev_has_event_code + @see libevdev_disable_event_type*/ + pub fn libevdev_disable_event_code( + dev: *mut libevdev, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Set the device's EV_ABS axis to the value defined in the abs + parameter. This will be written to the kernel. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_ABS event code to modify, one of ABS_X, ABS_Y, etc. + @param abs Axis info to set the kernel axis to + + @return 0 on success, or a negative errno on failure + + @see libevdev_enable_event_code*/ + pub fn libevdev_kernel_set_abs_info( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + abs: *const input_absinfo, + ) -> ::std::os::raw::c_int; +} +///< Turn the LED on +pub const libevdev_led_value_LIBEVDEV_LED_ON: libevdev_led_value = 3; +///< Turn the LED off +pub const libevdev_led_value_LIBEVDEV_LED_OFF: libevdev_led_value = 4; +/// @ingroup kernel +pub type libevdev_led_value = ::std::os::raw::c_uint; +unsafe extern "C" { + /** @ingroup kernel + + Turn an LED on or off. Convenience function, if you need to modify multiple + LEDs simultaneously, use libevdev_kernel_set_led_values() instead. + + @note enabling an LED requires write permissions on the device's file descriptor. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param code The EV_LED event code to modify, one of LED_NUML, LED_CAPSL, ... + @param value Specifies whether to turn the LED on or off + @return 0 on success, or a negative errno on failure*/ + pub fn libevdev_kernel_set_led_value( + dev: *mut libevdev, + code: ::std::os::raw::c_uint, + value: libevdev_led_value, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Turn multiple LEDs on or off simultaneously. This function expects a pair + of LED codes and values to set them to, terminated by a -1. For example, to + switch the NumLock LED on but the CapsLock LED off, use: + + @code + libevdev_kernel_set_led_values(dev, LED_NUML, LIBEVDEV_LED_ON, + LED_CAPSL, LIBEVDEV_LED_OFF, + -1); + @endcode + + If any LED code or value is invalid, this function returns -EINVAL and no + LEDs are modified. + + @note enabling an LED requires write permissions on the device's file descriptor. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param ... A pair of LED_* event codes and libevdev_led_value_t, followed by + -1 to terminate the list. + @return 0 on success, or a negative errno on failure*/ + pub fn libevdev_kernel_set_led_values( + dev: *mut libevdev, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup kernel + + Set the clock ID to be used for timestamps. Further events from this device + will report an event time based on the given clock. + + This is a modification only affecting this representation of + this device. + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param clockid The clock to use for future events. Permitted values + are CLOCK_MONOTONIC and CLOCK_REALTIME (the default). + @return 0 on success, or a negative errno on failure*/ + pub fn libevdev_set_clock_id( + dev: *mut libevdev, + clockid: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Helper function to check if an event is of a specific type. This is + virtually the same as: + + ev->type == type + + with the exception that some sanity checks are performed to ensure type + is valid. + + @note The ranges for types are compiled into libevdev. If the kernel + changes the max value, libevdev will not automatically pick these up. + + @param ev The input event to check + @param type Input event type to compare the event against (EV_REL, EV_ABS, + etc.) + + @return 1 if the event type matches the given type, 0 otherwise (or if + type is invalid)*/ + pub fn libevdev_event_is_type( + ev: *const input_event, + type_: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Helper function to check if an event is of a specific type and code. This + is virtually the same as: + + ev->type == type && ev->code == code + + with the exception that some sanity checks are performed to ensure type and + code are valid. + + @note The ranges for types and codes are compiled into libevdev. If the kernel + changes the max value, libevdev will not automatically pick these up. + + @param ev The input event to check + @param type Input event type to compare the event against (EV_REL, EV_ABS, + etc.) + @param code Input event code to compare the event against (ABS_X, REL_X, + etc.) + + @return 1 if the event type matches the given type and code, 0 otherwise + (or if type/code are invalid)*/ + pub fn libevdev_event_is_code( + ev: *const input_event, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + @param type The event type to return the name for. + + @return The name of the given event type (e.g. EV_ABS) or NULL for an + invalid type + + @note The list of names is compiled into libevdev. If the kernel adds new + defines for new event types, libevdev will not automatically pick these up.*/ + pub fn libevdev_event_type_get_name( + type_: ::std::os::raw::c_uint, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup misc + + @param type The event type for the code to query (EV_SYN, EV_REL, etc.) + @param code The event code to return the name for (e.g. ABS_X) + + @return The name of the given event code (e.g. ABS_X) or NULL for an + invalid type or code + + @note The list of names is compiled into libevdev. If the kernel adds new + defines for new event codes, libevdev will not automatically pick these up.*/ + pub fn libevdev_event_code_get_name( + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup misc + + This function resolves the event value for a code. + + For almost all event codes this will return NULL as the value is just a + numerical value. As of kernel 4.17, the only event code that will return + a non-NULL value is EV_ABS/ABS_MT_TOOL_TYPE. + + @param type The event type for the value to query (EV_ABS, etc.) + @param code The event code for the value to query (e.g. ABS_MT_TOOL_TYPE) + @param value The event value to return the name for (e.g. MT_TOOL_PALM) + + @return The name of the given event value (e.g. MT_TOOL_PALM) or NULL for + an invalid type or code or NULL for an axis that has numerical values + only. + + @note The list of names is compiled into libevdev. If the kernel adds new + defines for new event values, libevdev will not automatically pick these up.*/ + pub fn libevdev_event_value_get_name( + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + value: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup misc + + @param prop The input prop to return the name for (e.g. INPUT_PROP_BUTTONPAD) + + @return The name of the given input prop (e.g. INPUT_PROP_BUTTONPAD) or NULL for an + invalid property + + @note The list of names is compiled into libevdev. If the kernel adds new + defines for new properties libevdev will not automatically pick these up. + @note On older kernels input properties may not be defined and + libevdev_property_get_name() will always return NULL*/ + pub fn libevdev_property_get_name( + prop: ::std::os::raw::c_uint, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup misc + + @param type The event type to return the maximum for (EV_ABS, EV_REL, etc.). No max is defined for + EV_SYN. + + @return The max value defined for the given event type, e.g. ABS_MAX for a type of EV_ABS, or -1 + for an invalid type. + + @note The max value is compiled into libevdev. If the kernel changes the + max value, libevdev will not automatically pick these up.*/ + pub fn libevdev_event_type_get_max( + type_: ::std::os::raw::c_uint, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event-type by its name. Event-types start with "EV_" followed by + the name (eg., "EV_ABS"). The "EV_" prefix must be included in the name. It + returns the constant assigned to the event-type or -1 if not found. + + @param name A non-NULL string describing an input-event type ("EV_KEY", + "EV_ABS", ...), zero-terminated. + + @return The given type constant for the passed name or -1 if not found. + + @note EV_MAX is also recognized.*/ + pub fn libevdev_event_type_from_name( + name: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event-type by its name. Event-types start with "EV_" followed by + the name (eg., "EV_ABS"). The "EV_" prefix must be included in the name. It + returns the constant assigned to the event-type or -1 if not found. + + @param name A non-NULL string describing an input-event type ("EV_KEY", + "EV_ABS", ...). + @param len The length of the passed string excluding any terminating 0 + character. + + @return The given type constant for the passed name or -1 if not found. + + @note EV_MAX is also recognized.*/ + pub fn libevdev_event_type_from_name_n( + name: *const ::std::os::raw::c_char, + len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event code by its type and name. Event codes start with a fixed + prefix followed by their name (eg., "ABS_X"). The prefix must be included in + the name. It returns the constant assigned to the event code or -1 if not + found. + + You have to pass the event type where to look for the name. For instance, to + resolve "ABS_X" you need to pass EV_ABS as type and "ABS_X" as string. + Supported event codes are codes starting with SYN_, KEY_, BTN_, REL_, ABS_, + MSC_, SND_, SW_, LED_, REP_, FF_. + + @param type The event type (EV_* constant) where to look for the name. + @param name A non-NULL string describing an input-event code ("KEY_A", + "ABS_X", "BTN_Y", ...), zero-terminated. + + @return The given code constant for the passed name or -1 if not found.*/ + pub fn libevdev_event_code_from_name( + type_: ::std::os::raw::c_uint, + name: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event code by its type and name. Event codes start with a fixed + prefix followed by their name (eg., "ABS_X"). The prefix must be included in + the name. It returns the constant assigned to the event code or -1 if not + found. + + You have to pass the event type where to look for the name. For instance, to + resolve "ABS_X" you need to pass EV_ABS as type and "ABS_X" as string. + Supported event codes are codes starting with SYN_, KEY_, BTN_, REL_, ABS_, + MSC_, SND_, SW_, LED_, REP_, FF_. + + @param type The event type (EV_* constant) where to look for the name. + @param name A non-NULL string describing an input-event code ("KEY_A", + "ABS_X", "BTN_Y", ...). + @param len The length of the string in @p name excluding any terminating 0 + character. + + @return The given code constant for the name or -1 if not found.*/ + pub fn libevdev_event_code_from_name_n( + type_: ::std::os::raw::c_uint, + name: *const ::std::os::raw::c_char, + len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event value by its type, code and name. Event values start + with a fixed prefix followed by their name (eg., "MT_TOOL_PALM"). The + prefix must be included in the name. It returns the constant assigned + to the event code or -1 if not found. + + You have to pass the event type and code where to look for the name. For + instance, to resolve "MT_TOOL_PALM" you need to pass EV_ABS as type, + ABS_MT_TOOL_TYPE as code and "MT_TOOL_PALM" as string. + + As of kernel 4.17, only EV_ABS/ABS_MT_TOOL_TYPE support name resolution. + + @param type The event type (EV_* constant) where to look for the name. + @param code The event code (ABS_* constant) where to look for the name. + @param name A non-NULL string describing an input-event value + ("MT_TOOL_TYPE", ...) + + @return The given value constant for the name or -1 if not found.*/ + pub fn libevdev_event_value_from_name( + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + name: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event type for a event code name. For example, the name + "ABS_Y" returns EV_ABS. For the lookup to succeed, the name must be + unique, which is the case for all defines as of kernel 5.0 and likely to + be the case in the future. + + This is equivalent to libevdev_event_type_from_name() but takes the code + name instead of the type name. + + @param name A non-NULL string describing an input-event value + ("ABS_X", "REL_Y", "KEY_A", ...) + + @return The given event code for the name or -1 if not found.*/ + pub fn libevdev_event_type_from_code_name( + name: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event type for a event code name. For example, the name + "ABS_Y" returns EV_ABS. For the lookup to succeed, the name must be + unique, which is the case for all defines as of kernel 5.0 and likely to + be the case in the future. + + This is equivalent to libevdev_event_type_from_name_n() but takes the code + name instead of the type name. + + @param name A non-NULL string describing an input-event value + ("ABS_X", "REL_Y", "KEY_A", ...) + @param len The length of the passed string excluding any terminating 0 + character. + + @return The given event code for the name or -1 if not found.*/ + pub fn libevdev_event_type_from_code_name_n( + name: *const ::std::os::raw::c_char, + len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event code by its name. For example, the name "ABS_Y" + returns 1. For the lookup to succeed, the name must be unique, which is + the case for all defines as of kernel 5.0 and likely to be the case in + the future. + + This is equivalent to libevdev_event_code_from_name() without the need + for knowing the event type. + + @param name A non-NULL string describing an input-event value + ("ABS_X", "REL_Y", "KEY_A", ...) + + @return The given event code for the name or -1 if not found.*/ + pub fn libevdev_event_code_from_code_name( + name: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event code by its name. For example, the name "ABS_Y" + returns 1. For the lookup to succeed, the name must be unique, which is + the case for all defines as of kernel 5.0 and likely to be the case in + the future. + + This is equivalent to libevdev_event_code_from_name_n() without the need + for knowing the event type. + + @param name A non-NULL string describing an input-event value + ("ABS_X", "REL_Y", "KEY_A", ...) + @param len The length of the passed string excluding any terminating 0 + character. + + @return The given event code for the name or -1 if not found.*/ + pub fn libevdev_event_code_from_code_name_n( + name: *const ::std::os::raw::c_char, + len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an event value by its type, code and name. Event values start + with a fixed prefix followed by their name (eg., "MT_TOOL_PALM"). The + prefix must be included in the name. It returns the constant assigned + to the event code or -1 if not found. + + You have to pass the event type and code where to look for the name. For + instance, to resolve "MT_TOOL_PALM" you need to pass EV_ABS as type, + ABS_MT_TOOL_TYPE as code and "MT_TOOL_PALM" as string. + + As of kernel 4.17, only EV_ABS/ABS_MT_TOOL_TYPE support name resolution. + + @param type The event type (EV_* constant) where to look for the name. + @param code The event code (ABS_* constant) where to look for the name. + @param name A non-NULL string describing an input-event value + ("MT_TOOL_TYPE", ...) + @param len The length of the string in @p name excluding any terminating 0 + character. + + @return The given value constant for the name or -1 if not found.*/ + pub fn libevdev_event_value_from_name_n( + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + name: *const ::std::os::raw::c_char, + len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an input property by its name. Properties start with the fixed + prefix "INPUT_PROP_" followed by their name (eg., "INPUT_PROP_POINTER"). + The prefix must be included in the name. It returns the constant assigned + to the property or -1 if not found. + + @param name A non-NULL string describing an input property + + @return The given code constant for the name or -1 if not found.*/ + pub fn libevdev_property_from_name( + name: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup misc + + Look up an input property by its name. Properties start with the fixed + prefix "INPUT_PROP_" followed by their name (eg., "INPUT_PROP_POINTER"). + The prefix must be included in the name. It returns the constant assigned + to the property or -1 if not found. + + @param name A non-NULL string describing an input property + @param len The length of the string in @p name excluding any terminating 0 + character. + + @return The given code constant for the name or -1 if not found.*/ + pub fn libevdev_property_from_name_n( + name: *const ::std::os::raw::c_char, + len: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup bits + + Get the repeat delay and repeat period values for this device. This + function is a convenience function only, EV_REP is supported by + libevdev_get_event_value(). + + @param dev The evdev device, already initialized with libevdev_set_fd() + @param delay If not null, set to the repeat delay value + @param period If not null, set to the repeat period value + + @return 0 on success, -1 if this device does not have repeat settings. + + @note This function is signal-safe + + @see libevdev_get_event_value*/ + pub fn libevdev_get_repeat( + dev: *const libevdev, + delay: *mut ::std::os::raw::c_int, + period: *mut ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +pub type fpos_t = off_t; +pub type fpos64_t = off64_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __sFILE { + _unused: [u8; 0], +} +pub type FILE = __sFILE; +unsafe extern "C" { + pub static mut stdin: *mut FILE; +} +unsafe extern "C" { + pub static mut stdout: *mut FILE; +} +unsafe extern "C" { + pub static mut stderr: *mut FILE; +} +unsafe extern "C" { + pub fn clearerr(__fp: *mut FILE); +} +unsafe extern "C" { + pub fn fclose(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn feof(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ferror(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fflush(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fgetc(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fgets( + __buf: *mut ::std::os::raw::c_char, + __size: ::std::os::raw::c_int, + __fp: *mut FILE, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn fprintf( + __fp: *mut FILE, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fputc(__ch: ::std::os::raw::c_int, __fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fputs( + __s: *const ::std::os::raw::c_char, + __fp: *mut FILE, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fread( + __buf: *mut ::std::os::raw::c_void, + __size: ::std::os::raw::c_ulong, + __count: ::std::os::raw::c_ulong, + __fp: *mut FILE, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn fscanf( + __fp: *mut FILE, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fwrite( + __buf: *const ::std::os::raw::c_void, + __size: ::std::os::raw::c_ulong, + __count: ::std::os::raw::c_ulong, + __fp: *mut FILE, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn getc(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getchar() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getdelim( + __line_ptr: *mut *mut ::std::os::raw::c_char, + __line_length_ptr: *mut usize, + __delimiter: ::std::os::raw::c_int, + __fp: *mut FILE, + ) -> isize; +} +unsafe extern "C" { + pub fn getline( + __line_ptr: *mut *mut ::std::os::raw::c_char, + __line_length_ptr: *mut usize, + __fp: *mut FILE, + ) -> isize; +} +unsafe extern "C" { + pub fn perror(__msg: *const ::std::os::raw::c_char); +} +unsafe extern "C" { + pub fn printf(__fmt: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn putc(__ch: ::std::os::raw::c_int, __fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn putchar(__ch: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn puts(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn remove(__path: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn rewind(__fp: *mut FILE); +} +unsafe extern "C" { + pub fn scanf(__fmt: *const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn setbuf(__fp: *mut FILE, __buf: *mut ::std::os::raw::c_char); +} +unsafe extern "C" { + pub fn setvbuf( + __fp: *mut FILE, + __buf: *mut ::std::os::raw::c_char, + __mode: ::std::os::raw::c_int, + __size: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sscanf( + __s: *const ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ungetc(__ch: ::std::os::raw::c_int, __fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vfprintf( + __fp: *mut FILE, + __fmt: *const ::std::os::raw::c_char, + __args: __BindgenOpaqueArray, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vprintf( + __fp: *const ::std::os::raw::c_char, + __args: __BindgenOpaqueArray, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn dprintf( + __fd: ::std::os::raw::c_int, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vdprintf( + __fd: ::std::os::raw::c_int, + __fmt: *const ::std::os::raw::c_char, + __args: va_list, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn sprintf( + __s: *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vsprintf( + __s: *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + __args: __BindgenOpaqueArray, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn tmpnam(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn tempnam( + __dir: *const ::std::os::raw::c_char, + __prefix: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn rename( + __old_path: *const ::std::os::raw::c_char, + __new_path: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn renameat( + __old_dir_fd: ::std::os::raw::c_int, + __old_path: *const ::std::os::raw::c_char, + __new_dir_fd: ::std::os::raw::c_int, + __new_path: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fseek( + __fp: *mut FILE, + __offset: ::std::os::raw::c_long, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ftell(__fp: *mut FILE) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn fgetpos(__fp: *mut FILE, __pos: *mut fpos_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fsetpos(__fp: *mut FILE, __pos: *const fpos_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fseeko( + __fp: *mut FILE, + __offset: off_t, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ftello(__fp: *mut FILE) -> off_t; +} +unsafe extern "C" { + pub fn fgetpos64(__fp: *mut FILE, __pos: *mut fpos64_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fsetpos64(__fp: *mut FILE, __pos: *const fpos64_t) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fseeko64( + __fp: *mut FILE, + __offset: off64_t, + __whence: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ftello64(__fp: *mut FILE) -> off64_t; +} +unsafe extern "C" { + pub fn fopen( + __path: *const ::std::os::raw::c_char, + __mode: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn fopen64( + __path: *const ::std::os::raw::c_char, + __mode: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn freopen( + __path: *const ::std::os::raw::c_char, + __mode: *const ::std::os::raw::c_char, + __fp: *mut FILE, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn freopen64( + __path: *const ::std::os::raw::c_char, + __mode: *const ::std::os::raw::c_char, + __fp: *mut FILE, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn tmpfile() -> *mut FILE; +} +unsafe extern "C" { + pub fn tmpfile64() -> *mut FILE; +} +unsafe extern "C" { + pub fn snprintf( + __buf: *mut ::std::os::raw::c_char, + __size: ::std::os::raw::c_ulong, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vfscanf( + __fp: *mut FILE, + __fmt: *const ::std::os::raw::c_char, + __args: __BindgenOpaqueArray, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vscanf( + __fmt: *const ::std::os::raw::c_char, + __args: __BindgenOpaqueArray, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vsnprintf( + __buf: *mut ::std::os::raw::c_char, + __size: ::std::os::raw::c_ulong, + __fmt: *const ::std::os::raw::c_char, + __args: __BindgenOpaqueArray, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vsscanf( + __s: *const ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + __args: __BindgenOpaqueArray, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ctermid(__buf: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn fdopen( + __fd: ::std::os::raw::c_int, + __mode: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn fileno(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn pclose(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn popen( + __command: *const ::std::os::raw::c_char, + __mode: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn flockfile(__fp: *mut FILE); +} +unsafe extern "C" { + pub fn ftrylockfile(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn funlockfile(__fp: *mut FILE); +} +unsafe extern "C" { + pub fn getc_unlocked(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getchar_unlocked() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn putc_unlocked( + __ch: ::std::os::raw::c_int, + __fp: *mut FILE, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn putchar_unlocked(__ch: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fmemopen( + __buf: *mut ::std::os::raw::c_void, + __size: usize, + __mode: *const ::std::os::raw::c_char, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn open_memstream( + __ptr: *mut *mut ::std::os::raw::c_char, + __size_ptr: *mut usize, + ) -> *mut FILE; +} +unsafe extern "C" { + pub fn asprintf( + __s_ptr: *mut *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + ... + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fgetln( + __fp: *mut FILE, + __length_ptr: *mut usize, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn fpurge(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn setbuffer( + __fp: *mut FILE, + __buf: *mut ::std::os::raw::c_char, + __size: ::std::os::raw::c_int, + ); +} +unsafe extern "C" { + pub fn setlinebuf(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn vasprintf( + __s_ptr: *mut *mut ::std::os::raw::c_char, + __fmt: *const ::std::os::raw::c_char, + __args: va_list, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn clearerr_unlocked(__fp: *mut FILE); +} +unsafe extern "C" { + pub fn feof_unlocked(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ferror_unlocked(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn fileno_unlocked(__fp: *mut FILE) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn malloc(__byte_count: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn calloc( + __item_count: ::std::os::raw::c_ulong, + __item_size: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn realloc( + __ptr: *mut ::std::os::raw::c_void, + __byte_count: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn reallocarray( + __ptr: *mut ::std::os::raw::c_void, + __item_count: usize, + __item_size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn free(__ptr: *mut ::std::os::raw::c_void); +} +unsafe extern "C" { + pub fn memalign( + __alignment: ::std::os::raw::c_ulong, + __byte_count: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn malloc_usable_size(__ptr: *const ::std::os::raw::c_void) -> usize; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mallinfo { + pub arena: usize, + pub ordblks: usize, + pub smblks: usize, + pub hblks: usize, + pub hblkhd: usize, + pub usmblks: usize, + pub fsmblks: usize, + pub uordblks: usize, + pub fordblks: usize, + pub keepcost: usize, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of mallinfo"][::std::mem::size_of::() - 80usize]; + ["Alignment of mallinfo"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: mallinfo::arena", + ][::std::mem::offset_of!(mallinfo, arena) - 0usize]; + [ + "Offset of field: mallinfo::ordblks", + ][::std::mem::offset_of!(mallinfo, ordblks) - 8usize]; + [ + "Offset of field: mallinfo::smblks", + ][::std::mem::offset_of!(mallinfo, smblks) - 16usize]; + [ + "Offset of field: mallinfo::hblks", + ][::std::mem::offset_of!(mallinfo, hblks) - 24usize]; + [ + "Offset of field: mallinfo::hblkhd", + ][::std::mem::offset_of!(mallinfo, hblkhd) - 32usize]; + [ + "Offset of field: mallinfo::usmblks", + ][::std::mem::offset_of!(mallinfo, usmblks) - 40usize]; + [ + "Offset of field: mallinfo::fsmblks", + ][::std::mem::offset_of!(mallinfo, fsmblks) - 48usize]; + [ + "Offset of field: mallinfo::uordblks", + ][::std::mem::offset_of!(mallinfo, uordblks) - 56usize]; + [ + "Offset of field: mallinfo::fordblks", + ][::std::mem::offset_of!(mallinfo, fordblks) - 64usize]; + [ + "Offset of field: mallinfo::keepcost", + ][::std::mem::offset_of!(mallinfo, keepcost) - 72usize]; +}; +unsafe extern "C" { + pub fn mallinfo() -> mallinfo; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct mallinfo2 { + pub arena: usize, + pub ordblks: usize, + pub smblks: usize, + pub hblks: usize, + pub hblkhd: usize, + pub usmblks: usize, + pub fsmblks: usize, + pub uordblks: usize, + pub fordblks: usize, + pub keepcost: usize, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of mallinfo2"][::std::mem::size_of::() - 80usize]; + ["Alignment of mallinfo2"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: mallinfo2::arena", + ][::std::mem::offset_of!(mallinfo2, arena) - 0usize]; + [ + "Offset of field: mallinfo2::ordblks", + ][::std::mem::offset_of!(mallinfo2, ordblks) - 8usize]; + [ + "Offset of field: mallinfo2::smblks", + ][::std::mem::offset_of!(mallinfo2, smblks) - 16usize]; + [ + "Offset of field: mallinfo2::hblks", + ][::std::mem::offset_of!(mallinfo2, hblks) - 24usize]; + [ + "Offset of field: mallinfo2::hblkhd", + ][::std::mem::offset_of!(mallinfo2, hblkhd) - 32usize]; + [ + "Offset of field: mallinfo2::usmblks", + ][::std::mem::offset_of!(mallinfo2, usmblks) - 40usize]; + [ + "Offset of field: mallinfo2::fsmblks", + ][::std::mem::offset_of!(mallinfo2, fsmblks) - 48usize]; + [ + "Offset of field: mallinfo2::uordblks", + ][::std::mem::offset_of!(mallinfo2, uordblks) - 56usize]; + [ + "Offset of field: mallinfo2::fordblks", + ][::std::mem::offset_of!(mallinfo2, fordblks) - 64usize]; + [ + "Offset of field: mallinfo2::keepcost", + ][::std::mem::offset_of!(mallinfo2, keepcost) - 72usize]; +}; +unsafe extern "C" { + pub fn malloc_info( + __must_be_zero: ::std::os::raw::c_int, + __fp: *mut FILE, + ) -> ::std::os::raw::c_int; +} +pub const HeapTaggingLevel_M_HEAP_TAGGING_LEVEL_NONE: HeapTaggingLevel = 0; +pub const HeapTaggingLevel_M_HEAP_TAGGING_LEVEL_TBI: HeapTaggingLevel = 1; +pub const HeapTaggingLevel_M_HEAP_TAGGING_LEVEL_ASYNC: HeapTaggingLevel = 2; +pub const HeapTaggingLevel_M_HEAP_TAGGING_LEVEL_SYNC: HeapTaggingLevel = 3; +pub type HeapTaggingLevel = ::std::os::raw::c_uint; +unsafe extern "C" { + pub fn mallopt( + __option: ::std::os::raw::c_int, + __value: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub static mut __malloc_hook: ::std::option::Option< + unsafe extern "C" fn( + __byte_count: usize, + __caller: *const ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >; +} +unsafe extern "C" { + pub static mut __realloc_hook: ::std::option::Option< + unsafe extern "C" fn( + __ptr: *mut ::std::os::raw::c_void, + __byte_count: usize, + __caller: *const ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >; +} +unsafe extern "C" { + pub static mut __free_hook: ::std::option::Option< + unsafe extern "C" fn( + __ptr: *mut ::std::os::raw::c_void, + __caller: *const ::std::os::raw::c_void, + ), + >; +} +unsafe extern "C" { + pub static mut __memalign_hook: ::std::option::Option< + unsafe extern "C" fn( + __alignment: usize, + __byte_count: usize, + __caller: *const ::std::os::raw::c_void, + ) -> *mut ::std::os::raw::c_void, + >; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __locale_t { + _unused: [u8; 0], +} +pub type locale_t = *mut __locale_t; +unsafe extern "C" { + pub fn abort() -> !; +} +unsafe extern "C" { + pub fn exit(__status: ::std::os::raw::c_int) -> !; +} +unsafe extern "C" { + pub fn _Exit(__status: ::std::os::raw::c_int) -> !; +} +unsafe extern "C" { + pub fn atexit( + __fn: ::std::option::Option, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn at_quick_exit( + __fn: ::std::option::Option, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn quick_exit(__status: ::std::os::raw::c_int) -> !; +} +unsafe extern "C" { + pub fn getenv(__name: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn putenv(__assignment: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn setenv( + __name: *const ::std::os::raw::c_char, + __value: *const ::std::os::raw::c_char, + __overwrite: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn unsetenv(__name: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn clearenv() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkdtemp( + __template: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn mktemp( + __template: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn mkostemp64( + __template: *mut ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkostemp( + __template: *mut ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkostemps64( + __template: *mut ::std::os::raw::c_char, + __suffix_length: ::std::os::raw::c_int, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkostemps( + __template: *mut ::std::os::raw::c_char, + __suffix_length: ::std::os::raw::c_int, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkstemp64(__template: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkstemp(__template: *mut ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkstemps64( + __template: *mut ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mkstemps( + __template: *mut ::std::os::raw::c_char, + __flags: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strtol( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn strtoll( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn strtoul( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn strtoull( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_ulonglong; +} +unsafe extern "C" { + pub fn posix_memalign( + __memptr: *mut *mut ::std::os::raw::c_void, + __alignment: usize, + __size: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn aligned_alloc( + __alignment: ::std::os::raw::c_ulong, + __size: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn strtod( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + ) -> f64; +} +unsafe extern "C" { + pub fn strtold( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + ) -> u128; +} +unsafe extern "C" { + pub fn strtoul_l( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + __l: locale_t, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn atoi(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn atol(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn atoll(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn realpath( + __path: *const ::std::os::raw::c_char, + __resolved: *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn system(__command: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn bsearch( + __key: *const ::std::os::raw::c_void, + __base: *const ::std::os::raw::c_void, + __nmemb: usize, + __size: usize, + __comparator: ::std::option::Option< + unsafe extern "C" fn( + __lhs: *const ::std::os::raw::c_void, + __rhs: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn qsort( + __base: *mut ::std::os::raw::c_void, + __nmemb: usize, + __size: usize, + __comparator: ::std::option::Option< + unsafe extern "C" fn( + __lhs: *const ::std::os::raw::c_void, + __rhs: *const ::std::os::raw::c_void, + ) -> ::std::os::raw::c_int, + >, + ); +} +unsafe extern "C" { + pub fn arc4random() -> u32; +} +unsafe extern "C" { + pub fn arc4random_uniform(__upper_bound: u32) -> u32; +} +unsafe extern "C" { + pub fn arc4random_buf(__buf: *mut ::std::os::raw::c_void, __n: usize); +} +unsafe extern "C" { + pub fn rand_r(__seed_ptr: *mut ::std::os::raw::c_uint) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn drand48() -> f64; +} +unsafe extern "C" { + pub fn erand48(__xsubi: *mut ::std::os::raw::c_ushort) -> f64; +} +unsafe extern "C" { + pub fn jrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn lcong48(__param: *mut ::std::os::raw::c_ushort); +} +unsafe extern "C" { + pub fn lrand48() -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn mrand48() -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn nrand48(__xsubi: *mut ::std::os::raw::c_ushort) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn seed48( + __seed16v: *mut ::std::os::raw::c_ushort, + ) -> *mut ::std::os::raw::c_ushort; +} +unsafe extern "C" { + pub fn srand48(__seed: ::std::os::raw::c_long); +} +unsafe extern "C" { + pub fn initstate( + __seed: ::std::os::raw::c_uint, + __state: *mut ::std::os::raw::c_char, + __n: usize, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn setstate(__state: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn getpt() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn posix_openpt(__flags: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn ptsname(__fd: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn ptsname_r( + __fd: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __n: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn unlockpt(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getsubopt( + __option: *mut *mut ::std::os::raw::c_char, + __tokens: *const *mut ::std::os::raw::c_char, + __value_ptr: *mut *mut ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct div_t { + pub quot: ::std::os::raw::c_int, + pub rem: ::std::os::raw::c_int, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of div_t"][::std::mem::size_of::() - 8usize]; + ["Alignment of div_t"][::std::mem::align_of::() - 4usize]; + ["Offset of field: div_t::quot"][::std::mem::offset_of!(div_t, quot) - 0usize]; + ["Offset of field: div_t::rem"][::std::mem::offset_of!(div_t, rem) - 4usize]; +}; +unsafe extern "C" { + pub fn div( + __numerator: ::std::os::raw::c_int, + __denominator: ::std::os::raw::c_int, + ) -> div_t; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct ldiv_t { + pub quot: ::std::os::raw::c_long, + pub rem: ::std::os::raw::c_long, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of ldiv_t"][::std::mem::size_of::() - 16usize]; + ["Alignment of ldiv_t"][::std::mem::align_of::() - 8usize]; + ["Offset of field: ldiv_t::quot"][::std::mem::offset_of!(ldiv_t, quot) - 0usize]; + ["Offset of field: ldiv_t::rem"][::std::mem::offset_of!(ldiv_t, rem) - 8usize]; +}; +unsafe extern "C" { + pub fn ldiv( + __numerator: ::std::os::raw::c_long, + __denominator: ::std::os::raw::c_long, + ) -> ldiv_t; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct lldiv_t { + pub quot: ::std::os::raw::c_longlong, + pub rem: ::std::os::raw::c_longlong, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of lldiv_t"][::std::mem::size_of::() - 16usize]; + ["Alignment of lldiv_t"][::std::mem::align_of::() - 8usize]; + ["Offset of field: lldiv_t::quot"][::std::mem::offset_of!(lldiv_t, quot) - 0usize]; + ["Offset of field: lldiv_t::rem"][::std::mem::offset_of!(lldiv_t, rem) - 8usize]; +}; +unsafe extern "C" { + pub fn lldiv( + __numerator: ::std::os::raw::c_longlong, + __denominator: ::std::os::raw::c_longlong, + ) -> lldiv_t; +} +unsafe extern "C" { + pub fn getloadavg( + __averages: *mut f64, + __n: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn getprogname() -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn setprogname(__name: *const ::std::os::raw::c_char); +} +unsafe extern "C" { + pub fn mblen( + __s: *const ::std::os::raw::c_char, + __n: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn mbstowcs( + __dst: *mut wchar_t, + __src: *const ::std::os::raw::c_char, + __n: usize, + ) -> usize; +} +unsafe extern "C" { + pub fn mbtowc( + __wc_ptr: *mut wchar_t, + __s: *const ::std::os::raw::c_char, + __n: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn wctomb( + __dst: *mut ::std::os::raw::c_char, + __wc: wchar_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn wcstombs( + __dst: *mut ::std::os::raw::c_char, + __src: *const wchar_t, + __n: usize, + ) -> usize; +} +unsafe extern "C" { + pub fn __ctype_get_mb_cur_max() -> usize; +} +unsafe extern "C" { + pub fn abs(__x: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn labs(__x: ::std::os::raw::c_long) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn llabs(__x: ::std::os::raw::c_longlong) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn strtof( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + ) -> f32; +} +unsafe extern "C" { + pub fn atof(__s: *const ::std::os::raw::c_char) -> f64; +} +unsafe extern "C" { + pub fn rand() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn srand(__seed: ::std::os::raw::c_uint); +} +unsafe extern "C" { + pub fn random() -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn srandom(__seed: ::std::os::raw::c_uint); +} +unsafe extern "C" { + pub fn grantpt(__fd: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strtoll_l( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + __l: locale_t, + ) -> ::std::os::raw::c_longlong; +} +unsafe extern "C" { + pub fn strtoull_l( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __base: ::std::os::raw::c_int, + __l: locale_t, + ) -> ::std::os::raw::c_ulonglong; +} +unsafe extern "C" { + pub fn strtold_l( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __l: locale_t, + ) -> u128; +} +unsafe extern "C" { + pub fn strtod_l( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __l: locale_t, + ) -> f64; +} +unsafe extern "C" { + pub fn strtof_l( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + __l: locale_t, + ) -> f32; +} +unsafe extern "C" { + pub fn strtol_l( + __s: *const ::std::os::raw::c_char, + __end_ptr: *mut *mut ::std::os::raw::c_char, + arg1: ::std::os::raw::c_int, + __l: locale_t, + ) -> ::std::os::raw::c_long; +} +unsafe extern "C" { + pub fn __errno() -> *mut ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strcasecmp( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strcasecmp_l( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __l: locale_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strncasecmp( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strncasecmp_l( + __s1: *const ::std::os::raw::c_char, + __s2: *const ::std::os::raw::c_char, + __n: usize, + __l: locale_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn memccpy( + __dst: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __stop_char: ::std::os::raw::c_int, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn memchr( + __s: *const ::std::os::raw::c_void, + __ch: ::std::os::raw::c_int, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn memrchr( + __s: *const ::std::os::raw::c_void, + __ch: ::std::os::raw::c_int, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn memcmp( + __lhs: *const ::std::os::raw::c_void, + __rhs: *const ::std::os::raw::c_void, + __n: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn memcpy( + arg1: *mut ::std::os::raw::c_void, + arg2: *const ::std::os::raw::c_void, + arg3: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn memmove( + __dst: *mut ::std::os::raw::c_void, + __src: *const ::std::os::raw::c_void, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn memset( + __dst: *mut ::std::os::raw::c_void, + __ch: ::std::os::raw::c_int, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn memset_explicit( + __dst: *mut ::std::os::raw::c_void, + __ch: ::std::os::raw::c_int, + __n: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn memmem( + __haystack: *const ::std::os::raw::c_void, + __haystack_size: usize, + __needle: *const ::std::os::raw::c_void, + __needle_size: usize, + ) -> *mut ::std::os::raw::c_void; +} +unsafe extern "C" { + pub fn strchr( + __s: *const ::std::os::raw::c_char, + __ch: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn __strchr_chk( + __s: *const ::std::os::raw::c_char, + __ch: ::std::os::raw::c_int, + __n: usize, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strrchr( + __s: *const ::std::os::raw::c_char, + __ch: ::std::os::raw::c_int, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn __strrchr_chk( + __s: *const ::std::os::raw::c_char, + __ch: ::std::os::raw::c_int, + __n: usize, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strlen(__s: *const ::std::os::raw::c_char) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn __strlen_chk(__s: *const ::std::os::raw::c_char, __n: usize) -> usize; +} +unsafe extern "C" { + pub fn strcmp( + __lhs: *const ::std::os::raw::c_char, + __rhs: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn stpcpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strcpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strcat( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strdup(__s: *const ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strstr( + __haystack: *const ::std::os::raw::c_char, + __needle: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strcasestr( + __haystack: *const ::std::os::raw::c_char, + __needle: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strtok( + __s: *mut ::std::os::raw::c_char, + __delimiter: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strtok_r( + __s: *mut ::std::os::raw::c_char, + __delimiter: *const ::std::os::raw::c_char, + __pos_ptr: *mut *mut ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strerror(__errno_value: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strerror_l( + __errno_value: ::std::os::raw::c_int, + __l: locale_t, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strerror_r( + __errno_value: ::std::os::raw::c_int, + __buf: *mut ::std::os::raw::c_char, + __n: usize, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strnlen(__s: *const ::std::os::raw::c_char, __n: usize) -> usize; +} +unsafe extern "C" { + pub fn strncat( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strndup( + __s: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strncmp( + __lhs: *const ::std::os::raw::c_char, + __rhs: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn stpncpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strncpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strlcat( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn strlcpy( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn strcspn( + __s: *const ::std::os::raw::c_char, + __reject: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn strpbrk( + __s: *const ::std::os::raw::c_char, + __accept: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strsep( + __s_ptr: *mut *mut ::std::os::raw::c_char, + __delimiter: *const ::std::os::raw::c_char, + ) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strspn( + __s: *const ::std::os::raw::c_char, + __accept: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn strsignal(__signal: ::std::os::raw::c_int) -> *mut ::std::os::raw::c_char; +} +unsafe extern "C" { + pub fn strcoll( + __lhs: *const ::std::os::raw::c_char, + __rhs: *const ::std::os::raw::c_char, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strxfrm( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: ::std::os::raw::c_ulong, + ) -> ::std::os::raw::c_ulong; +} +unsafe extern "C" { + pub fn strcoll_l( + __lhs: *const ::std::os::raw::c_char, + __rhs: *const ::std::os::raw::c_char, + __l: locale_t, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn strxfrm_l( + __dst: *mut ::std::os::raw::c_char, + __src: *const ::std::os::raw::c_char, + __n: usize, + __l: locale_t, + ) -> usize; +} +pub const SyncState_SYNC_NONE: SyncState = 0; +pub const SyncState_SYNC_NEEDED: SyncState = 1; +pub const SyncState_SYNC_IN_PROGRESS: SyncState = 2; +/** Sync state machine: + default state: SYNC_NONE + + SYNC_NONE → SYN_DROPPED or forced sync → SYNC_NEEDED + SYNC_NEEDED → libevdev_next_event(LIBEVDEV_READ_FLAG_SYNC) → SYNC_IN_PROGRESS + SYNC_NEEDED → libevdev_next_event(LIBEVDEV_READ_FLAG_SYNC_NONE) → SYNC_NONE + SYNC_IN_PROGRESS → libevdev_next_event(LIBEVDEV_READ_FLAG_SYNC_NONE) → SYNC_NONE + SYNC_IN_PROGRESS → no sync events left → SYNC_NONE +*/ +pub type SyncState = ::std::os::raw::c_uint; +/** Internal only: log data used to send messages to the respective log + handler. We re-use the same struct for a global and inside + struct libevdev. + For the global, device_handler is NULL, for per-device instance + global_handler is NULL.*/ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct logdata { + pub priority: libevdev_log_priority, + /// minimum logging priority + pub global_handler: libevdev_log_func_t, + /// global handler function + pub device_handler: libevdev_device_log_func_t, + /// per-device handler function + pub userdata: *mut ::std::os::raw::c_void, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of logdata"][::std::mem::size_of::() - 32usize]; + ["Alignment of logdata"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: logdata::priority", + ][::std::mem::offset_of!(logdata, priority) - 0usize]; + [ + "Offset of field: logdata::global_handler", + ][::std::mem::offset_of!(logdata, global_handler) - 8usize]; + [ + "Offset of field: logdata::device_handler", + ][::std::mem::offset_of!(logdata, device_handler) - 16usize]; + [ + "Offset of field: logdata::userdata", + ][::std::mem::offset_of!(logdata, userdata) - 24usize]; +}; +/** @ingroup init + + Opaque struct representing an evdev device.*/ +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libevdev { + pub fd: ::std::os::raw::c_int, + pub initialized: bool, + pub name: *mut ::std::os::raw::c_char, + pub phys: *mut ::std::os::raw::c_char, + pub uniq: *mut ::std::os::raw::c_char, + pub ids: input_id, + pub driver_version: ::std::os::raw::c_int, + pub bits: [::std::os::raw::c_ulong; 1usize], + pub props: [::std::os::raw::c_ulong; 1usize], + pub key_bits: [::std::os::raw::c_ulong; 12usize], + pub rel_bits: [::std::os::raw::c_ulong; 1usize], + pub abs_bits: [::std::os::raw::c_ulong; 1usize], + pub led_bits: [::std::os::raw::c_ulong; 1usize], + pub msc_bits: [::std::os::raw::c_ulong; 1usize], + pub sw_bits: [::std::os::raw::c_ulong; 1usize], + pub rep_bits: [::std::os::raw::c_ulong; 1usize], + pub ff_bits: [::std::os::raw::c_ulong; 2usize], + pub snd_bits: [::std::os::raw::c_ulong; 1usize], + pub key_values: [::std::os::raw::c_ulong; 12usize], + pub led_values: [::std::os::raw::c_ulong; 1usize], + pub sw_values: [::std::os::raw::c_ulong; 1usize], + pub abs_info: [input_absinfo; 64usize], + pub mt_slot_vals: *mut ::std::os::raw::c_int, + ///< valid slots in mt_slot_vals + pub num_slots: ::std::os::raw::c_int, + pub current_slot: ::std::os::raw::c_int, + pub rep_values: [::std::os::raw::c_int; 2usize], + pub sync_state: SyncState, + pub grabbed: libevdev_grab_mode, + pub queue: *mut input_event, + ///< size of queue in elements + pub queue_size: usize, + ///< next event index + pub queue_next: usize, + ///< number of sync events + pub queue_nsync: usize, + pub last_event_time: timeval, + pub log: logdata, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of libevdev"][::std::mem::size_of::() - 1992usize]; + ["Alignment of libevdev"][::std::mem::align_of::() - 8usize]; + ["Offset of field: libevdev::fd"][::std::mem::offset_of!(libevdev, fd) - 0usize]; + [ + "Offset of field: libevdev::initialized", + ][::std::mem::offset_of!(libevdev, initialized) - 4usize]; + ["Offset of field: libevdev::name"][::std::mem::offset_of!(libevdev, name) - 8usize]; + [ + "Offset of field: libevdev::phys", + ][::std::mem::offset_of!(libevdev, phys) - 16usize]; + [ + "Offset of field: libevdev::uniq", + ][::std::mem::offset_of!(libevdev, uniq) - 24usize]; + ["Offset of field: libevdev::ids"][::std::mem::offset_of!(libevdev, ids) - 32usize]; + [ + "Offset of field: libevdev::driver_version", + ][::std::mem::offset_of!(libevdev, driver_version) - 40usize]; + [ + "Offset of field: libevdev::bits", + ][::std::mem::offset_of!(libevdev, bits) - 48usize]; + [ + "Offset of field: libevdev::props", + ][::std::mem::offset_of!(libevdev, props) - 56usize]; + [ + "Offset of field: libevdev::key_bits", + ][::std::mem::offset_of!(libevdev, key_bits) - 64usize]; + [ + "Offset of field: libevdev::rel_bits", + ][::std::mem::offset_of!(libevdev, rel_bits) - 160usize]; + [ + "Offset of field: libevdev::abs_bits", + ][::std::mem::offset_of!(libevdev, abs_bits) - 168usize]; + [ + "Offset of field: libevdev::led_bits", + ][::std::mem::offset_of!(libevdev, led_bits) - 176usize]; + [ + "Offset of field: libevdev::msc_bits", + ][::std::mem::offset_of!(libevdev, msc_bits) - 184usize]; + [ + "Offset of field: libevdev::sw_bits", + ][::std::mem::offset_of!(libevdev, sw_bits) - 192usize]; + [ + "Offset of field: libevdev::rep_bits", + ][::std::mem::offset_of!(libevdev, rep_bits) - 200usize]; + [ + "Offset of field: libevdev::ff_bits", + ][::std::mem::offset_of!(libevdev, ff_bits) - 208usize]; + [ + "Offset of field: libevdev::snd_bits", + ][::std::mem::offset_of!(libevdev, snd_bits) - 224usize]; + [ + "Offset of field: libevdev::key_values", + ][::std::mem::offset_of!(libevdev, key_values) - 232usize]; + [ + "Offset of field: libevdev::led_values", + ][::std::mem::offset_of!(libevdev, led_values) - 328usize]; + [ + "Offset of field: libevdev::sw_values", + ][::std::mem::offset_of!(libevdev, sw_values) - 336usize]; + [ + "Offset of field: libevdev::abs_info", + ][::std::mem::offset_of!(libevdev, abs_info) - 344usize]; + [ + "Offset of field: libevdev::mt_slot_vals", + ][::std::mem::offset_of!(libevdev, mt_slot_vals) - 1880usize]; + [ + "Offset of field: libevdev::num_slots", + ][::std::mem::offset_of!(libevdev, num_slots) - 1888usize]; + [ + "Offset of field: libevdev::current_slot", + ][::std::mem::offset_of!(libevdev, current_slot) - 1892usize]; + [ + "Offset of field: libevdev::rep_values", + ][::std::mem::offset_of!(libevdev, rep_values) - 1896usize]; + [ + "Offset of field: libevdev::sync_state", + ][::std::mem::offset_of!(libevdev, sync_state) - 1904usize]; + [ + "Offset of field: libevdev::grabbed", + ][::std::mem::offset_of!(libevdev, grabbed) - 1908usize]; + [ + "Offset of field: libevdev::queue", + ][::std::mem::offset_of!(libevdev, queue) - 1912usize]; + [ + "Offset of field: libevdev::queue_size", + ][::std::mem::offset_of!(libevdev, queue_size) - 1920usize]; + [ + "Offset of field: libevdev::queue_next", + ][::std::mem::offset_of!(libevdev, queue_next) - 1928usize]; + [ + "Offset of field: libevdev::queue_nsync", + ][::std::mem::offset_of!(libevdev, queue_nsync) - 1936usize]; + [ + "Offset of field: libevdev::last_event_time", + ][::std::mem::offset_of!(libevdev, last_event_time) - 1944usize]; + [ + "Offset of field: libevdev::log", + ][::std::mem::offset_of!(libevdev, log) - 1960usize]; +}; +unsafe extern "C" { + pub fn _libevdev_log_msg( + dev: *const libevdev, + priority: libevdev_log_priority, + file: *const ::std::os::raw::c_char, + line: ::std::os::raw::c_int, + func: *const ::std::os::raw::c_char, + format: *const ::std::os::raw::c_char, + ... + ); +} +unsafe extern "C" { + pub fn _libevdev_log_priority(dev: *const libevdev) -> libevdev_log_priority; +} +///< let libevdev open and close @c /dev/uinput +pub const libevdev_uinput_open_mode_LIBEVDEV_UINPUT_OPEN_MANAGED: libevdev_uinput_open_mode = -2; +/** @defgroup uinput uinput device creation + + Creation of uinput devices based on existing libevdev devices. These functions + help to create uinput devices that emulate libevdev devices. In the simplest + form it serves to duplicate an existing device: + + @code + int err; + int fd, uifd; + struct libevdev *dev; + struct libevdev_uinput *uidev; + + fd = open("/dev/input/event0", O_RDONLY); + if (fd < 0) + return -errno; + + err = libevdev_new_from_fd(fd, &dev); + if (err != 0) + return err; + + uifd = open("/dev/uinput", O_RDWR); + if (uifd < 0) + return -errno; + + err = libevdev_uinput_create_from_device(dev, uifd, &uidev); + if (err != 0) + return err; + + // post a REL_X event + err = libevdev_uinput_write_event(uidev, EV_REL, REL_X, -1); + if (err != 0) + return err; + err = libevdev_uinput_write_event(uidev, EV_SYN, SYN_REPORT, 0); + if (err != 0) + return err; + + libevdev_uinput_destroy(uidev); + libevdev_free(dev); + close(uifd); + close(fd); + + @endcode + + Alternatively, a device can be constructed from scratch: + + @code + int err; + struct libevdev *dev; + struct libevdev_uinput *uidev; + + dev = libevdev_new(); + libevdev_set_name(dev, "test device"); + libevdev_enable_event_type(dev, EV_REL); + libevdev_enable_event_code(dev, EV_REL, REL_X, NULL); + libevdev_enable_event_code(dev, EV_REL, REL_Y, NULL); + libevdev_enable_event_type(dev, EV_KEY); + libevdev_enable_event_code(dev, EV_KEY, BTN_LEFT, NULL); + libevdev_enable_event_code(dev, EV_KEY, BTN_MIDDLE, NULL); + libevdev_enable_event_code(dev, EV_KEY, BTN_RIGHT, NULL); + + err = libevdev_uinput_create_from_device(dev, + LIBEVDEV_UINPUT_OPEN_MANAGED, + &uidev); + if (err != 0) + return err; + + // ... do something ... + + libevdev_uinput_destroy(uidev); + + @endcode*/ +pub type libevdev_uinput_open_mode = ::std::os::raw::c_int; +unsafe extern "C" { + /** @ingroup uinput + + Create a uinput device based on the given libevdev device. The uinput device + will be an exact copy of the libevdev device, minus the bits that uinput doesn't + allow to be set. + + If uinput_fd is @ref LIBEVDEV_UINPUT_OPEN_MANAGED, libevdev_uinput_create_from_device() + will open @c /dev/uinput in read/write mode and manage the file descriptor. + Otherwise, uinput_fd must be opened by the caller and opened with the + appropriate permissions. + + The device's lifetime is tied to the uinput file descriptor, closing it will + destroy the uinput device. You should call libevdev_uinput_destroy() before + closing the file descriptor to free allocated resources. + A file descriptor can only create one uinput device at a time; the second device + will fail with -EINVAL. + + You don't need to keep the file descriptor variable around, + libevdev_uinput_get_fd() will return it when needed. + + @note Due to limitations in the uinput kernel module, REP_DELAY and + REP_PERIOD will default to the kernel defaults, not to the ones set in the + source device. + + @note On FreeBSD, if the UI_GET_SYSNAME ioctl() fails, there is no other way + to get a device, and the function call will fail. + + @param dev The device to duplicate + @param uinput_fd @ref LIBEVDEV_UINPUT_OPEN_MANAGED or a file descriptor to @c /dev/uinput, + @param[out] uinput_dev The newly created libevdev device. + + @return 0 on success or a negative errno on failure. On failure, the value of + uinput_dev is unmodified. + + @see libevdev_uinput_destroy*/ + pub fn libevdev_uinput_create_from_device( + dev: *const libevdev, + uinput_fd: ::std::os::raw::c_int, + uinput_dev: *mut *mut libevdev_uinput, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup uinput + + Destroy a previously created uinput device and free associated memory. + + If the device was opened with @ref LIBEVDEV_UINPUT_OPEN_MANAGED, + libevdev_uinput_destroy() also closes the file descriptor. Otherwise, the + fd is left as-is and must be closed by the caller. + + @param uinput_dev A previously created uinput device.*/ + pub fn libevdev_uinput_destroy(uinput_dev: *mut libevdev_uinput); +} +unsafe extern "C" { + /** @ingroup uinput + + Return the file descriptor used to create this uinput device. This is the + fd pointing to /dev/uinput. This file descriptor may be used to write + events that are emitted by the uinput device. + Closing this file descriptor will destroy the uinput device, you should + call libevdev_uinput_destroy() first to free allocated resources. + + @param uinput_dev A previously created uinput device. + + @return The file descriptor used to create this device*/ + pub fn libevdev_uinput_get_fd( + uinput_dev: *const libevdev_uinput, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + /** @ingroup uinput + + Return the syspath representing this uinput device. If the UI_GET_SYSNAME + ioctl is not available, libevdev makes an educated guess. + The UI_GET_SYSNAME ioctl is available since Linux 3.15. + + The syspath returned is the one of the input node itself + (e.g. /sys/devices/virtual/input/input123), not the syspath of the device + node returned with libevdev_uinput_get_devnode(). + + @note This function may return NULL if UI_GET_SYSNAME is not available. + In that case, libevdev uses ctime and the device name to guess devices. + To avoid false positives, wait at least 1.5s between creating devices that + have the same name. + + @note FreeBSD does not have sysfs, on FreeBSD this function always returns + NULL. + + @param uinput_dev A previously created uinput device. + @return The syspath for this device, including the preceding /sys + + @see libevdev_uinput_get_devnode*/ + pub fn libevdev_uinput_get_syspath( + uinput_dev: *mut libevdev_uinput, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup uinput + + Return the device node representing this uinput device. + + This relies on libevdev_uinput_get_syspath() to provide a valid syspath. + See libevdev_uinput_get_syspath() for more details. + + @note This function may return NULL. libevdev may have to guess the + syspath and the device node. See libevdev_uinput_get_syspath() for details. + + @note On FreeBSD, this function can not return NULL. libudev uses the + UI_GET_SYSNAME ioctl to get the device node on this platform and if that + fails, the call to libevdev_uinput_create_from_device() fails. + + @param uinput_dev A previously created uinput device. + @return The device node for this device, in the form of /dev/input/eventN + + @see libevdev_uinput_get_syspath*/ + pub fn libevdev_uinput_get_devnode( + uinput_dev: *mut libevdev_uinput, + ) -> *const ::std::os::raw::c_char; +} +unsafe extern "C" { + /** @ingroup uinput + + Post an event through the uinput device. It is the caller's responsibility + that any event sequence is terminated with an EV_SYN/SYN_REPORT/0 event. + Otherwise, listeners on the device node will not see the events until the + next EV_SYN event is posted. + + @param uinput_dev A previously created uinput device. + @param type Event type (EV_ABS, EV_REL, etc.) + @param code Event code (ABS_X, REL_Y, etc.) + @param value The event value + @return 0 on success or a negative errno on error*/ + pub fn libevdev_uinput_write_event( + uinput_dev: *const libevdev_uinput, + type_: ::std::os::raw::c_uint, + code: ::std::os::raw::c_uint, + value: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct libevdev_uinput { + ///< file descriptor to uinput + pub fd: ::std::os::raw::c_int, + ///< do we need to close it? + pub fd_is_managed: ::std::os::raw::c_int, + ///< device name + pub name: *mut ::std::os::raw::c_char, + ///< /sys path + pub syspath: *mut ::std::os::raw::c_char, + ///< device node + pub devnode: *mut ::std::os::raw::c_char, + ///< before/after UI_DEV_CREATE + pub ctime: [time_t; 2usize], +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of libevdev_uinput"][::std::mem::size_of::() - 48usize]; + ["Alignment of libevdev_uinput"][::std::mem::align_of::() - 8usize]; + [ + "Offset of field: libevdev_uinput::fd", + ][::std::mem::offset_of!(libevdev_uinput, fd) - 0usize]; + [ + "Offset of field: libevdev_uinput::fd_is_managed", + ][::std::mem::offset_of!(libevdev_uinput, fd_is_managed) - 4usize]; + [ + "Offset of field: libevdev_uinput::name", + ][::std::mem::offset_of!(libevdev_uinput, name) - 8usize]; + [ + "Offset of field: libevdev_uinput::syspath", + ][::std::mem::offset_of!(libevdev_uinput, syspath) - 16usize]; + [ + "Offset of field: libevdev_uinput::devnode", + ][::std::mem::offset_of!(libevdev_uinput, devnode) - 24usize]; + [ + "Offset of field: libevdev_uinput::ctime", + ][::std::mem::offset_of!(libevdev_uinput, ctime) - 32usize]; +}; +pub type __uint128_t = u128; diff --git a/evdev/src/main/rust/evdev_manager/src/enums.rs b/evdev/src/main/rust/evdev_manager/src/enums.rs new file mode 100644 index 0000000000..c71cb67b60 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/src/enums.rs @@ -0,0 +1,385 @@ +use crate::bindings; +use std::fmt; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[repr(u32)] +pub enum EventType { + Syn = bindings::EV_SYN, + Key = bindings::EV_KEY, + Rel = bindings::EV_REL, + Abs = bindings::EV_ABS, + Msc = bindings::EV_MSC, + Sw = bindings::EV_SW, + Led = bindings::EV_LED, + Snd = bindings::EV_SND, + Rep = bindings::EV_REP, + Ff = bindings::EV_FF, + Pwr = bindings::EV_PWR, + FfStatus = bindings::EV_FF_STATUS, +} + +impl EventType { + /// Convert a u32 value to an EventType + pub fn from_raw(value: u32) -> Option { + match value { + bindings::EV_SYN => Some(Self::Syn), + bindings::EV_KEY => Some(Self::Key), + bindings::EV_REL => Some(Self::Rel), + bindings::EV_ABS => Some(Self::Abs), + bindings::EV_MSC => Some(Self::Msc), + bindings::EV_SW => Some(Self::Sw), + bindings::EV_LED => Some(Self::Led), + bindings::EV_SND => Some(Self::Snd), + bindings::EV_REP => Some(Self::Rep), + bindings::EV_FF => Some(Self::Ff), + bindings::EV_PWR => Some(Self::Pwr), + bindings::EV_FF_STATUS => Some(Self::FfStatus), + _ => None, + } + } + + /// Convert EventType to u32 + pub const fn as_raw(self) -> u32 { + self as u32 + } +} + +impl std::fmt::Display for EventType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for u32 { + fn from(event_type: EventType) -> Self { + event_type.as_raw() + } +} + +impl TryFrom for EventType { + type Error = (); + + fn try_from(value: u32) -> Result { + Self::from_raw(value).ok_or(()) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[repr(u32)] +pub enum EvRel { + X = bindings::REL_X, + Y = bindings::REL_Y, + Z = bindings::REL_Z, + Rx = bindings::REL_RX, + Ry = bindings::REL_RY, + Rz = bindings::REL_RZ, + Hwheel = bindings::REL_HWHEEL, + Dial = bindings::REL_DIAL, + Wheel = bindings::REL_WHEEL, + Misc = bindings::REL_MISC, + Reserved = bindings::REL_RESERVED, + WheelHiRes = bindings::REL_WHEEL_HI_RES, + HwheelHiRes = bindings::REL_HWHEEL_HI_RES, +} + +impl EvRel { + pub fn from_raw(value: u32) -> Option { + match value { + bindings::REL_X => Some(Self::X), + bindings::REL_Y => Some(Self::Y), + bindings::REL_Z => Some(Self::Z), + bindings::REL_RX => Some(Self::Rx), + bindings::REL_RY => Some(Self::Ry), + bindings::REL_RZ => Some(Self::Rz), + bindings::REL_HWHEEL => Some(Self::Hwheel), + bindings::REL_DIAL => Some(Self::Dial), + bindings::REL_WHEEL => Some(Self::Wheel), + bindings::REL_MISC => Some(Self::Misc), + bindings::REL_RESERVED => Some(Self::Reserved), + bindings::REL_WHEEL_HI_RES => Some(Self::WheelHiRes), + bindings::REL_HWHEEL_HI_RES => Some(Self::HwheelHiRes), + _ => None, + } + } + + pub const fn as_raw(self) -> u32 { + self as u32 + } +} + +impl std::fmt::Display for EvRel { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for u32 { + fn from(ev_rel: EvRel) -> Self { + ev_rel.as_raw() + } +} + +impl TryFrom for EvRel { + type Error = (); + + fn try_from(value: u32) -> Result { + Self::from_raw(value).ok_or(()) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[repr(u32)] +pub enum EvAbs { + X = bindings::ABS_X, + Y = bindings::ABS_Y, + Z = bindings::ABS_Z, + Rx = bindings::ABS_RX, + Ry = bindings::ABS_RY, + Rz = bindings::ABS_RZ, + Throttle = bindings::ABS_THROTTLE, + Rudder = bindings::ABS_RUDDER, + Wheel = bindings::ABS_WHEEL, + Gas = bindings::ABS_GAS, + Brake = bindings::ABS_BRAKE, + Hat0X = bindings::ABS_HAT0X, + Hat0Y = bindings::ABS_HAT0Y, + Hat1X = bindings::ABS_HAT1X, + Hat1Y = bindings::ABS_HAT1Y, + Hat2X = bindings::ABS_HAT2X, + Hat2Y = bindings::ABS_HAT2Y, + Hat3X = bindings::ABS_HAT3X, + Hat3Y = bindings::ABS_HAT3Y, + Pressure = bindings::ABS_PRESSURE, + Distance = bindings::ABS_DISTANCE, + TiltX = bindings::ABS_TILT_X, + TiltY = bindings::ABS_TILT_Y, + ToolWidth = bindings::ABS_TOOL_WIDTH, + Volume = bindings::ABS_VOLUME, + Profile = bindings::ABS_PROFILE, + Misc = bindings::ABS_MISC, + Reserved = bindings::ABS_RESERVED, + MtSlot = bindings::ABS_MT_SLOT, + MtTouchMajor = bindings::ABS_MT_TOUCH_MAJOR, + MtTouchMinor = bindings::ABS_MT_TOUCH_MINOR, + MtWidthMajor = bindings::ABS_MT_WIDTH_MAJOR, + MtWidthMinor = bindings::ABS_MT_WIDTH_MINOR, + MtOrientation = bindings::ABS_MT_ORIENTATION, + MtPositionX = bindings::ABS_MT_POSITION_X, + MtPositionY = bindings::ABS_MT_POSITION_Y, + MtToolType = bindings::ABS_MT_TOOL_TYPE, + MtBlobId = bindings::ABS_MT_BLOB_ID, + MtTrackingId = bindings::ABS_MT_TRACKING_ID, + MtPressure = bindings::ABS_MT_PRESSURE, + MtDistance = bindings::ABS_MT_DISTANCE, + MtToolX = bindings::ABS_MT_TOOL_X, + MtToolY = bindings::ABS_MT_TOOL_Y, +} + +impl EvAbs { + pub fn from_raw(value: u32) -> Option { + match value { + bindings::ABS_X => Some(Self::X), + bindings::ABS_Y => Some(Self::Y), + bindings::ABS_Z => Some(Self::Z), + bindings::ABS_RX => Some(Self::Rx), + bindings::ABS_RY => Some(Self::Ry), + bindings::ABS_RZ => Some(Self::Rz), + bindings::ABS_THROTTLE => Some(Self::Throttle), + bindings::ABS_RUDDER => Some(Self::Rudder), + bindings::ABS_WHEEL => Some(Self::Wheel), + bindings::ABS_GAS => Some(Self::Gas), + bindings::ABS_BRAKE => Some(Self::Brake), + bindings::ABS_HAT0X => Some(Self::Hat0X), + bindings::ABS_HAT0Y => Some(Self::Hat0Y), + bindings::ABS_HAT1X => Some(Self::Hat1X), + bindings::ABS_HAT1Y => Some(Self::Hat1Y), + bindings::ABS_HAT2X => Some(Self::Hat2X), + bindings::ABS_HAT2Y => Some(Self::Hat2Y), + bindings::ABS_HAT3X => Some(Self::Hat3X), + bindings::ABS_HAT3Y => Some(Self::Hat3Y), + bindings::ABS_PRESSURE => Some(Self::Pressure), + bindings::ABS_DISTANCE => Some(Self::Distance), + bindings::ABS_TILT_X => Some(Self::TiltX), + bindings::ABS_TILT_Y => Some(Self::TiltY), + bindings::ABS_TOOL_WIDTH => Some(Self::ToolWidth), + bindings::ABS_VOLUME => Some(Self::Volume), + bindings::ABS_PROFILE => Some(Self::Profile), + bindings::ABS_MISC => Some(Self::Misc), + bindings::ABS_RESERVED => Some(Self::Reserved), + bindings::ABS_MT_SLOT => Some(Self::MtSlot), + bindings::ABS_MT_TOUCH_MAJOR => Some(Self::MtTouchMajor), + bindings::ABS_MT_TOUCH_MINOR => Some(Self::MtTouchMinor), + bindings::ABS_MT_WIDTH_MAJOR => Some(Self::MtWidthMajor), + bindings::ABS_MT_WIDTH_MINOR => Some(Self::MtWidthMinor), + bindings::ABS_MT_ORIENTATION => Some(Self::MtOrientation), + bindings::ABS_MT_POSITION_X => Some(Self::MtPositionX), + bindings::ABS_MT_POSITION_Y => Some(Self::MtPositionY), + bindings::ABS_MT_TOOL_TYPE => Some(Self::MtToolType), + bindings::ABS_MT_BLOB_ID => Some(Self::MtBlobId), + bindings::ABS_MT_TRACKING_ID => Some(Self::MtTrackingId), + bindings::ABS_MT_PRESSURE => Some(Self::MtPressure), + bindings::ABS_MT_DISTANCE => Some(Self::MtDistance), + bindings::ABS_MT_TOOL_X => Some(Self::MtToolX), + bindings::ABS_MT_TOOL_Y => Some(Self::MtToolY), + _ => None, + } + } + + pub const fn as_raw(self) -> u32 { + self as u32 + } +} + +impl std::fmt::Display for EvAbs { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for u32 { + fn from(ev_abs: EvAbs) -> Self { + ev_abs.as_raw() + } +} + +impl TryFrom for EvAbs { + type Error = (); + + fn try_from(value: u32) -> Result { + Self::from_raw(value).ok_or(()) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[repr(u32)] +pub enum InputProp { + Pointer = bindings::INPUT_PROP_POINTER, + Direct = bindings::INPUT_PROP_DIRECT, + Buttonpad = bindings::INPUT_PROP_BUTTONPAD, + SemiMt = bindings::INPUT_PROP_SEMI_MT, + TopButtonpad = bindings::INPUT_PROP_TOPBUTTONPAD, + PointingStick = bindings::INPUT_PROP_POINTING_STICK, + Accelerometer = bindings::INPUT_PROP_ACCELEROMETER, +} + +impl InputProp { + pub fn from_raw(value: u32) -> Option { + match value { + bindings::INPUT_PROP_POINTER => Some(Self::Pointer), + bindings::INPUT_PROP_DIRECT => Some(Self::Direct), + bindings::INPUT_PROP_BUTTONPAD => Some(Self::Buttonpad), + bindings::INPUT_PROP_SEMI_MT => Some(Self::SemiMt), + bindings::INPUT_PROP_TOPBUTTONPAD => Some(Self::TopButtonpad), + bindings::INPUT_PROP_POINTING_STICK => Some(Self::PointingStick), + bindings::INPUT_PROP_ACCELEROMETER => Some(Self::Accelerometer), + _ => None, + } + } + + pub const fn as_raw(self) -> u32 { + self as u32 + } +} + +impl std::fmt::Display for InputProp { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for u32 { + fn from(input_prop: InputProp) -> Self { + input_prop.as_raw() + } +} + +impl TryFrom for InputProp { + type Error = (); + + fn try_from(value: u32) -> Result { + Self::from_raw(value).ok_or(()) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[repr(u32)] +pub enum BusType { + Pci = bindings::BUS_PCI, + Isapnp = bindings::BUS_ISAPNP, + Usb = bindings::BUS_USB, + Hil = bindings::BUS_HIL, + Bluetooth = bindings::BUS_BLUETOOTH, + Virtual = bindings::BUS_VIRTUAL, + Isa = bindings::BUS_ISA, + I8042 = bindings::BUS_I8042, + Xtkbd = bindings::BUS_XTKBD, + Rs232 = bindings::BUS_RS232, + Gameport = bindings::BUS_GAMEPORT, + Parport = bindings::BUS_PARPORT, + Amiga = bindings::BUS_AMIGA, + Adb = bindings::BUS_ADB, + I2c = bindings::BUS_I2C, + Host = bindings::BUS_HOST, + Gsc = bindings::BUS_GSC, + Atari = bindings::BUS_ATARI, + Spi = bindings::BUS_SPI, + Rmi = bindings::BUS_RMI, + Cec = bindings::BUS_CEC, + IntelIshtp = bindings::BUS_INTEL_ISHTP, + AmdSfh = bindings::BUS_AMD_SFH, +} + +impl BusType { + pub fn from_raw(value: u32) -> Option { + match value { + bindings::BUS_PCI => Some(Self::Pci), + bindings::BUS_ISAPNP => Some(Self::Isapnp), + bindings::BUS_USB => Some(Self::Usb), + bindings::BUS_HIL => Some(Self::Hil), + bindings::BUS_BLUETOOTH => Some(Self::Bluetooth), + bindings::BUS_VIRTUAL => Some(Self::Virtual), + bindings::BUS_ISA => Some(Self::Isa), + bindings::BUS_I8042 => Some(Self::I8042), + bindings::BUS_XTKBD => Some(Self::Xtkbd), + bindings::BUS_RS232 => Some(Self::Rs232), + bindings::BUS_GAMEPORT => Some(Self::Gameport), + bindings::BUS_PARPORT => Some(Self::Parport), + bindings::BUS_AMIGA => Some(Self::Amiga), + bindings::BUS_ADB => Some(Self::Adb), + bindings::BUS_I2C => Some(Self::I2c), + bindings::BUS_HOST => Some(Self::Host), + bindings::BUS_GSC => Some(Self::Gsc), + bindings::BUS_ATARI => Some(Self::Atari), + bindings::BUS_SPI => Some(Self::Spi), + bindings::BUS_RMI => Some(Self::Rmi), + bindings::BUS_CEC => Some(Self::Cec), + bindings::BUS_INTEL_ISHTP => Some(Self::IntelIshtp), + bindings::BUS_AMD_SFH => Some(Self::AmdSfh), + _ => None, + } + } + + pub const fn as_raw(self) -> u32 { + self as u32 + } +} + +impl std::fmt::Display for BusType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for u32 { + fn from(bus_type: BusType) -> Self { + bus_type.as_raw() + } +} + +impl TryFrom for BusType { + type Error = (); + + fn try_from(value: u32) -> Result { + Self::from_raw(value).ok_or(()) + } +} diff --git a/evdev/src/main/rust/evdev_manager/src/evdev.rs b/evdev/src/main/rust/evdev_manager/src/evdev.rs new file mode 100644 index 0000000000..21533f2ce9 --- /dev/null +++ b/evdev/src/main/rust/evdev_manager/src/evdev.rs @@ -0,0 +1,416 @@ +use crate::bindings; +use crate::enums::{EvAbs, EventType, InputProp}; +use std::error::Error; +use std::ffi::{c_void, CStr, CString}; +use std::io::Error as IOError; +use std::io::ErrorKind; +use std::mem::MaybeUninit; +use std::os::fd::{AsRawFd, FromRawFd, IntoRawFd, OwnedFd}; +use std::os::raw::c_int; +use std::ptr; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum EvdevErrorCode { + NoSuchFileOrDirectory, + IoError, + NoSuchDevice, + BadFileDescriptor, + OutOfMemory, + WouldBlock, + PermissionDenied, + InvalidArgument, + Unknown(i32), +} + +impl EvdevErrorCode { + pub fn from_code(code: i32) -> Self { + // libevdev returns negative errno values + match -code as u32 { + bindings::ENOENT => Self::NoSuchFileOrDirectory, + bindings::EIO => Self::IoError, + bindings::EBADF => Self::BadFileDescriptor, + bindings::EAGAIN => Self::WouldBlock, + bindings::ENOMEM => Self::OutOfMemory, + bindings::EACCES => Self::PermissionDenied, + bindings::ENODEV => Self::NoSuchDevice, + bindings::EINVAL => Self::InvalidArgument, + _ => Self::Unknown(code), + } + } + + pub fn to_code(self) -> i32 { + -(match self { + Self::NoSuchFileOrDirectory => bindings::ENOENT as i32, + Self::IoError => bindings::EIO as i32, + Self::BadFileDescriptor => bindings::EBADF as i32, + Self::WouldBlock => bindings::EAGAIN as i32, + Self::OutOfMemory => bindings::ENOMEM as i32, + Self::PermissionDenied => bindings::EACCES as i32, + Self::NoSuchDevice => bindings::ENODEV as i32, + Self::InvalidArgument => bindings::EINVAL as i32, + Self::Unknown(code) => return code, + }) + } + + pub fn description(&self) -> &'static str { + match self { + Self::NoSuchFileOrDirectory => "No such file or directory (device not found)", + Self::IoError => "Input/output error", + Self::NoSuchDevice => "No such device", + Self::BadFileDescriptor => "Bad file descriptor", + Self::OutOfMemory => "Out of memory", + Self::WouldBlock => "Resource temporarily unavailable", + Self::PermissionDenied => "Permission denied", + Self::InvalidArgument => "Invalid argument", + Self::Unknown(_) => "Unknown error", + } + } +} + +#[derive(Debug)] +pub struct EvdevError { + kind: EvdevErrorCode, + code: i32, + message: String, +} + +impl EvdevError { + fn new(code: i32) -> Self { + let kind = EvdevErrorCode::from_code(code); + let message = if let EvdevErrorCode::Unknown(_) = kind { + format!("libevdev error: {}", code) + } else { + format!("libevdev error: {} ({})", kind.description(), -code) + }; + + Self { + kind, + code, + message, + } + } + + pub fn code(&self) -> i32 { + self.code + } + + pub fn kind(&self) -> EvdevErrorCode { + self.kind + } +} + +impl std::fmt::Display for EvdevError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message) + } +} + +impl Error for EvdevError {} + +impl From for IOError { + fn from(err: EvdevError) -> Self { + IOError::from_raw_os_error(-err.code) + } +} + +pub struct EvdevDevice { + ptr: *mut bindings::libevdev, + fd: Option, +} + +impl EvdevDevice { + /// Create a new libevdev device from a file descriptor + /// Must use IntoRawFd so ownership is transferred, instead of borrowing and it + /// automatically being closed. + pub fn new_from_fd(file: F) -> Result { + let owned_fd = unsafe { OwnedFd::from_raw_fd(file.into_raw_fd()) }; + let mut dev: *mut bindings::libevdev = ptr::null_mut(); + + let result = unsafe { bindings::libevdev_new_from_fd(owned_fd.as_raw_fd(), &mut dev) }; + + if result < 0 { + return Err(EvdevError::new(result)); + } + + Ok(Self { + ptr: dev, + fd: Some(owned_fd), + }) + } + + /// Create a new libevdev device struct + pub fn new() -> Result { + let dev: *mut bindings::libevdev = unsafe { bindings::libevdev_new() }; + Ok(Self { ptr: dev, fd: None }) + } + + pub fn set_name(&mut self, name: &str) -> Result<(), Box> { + let name_cstr = CString::new(name)?; + unsafe { + bindings::libevdev_set_name(self.ptr, name_cstr.as_ptr()); + } + Ok(()) + } + + /// Get the device name + pub fn name(&self) -> String { + let name_ptr = unsafe { bindings::libevdev_get_name(self.ptr) }; + + if name_ptr.is_null() { + String::new() + } else { + let name_cstr = unsafe { CStr::from_ptr(name_ptr) }; + name_cstr.to_string_lossy().into_owned() + } + } + + pub fn enable_property(&mut self, prop: InputProp) -> Result<(), Box> { + let result = unsafe { bindings::libevdev_enable_property(self.ptr, prop.into()) }; + + if result < 0 { + return Err(Box::new(EvdevError::new(result))); + } + + Ok(()) + } + + /// Enable an event code. + pub fn enable_event_code( + &mut self, + event_type: EventType, + event_code: u32, + ) -> Result<(), Box> { + if event_type == EventType::Abs { + let error = IOError::new( + ErrorKind::InvalidInput, + "Enabling EV_ABS requires abs_info. Use enable_event_abs function.", + ); + + return Err(Box::new(error)); + } + + if event_type == EventType::Rep { + let error = IOError::new( + ErrorKind::InvalidInput, + "EV_REP requires an integer is not supported in this wrapper. A dedicated function must be created.", ); + + return Err(Box::new(error)); + } + + let result = unsafe { + bindings::libevdev_enable_event_code( + self.ptr, + event_type.into(), + event_code, + ptr::null(), + ) + }; + + if result < 0 { + return Err(Box::new(EvdevError::new(result))); + } + + Ok(()) + } + + /// libevdev will automatically enable the event type. + pub fn enable_event_abs( + &mut self, + abs_code: EvAbs, + abs_info: impl Into, + ) -> Result<(), EvdevError> { + let abs_info_raw = abs_info.into(); + + let result = unsafe { + bindings::libevdev_enable_event_code( + self.ptr, + EventType::Abs.into(), + abs_code.into(), + ptr::from_ref(&abs_info_raw) as *const c_void, + ) + }; + + if result < 0 { + return Err(EvdevError::new(result)); + } + + Ok(()) + } + + /// Grab the device through a kernel EVIOCGRAB + /// + /// This prevents other clients (including kernel-internal ones such as rfkill) + /// from receiving events from this device. + /// + /// **Warning:** This is generally a bad idea. Use with caution. + /// + /// Grabbing an already grabbed device is a no-op and always succeeds. + /// + /// A grab is an operation tied to a file descriptor, not a device. If you + /// change the file descriptor, you must also re-issue a grab. + /// + /// # Returns + /// * `Ok(())` - If the device was successfully grabbed + /// * `Err(EvdevError)` - If the grab failed + pub fn grab(&mut self) -> Result<(), EvdevError> { + self.set_grab_mode(bindings::libevdev_grab_mode_LIBEVDEV_GRAB) + } + + /// Ungrab the device if currently grabbed + /// + /// This allows other clients to receive events from this device again. + /// + /// Ungrabbing an ungrabbed device is a no-op and always succeeds. + /// + /// # Returns + /// * `Ok(())` - If the device was successfully ungrabbed + /// * `Err(EvdevError)` - If the ungrab failed + pub fn ungrab(&mut self) -> Result<(), EvdevError> { + self.set_grab_mode(bindings::libevdev_grab_mode_LIBEVDEV_UNGRAB) + } + + fn set_grab_mode(&mut self, mode: u32) -> Result<(), EvdevError> { + let result = unsafe { bindings::libevdev_grab(self.ptr, mode) }; + + if result < 0 { + return Err(EvdevError::new(result)); + } + + Ok(()) + } + + /// Read the next event from the device (non-blocking) + /// + /// Returns `Ok(Some(InputEvent))` if an event was read, + /// `Ok(None)` if no events are available (EAGAIN), + /// or `Err(EvdevError)` on error. + pub fn next_event(&mut self) -> Result, EvdevError> { + let mut ev = MaybeUninit::::uninit(); + + let result = unsafe { + bindings::libevdev_next_event( + self.ptr, + // TODO use same setup as sysbridge for reading from multiple devices at once in a blocking mannerz + bindings::libevdev_read_flag_LIBEVDEV_READ_FLAG_BLOCKING, + ev.as_mut_ptr(), + ) + }; + + match result { + 0.. => { + let ev = unsafe { ev.assume_init() }; + Ok(Some(InputEvent { + time_sec: ev.time.tv_sec, + time_usec: ev.time.tv_usec, + event_type: EventType::from_raw(ev.type_ as u32).expect("Unknown event type"), + code: ev.code as u32, + value: ev.value, + })) + } + -11 => Ok(None), + _ => Err(EvdevError::new(result)), + } + } + + /// Get the raw pointer (for internal use) + pub(crate) fn as_ptr(&self) -> *const bindings::libevdev { + self.ptr as *const bindings::libevdev + } +} + +/// Represents a single input event +#[derive(Debug, Clone, Copy)] +pub struct InputEvent { + pub time_sec: i64, + pub time_usec: i64, + pub event_type: EventType, + pub code: u32, + pub value: i32, +} + +impl Drop for EvdevDevice { + fn drop(&mut self) { + unsafe { + if !self.ptr.is_null() { + bindings::libevdev_free(self.ptr); + } + } + + // fd is dropped automatically + } +} + +pub struct UInputDevice { + ptr: *mut bindings::libevdev_uinput, +} + +impl UInputDevice { + /// Create a uinput device from an existing libevdev device + pub fn create_from_device(device: &EvdevDevice) -> Result { + let mut uinput_dev: *mut bindings::libevdev_uinput = ptr::null_mut(); + + let result = unsafe { + bindings::libevdev_uinput_create_from_device( + device.as_ptr(), + bindings::libevdev_uinput_open_mode_LIBEVDEV_UINPUT_OPEN_MANAGED, + &mut uinput_dev, + ) + }; + + if result < 0 { + return Err(EvdevError::new(result)); + } + + Ok(Self { ptr: uinput_dev }) + } + + /// Get the device node path (e.g., "/dev/input/eventN") + pub fn devnode(&self) -> Option { + let devnode_ptr = unsafe { bindings::libevdev_uinput_get_devnode(self.ptr) }; + + if !devnode_ptr.is_null() { + let devnode_cstr = unsafe { CStr::from_ptr(devnode_ptr) }; + Some(devnode_cstr.to_string_lossy().into_owned()) + } else { + None + } + } + + /// Get the file descriptor for this uinput device + pub fn fd(&self) -> c_int { + unsafe { bindings::libevdev_uinput_get_fd(self.ptr) } + } + + /// Write a generic event to the uinput device + /// + /// # Arguments + /// * `event_type` - Event type (EV_ABS, EV_KEY, EV_SYN, etc.) + /// * `event_code` - Event code (ABS_X, BTN_LEFT, SYN_REPORT, etc.) + /// * `value` - Event value + pub fn write_event( + &self, + event_type: EventType, + event_code: u32, + value: i32, + ) -> Result<(), EvdevError> { + let result = unsafe { + bindings::libevdev_uinput_write_event(self.ptr, event_type.into(), event_code, value) + }; + + if result < 0 { + return Err(EvdevError::new(result)); + } + + Ok(()) + } +} + +impl Drop for UInputDevice { + fn drop(&mut self) { + unsafe { + if !self.ptr.is_null() { + bindings::libevdev_uinput_destroy(self.ptr); + } + } + } +} diff --git a/evdev/src/main/rust/evdev_manager/src/lib.rs b/evdev/src/main/rust/evdev_manager/src/lib.rs index f3c3dc3679..598de37b42 100644 --- a/evdev/src/main/rust/evdev_manager/src/lib.rs +++ b/evdev/src/main/rust/evdev_manager/src/lib.rs @@ -1,3 +1,7 @@ +mod bindings; +mod enums; +mod evdev; + #[macro_use] extern crate log; extern crate android_log; diff --git a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt index 68a3c4f544..485321f3ab 100644 --- a/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt +++ b/sysbridge/src/main/java/io/github/sds100/keymapper/sysbridge/service/BaseSystemBridge.kt @@ -197,7 +197,6 @@ abstract class BaseSystemBridge : ISystemBridge.Stub() { val libraryPath = System.getProperty("keymapper_sysbridge.library.path") @SuppressLint("UnsafeDynamicallyLoadedCode") - System.load("$libraryPath/libevdev.so") System.load("$libraryPath/libevdev_manager.so") helloEvdevManager("test input") From bce9b3d162dc3200db861ff6812f4809943be0aa Mon Sep 17 00:00:00 2001 From: sds100 Date: Wed, 12 Nov 2025 15:19:07 +0100 Subject: [PATCH 05/65] #1897 create C wrapper for KeyLayoutMap --- evdev/src/main/cpp/keylayoutmap_c.cpp | 100 ++++++++++++++++++ evdev/src/main/cpp/keylayoutmap_c.h | 57 ++++++++++ evdev/src/main/cpp/libevdev_jni.cpp | 1 + evdev/src/main/rust/evdev_manager/build.rs | 47 +++++--- .../main/rust/evdev_manager/src/bindings.rs | 59 +++++++++++ evdev/src/main/rust/evdev_manager/src/lib.rs | 2 +- 6 files changed, 251 insertions(+), 15 deletions(-) create mode 100644 evdev/src/main/cpp/keylayoutmap_c.cpp create mode 100644 evdev/src/main/cpp/keylayoutmap_c.h diff --git a/evdev/src/main/cpp/keylayoutmap_c.cpp b/evdev/src/main/cpp/keylayoutmap_c.cpp new file mode 100644 index 0000000000..e4342aa93e --- /dev/null +++ b/evdev/src/main/cpp/keylayoutmap_c.cpp @@ -0,0 +1,100 @@ +/* + * C interface implementation for KeyLayoutMap + */ + +#include "keylayoutmap_c.h" +#include "android/input/KeyLayoutMap.h" +#include "android/utils/Errors.h" + +extern "C" { + +int keylayoutmap_load(const char* filename, KeyLayoutMapHandle* out_handle) { + if (!filename || !out_handle) { + return -1; // Invalid argument + } + + auto result = android::KeyLayoutMap::load(filename, nullptr); + if (!result.ok()) { + *out_handle = nullptr; + return -2; // Load failed + } + + // Extract the shared_ptr and store it + // We need to keep the shared_ptr alive, so we'll new it + std::shared_ptr* map_ptr = new std::shared_ptr(*result); + *out_handle = reinterpret_cast(map_ptr); + return 0; // Success +} + +int keylayoutmap_load_contents(const char* filename, const char* contents, KeyLayoutMapHandle* out_handle) { + if (!filename || !contents || !out_handle) { + return -1; // Invalid argument + } + + auto result = android::KeyLayoutMap::loadContents(filename, contents); + if (!result.ok()) { + *out_handle = nullptr; + return -2; // Load failed + } + + std::shared_ptr* map_ptr = new std::shared_ptr(*result); + *out_handle = reinterpret_cast(map_ptr); + return 0; // Success +} + +int keylayoutmap_map_key(KeyLayoutMapHandle handle, int32_t scan_code, int32_t usage_code, + int32_t* out_key_code, uint32_t* out_flags) { + if (!handle || !out_key_code || !out_flags) { + return -1; // Invalid argument + } + + std::shared_ptr* map_ptr = + reinterpret_cast*>(handle); + + if (!map_ptr || !*map_ptr) { + return -1; // Invalid handle + } + + android::status_t status = (*map_ptr)->mapKey(scan_code, usage_code, out_key_code, out_flags); + return static_cast(status); +} + +int keylayoutmap_map_axis(KeyLayoutMapHandle handle, int32_t scan_code, AxisInfo* out_axis_info) { + if (!handle || !out_axis_info) { + return -1; // Invalid argument + } + + std::shared_ptr* map_ptr = + reinterpret_cast*>(handle); + + if (!map_ptr || !*map_ptr) { + return -1; // Invalid handle + } + + auto axis_opt = (*map_ptr)->mapAxis(scan_code); + if (!axis_opt.has_value()) { + return -2; // Axis not found + } + + const android::AxisInfo& axis = axis_opt.value(); + out_axis_info->mode = static_cast(axis.mode); + out_axis_info->axis = axis.axis; + out_axis_info->highAxis = axis.highAxis; + out_axis_info->splitValue = axis.splitValue; + out_axis_info->flatOverride = axis.flatOverride; + return 0; // Success +} + +void keylayoutmap_destroy(KeyLayoutMapHandle handle) { + if (!handle) { + return; + } + + std::shared_ptr* map_ptr = + reinterpret_cast*>(handle); + + delete map_ptr; +} + +} // extern "C" + diff --git a/evdev/src/main/cpp/keylayoutmap_c.h b/evdev/src/main/cpp/keylayoutmap_c.h new file mode 100644 index 0000000000..4787f6611c --- /dev/null +++ b/evdev/src/main/cpp/keylayoutmap_c.h @@ -0,0 +1,57 @@ +/* + * C interface wrapper for KeyLayoutMap + * This provides a simple C API that can be easily bound from Rust + */ + +#ifndef KEYLAYOUTMAP_C_H +#define KEYLAYOUTMAP_C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Opaque handle to KeyLayoutMap +typedef void* KeyLayoutMapHandle; + +// AxisInfo structure (matches android::AxisInfo) +typedef struct { + int32_t mode; // 0 = MODE_NORMAL, 1 = MODE_INVERT, 2 = MODE_SPLIT + int32_t axis; + int32_t highAxis; + int32_t splitValue; + int32_t flatOverride; +} AxisInfo; + +// Load KeyLayoutMap from file +// Returns 0 on success, non-zero error code on failure +// On success, *out_handle will be set to a valid handle (must be freed with keylayoutmap_destroy) +// On failure, *out_handle will be NULL +int keylayoutmap_load(const char* filename, KeyLayoutMapHandle* out_handle); + +// Load KeyLayoutMap from file contents +// Returns 0 on success, non-zero error code on failure +int keylayoutmap_load_contents(const char* filename, const char* contents, KeyLayoutMapHandle* out_handle); + +// Map a key (scan code or usage code) to Android key code +// Returns 0 on success, non-zero error code on failure +// On success, *out_key_code and *out_flags will be set +int keylayoutmap_map_key(KeyLayoutMapHandle handle, int32_t scan_code, int32_t usage_code, + int32_t* out_key_code, uint32_t* out_flags); + +// Map an axis (scan code) to AxisInfo +// Returns 0 if axis was found, non-zero if not found +// On success, *out_axis_info will be set +int keylayoutmap_map_axis(KeyLayoutMapHandle handle, int32_t scan_code, AxisInfo* out_axis_info); + +// Destroy a KeyLayoutMap handle +// Safe to call with NULL handle +void keylayoutmap_destroy(KeyLayoutMapHandle handle); + +#ifdef __cplusplus +} +#endif + +#endif // KEYLAYOUTMAP_C_H + diff --git a/evdev/src/main/cpp/libevdev_jni.cpp b/evdev/src/main/cpp/libevdev_jni.cpp index 7aa338dd31..f3e21ef39b 100644 --- a/evdev/src/main/cpp/libevdev_jni.cpp +++ b/evdev/src/main/cpp/libevdev_jni.cpp @@ -124,6 +124,7 @@ Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_grabEvdevDevi identifier.vendor = libevdev_get_id_vendor(dev); identifier.product = libevdev_get_id_product(dev); + // TODO convert this code into rust std::string klPath = android::getInputDeviceConfigurationFilePathByDeviceIdentifier( identifier, android::InputDeviceConfigurationFileType::KEY_LAYOUT); diff --git a/evdev/src/main/rust/evdev_manager/build.rs b/evdev/src/main/rust/evdev_manager/build.rs index 2851b27740..2f77416a51 100644 --- a/evdev/src/main/rust/evdev_manager/build.rs +++ b/evdev/src/main/rust/evdev_manager/build.rs @@ -13,7 +13,10 @@ fn main() { let is_android = target.contains("android"); if !is_android { - eprintln!("Warning: Building for non-Android target '{}'. Skipping C/C++ compilation.", target); + eprintln!( + "Warning: Building for non-Android target '{}'. Skipping C/C++ compilation.", + target + ); eprintln!("This crate is designed for Android. Use Gradle for actual builds."); // Skip all compilation but succeed to allow cargo check to work return; @@ -62,6 +65,8 @@ fn main() { .file(android_dir.join("input/InputEventLabels.cpp")) .file(android_dir.join("input/InputDevice.cpp")) .file(android_dir.join("input/Input.cpp")) + // C interface wrapper for KeyLayoutMap + .file(cpp_dir.join("keylayoutmap_c.cpp")) // Android base library files .file(android_dir.join("libbase/result.cpp")) .file(android_dir.join("libbase/stringprintf.cpp")) @@ -103,20 +108,33 @@ fn main() { println!("cargo:rustc-link-lib=log"); println!("cargo:rustc-link-lib=binder_ndk"); - // Generate Rust bindings from libevdev headers + // Generate Rust bindings from headers + // We generate C and C++ bindings separately because: + // 1. C headers (libevdev) need C mode to allow implicit void* conversions + // 2. C++ headers (KeyLayoutMap.h) need C++ mode to find cstdint let evdev_headers_path = libevdev_dir.clone(); - // Configure bindgen with Android NDK sysroot and include paths - let mut bindgen_builder = bindgen::Builder::default() - .formatter(bindgen::Formatter::Prettyplease) - // Disable all format/style warnings for generated code - .raw_line("#![allow(clippy::all)]") - .raw_line("#![allow(non_camel_case_types)]") - .raw_line("#![allow(non_snake_case)]") - .raw_line("#![allow(non_upper_case_globals)]") - .raw_line("#![allow(dead_code)]") - .raw_line("#![allow(rustdoc::broken_intra_doc_links)]") - .raw_line("#![allow(rustdoc::private_intra_doc_links)]") + // Common bindgen configuration + let common_allow_attributes = vec![ + "#![allow(clippy::all)]", + "#![allow(non_camel_case_types)]", + "#![allow(non_snake_case)]", + "#![allow(non_upper_case_globals)]", + "#![allow(dead_code)]", + "#![allow(rustdoc::broken_intra_doc_links)]", + "#![allow(rustdoc::private_intra_doc_links)]", + "#![allow(arithmetic_overflow)]", // Needed for bindgen-generated array size calculations + ]; + + // Generate C bindings (libevdev headers) in C mode + let mut bindgen_builder = + bindgen::Builder::default().formatter(bindgen::Formatter::Prettyplease); + + for attr in &common_allow_attributes { + bindgen_builder = bindgen_builder.raw_line(*attr); + } + + bindgen_builder = bindgen_builder .header(evdev_headers_path.join("libevdev.h").display().to_string()) .header( evdev_headers_path @@ -136,6 +154,7 @@ fn main() { .display() .to_string(), ) + .header(cpp_dir.join("keylayoutmap_c.h").display().to_string()) .clang_arg(format!("--sysroot={}", ndk_sysroot.display())) .clang_arg(format!("-I{}", sysroot_include.display())); @@ -147,7 +166,7 @@ fn main() { let bindings = bindgen_builder .generate() - .expect("Unable to generate bindings"); + .expect("Unable to generate C bindings"); let out_path = manifest_dir.join("src"); diff --git a/evdev/src/main/rust/evdev_manager/src/bindings.rs b/evdev/src/main/rust/evdev_manager/src/bindings.rs index 1acd99bfe1..db1a441919 100644 --- a/evdev/src/main/rust/evdev_manager/src/bindings.rs +++ b/evdev/src/main/rust/evdev_manager/src/bindings.rs @@ -7,6 +7,7 @@ #![allow(dead_code)] #![allow(rustdoc::broken_intra_doc_links)] #![allow(rustdoc::private_intra_doc_links)] +#![allow(arithmetic_overflow)] /// If Bindgen could only determine the size and alignment of a /// type, it is represented like this. @@ -7626,4 +7627,62 @@ const _: () = { "Offset of field: libevdev_uinput::ctime", ][::std::mem::offset_of!(libevdev_uinput, ctime) - 32usize]; }; +pub type KeyLayoutMapHandle = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct AxisInfo { + pub mode: i32, + pub axis: i32, + pub highAxis: i32, + pub splitValue: i32, + pub flatOverride: i32, +} +#[allow(clippy::unnecessary_operation, clippy::identity_op)] +const _: () = { + ["Size of AxisInfo"][::std::mem::size_of::() - 20usize]; + ["Alignment of AxisInfo"][::std::mem::align_of::() - 4usize]; + ["Offset of field: AxisInfo::mode"][::std::mem::offset_of!(AxisInfo, mode) - 0usize]; + ["Offset of field: AxisInfo::axis"][::std::mem::offset_of!(AxisInfo, axis) - 4usize]; + [ + "Offset of field: AxisInfo::highAxis", + ][::std::mem::offset_of!(AxisInfo, highAxis) - 8usize]; + [ + "Offset of field: AxisInfo::splitValue", + ][::std::mem::offset_of!(AxisInfo, splitValue) - 12usize]; + [ + "Offset of field: AxisInfo::flatOverride", + ][::std::mem::offset_of!(AxisInfo, flatOverride) - 16usize]; +}; +unsafe extern "C" { + pub fn keylayoutmap_load( + filename: *const ::std::os::raw::c_char, + out_handle: *mut KeyLayoutMapHandle, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn keylayoutmap_load_contents( + filename: *const ::std::os::raw::c_char, + contents: *const ::std::os::raw::c_char, + out_handle: *mut KeyLayoutMapHandle, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn keylayoutmap_map_key( + handle: KeyLayoutMapHandle, + scan_code: i32, + usage_code: i32, + out_key_code: *mut i32, + out_flags: *mut u32, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn keylayoutmap_map_axis( + handle: KeyLayoutMapHandle, + scan_code: i32, + out_axis_info: *mut AxisInfo, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn keylayoutmap_destroy(handle: KeyLayoutMapHandle); +} pub type __uint128_t = u128; diff --git a/evdev/src/main/rust/evdev_manager/src/lib.rs b/evdev/src/main/rust/evdev_manager/src/lib.rs index 598de37b42..7cffe6e098 100644 --- a/evdev/src/main/rust/evdev_manager/src/lib.rs +++ b/evdev/src/main/rust/evdev_manager/src/lib.rs @@ -1,4 +1,4 @@ -mod bindings; +mod bindings; // libevdev C bindings + KeyLayoutMap C interface bindings mod enums; mod evdev; From 325facba57c0588c2f55ff624d63b621be24e20a Mon Sep 17 00:00:00 2001 From: sds100 Date: Sat, 15 Nov 2025 12:38:40 +0100 Subject: [PATCH 06/65] style: reformat --- .../sds100/keymapper/base/trigger/TriggerErrorSnapshotTest.kt | 1 + evdev/src/main/cpp/keylayoutmap_c.cpp | 1 + evdev/src/main/cpp/keylayoutmap_c.h | 1 + 3 files changed, 3 insertions(+) diff --git a/base/src/test/java/io/github/sds100/keymapper/base/trigger/TriggerErrorSnapshotTest.kt b/base/src/test/java/io/github/sds100/keymapper/base/trigger/TriggerErrorSnapshotTest.kt index 3466ea36fc..86c79e1889 100644 --- a/base/src/test/java/io/github/sds100/keymapper/base/trigger/TriggerErrorSnapshotTest.kt +++ b/base/src/test/java/io/github/sds100/keymapper/base/trigger/TriggerErrorSnapshotTest.kt @@ -204,3 +204,4 @@ class TriggerErrorSnapshotTest { ) } } + diff --git a/evdev/src/main/cpp/keylayoutmap_c.cpp b/evdev/src/main/cpp/keylayoutmap_c.cpp index e4342aa93e..eb1fceddab 100644 --- a/evdev/src/main/cpp/keylayoutmap_c.cpp +++ b/evdev/src/main/cpp/keylayoutmap_c.cpp @@ -98,3 +98,4 @@ void keylayoutmap_destroy(KeyLayoutMapHandle handle) { } // extern "C" + diff --git a/evdev/src/main/cpp/keylayoutmap_c.h b/evdev/src/main/cpp/keylayoutmap_c.h index 4787f6611c..618a3410b3 100644 --- a/evdev/src/main/cpp/keylayoutmap_c.h +++ b/evdev/src/main/cpp/keylayoutmap_c.h @@ -55,3 +55,4 @@ void keylayoutmap_destroy(KeyLayoutMapHandle handle); #endif // KEYLAYOUTMAP_C_H + From d122e26d8fe672403746451b0fa02742d8840e03 Mon Sep 17 00:00:00 2001 From: sds100 Date: Sat, 15 Nov 2025 15:50:30 +0100 Subject: [PATCH 07/65] #1897 manage the IEvdevCallback in C++ with JNI world and expose simple bindings to Rust --- .../main/cpp/evdev_callback_jni_manager.cpp | 142 ++++++++++++++++++ .../src/main/cpp/evdev_callback_jni_manager.h | 62 ++++++++ .../cpp/{ => wrappers}/keylayoutmap_c.cpp | 0 .../main/cpp/{ => wrappers}/keylayoutmap_c.h | 0 evdev/src/main/rust/evdev_manager/build.rs | 10 +- .../main/rust/evdev_manager/src/bindings.rs | 33 ++++ 6 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 evdev/src/main/cpp/evdev_callback_jni_manager.cpp create mode 100644 evdev/src/main/cpp/evdev_callback_jni_manager.h rename evdev/src/main/cpp/{ => wrappers}/keylayoutmap_c.cpp (100%) rename evdev/src/main/cpp/{ => wrappers}/keylayoutmap_c.h (100%) diff --git a/evdev/src/main/cpp/evdev_callback_jni_manager.cpp b/evdev/src/main/cpp/evdev_callback_jni_manager.cpp new file mode 100644 index 0000000000..0afb140a13 --- /dev/null +++ b/evdev/src/main/cpp/evdev_callback_jni_manager.cpp @@ -0,0 +1,142 @@ +/* + * JNI Manager implementation for IEvdevCallback + * Handles JNI binder registration and lifecycle management + * Exposes simple C-style functions for interacting with the callback + */ + +#include "evdev_callback_jni_manager.h" +#include "aidl/io/github/sds100/keymapper/evdev/IEvdevCallback.h" +#include "logging.h" +#include +#include +#include +#include +#include + +using aidl::io::github::sds100::keymapper::evdev::IEvdevCallback; + +// Static storage for the callback instance +static std::shared_ptr g_callback = nullptr; +static std::mutex g_callback_mutex; + +extern "C" { + +// JNI method to register the callback from Java +JNIEXPORT jint JNICALL +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_registerEvdevCallbackNative( + JNIEnv *env, + jobject thiz, + jobject jCallbackBinder) { + + if (!jCallbackBinder) { + return EVDEV_CALLBACK_ERROR_INVALID_ARG; + } + + AIBinder *callbackAIBinder = AIBinder_fromJavaBinder(env, jCallbackBinder); + if (!callbackAIBinder) { + return EVDEV_CALLBACK_ERROR_BINDER_CONVERSION_FAILED; + } + + const ::ndk::SpAIBinder spBinder(callbackAIBinder); + std::shared_ptr callback = IEvdevCallback::fromBinder(spBinder); + + if (!callback) { + return EVDEV_CALLBACK_ERROR_CALLBACK_CREATION_FAILED; + } + + std::lock_guard lock(g_callback_mutex); + g_callback = callback; + LOGI("Registered evdev callback via JNI"); + return EVDEV_CALLBACK_SUCCESS; +} + +// JNI method to unregister the callback +JNIEXPORT void JNICALL +Java_io_github_sds100_keymapper_sysbridge_service_BaseSystemBridge_unregisterEvdevCallbackNative( + JNIEnv *env, + jobject thiz) { + + std::lock_guard lock(g_callback_mutex); + g_callback = nullptr; + LOGI("Unregistered evdev callback via JNI"); +} + +int evdev_callback_on_evdev_event_loop_started() { + std::lock_guard lock(g_callback_mutex); + if (!g_callback) { + return EVDEV_CALLBACK_ERROR_NO_CALLBACK; + } + + ndk::ScopedAStatus status = g_callback->onEvdevEventLoopStarted(); + if (!status.isOk()) { + return EVDEV_CALLBACK_ERROR_CALLBACK_FAILED; + } + + return EVDEV_CALLBACK_SUCCESS; +} + +int evdev_callback_on_evdev_event( + const char* device_path, + int64_t time_sec, + int64_t time_usec, + int32_t type, + int32_t code, + int32_t value, + int32_t android_code +) { + if (!device_path) { + return EVDEV_CALLBACK_ERROR_INVALID_ARG; + } + + std::lock_guard lock(g_callback_mutex); + if (!g_callback) { + return EVDEV_CALLBACK_ERROR_NO_CALLBACK; + } + + std::string device_path_str(device_path); + bool return_value = false; + ndk::ScopedAStatus status = g_callback->onEvdevEvent( + device_path_str, + time_sec, + time_usec, + type, + code, + value, + android_code, + &return_value + ); + + if (!status.isOk()) { + return EVDEV_CALLBACK_ERROR_CALLBACK_FAILED; + } + + return EVDEV_CALLBACK_SUCCESS; +} + +int evdev_callback_on_emergency_kill_system_bridge() { + std::lock_guard lock(g_callback_mutex); + if (!g_callback) { + return EVDEV_CALLBACK_ERROR_NO_CALLBACK; + } + + ndk::ScopedAStatus status = g_callback->onEmergencyKillSystemBridge(); + if (!status.isOk()) { + return EVDEV_CALLBACK_ERROR_CALLBACK_FAILED; + } + + return EVDEV_CALLBACK_SUCCESS; +} + +void evdev_callback_destroy(IEvdevCallbackHandle handle) { + if (!handle) { + return; + } + + std::shared_ptr* callback_ptr = + reinterpret_cast*>(handle); + + delete callback_ptr; +} + +} // extern "C" + diff --git a/evdev/src/main/cpp/evdev_callback_jni_manager.h b/evdev/src/main/cpp/evdev_callback_jni_manager.h new file mode 100644 index 0000000000..15a2c51c6b --- /dev/null +++ b/evdev/src/main/cpp/evdev_callback_jni_manager.h @@ -0,0 +1,62 @@ +/* + * JNI Manager for IEvdevCallback + * Manages the registration and lifecycle of the evdev callback via JNI + * and provides a simple C API for interacting with the callback + */ + +#ifndef EVDEV_CALLBACK_JNI_MANAGER_H +#define EVDEV_CALLBACK_JNI_MANAGER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Error codes for evdev callback operations +enum EvdevCallbackError { + EVDEV_CALLBACK_SUCCESS = 0, // Operation succeeded + EVDEV_CALLBACK_ERROR_INVALID_ARG = -1, // Invalid argument (null pointer, etc.) + EVDEV_CALLBACK_ERROR_BINDER_CONVERSION_FAILED = -2, // Failed to convert Java binder to AIBinder + EVDEV_CALLBACK_ERROR_CALLBACK_CREATION_FAILED = -3, // Failed to create callback from binder + EVDEV_CALLBACK_ERROR_NO_CALLBACK = -4, // No callback registered + EVDEV_CALLBACK_ERROR_INVALID_HANDLE = -5, // Invalid callback handle + EVDEV_CALLBACK_ERROR_CALLBACK_FAILED = -6, // Callback method returned error +}; + +// Opaque handle to IEvdevCallback +typedef void* IEvdevCallbackHandle; + +// Opaque handle to AIBinder (from Android NDK) +typedef void* AIBinderHandle; + +// Call onEvdevEventLoopStarted using stored callback +// Returns 0 on success, non-zero error code on failure +int evdev_callback_on_evdev_event_loop_started(); + +// Call onEvdevEvent using stored callback +// Returns 0 on success, non-zero error code on failure +int evdev_callback_on_evdev_event( + const char* device_path, + int64_t time_sec, + int64_t time_usec, + int32_t type, + int32_t code, + int32_t value, + int32_t android_code +); + +// Call onEmergencyKillSystemBridge using stored callback +// Returns 0 on success, non-zero error code on failure +int evdev_callback_on_emergency_kill_system_bridge(); + +// Destroy an IEvdevCallback handle +// Safe to call with NULL handle +void evdev_callback_destroy(IEvdevCallbackHandle handle); + +#ifdef __cplusplus +} +#endif + +#endif // EVDEV_CALLBACK_JNI_MANAGER_H + diff --git a/evdev/src/main/cpp/keylayoutmap_c.cpp b/evdev/src/main/cpp/wrappers/keylayoutmap_c.cpp similarity index 100% rename from evdev/src/main/cpp/keylayoutmap_c.cpp rename to evdev/src/main/cpp/wrappers/keylayoutmap_c.cpp diff --git a/evdev/src/main/cpp/keylayoutmap_c.h b/evdev/src/main/cpp/wrappers/keylayoutmap_c.h similarity index 100% rename from evdev/src/main/cpp/keylayoutmap_c.h rename to evdev/src/main/cpp/wrappers/keylayoutmap_c.h diff --git a/evdev/src/main/rust/evdev_manager/build.rs b/evdev/src/main/rust/evdev_manager/build.rs index 2f77416a51..31f7f8f6af 100644 --- a/evdev/src/main/rust/evdev_manager/build.rs +++ b/evdev/src/main/rust/evdev_manager/build.rs @@ -66,7 +66,9 @@ fn main() { .file(android_dir.join("input/InputDevice.cpp")) .file(android_dir.join("input/Input.cpp")) // C interface wrapper for KeyLayoutMap - .file(cpp_dir.join("keylayoutmap_c.cpp")) + .file(cpp_dir.join("wrappers/keylayoutmap_c.cpp")) + // JNI manager for IEvdevCallback so don't need to use a Rust binder library + .file(cpp_dir.join("evdev_callback_jni_manager.cpp")) // Android base library files .file(android_dir.join("libbase/result.cpp")) .file(android_dir.join("libbase/stringprintf.cpp")) @@ -81,6 +83,7 @@ fn main() { .file(aidl_dir.join("io/github/sds100/keymapper/evdev/IEvdevCallback.cpp")) // Include directories .include(&cpp_dir) + .include(&cpp_dir.join("wrappers")) .include(&android_dir) .include(&android_dir.join("input")) .include(&android_dir.join("libbase")) @@ -154,7 +157,10 @@ fn main() { .display() .to_string(), ) - .header(cpp_dir.join("keylayoutmap_c.h").display().to_string()) + .header(cpp_dir.join("evdev_callback_jni_manager.h").display().to_string()) + .header(cpp_dir.join("wrappers/keylayoutmap_c.h").display().to_string()) + // Generate a proper Rust enum for EvdevCallbackError + .rustified_enum("EvdevCallbackError") .clang_arg(format!("--sysroot={}", ndk_sysroot.display())) .clang_arg(format!("-I{}", sysroot_include.display())); diff --git a/evdev/src/main/rust/evdev_manager/src/bindings.rs b/evdev/src/main/rust/evdev_manager/src/bindings.rs index db1a441919..22fb0fd0f2 100644 --- a/evdev/src/main/rust/evdev_manager/src/bindings.rs +++ b/evdev/src/main/rust/evdev_manager/src/bindings.rs @@ -7627,6 +7627,39 @@ const _: () = { "Offset of field: libevdev_uinput::ctime", ][::std::mem::offset_of!(libevdev_uinput, ctime) - 32usize]; }; +#[repr(i32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub enum EvdevCallbackError { + EVDEV_CALLBACK_SUCCESS = 0, + EVDEV_CALLBACK_ERROR_INVALID_ARG = -1, + EVDEV_CALLBACK_ERROR_BINDER_CONVERSION_FAILED = -2, + EVDEV_CALLBACK_ERROR_CALLBACK_CREATION_FAILED = -3, + EVDEV_CALLBACK_ERROR_NO_CALLBACK = -4, + EVDEV_CALLBACK_ERROR_INVALID_HANDLE = -5, + EVDEV_CALLBACK_ERROR_CALLBACK_FAILED = -6, +} +pub type IEvdevCallbackHandle = *mut ::std::os::raw::c_void; +pub type AIBinderHandle = *mut ::std::os::raw::c_void; +unsafe extern "C" { + pub fn evdev_callback_on_evdev_event_loop_started() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn evdev_callback_on_evdev_event( + device_path: *const ::std::os::raw::c_char, + time_sec: i64, + time_usec: i64, + type_: i32, + code: i32, + value: i32, + android_code: i32, + ) -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn evdev_callback_on_emergency_kill_system_bridge() -> ::std::os::raw::c_int; +} +unsafe extern "C" { + pub fn evdev_callback_destroy(handle: IEvdevCallbackHandle); +} pub type KeyLayoutMapHandle = *mut ::std::os::raw::c_void; #[repr(C)] #[derive(Debug, Copy, Clone)] From 5bf7870e0df59e5e287ce7694eb9f06b544e3529 Mon Sep 17 00:00:00 2001 From: sds100 Date: Sat, 15 Nov 2025 17:05:37 +0100 Subject: [PATCH 08/65] #1897 WIP: refactor libevdev_jni.cpp into Rust --- evdev/.idea/gradle.xml | 1 + evdev/src/main/cpp/keylayoutmap_c.cpp | 102 +++ evdev/src/main/cpp/keylayoutmap_c.h | 58 ++ evdev/src/main/cpp/libevdev_jni.cpp | 708 ------------------ .../wrappers/evdev_callback_jni_manager.cpp | 277 +++++++ .../cpp/wrappers/evdev_callback_jni_manager.h | 110 +++ .../main/cpp/wrappers/ievdevcallback_c.cpp | 275 +++++++ .../src/main/cpp/wrappers/ievdevcallback_c.h | 99 +++ .../src/main/cpp/wrappers/keylayoutmap_c.cpp | 5 +- evdev/src/main/cpp/wrappers/keylayoutmap_c.h | 4 +- evdev/src/main/rust/evdev_manager/Cargo.lock | 39 +- evdev/src/main/rust/evdev_manager/Cargo.toml | 3 +- .../main/rust/evdev_manager/src/bindings.rs | 1 - .../rust/evdev_manager/src/device_manager.rs | 92 +++ .../src/main/rust/evdev_manager/src/evdev.rs | 12 +- .../src/evdevcallback_binder_observer.rs | 125 ++++ .../main/rust/evdev_manager/src/event_loop.rs | 402 ++++++++++ .../evdev_manager/src/input_event_lookup.rs | 539 +++++++++++++ .../main/rust/evdev_manager/src/jni_bridge.rs | 362 +++++++++ .../rust/evdev_manager/src/key_layout_map.rs | 449 +++++++++++ .../src/key_layout_map_manager.rs | 232 ++++++ evdev/src/main/rust/evdev_manager/src/lib.rs | 6 + .../main/rust/evdev_manager/src/observer.rs | 61 ++ .../main/rust/evdev_manager/src/tokenizer.rs | 289 +++++++ .../tests/key_layout_map_integration.rs | 165 ++++ 25 files changed, 3686 insertions(+), 730 deletions(-) create mode 100644 evdev/src/main/cpp/keylayoutmap_c.cpp create mode 100644 evdev/src/main/cpp/keylayoutmap_c.h delete mode 100644 evdev/src/main/cpp/libevdev_jni.cpp create mode 100644 evdev/src/main/cpp/wrappers/evdev_callback_jni_manager.cpp create mode 100644 evdev/src/main/cpp/wrappers/evdev_callback_jni_manager.h create mode 100644 evdev/src/main/cpp/wrappers/ievdevcallback_c.cpp create mode 100644 evdev/src/main/cpp/wrappers/ievdevcallback_c.h create mode 100644 evdev/src/main/rust/evdev_manager/src/device_manager.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/evdevcallback_binder_observer.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/event_loop.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/input_event_lookup.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/jni_bridge.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/key_layout_map.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/key_layout_map_manager.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/observer.rs create mode 100644 evdev/src/main/rust/evdev_manager/src/tokenizer.rs create mode 100644 evdev/src/main/rust/evdev_manager/tests/key_layout_map_integration.rs diff --git a/evdev/.idea/gradle.xml b/evdev/.idea/gradle.xml index 1b387c73e6..e77e5a3224 100644 --- a/evdev/.idea/gradle.xml +++ b/evdev/.idea/gradle.xml @@ -1,5 +1,6 @@ +