diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 65d8be8c..0eccb496 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -23,7 +23,15 @@ jobs: with: gradle-home-cache-cleanup: true + - uses: goto-bus-stop/setup-zig@v2 + with: + version: 0.13.0 + - run: zig build -p src/jvmMain/resources/jni + working-directory: mosaic-terminal + - run: ./gradlew build :samples:jest:run :mosaic-runtime:dokkaHtml + env: + MOSAIC_RAW_MODE: false - run: ./gradlew publish if: ${{ github.ref == 'refs/heads/trunk' && github.repository == 'JakeWharton/mosaic' }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 70231008..9ef3840e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -16,6 +16,12 @@ jobs: distribution: 'zulu' java-version: 11 + - uses: goto-bus-stop/setup-zig@v2 + with: + version: 0.13.0 + - run: zig build -p src/jvmMain/resources/jni + working-directory: mosaic-terminal + - run: ./gradlew publish env: ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 65c0526c..e8f3aed2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ New: - Support synchronized terminal update for rendering. +- The terminal cursor is now automatically hidden during rendering and restored afterwards. +- Use `Modifier.onKeyEvent` or `Modifier.onPreKeyEvent` to listen to keyboard events. Changed: - Сhange `DrawScope#drawRect` API with the ability to draw with text characters and specify `DrawStyle` (`Fill` or `Stroke`). diff --git a/build.gradle b/build.gradle index e159b675..c5afbfd5 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,7 @@ buildscript { classpath libs.poko.gradlePlugin classpath libs.spotless.gradlePlugin classpath libs.binary.compatibility.validator.gradlePlugin + classpath libs.cklib.gradlePlugin } repositories { mavenCentral() @@ -44,7 +45,7 @@ allprojects { apply plugin: 'com.diffplug.spotless' spotless { kotlin { - target("src/**/*.kt") + target('src/**/*.kt') ktlint(libs.ktlint.core.get().version) .editorConfigOverride([ 'ktlint_standard_filename': 'disabled', diff --git a/gradle.properties b/gradle.properties index 6754981d..db64595c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,6 +24,7 @@ kotlin.mpp.stability.nowarn=true # This is needed for the JB Compose runtime to link on native targets. They also use this flag # in their samples. Over time it should be removed once they figure out why it was needed. kotlin.native.cacheKind=none +kotlin.mpp.enableCInteropCommonization=true systemProp.org.gradle.internal.http.socketTimeout=120000 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 829ef31e..0667ea73 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,7 @@ [versions] kotlin = "2.0.20" kotlinx-coroutines = "1.8.1" +mordant = "3.0.0" [libraries] kotlin-plugin-core = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } @@ -16,14 +17,19 @@ maven-publish-gradlePlugin = "com.vanniktech:gradle-maven-publish-plugin:0.29.0" dokka-gradlePlugin = "org.jetbrains.dokka:dokka-gradle-plugin:1.9.20" poko-gradlePlugin = "dev.drewhamilton.poko:poko-gradle-plugin:0.17.0" binary-compatibility-validator-gradlePlugin = "org.jetbrains.kotlinx:binary-compatibility-validator:0.16.3" +cklib-gradlePlugin = "co.touchlab:cklib-gradle-plugin:0.3.3" spotless-gradlePlugin = "com.diffplug.spotless:spotless-plugin-gradle:6.25.0" ktlint-core = "com.pinterest.ktlint:ktlint-cli:1.3.1" -ktlint-composeRules = "io.nlopez.compose.rules:ktlint:0.4.10" +ktlint-composeRules = "io.nlopez.compose.rules:ktlint:0.4.12" + +mordant-core = { module = "com.github.ajalt.mordant:mordant-core", version.ref = "mordant" } +mordant-jvmJna = { module = "com.github.ajalt.mordant:mordant-jvm-jna", version.ref = "mordant" } jansi = "org.fusesource.jansi:jansi:2.4.1" -mordant = "com.github.ajalt.mordant:mordant:2.7.2" +clikt = "com.github.ajalt.clikt:clikt:4.4.0" codepoints = "de.cketti.unicode:kotlin-codepoints:0.9.0" +finalizationHook = "com.jakewharton.finalization:finalization-hook:0.1.0" junit4 = "junit:junit:4.13.2" assertk = "com.willowtreeapps.assertk:assertk:0.28.1" diff --git a/mosaic-runtime/api/mosaic-runtime.api b/mosaic-runtime/api/mosaic-runtime.api index 5e49fa66..acd2dbe2 100644 --- a/mosaic-runtime/api/mosaic-runtime.api +++ b/mosaic-runtime/api/mosaic-runtime.api @@ -1,10 +1,7 @@ -public final class com/jakewharton/mosaic/BlockingKt { - public static final fun runMosaicBlocking (Lkotlin/jvm/functions/Function2;)V -} - public final class com/jakewharton/mosaic/MosaicKt { public static final fun renderMosaic (Lkotlin/jvm/functions/Function2;)Ljava/lang/String; public static final fun runMosaic (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun runMosaicBlocking (Lkotlin/jvm/functions/Function2;)V } public final class com/jakewharton/mosaic/Terminal { @@ -84,6 +81,29 @@ public abstract interface class com/jakewharton/mosaic/layout/IntrinsicMeasurabl public abstract fun minIntrinsicWidth (I)I } +public final class com/jakewharton/mosaic/layout/KeyEvent { + public static final field $stable I + public fun (Ljava/lang/String;ZZZ)V + public synthetic fun (Ljava/lang/String;ZZZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getAlt ()Z + public final fun getCtrl ()Z + public final fun getKey ()Ljava/lang/String; + public final fun getShift ()Z + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class com/jakewharton/mosaic/layout/KeyModifier : com/jakewharton/mosaic/modifier/Modifier$Element { + public abstract fun onKeyEvent (Lcom/jakewharton/mosaic/layout/KeyEvent;)Z + public abstract fun onPreKeyEvent (Lcom/jakewharton/mosaic/layout/KeyEvent;)Z +} + +public final class com/jakewharton/mosaic/layout/KeyModifierKt { + public static final fun onKeyEvent (Lcom/jakewharton/mosaic/modifier/Modifier;Lkotlin/jvm/functions/Function1;)Lcom/jakewharton/mosaic/modifier/Modifier; + public static final fun onPreviewKeyEvent (Lcom/jakewharton/mosaic/modifier/Modifier;Lkotlin/jvm/functions/Function1;)Lcom/jakewharton/mosaic/modifier/Modifier; +} + public abstract interface class com/jakewharton/mosaic/layout/LayoutModifier : com/jakewharton/mosaic/modifier/Modifier$Element { public fun maxIntrinsicHeight (Lcom/jakewharton/mosaic/layout/IntrinsicMeasurable;I)I public fun maxIntrinsicWidth (Lcom/jakewharton/mosaic/layout/IntrinsicMeasurable;I)I diff --git a/mosaic-runtime/api/mosaic-runtime.klib.api b/mosaic-runtime/api/mosaic-runtime.klib.api new file mode 100644 index 00000000..6680cfd2 --- /dev/null +++ b/mosaic-runtime/api/mosaic-runtime.klib.api @@ -0,0 +1,745 @@ +// Klib ABI Dump +// Targets: [linuxArm64, linuxX64, macosArm64, macosX64, mingwX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +open annotation class com.jakewharton.mosaic.ui/LayoutScopeMarker : kotlin/Annotation { // com.jakewharton.mosaic.ui/LayoutScopeMarker|null[0] + constructor () // com.jakewharton.mosaic.ui/LayoutScopeMarker.|(){}[0] +} + +open annotation class com.jakewharton.mosaic.ui/MosaicComposable : kotlin/Annotation { // com.jakewharton.mosaic.ui/MosaicComposable|null[0] + constructor () // com.jakewharton.mosaic.ui/MosaicComposable.|(){}[0] +} + +abstract fun interface com.jakewharton.mosaic.layout/MeasurePolicy { // com.jakewharton.mosaic.layout/MeasurePolicy|null[0] + abstract fun (com.jakewharton.mosaic.layout/MeasureScope).measure(kotlin.collections/List, com.jakewharton.mosaic.ui.unit/Constraints): com.jakewharton.mosaic.layout/MeasureResult // com.jakewharton.mosaic.layout/MeasurePolicy.measure|measure@com.jakewharton.mosaic.layout.MeasureScope(kotlin.collections.List;com.jakewharton.mosaic.ui.unit.Constraints){}[0] + open fun maxIntrinsicHeight(kotlin.collections/List, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/MeasurePolicy.maxIntrinsicHeight|maxIntrinsicHeight(kotlin.collections.List;kotlin.Int){}[0] + open fun maxIntrinsicWidth(kotlin.collections/List, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/MeasurePolicy.maxIntrinsicWidth|maxIntrinsicWidth(kotlin.collections.List;kotlin.Int){}[0] + open fun minIntrinsicHeight(kotlin.collections/List, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/MeasurePolicy.minIntrinsicHeight|minIntrinsicHeight(kotlin.collections.List;kotlin.Int){}[0] + open fun minIntrinsicWidth(kotlin.collections/List, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/MeasurePolicy.minIntrinsicWidth|minIntrinsicWidth(kotlin.collections.List;kotlin.Int){}[0] +} + +abstract fun interface com.jakewharton.mosaic.ui/Alignment { // com.jakewharton.mosaic.ui/Alignment|null[0] + abstract fun align(com.jakewharton.mosaic.ui.unit/IntSize, com.jakewharton.mosaic.ui.unit/IntSize): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui/Alignment.align|align(com.jakewharton.mosaic.ui.unit.IntSize;com.jakewharton.mosaic.ui.unit.IntSize){}[0] + + abstract fun interface Horizontal { // com.jakewharton.mosaic.ui/Alignment.Horizontal|null[0] + abstract fun align(kotlin/Int, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.ui/Alignment.Horizontal.align|align(kotlin.Int;kotlin.Int){}[0] + } + + abstract fun interface Vertical { // com.jakewharton.mosaic.ui/Alignment.Vertical|null[0] + abstract fun align(kotlin/Int, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.ui/Alignment.Vertical.align|align(kotlin.Int;kotlin.Int){}[0] + } + + final object Companion { // com.jakewharton.mosaic.ui/Alignment.Companion|null[0] + final val Bottom // com.jakewharton.mosaic.ui/Alignment.Companion.Bottom|{}Bottom[0] + final fun (): com.jakewharton.mosaic.ui/Alignment.Vertical // com.jakewharton.mosaic.ui/Alignment.Companion.Bottom.|(){}[0] + final val BottomCenter // com.jakewharton.mosaic.ui/Alignment.Companion.BottomCenter|{}BottomCenter[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.BottomCenter.|(){}[0] + final val BottomEnd // com.jakewharton.mosaic.ui/Alignment.Companion.BottomEnd|{}BottomEnd[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.BottomEnd.|(){}[0] + final val BottomStart // com.jakewharton.mosaic.ui/Alignment.Companion.BottomStart|{}BottomStart[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.BottomStart.|(){}[0] + final val Center // com.jakewharton.mosaic.ui/Alignment.Companion.Center|{}Center[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.Center.|(){}[0] + final val CenterEnd // com.jakewharton.mosaic.ui/Alignment.Companion.CenterEnd|{}CenterEnd[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.CenterEnd.|(){}[0] + final val CenterHorizontally // com.jakewharton.mosaic.ui/Alignment.Companion.CenterHorizontally|{}CenterHorizontally[0] + final fun (): com.jakewharton.mosaic.ui/Alignment.Horizontal // com.jakewharton.mosaic.ui/Alignment.Companion.CenterHorizontally.|(){}[0] + final val CenterStart // com.jakewharton.mosaic.ui/Alignment.Companion.CenterStart|{}CenterStart[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.CenterStart.|(){}[0] + final val CenterVertically // com.jakewharton.mosaic.ui/Alignment.Companion.CenterVertically|{}CenterVertically[0] + final fun (): com.jakewharton.mosaic.ui/Alignment.Vertical // com.jakewharton.mosaic.ui/Alignment.Companion.CenterVertically.|(){}[0] + final val End // com.jakewharton.mosaic.ui/Alignment.Companion.End|{}End[0] + final fun (): com.jakewharton.mosaic.ui/Alignment.Horizontal // com.jakewharton.mosaic.ui/Alignment.Companion.End.|(){}[0] + final val Start // com.jakewharton.mosaic.ui/Alignment.Companion.Start|{}Start[0] + final fun (): com.jakewharton.mosaic.ui/Alignment.Horizontal // com.jakewharton.mosaic.ui/Alignment.Companion.Start.|(){}[0] + final val Top // com.jakewharton.mosaic.ui/Alignment.Companion.Top|{}Top[0] + final fun (): com.jakewharton.mosaic.ui/Alignment.Vertical // com.jakewharton.mosaic.ui/Alignment.Companion.Top.|(){}[0] + final val TopCenter // com.jakewharton.mosaic.ui/Alignment.Companion.TopCenter|{}TopCenter[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.TopCenter.|(){}[0] + final val TopEnd // com.jakewharton.mosaic.ui/Alignment.Companion.TopEnd|{}TopEnd[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.TopEnd.|(){}[0] + final val TopStart // com.jakewharton.mosaic.ui/Alignment.Companion.TopStart|{}TopStart[0] + final fun (): com.jakewharton.mosaic.ui/Alignment // com.jakewharton.mosaic.ui/Alignment.Companion.TopStart.|(){}[0] + } +} + +abstract interface com.jakewharton.mosaic.layout/ContentDrawScope : com.jakewharton.mosaic.layout/DrawScope { // com.jakewharton.mosaic.layout/ContentDrawScope|null[0] + abstract fun drawContent() // com.jakewharton.mosaic.layout/ContentDrawScope.drawContent|drawContent(){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/DrawModifier : com.jakewharton.mosaic.modifier/Modifier.Element { // com.jakewharton.mosaic.layout/DrawModifier|null[0] + abstract fun (com.jakewharton.mosaic.layout/ContentDrawScope).draw() // com.jakewharton.mosaic.layout/DrawModifier.draw|draw@com.jakewharton.mosaic.layout.ContentDrawScope(){}[0] + abstract fun toString(): kotlin/String // com.jakewharton.mosaic.layout/DrawModifier.toString|toString(){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/DrawScope { // com.jakewharton.mosaic.layout/DrawScope|null[0] + abstract val height // com.jakewharton.mosaic.layout/DrawScope.height|{}height[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/DrawScope.height.|(){}[0] + abstract val width // com.jakewharton.mosaic.layout/DrawScope.width|{}width[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/DrawScope.width.|(){}[0] + + abstract fun drawRect(kotlin/Char, com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/TextStyle = ..., com.jakewharton.mosaic.ui.unit/IntOffset = ..., com.jakewharton.mosaic.ui.unit/IntSize = ..., com.jakewharton.mosaic.layout/DrawStyle = ...) // com.jakewharton.mosaic.layout/DrawScope.drawRect|drawRect(kotlin.Char;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;com.jakewharton.mosaic.ui.unit.IntOffset;com.jakewharton.mosaic.ui.unit.IntSize;com.jakewharton.mosaic.layout.DrawStyle){}[0] + abstract fun drawRect(kotlin/Int = ..., com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/TextStyle = ..., com.jakewharton.mosaic.ui.unit/IntOffset = ..., com.jakewharton.mosaic.ui.unit/IntSize = ..., com.jakewharton.mosaic.layout/DrawStyle = ...) // com.jakewharton.mosaic.layout/DrawScope.drawRect|drawRect(kotlin.Int;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;com.jakewharton.mosaic.ui.unit.IntOffset;com.jakewharton.mosaic.ui.unit.IntSize;com.jakewharton.mosaic.layout.DrawStyle){}[0] + abstract fun drawText(kotlin/Int, kotlin/Int, com.jakewharton.mosaic.text/AnnotatedString, com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/TextStyle = ...) // com.jakewharton.mosaic.layout/DrawScope.drawText|drawText(kotlin.Int;kotlin.Int;com.jakewharton.mosaic.text.AnnotatedString;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle){}[0] + abstract fun drawText(kotlin/Int, kotlin/Int, kotlin/String, com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/TextStyle = ...) // com.jakewharton.mosaic.layout/DrawScope.drawText|drawText(kotlin.Int;kotlin.Int;kotlin.String;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/IntrinsicMeasurable { // com.jakewharton.mosaic.layout/IntrinsicMeasurable|null[0] + abstract val parentData // com.jakewharton.mosaic.layout/IntrinsicMeasurable.parentData|{}parentData[0] + abstract fun (): kotlin/Any? // com.jakewharton.mosaic.layout/IntrinsicMeasurable.parentData.|(){}[0] + + abstract fun maxIntrinsicHeight(kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/IntrinsicMeasurable.maxIntrinsicHeight|maxIntrinsicHeight(kotlin.Int){}[0] + abstract fun maxIntrinsicWidth(kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/IntrinsicMeasurable.maxIntrinsicWidth|maxIntrinsicWidth(kotlin.Int){}[0] + abstract fun minIntrinsicHeight(kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/IntrinsicMeasurable.minIntrinsicHeight|minIntrinsicHeight(kotlin.Int){}[0] + abstract fun minIntrinsicWidth(kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/IntrinsicMeasurable.minIntrinsicWidth|minIntrinsicWidth(kotlin.Int){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/KeyModifier : com.jakewharton.mosaic.modifier/Modifier.Element { // com.jakewharton.mosaic.layout/KeyModifier|null[0] + abstract fun onKeyEvent(com.jakewharton.mosaic.layout/KeyEvent): kotlin/Boolean // com.jakewharton.mosaic.layout/KeyModifier.onKeyEvent|onKeyEvent(com.jakewharton.mosaic.layout.KeyEvent){}[0] + abstract fun onPreKeyEvent(com.jakewharton.mosaic.layout/KeyEvent): kotlin/Boolean // com.jakewharton.mosaic.layout/KeyModifier.onPreKeyEvent|onPreKeyEvent(com.jakewharton.mosaic.layout.KeyEvent){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/LayoutModifier : com.jakewharton.mosaic.modifier/Modifier.Element { // com.jakewharton.mosaic.layout/LayoutModifier|null[0] + abstract fun (com.jakewharton.mosaic.layout/MeasureScope).measure(com.jakewharton.mosaic.layout/Measurable, com.jakewharton.mosaic.ui.unit/Constraints): com.jakewharton.mosaic.layout/MeasureResult // com.jakewharton.mosaic.layout/LayoutModifier.measure|measure@com.jakewharton.mosaic.layout.MeasureScope(com.jakewharton.mosaic.layout.Measurable;com.jakewharton.mosaic.ui.unit.Constraints){}[0] + abstract fun toString(): kotlin/String // com.jakewharton.mosaic.layout/LayoutModifier.toString|toString(){}[0] + open fun maxIntrinsicHeight(com.jakewharton.mosaic.layout/IntrinsicMeasurable, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/LayoutModifier.maxIntrinsicHeight|maxIntrinsicHeight(com.jakewharton.mosaic.layout.IntrinsicMeasurable;kotlin.Int){}[0] + open fun maxIntrinsicWidth(com.jakewharton.mosaic.layout/IntrinsicMeasurable, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/LayoutModifier.maxIntrinsicWidth|maxIntrinsicWidth(com.jakewharton.mosaic.layout.IntrinsicMeasurable;kotlin.Int){}[0] + open fun minIntrinsicHeight(com.jakewharton.mosaic.layout/IntrinsicMeasurable, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/LayoutModifier.minIntrinsicHeight|minIntrinsicHeight(com.jakewharton.mosaic.layout.IntrinsicMeasurable;kotlin.Int){}[0] + open fun minIntrinsicWidth(com.jakewharton.mosaic.layout/IntrinsicMeasurable, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.layout/LayoutModifier.minIntrinsicWidth|minIntrinsicWidth(com.jakewharton.mosaic.layout.IntrinsicMeasurable;kotlin.Int){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/Measurable : com.jakewharton.mosaic.layout/IntrinsicMeasurable { // com.jakewharton.mosaic.layout/Measurable|null[0] + abstract fun measure(com.jakewharton.mosaic.ui.unit/Constraints): com.jakewharton.mosaic.layout/Placeable // com.jakewharton.mosaic.layout/Measurable.measure|measure(com.jakewharton.mosaic.ui.unit.Constraints){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/MeasureResult { // com.jakewharton.mosaic.layout/MeasureResult|null[0] + abstract val height // com.jakewharton.mosaic.layout/MeasureResult.height|{}height[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/MeasureResult.height.|(){}[0] + abstract val width // com.jakewharton.mosaic.layout/MeasureResult.width|{}width[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/MeasureResult.width.|(){}[0] + + abstract fun placeChildren() // com.jakewharton.mosaic.layout/MeasureResult.placeChildren|placeChildren(){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/MeasureScope { // com.jakewharton.mosaic.layout/MeasureScope|null[0] + open fun layout(kotlin/Int, kotlin/Int, kotlin/Function1): com.jakewharton.mosaic.layout/MeasureResult // com.jakewharton.mosaic.layout/MeasureScope.layout|layout(kotlin.Int;kotlin.Int;kotlin.Function1){}[0] +} + +abstract interface com.jakewharton.mosaic.layout/ParentDataModifier : com.jakewharton.mosaic.modifier/Modifier.Element { // com.jakewharton.mosaic.layout/ParentDataModifier|null[0] + abstract fun modifyParentData(kotlin/Any?): kotlin/Any? // com.jakewharton.mosaic.layout/ParentDataModifier.modifyParentData|modifyParentData(kotlin.Any?){}[0] +} + +abstract interface com.jakewharton.mosaic.modifier/Modifier { // com.jakewharton.mosaic.modifier/Modifier|null[0] + abstract fun <#A1: kotlin/Any?> foldIn(#A1, kotlin/Function2<#A1, com.jakewharton.mosaic.modifier/Modifier.Element, #A1>): #A1 // com.jakewharton.mosaic.modifier/Modifier.foldIn|foldIn(0:0;kotlin.Function2<0:0,com.jakewharton.mosaic.modifier.Modifier.Element,0:0>){0§}[0] + abstract fun <#A1: kotlin/Any?> foldOut(#A1, kotlin/Function2): #A1 // com.jakewharton.mosaic.modifier/Modifier.foldOut|foldOut(0:0;kotlin.Function2){0§}[0] + abstract fun all(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/Modifier.all|all(kotlin.Function1){}[0] + abstract fun any(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/Modifier.any|any(kotlin.Function1){}[0] + open fun then(com.jakewharton.mosaic.modifier/Modifier): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.modifier/Modifier.then|then(com.jakewharton.mosaic.modifier.Modifier){}[0] + + abstract interface Element : com.jakewharton.mosaic.modifier/Modifier { // com.jakewharton.mosaic.modifier/Modifier.Element|null[0] + open fun <#A2: kotlin/Any?> foldIn(#A2, kotlin/Function2<#A2, com.jakewharton.mosaic.modifier/Modifier.Element, #A2>): #A2 // com.jakewharton.mosaic.modifier/Modifier.Element.foldIn|foldIn(0:0;kotlin.Function2<0:0,com.jakewharton.mosaic.modifier.Modifier.Element,0:0>){0§}[0] + open fun <#A2: kotlin/Any?> foldOut(#A2, kotlin/Function2): #A2 // com.jakewharton.mosaic.modifier/Modifier.Element.foldOut|foldOut(0:0;kotlin.Function2){0§}[0] + open fun all(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/Modifier.Element.all|all(kotlin.Function1){}[0] + open fun any(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/Modifier.Element.any|any(kotlin.Function1){}[0] + } + + final object Companion : com.jakewharton.mosaic.modifier/Modifier { // com.jakewharton.mosaic.modifier/Modifier.Companion|null[0] + final fun <#A2: kotlin/Any?> foldIn(#A2, kotlin/Function2<#A2, com.jakewharton.mosaic.modifier/Modifier.Element, #A2>): #A2 // com.jakewharton.mosaic.modifier/Modifier.Companion.foldIn|foldIn(0:0;kotlin.Function2<0:0,com.jakewharton.mosaic.modifier.Modifier.Element,0:0>){0§}[0] + final fun <#A2: kotlin/Any?> foldOut(#A2, kotlin/Function2): #A2 // com.jakewharton.mosaic.modifier/Modifier.Companion.foldOut|foldOut(0:0;kotlin.Function2){0§}[0] + final fun all(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/Modifier.Companion.all|all(kotlin.Function1){}[0] + final fun any(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/Modifier.Companion.any|any(kotlin.Function1){}[0] + final fun then(com.jakewharton.mosaic.modifier/Modifier): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.modifier/Modifier.Companion.then|then(com.jakewharton.mosaic.modifier.Modifier){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.modifier/Modifier.Companion.toString|toString(){}[0] + } +} + +abstract interface com.jakewharton.mosaic.ui/BoxScope { // com.jakewharton.mosaic.ui/BoxScope|null[0] + abstract fun (com.jakewharton.mosaic.modifier/Modifier).align(com.jakewharton.mosaic.ui/Alignment): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.ui/BoxScope.align|align@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.Alignment){}[0] + abstract fun (com.jakewharton.mosaic.modifier/Modifier).matchParentSize(): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.ui/BoxScope.matchParentSize|matchParentSize@com.jakewharton.mosaic.modifier.Modifier(){}[0] +} + +abstract interface com.jakewharton.mosaic.ui/ColumnScope { // com.jakewharton.mosaic.ui/ColumnScope|null[0] + abstract fun (com.jakewharton.mosaic.modifier/Modifier).align(com.jakewharton.mosaic.ui/Alignment.Horizontal): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.ui/ColumnScope.align|align@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.Alignment.Horizontal){}[0] + abstract fun (com.jakewharton.mosaic.modifier/Modifier).weight(kotlin/Float, kotlin/Boolean = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.ui/ColumnScope.weight|weight@com.jakewharton.mosaic.modifier.Modifier(kotlin.Float;kotlin.Boolean){}[0] +} + +abstract interface com.jakewharton.mosaic.ui/RowScope { // com.jakewharton.mosaic.ui/RowScope|null[0] + abstract fun (com.jakewharton.mosaic.modifier/Modifier).align(com.jakewharton.mosaic.ui/Alignment.Vertical): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.ui/RowScope.align|align@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.Alignment.Vertical){}[0] + abstract fun (com.jakewharton.mosaic.modifier/Modifier).weight(kotlin/Float, kotlin/Boolean = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.ui/RowScope.weight|weight@com.jakewharton.mosaic.modifier.Modifier(kotlin.Float;kotlin.Boolean){}[0] +} + +sealed interface com.jakewharton.mosaic.layout/DrawStyle { // com.jakewharton.mosaic.layout/DrawStyle|null[0] + final class Stroke : com.jakewharton.mosaic.layout/DrawStyle { // com.jakewharton.mosaic.layout/DrawStyle.Stroke|null[0] + constructor (kotlin/Int = ...) // com.jakewharton.mosaic.layout/DrawStyle.Stroke.|(kotlin.Int){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.layout/DrawStyle.Stroke.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.layout/DrawStyle.Stroke.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.layout/DrawStyle.Stroke.toString|toString(){}[0] + } + + final object Fill : com.jakewharton.mosaic.layout/DrawStyle { // com.jakewharton.mosaic.layout/DrawStyle.Fill|null[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.layout/DrawStyle.Fill.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.layout/DrawStyle.Fill.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.layout/DrawStyle.Fill.toString|toString(){}[0] + } +} + +abstract class com.jakewharton.mosaic.layout/Placeable { // com.jakewharton.mosaic.layout/Placeable|null[0] + constructor () // com.jakewharton.mosaic.layout/Placeable.|(){}[0] + + abstract val height // com.jakewharton.mosaic.layout/Placeable.height|{}height[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/Placeable.height.|(){}[0] + abstract val width // com.jakewharton.mosaic.layout/Placeable.width|{}width[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/Placeable.width.|(){}[0] + + abstract fun placeAt(kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.layout/Placeable.placeAt|placeAt(kotlin.Int;kotlin.Int){}[0] + + abstract interface PlacementScope { // com.jakewharton.mosaic.layout/Placeable.PlacementScope|null[0] + abstract val x // com.jakewharton.mosaic.layout/Placeable.PlacementScope.x|{}x[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/Placeable.PlacementScope.x.|(){}[0] + abstract val y // com.jakewharton.mosaic.layout/Placeable.PlacementScope.y|{}y[0] + abstract fun (): kotlin/Int // com.jakewharton.mosaic.layout/Placeable.PlacementScope.y.|(){}[0] + + open fun (com.jakewharton.mosaic.layout/Placeable).place(com.jakewharton.mosaic.ui.unit/IntOffset) // com.jakewharton.mosaic.layout/Placeable.PlacementScope.place|place@com.jakewharton.mosaic.layout.Placeable(com.jakewharton.mosaic.ui.unit.IntOffset){}[0] + open fun (com.jakewharton.mosaic.layout/Placeable).place(kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.layout/Placeable.PlacementScope.place|place@com.jakewharton.mosaic.layout.Placeable(kotlin.Int;kotlin.Int){}[0] + } +} + +final class com.jakewharton.mosaic.layout/KeyEvent { // com.jakewharton.mosaic.layout/KeyEvent|null[0] + constructor (kotlin/String, kotlin/Boolean = ..., kotlin/Boolean = ..., kotlin/Boolean = ...) // com.jakewharton.mosaic.layout/KeyEvent.|(kotlin.String;kotlin.Boolean;kotlin.Boolean;kotlin.Boolean){}[0] + + final val alt // com.jakewharton.mosaic.layout/KeyEvent.alt|{}alt[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.layout/KeyEvent.alt.|(){}[0] + final val ctrl // com.jakewharton.mosaic.layout/KeyEvent.ctrl|{}ctrl[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.layout/KeyEvent.ctrl.|(){}[0] + final val key // com.jakewharton.mosaic.layout/KeyEvent.key|{}key[0] + final fun (): kotlin/String // com.jakewharton.mosaic.layout/KeyEvent.key.|(){}[0] + final val shift // com.jakewharton.mosaic.layout/KeyEvent.shift|{}shift[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.layout/KeyEvent.shift.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.layout/KeyEvent.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.layout/KeyEvent.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.layout/KeyEvent.toString|toString(){}[0] +} + +final class com.jakewharton.mosaic.modifier/CombinedModifier : com.jakewharton.mosaic.modifier/Modifier { // com.jakewharton.mosaic.modifier/CombinedModifier|null[0] + constructor (com.jakewharton.mosaic.modifier/Modifier, com.jakewharton.mosaic.modifier/Modifier) // com.jakewharton.mosaic.modifier/CombinedModifier.|(com.jakewharton.mosaic.modifier.Modifier;com.jakewharton.mosaic.modifier.Modifier){}[0] + + final fun <#A1: kotlin/Any?> foldIn(#A1, kotlin/Function2<#A1, com.jakewharton.mosaic.modifier/Modifier.Element, #A1>): #A1 // com.jakewharton.mosaic.modifier/CombinedModifier.foldIn|foldIn(0:0;kotlin.Function2<0:0,com.jakewharton.mosaic.modifier.Modifier.Element,0:0>){0§}[0] + final fun <#A1: kotlin/Any?> foldOut(#A1, kotlin/Function2): #A1 // com.jakewharton.mosaic.modifier/CombinedModifier.foldOut|foldOut(0:0;kotlin.Function2){0§}[0] + final fun all(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/CombinedModifier.all|all(kotlin.Function1){}[0] + final fun any(kotlin/Function1): kotlin/Boolean // com.jakewharton.mosaic.modifier/CombinedModifier.any|any(kotlin.Function1){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.modifier/CombinedModifier.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.modifier/CombinedModifier.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.modifier/CombinedModifier.toString|toString(){}[0] +} + +final class com.jakewharton.mosaic.text/AnnotatedString : kotlin/CharSequence { // com.jakewharton.mosaic.text/AnnotatedString|null[0] + final val length // com.jakewharton.mosaic.text/AnnotatedString.length|{}length[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.text/AnnotatedString.length.|(){}[0] + final val spanStyles // com.jakewharton.mosaic.text/AnnotatedString.spanStyles|{}spanStyles[0] + final fun (): kotlin.collections/List> // com.jakewharton.mosaic.text/AnnotatedString.spanStyles.|(){}[0] + final val text // com.jakewharton.mosaic.text/AnnotatedString.text|{}text[0] + final fun (): kotlin/String // com.jakewharton.mosaic.text/AnnotatedString.text.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.text/AnnotatedString.equals|equals(kotlin.Any?){}[0] + final fun get(kotlin/Int): kotlin/Char // com.jakewharton.mosaic.text/AnnotatedString.get|get(kotlin.Int){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.text/AnnotatedString.hashCode|hashCode(){}[0] + final fun plus(com.jakewharton.mosaic.text/AnnotatedString): com.jakewharton.mosaic.text/AnnotatedString // com.jakewharton.mosaic.text/AnnotatedString.plus|plus(com.jakewharton.mosaic.text.AnnotatedString){}[0] + final fun subSequence(kotlin/Int, kotlin/Int): com.jakewharton.mosaic.text/AnnotatedString // com.jakewharton.mosaic.text/AnnotatedString.subSequence|subSequence(kotlin.Int;kotlin.Int){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.text/AnnotatedString.toString|toString(){}[0] + + final class <#A1: kotlin/Any?> Range { // com.jakewharton.mosaic.text/AnnotatedString.Range|null[0] + constructor (#A1, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.text/AnnotatedString.Range.|(1:0;kotlin.Int;kotlin.Int){}[0] + + final val end // com.jakewharton.mosaic.text/AnnotatedString.Range.end|{}end[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.text/AnnotatedString.Range.end.|(){}[0] + final val item // com.jakewharton.mosaic.text/AnnotatedString.Range.item|{}item[0] + final fun (): #A1 // com.jakewharton.mosaic.text/AnnotatedString.Range.item.|(){}[0] + final val start // com.jakewharton.mosaic.text/AnnotatedString.Range.start|{}start[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.text/AnnotatedString.Range.start.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.text/AnnotatedString.Range.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.text/AnnotatedString.Range.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.text/AnnotatedString.Range.toString|toString(){}[0] + } + + final class Builder : kotlin.text/Appendable { // com.jakewharton.mosaic.text/AnnotatedString.Builder|null[0] + constructor (com.jakewharton.mosaic.text/AnnotatedString) // com.jakewharton.mosaic.text/AnnotatedString.Builder.|(com.jakewharton.mosaic.text.AnnotatedString){}[0] + constructor (kotlin/Int = ...) // com.jakewharton.mosaic.text/AnnotatedString.Builder.|(kotlin.Int){}[0] + constructor (kotlin/String) // com.jakewharton.mosaic.text/AnnotatedString.Builder.|(kotlin.String){}[0] + + final val length // com.jakewharton.mosaic.text/AnnotatedString.Builder.length|{}length[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.text/AnnotatedString.Builder.length.|(){}[0] + + final fun addStyle(com.jakewharton.mosaic.text/SpanStyle, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.text/AnnotatedString.Builder.addStyle|addStyle(com.jakewharton.mosaic.text.SpanStyle;kotlin.Int;kotlin.Int){}[0] + final fun append(com.jakewharton.mosaic.text/AnnotatedString) // com.jakewharton.mosaic.text/AnnotatedString.Builder.append|append(com.jakewharton.mosaic.text.AnnotatedString){}[0] + final fun append(com.jakewharton.mosaic.text/AnnotatedString, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.text/AnnotatedString.Builder.append|append(com.jakewharton.mosaic.text.AnnotatedString;kotlin.Int;kotlin.Int){}[0] + final fun append(kotlin/Char): com.jakewharton.mosaic.text/AnnotatedString.Builder // com.jakewharton.mosaic.text/AnnotatedString.Builder.append|append(kotlin.Char){}[0] + final fun append(kotlin/CharSequence?): com.jakewharton.mosaic.text/AnnotatedString.Builder // com.jakewharton.mosaic.text/AnnotatedString.Builder.append|append(kotlin.CharSequence?){}[0] + final fun append(kotlin/CharSequence?, kotlin/Int, kotlin/Int): com.jakewharton.mosaic.text/AnnotatedString.Builder // com.jakewharton.mosaic.text/AnnotatedString.Builder.append|append(kotlin.CharSequence?;kotlin.Int;kotlin.Int){}[0] + final fun append(kotlin/String) // com.jakewharton.mosaic.text/AnnotatedString.Builder.append|append(kotlin.String){}[0] + final fun pop() // com.jakewharton.mosaic.text/AnnotatedString.Builder.pop|pop(){}[0] + final fun pop(kotlin/Int) // com.jakewharton.mosaic.text/AnnotatedString.Builder.pop|pop(kotlin.Int){}[0] + final fun pushStyle(com.jakewharton.mosaic.text/SpanStyle): kotlin/Int // com.jakewharton.mosaic.text/AnnotatedString.Builder.pushStyle|pushStyle(com.jakewharton.mosaic.text.SpanStyle){}[0] + final fun toAnnotatedString(): com.jakewharton.mosaic.text/AnnotatedString // com.jakewharton.mosaic.text/AnnotatedString.Builder.toAnnotatedString|toAnnotatedString(){}[0] + } +} + +final class com.jakewharton.mosaic.text/SpanStyle { // com.jakewharton.mosaic.text/SpanStyle|null[0] + constructor (com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/TextStyle = ..., com.jakewharton.mosaic.ui/Color = ...) // com.jakewharton.mosaic.text/SpanStyle.|(com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;com.jakewharton.mosaic.ui.Color){}[0] + + final val background // com.jakewharton.mosaic.text/SpanStyle.background|{}background[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.text/SpanStyle.background.|(){}[0] + final val color // com.jakewharton.mosaic.text/SpanStyle.color|{}color[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.text/SpanStyle.color.|(){}[0] + final val textStyle // com.jakewharton.mosaic.text/SpanStyle.textStyle|{}textStyle[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.text/SpanStyle.textStyle.|(){}[0] + + final fun copy(com.jakewharton.mosaic.ui/Color = ..., com.jakewharton.mosaic.ui/TextStyle = ..., com.jakewharton.mosaic.ui/Color = ...): com.jakewharton.mosaic.text/SpanStyle // com.jakewharton.mosaic.text/SpanStyle.copy|copy(com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;com.jakewharton.mosaic.ui.Color){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.text/SpanStyle.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.text/SpanStyle.hashCode|hashCode(){}[0] + final fun merge(com.jakewharton.mosaic.text/SpanStyle? = ...): com.jakewharton.mosaic.text/SpanStyle // com.jakewharton.mosaic.text/SpanStyle.merge|merge(com.jakewharton.mosaic.text.SpanStyle?){}[0] + final fun plus(com.jakewharton.mosaic.text/SpanStyle): com.jakewharton.mosaic.text/SpanStyle // com.jakewharton.mosaic.text/SpanStyle.plus|plus(com.jakewharton.mosaic.text.SpanStyle){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.text/SpanStyle.toString|toString(){}[0] +} + +final class com.jakewharton.mosaic.ui/BiasAlignment : com.jakewharton.mosaic.ui/Alignment { // com.jakewharton.mosaic.ui/BiasAlignment|null[0] + constructor (kotlin/Float, kotlin/Float) // com.jakewharton.mosaic.ui/BiasAlignment.|(kotlin.Float;kotlin.Float){}[0] + + final val horizontalBias // com.jakewharton.mosaic.ui/BiasAlignment.horizontalBias|{}horizontalBias[0] + final fun (): kotlin/Float // com.jakewharton.mosaic.ui/BiasAlignment.horizontalBias.|(){}[0] + final val verticalBias // com.jakewharton.mosaic.ui/BiasAlignment.verticalBias|{}verticalBias[0] + final fun (): kotlin/Float // com.jakewharton.mosaic.ui/BiasAlignment.verticalBias.|(){}[0] + + final fun align(com.jakewharton.mosaic.ui.unit/IntSize, com.jakewharton.mosaic.ui.unit/IntSize): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui/BiasAlignment.align|align(com.jakewharton.mosaic.ui.unit.IntSize;com.jakewharton.mosaic.ui.unit.IntSize){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui/BiasAlignment.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui/BiasAlignment.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui/BiasAlignment.toString|toString(){}[0] + + final class Horizontal : com.jakewharton.mosaic.ui/Alignment.Horizontal { // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal|null[0] + constructor (kotlin/Float) // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal.|(kotlin.Float){}[0] + + final val bias // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal.bias|{}bias[0] + final fun (): kotlin/Float // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal.bias.|(){}[0] + + final fun align(kotlin/Int, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal.align|align(kotlin.Int;kotlin.Int){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui/BiasAlignment.Horizontal.toString|toString(){}[0] + } + + final class Vertical : com.jakewharton.mosaic.ui/Alignment.Vertical { // com.jakewharton.mosaic.ui/BiasAlignment.Vertical|null[0] + constructor (kotlin/Float) // com.jakewharton.mosaic.ui/BiasAlignment.Vertical.|(kotlin.Float){}[0] + + final val bias // com.jakewharton.mosaic.ui/BiasAlignment.Vertical.bias|{}bias[0] + final fun (): kotlin/Float // com.jakewharton.mosaic.ui/BiasAlignment.Vertical.bias.|(){}[0] + + final fun align(kotlin/Int, kotlin/Int): kotlin/Int // com.jakewharton.mosaic.ui/BiasAlignment.Vertical.align|align(kotlin.Int;kotlin.Int){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui/BiasAlignment.Vertical.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui/BiasAlignment.Vertical.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui/BiasAlignment.Vertical.toString|toString(){}[0] + } +} + +final class com.jakewharton.mosaic/Terminal { // com.jakewharton.mosaic/Terminal|null[0] + constructor (com.jakewharton.mosaic.ui.unit/IntSize) // com.jakewharton.mosaic/Terminal.|(com.jakewharton.mosaic.ui.unit.IntSize){}[0] + + final val size // com.jakewharton.mosaic/Terminal.size|{}size[0] + final fun (): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic/Terminal.size.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic/Terminal.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic/Terminal.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic/Terminal.toString|toString(){}[0] +} + +final value class com.jakewharton.mosaic.ui.unit/Constraints { // com.jakewharton.mosaic.ui.unit/Constraints|null[0] + constructor (kotlin/Long) // com.jakewharton.mosaic.ui.unit/Constraints.|(kotlin.Long){}[0] + + final val hasBoundedHeight // com.jakewharton.mosaic.ui.unit/Constraints.hasBoundedHeight|{}hasBoundedHeight[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/Constraints.hasBoundedHeight.|(){}[0] + final val hasBoundedWidth // com.jakewharton.mosaic.ui.unit/Constraints.hasBoundedWidth|{}hasBoundedWidth[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/Constraints.hasBoundedWidth.|(){}[0] + final val hasFixedHeight // com.jakewharton.mosaic.ui.unit/Constraints.hasFixedHeight|{}hasFixedHeight[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/Constraints.hasFixedHeight.|(){}[0] + final val hasFixedWidth // com.jakewharton.mosaic.ui.unit/Constraints.hasFixedWidth|{}hasFixedWidth[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/Constraints.hasFixedWidth.|(){}[0] + final val isZero // com.jakewharton.mosaic.ui.unit/Constraints.isZero|{}isZero[0] + final fun (): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/Constraints.isZero.|(){}[0] + final val maxHeight // com.jakewharton.mosaic.ui.unit/Constraints.maxHeight|{}maxHeight[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/Constraints.maxHeight.|(){}[0] + final val maxWidth // com.jakewharton.mosaic.ui.unit/Constraints.maxWidth|{}maxWidth[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/Constraints.maxWidth.|(){}[0] + final val minHeight // com.jakewharton.mosaic.ui.unit/Constraints.minHeight|{}minHeight[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/Constraints.minHeight.|(){}[0] + final val minWidth // com.jakewharton.mosaic.ui.unit/Constraints.minWidth|{}minWidth[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/Constraints.minWidth.|(){}[0] + final val value // com.jakewharton.mosaic.ui.unit/Constraints.value|{}value[0] + final fun (): kotlin/Long // com.jakewharton.mosaic.ui.unit/Constraints.value.|(){}[0] + + final fun copy(kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.ui.unit/Constraints // com.jakewharton.mosaic.ui.unit/Constraints.copy|copy(kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Int){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/Constraints.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui.unit/Constraints.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui.unit/Constraints.toString|toString(){}[0] + + final object Companion { // com.jakewharton.mosaic.ui.unit/Constraints.Companion|null[0] + final const val Infinity // com.jakewharton.mosaic.ui.unit/Constraints.Companion.Infinity|{}Infinity[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/Constraints.Companion.Infinity.|(){}[0] + + final fun fixed(kotlin/Int, kotlin/Int): com.jakewharton.mosaic.ui.unit/Constraints // com.jakewharton.mosaic.ui.unit/Constraints.Companion.fixed|fixed(kotlin.Int;kotlin.Int){}[0] + final fun fixedHeight(kotlin/Int): com.jakewharton.mosaic.ui.unit/Constraints // com.jakewharton.mosaic.ui.unit/Constraints.Companion.fixedHeight|fixedHeight(kotlin.Int){}[0] + final fun fixedWidth(kotlin/Int): com.jakewharton.mosaic.ui.unit/Constraints // com.jakewharton.mosaic.ui.unit/Constraints.Companion.fixedWidth|fixedWidth(kotlin.Int){}[0] + } +} + +final value class com.jakewharton.mosaic.ui.unit/IntOffset { // com.jakewharton.mosaic.ui.unit/IntOffset|null[0] + final val packedValue // com.jakewharton.mosaic.ui.unit/IntOffset.packedValue|{}packedValue[0] + final fun (): kotlin/Long // com.jakewharton.mosaic.ui.unit/IntOffset.packedValue.|(){}[0] + final val x // com.jakewharton.mosaic.ui.unit/IntOffset.x|{}x[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntOffset.x.|(){}[0] + final val y // com.jakewharton.mosaic.ui.unit/IntOffset.y|{}y[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntOffset.y.|(){}[0] + + final fun component1(): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntOffset.component1|component1(){}[0] + final fun component2(): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntOffset.component2|component2(){}[0] + final fun copy(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.copy|copy(kotlin.Int;kotlin.Int){}[0] + final fun div(kotlin/Float): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.div|div(kotlin.Float){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/IntOffset.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntOffset.hashCode|hashCode(){}[0] + final fun rem(kotlin/Int): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.rem|rem(kotlin.Int){}[0] + final fun times(kotlin/Float): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.times|times(kotlin.Float){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui.unit/IntOffset.toString|toString(){}[0] + final inline fun minus(com.jakewharton.mosaic.ui.unit/IntOffset): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.minus|minus(com.jakewharton.mosaic.ui.unit.IntOffset){}[0] + final inline fun plus(com.jakewharton.mosaic.ui.unit/IntOffset): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.plus|plus(com.jakewharton.mosaic.ui.unit.IntOffset){}[0] + final inline fun unaryMinus(): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.unaryMinus|unaryMinus(){}[0] + + final object Companion { // com.jakewharton.mosaic.ui.unit/IntOffset.Companion|null[0] + final val Zero // com.jakewharton.mosaic.ui.unit/IntOffset.Companion.Zero|{}Zero[0] + final fun (): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset.Companion.Zero.|(){}[0] + } +} + +final value class com.jakewharton.mosaic.ui.unit/IntSize { // com.jakewharton.mosaic.ui.unit/IntSize|null[0] + final val height // com.jakewharton.mosaic.ui.unit/IntSize.height|{}height[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntSize.height.|(){}[0] + final val packedValue // com.jakewharton.mosaic.ui.unit/IntSize.packedValue|{}packedValue[0] + final fun (): kotlin/Long // com.jakewharton.mosaic.ui.unit/IntSize.packedValue.|(){}[0] + final val width // com.jakewharton.mosaic.ui.unit/IntSize.width|{}width[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntSize.width.|(){}[0] + + final fun div(kotlin/Int): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic.ui.unit/IntSize.div|div(kotlin.Int){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/IntSize.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntSize.hashCode|hashCode(){}[0] + final fun times(kotlin/Int): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic.ui.unit/IntSize.times|times(kotlin.Int){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui.unit/IntSize.toString|toString(){}[0] + final inline fun component1(): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntSize.component1|component1(){}[0] + final inline fun component2(): kotlin/Int // com.jakewharton.mosaic.ui.unit/IntSize.component2|component2(){}[0] + + final object Companion { // com.jakewharton.mosaic.ui.unit/IntSize.Companion|null[0] + final val Zero // com.jakewharton.mosaic.ui.unit/IntSize.Companion.Zero|{}Zero[0] + final fun (): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic.ui.unit/IntSize.Companion.Zero.|(){}[0] + } +} + +final value class com.jakewharton.mosaic.ui/Color { // com.jakewharton.mosaic.ui/Color|null[0] + final val value // com.jakewharton.mosaic.ui/Color.value|{}value[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui/Color.value.|(){}[0] + + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui/Color.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui/Color.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui/Color.toString|toString(){}[0] + + final object Companion { // com.jakewharton.mosaic.ui/Color.Companion|null[0] + final val Black // com.jakewharton.mosaic.ui/Color.Companion.Black|{}Black[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Black.|(){}[0] + final val Blue // com.jakewharton.mosaic.ui/Color.Companion.Blue|{}Blue[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Blue.|(){}[0] + final val Cyan // com.jakewharton.mosaic.ui/Color.Companion.Cyan|{}Cyan[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Cyan.|(){}[0] + final val Green // com.jakewharton.mosaic.ui/Color.Companion.Green|{}Green[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Green.|(){}[0] + final val Magenta // com.jakewharton.mosaic.ui/Color.Companion.Magenta|{}Magenta[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Magenta.|(){}[0] + final val Red // com.jakewharton.mosaic.ui/Color.Companion.Red|{}Red[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Red.|(){}[0] + final val Unspecified // com.jakewharton.mosaic.ui/Color.Companion.Unspecified|{}Unspecified[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Unspecified.|(){}[0] + final val White // com.jakewharton.mosaic.ui/Color.Companion.White|{}White[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.White.|(){}[0] + final val Yellow // com.jakewharton.mosaic.ui/Color.Companion.Yellow|{}Yellow[0] + final fun (): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color.Companion.Yellow.|(){}[0] + } +} + +final value class com.jakewharton.mosaic.ui/TextStyle { // com.jakewharton.mosaic.ui/TextStyle|null[0] + final val bits // com.jakewharton.mosaic.ui/TextStyle.bits|{}bits[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui/TextStyle.bits.|(){}[0] + + final fun contains(com.jakewharton.mosaic.ui/TextStyle): kotlin/Boolean // com.jakewharton.mosaic.ui/TextStyle.contains|contains(com.jakewharton.mosaic.ui.TextStyle){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // com.jakewharton.mosaic.ui/TextStyle.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // com.jakewharton.mosaic.ui/TextStyle.hashCode|hashCode(){}[0] + final fun plus(com.jakewharton.mosaic.ui/TextStyle): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.plus|plus(com.jakewharton.mosaic.ui.TextStyle){}[0] + final fun toString(): kotlin/String // com.jakewharton.mosaic.ui/TextStyle.toString|toString(){}[0] + + final object Companion { // com.jakewharton.mosaic.ui/TextStyle.Companion|null[0] + final val Bold // com.jakewharton.mosaic.ui/TextStyle.Companion.Bold|{}Bold[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Bold.|(){}[0] + final val Dim // com.jakewharton.mosaic.ui/TextStyle.Companion.Dim|{}Dim[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Dim.|(){}[0] + final val Empty // com.jakewharton.mosaic.ui/TextStyle.Companion.Empty|{}Empty[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Empty.|(){}[0] + final val Invert // com.jakewharton.mosaic.ui/TextStyle.Companion.Invert|{}Invert[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Invert.|(){}[0] + final val Italic // com.jakewharton.mosaic.ui/TextStyle.Companion.Italic|{}Italic[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Italic.|(){}[0] + final val Strikethrough // com.jakewharton.mosaic.ui/TextStyle.Companion.Strikethrough|{}Strikethrough[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Strikethrough.|(){}[0] + final val Underline // com.jakewharton.mosaic.ui/TextStyle.Companion.Underline|{}Underline[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Underline.|(){}[0] + final val Unspecified // com.jakewharton.mosaic.ui/TextStyle.Companion.Unspecified|{}Unspecified[0] + final fun (): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/TextStyle.Companion.Unspecified.|(){}[0] + } +} + +final object com.jakewharton.mosaic.ui/Arrangement { // com.jakewharton.mosaic.ui/Arrangement|null[0] + final val Bottom // com.jakewharton.mosaic.ui/Arrangement.Bottom|{}Bottom[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Vertical // com.jakewharton.mosaic.ui/Arrangement.Bottom.|(){}[0] + final val Center // com.jakewharton.mosaic.ui/Arrangement.Center|{}Center[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical // com.jakewharton.mosaic.ui/Arrangement.Center.|(){}[0] + final val End // com.jakewharton.mosaic.ui/Arrangement.End|{}End[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.End.|(){}[0] + final val SpaceAround // com.jakewharton.mosaic.ui/Arrangement.SpaceAround|{}SpaceAround[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical // com.jakewharton.mosaic.ui/Arrangement.SpaceAround.|(){}[0] + final val SpaceBetween // com.jakewharton.mosaic.ui/Arrangement.SpaceBetween|{}SpaceBetween[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical // com.jakewharton.mosaic.ui/Arrangement.SpaceBetween.|(){}[0] + final val SpaceEvenly // com.jakewharton.mosaic.ui/Arrangement.SpaceEvenly|{}SpaceEvenly[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical // com.jakewharton.mosaic.ui/Arrangement.SpaceEvenly.|(){}[0] + final val Start // com.jakewharton.mosaic.ui/Arrangement.Start|{}Start[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Start.|(){}[0] + final val Top // com.jakewharton.mosaic.ui/Arrangement.Top|{}Top[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Vertical // com.jakewharton.mosaic.ui/Arrangement.Top.|(){}[0] + + final fun aligned(com.jakewharton.mosaic.ui/Alignment.Horizontal): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.aligned|aligned(com.jakewharton.mosaic.ui.Alignment.Horizontal){}[0] + final fun aligned(com.jakewharton.mosaic.ui/Alignment.Vertical): com.jakewharton.mosaic.ui/Arrangement.Vertical // com.jakewharton.mosaic.ui/Arrangement.aligned|aligned(com.jakewharton.mosaic.ui.Alignment.Vertical){}[0] + final fun spacedBy(kotlin/Int): com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical // com.jakewharton.mosaic.ui/Arrangement.spacedBy|spacedBy(kotlin.Int){}[0] + final fun spacedBy(kotlin/Int, com.jakewharton.mosaic.ui/Alignment.Horizontal): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.spacedBy|spacedBy(kotlin.Int;com.jakewharton.mosaic.ui.Alignment.Horizontal){}[0] + final fun spacedBy(kotlin/Int, com.jakewharton.mosaic.ui/Alignment.Vertical): com.jakewharton.mosaic.ui/Arrangement.Vertical // com.jakewharton.mosaic.ui/Arrangement.spacedBy|spacedBy(kotlin.Int;com.jakewharton.mosaic.ui.Alignment.Vertical){}[0] + + abstract interface Horizontal { // com.jakewharton.mosaic.ui/Arrangement.Horizontal|null[0] + open val spacing // com.jakewharton.mosaic.ui/Arrangement.Horizontal.spacing|{}spacing[0] + open fun (): kotlin/Int // com.jakewharton.mosaic.ui/Arrangement.Horizontal.spacing.|(){}[0] + + abstract fun arrange(kotlin/Int, kotlin/IntArray, kotlin/IntArray) // com.jakewharton.mosaic.ui/Arrangement.Horizontal.arrange|arrange(kotlin.Int;kotlin.IntArray;kotlin.IntArray){}[0] + } + + abstract interface HorizontalOrVertical : com.jakewharton.mosaic.ui/Arrangement.Horizontal, com.jakewharton.mosaic.ui/Arrangement.Vertical { // com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical|null[0] + open val spacing // com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical.spacing|{}spacing[0] + open fun (): kotlin/Int // com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical.spacing.|(){}[0] + } + + abstract interface Vertical { // com.jakewharton.mosaic.ui/Arrangement.Vertical|null[0] + open val spacing // com.jakewharton.mosaic.ui/Arrangement.Vertical.spacing|{}spacing[0] + open fun (): kotlin/Int // com.jakewharton.mosaic.ui/Arrangement.Vertical.spacing.|(){}[0] + + abstract fun arrange(kotlin/Int, kotlin/IntArray, kotlin/IntArray) // com.jakewharton.mosaic.ui/Arrangement.Vertical.arrange|arrange(kotlin.Int;kotlin.IntArray;kotlin.IntArray){}[0] + } + + final object Absolute { // com.jakewharton.mosaic.ui/Arrangement.Absolute|null[0] + final val Center // com.jakewharton.mosaic.ui/Arrangement.Absolute.Center|{}Center[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.Center.|(){}[0] + final val Left // com.jakewharton.mosaic.ui/Arrangement.Absolute.Left|{}Left[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.Left.|(){}[0] + final val Right // com.jakewharton.mosaic.ui/Arrangement.Absolute.Right|{}Right[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.Right.|(){}[0] + final val SpaceAround // com.jakewharton.mosaic.ui/Arrangement.Absolute.SpaceAround|{}SpaceAround[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.SpaceAround.|(){}[0] + final val SpaceBetween // com.jakewharton.mosaic.ui/Arrangement.Absolute.SpaceBetween|{}SpaceBetween[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.SpaceBetween.|(){}[0] + final val SpaceEvenly // com.jakewharton.mosaic.ui/Arrangement.Absolute.SpaceEvenly|{}SpaceEvenly[0] + final fun (): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.SpaceEvenly.|(){}[0] + + final fun aligned(com.jakewharton.mosaic.ui/Alignment.Horizontal): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.aligned|aligned(com.jakewharton.mosaic.ui.Alignment.Horizontal){}[0] + final fun spacedBy(kotlin/Int): com.jakewharton.mosaic.ui/Arrangement.HorizontalOrVertical // com.jakewharton.mosaic.ui/Arrangement.Absolute.spacedBy|spacedBy(kotlin.Int){}[0] + final fun spacedBy(kotlin/Int, com.jakewharton.mosaic.ui/Alignment.Horizontal): com.jakewharton.mosaic.ui/Arrangement.Horizontal // com.jakewharton.mosaic.ui/Arrangement.Absolute.spacedBy|spacedBy(kotlin.Int;com.jakewharton.mosaic.ui.Alignment.Horizontal){}[0] + final fun spacedBy(kotlin/Int, com.jakewharton.mosaic.ui/Alignment.Vertical): com.jakewharton.mosaic.ui/Arrangement.Vertical // com.jakewharton.mosaic.ui/Arrangement.Absolute.spacedBy|spacedBy(kotlin.Int;com.jakewharton.mosaic.ui.Alignment.Vertical){}[0] + } +} + +final const val com.jakewharton.mosaic.ui/EmptyTextStyle // com.jakewharton.mosaic.ui/EmptyTextStyle|{}EmptyTextStyle[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui/EmptyTextStyle.|(){}[0] +final const val com.jakewharton.mosaic.ui/UnspecifiedColor // com.jakewharton.mosaic.ui/UnspecifiedColor|{}UnspecifiedColor[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui/UnspecifiedColor.|(){}[0] +final const val com.jakewharton.mosaic.ui/UnspecifiedTextStyle // com.jakewharton.mosaic.ui/UnspecifiedTextStyle|{}UnspecifiedTextStyle[0] + final fun (): kotlin/Int // com.jakewharton.mosaic.ui/UnspecifiedTextStyle.|(){}[0] + +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Fill$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Fill$stableprop|#static{}com_jakewharton_mosaic_layout_DrawStyle_Fill$stableprop[0] +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Stroke$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Stroke$stableprop|#static{}com_jakewharton_mosaic_layout_DrawStyle_Stroke$stableprop[0] +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_KeyEvent$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_KeyEvent$stableprop|#static{}com_jakewharton_mosaic_layout_KeyEvent$stableprop[0] +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNode$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNode$stableprop|#static{}com_jakewharton_mosaic_layout_MosaicNode$stableprop[0] +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNodeLayer$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNodeLayer$stableprop|#static{}com_jakewharton_mosaic_layout_MosaicNodeLayer$stableprop[0] +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_NotMeasured$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_NotMeasured$stableprop|#static{}com_jakewharton_mosaic_layout_NotMeasured$stableprop[0] +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_Placeable$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_Placeable$stableprop|#static{}com_jakewharton_mosaic_layout_Placeable$stableprop[0] +final val com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_TextCanvasDrawScope$stableprop // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_TextCanvasDrawScope$stableprop|#static{}com_jakewharton_mosaic_layout_TextCanvasDrawScope$stableprop[0] +final val com.jakewharton.mosaic.modifier/com_jakewharton_mosaic_modifier_CombinedModifier$stableprop // com.jakewharton.mosaic.modifier/com_jakewharton_mosaic_modifier_CombinedModifier$stableprop|#static{}com_jakewharton_mosaic_modifier_CombinedModifier$stableprop[0] +final val com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString$stableprop // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString$stableprop|#static{}com_jakewharton_mosaic_text_AnnotatedString$stableprop[0] +final val com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedStringTextLayout$stableprop // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedStringTextLayout$stableprop|#static{}com_jakewharton_mosaic_text_AnnotatedStringTextLayout$stableprop[0] +final val com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Builder$stableprop // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Builder$stableprop|#static{}com_jakewharton_mosaic_text_AnnotatedString_Builder$stableprop[0] +final val com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Range$stableprop // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Range$stableprop|#static{}com_jakewharton_mosaic_text_AnnotatedString_Range$stableprop[0] +final val com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_SpanStyle$stableprop // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_SpanStyle$stableprop|#static{}com_jakewharton_mosaic_text_SpanStyle$stableprop[0] +final val com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_StringTextLayout$stableprop // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_StringTextLayout$stableprop|#static{}com_jakewharton_mosaic_text_StringTextLayout$stableprop[0] +final val com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_TextLayout$stableprop // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_TextLayout$stableprop|#static{}com_jakewharton_mosaic_text_TextLayout$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement$stableprop|#static{}com_jakewharton_mosaic_ui_Arrangement$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_Absolute$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_Absolute$stableprop|#static{}com_jakewharton_mosaic_ui_Arrangement_Absolute$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_SpacedAligned$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_SpacedAligned$stableprop|#static{}com_jakewharton_mosaic_ui_Arrangement_SpacedAligned$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment$stableprop|#static{}com_jakewharton_mosaic_ui_BiasAlignment$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Horizontal$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Horizontal$stableprop|#static{}com_jakewharton_mosaic_ui_BiasAlignment_Horizontal$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Vertical$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Vertical$stableprop|#static{}com_jakewharton_mosaic_ui_BiasAlignment_Vertical$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BoxMeasurePolicy$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BoxMeasurePolicy$stableprop|#static{}com_jakewharton_mosaic_ui_BoxMeasurePolicy$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_ColumnScopeInstance$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_ColumnScopeInstance$stableprop|#static{}com_jakewharton_mosaic_ui_ColumnScopeInstance$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_CrossAxisAlignment$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_CrossAxisAlignment$stableprop|#static{}com_jakewharton_mosaic_ui_CrossAxisAlignment$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_DefaultIntrinsicMeasurable$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_DefaultIntrinsicMeasurable$stableprop|#static{}com_jakewharton_mosaic_ui_DefaultIntrinsicMeasurable$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_HorizontalAlignModifier$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_HorizontalAlignModifier$stableprop|#static{}com_jakewharton_mosaic_ui_HorizontalAlignModifier$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_IntrinsicsMeasureScope$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_IntrinsicsMeasureScope$stableprop|#static{}com_jakewharton_mosaic_ui_IntrinsicsMeasureScope$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_LayoutWeightModifier$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_LayoutWeightModifier$stableprop|#static{}com_jakewharton_mosaic_ui_LayoutWeightModifier$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_NoContentMeasureScope$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_NoContentMeasureScope$stableprop|#static{}com_jakewharton_mosaic_ui_NoContentMeasureScope$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasureHelperResult$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasureHelperResult$stableprop|#static{}com_jakewharton_mosaic_ui_RowColumnMeasureHelperResult$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurePolicy$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurePolicy$stableprop|#static{}com_jakewharton_mosaic_ui_RowColumnMeasurePolicy$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurementHelper$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurementHelper$stableprop|#static{}com_jakewharton_mosaic_ui_RowColumnMeasurementHelper$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnParentData$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnParentData$stableprop|#static{}com_jakewharton_mosaic_ui_RowColumnParentData$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowScopeInstance$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowScopeInstance$stableprop|#static{}com_jakewharton_mosaic_ui_RowScopeInstance$stableprop[0] +final val com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_VerticalAlignModifier$stableprop // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_VerticalAlignModifier$stableprop|#static{}com_jakewharton_mosaic_ui_VerticalAlignModifier$stableprop[0] +final val com.jakewharton.mosaic.ui/isEmptyTextStyle // com.jakewharton.mosaic.ui/isEmptyTextStyle|@com.jakewharton.mosaic.ui.TextStyle{}isEmptyTextStyle[0] + final inline fun (com.jakewharton.mosaic.ui/TextStyle).(): kotlin/Boolean // com.jakewharton.mosaic.ui/isEmptyTextStyle.|@com.jakewharton.mosaic.ui.TextStyle(){}[0] +final val com.jakewharton.mosaic.ui/isNotEmptyTextStyle // com.jakewharton.mosaic.ui/isNotEmptyTextStyle|@com.jakewharton.mosaic.ui.TextStyle{}isNotEmptyTextStyle[0] + final inline fun (com.jakewharton.mosaic.ui/TextStyle).(): kotlin/Boolean // com.jakewharton.mosaic.ui/isNotEmptyTextStyle.|@com.jakewharton.mosaic.ui.TextStyle(){}[0] +final val com.jakewharton.mosaic.ui/isSpecifiedColor // com.jakewharton.mosaic.ui/isSpecifiedColor|@com.jakewharton.mosaic.ui.Color{}isSpecifiedColor[0] + final inline fun (com.jakewharton.mosaic.ui/Color).(): kotlin/Boolean // com.jakewharton.mosaic.ui/isSpecifiedColor.|@com.jakewharton.mosaic.ui.Color(){}[0] +final val com.jakewharton.mosaic.ui/isSpecifiedTextStyle // com.jakewharton.mosaic.ui/isSpecifiedTextStyle|@com.jakewharton.mosaic.ui.TextStyle{}isSpecifiedTextStyle[0] + final inline fun (com.jakewharton.mosaic.ui/TextStyle).(): kotlin/Boolean // com.jakewharton.mosaic.ui/isSpecifiedTextStyle.|@com.jakewharton.mosaic.ui.TextStyle(){}[0] +final val com.jakewharton.mosaic.ui/isUnspecifiedColor // com.jakewharton.mosaic.ui/isUnspecifiedColor|@com.jakewharton.mosaic.ui.Color{}isUnspecifiedColor[0] + final inline fun (com.jakewharton.mosaic.ui/Color).(): kotlin/Boolean // com.jakewharton.mosaic.ui/isUnspecifiedColor.|@com.jakewharton.mosaic.ui.Color(){}[0] +final val com.jakewharton.mosaic.ui/isUnspecifiedTextStyle // com.jakewharton.mosaic.ui/isUnspecifiedTextStyle|@com.jakewharton.mosaic.ui.TextStyle{}isUnspecifiedTextStyle[0] + final inline fun (com.jakewharton.mosaic.ui/TextStyle).(): kotlin/Boolean // com.jakewharton.mosaic.ui/isUnspecifiedTextStyle.|@com.jakewharton.mosaic.ui.TextStyle(){}[0] +final val com.jakewharton.mosaic/LocalTerminal // com.jakewharton.mosaic/LocalTerminal|{}LocalTerminal[0] + final fun (): androidx.compose.runtime/ProvidableCompositionLocal // com.jakewharton.mosaic/LocalTerminal.|(){}[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_AnsiRendering$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_AnsiRendering$stableprop|#static{}com_jakewharton_mosaic_AnsiRendering$stableprop[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_DebugRendering$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_DebugRendering$stableprop|#static{}com_jakewharton_mosaic_DebugRendering$stableprop[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_GlobalSnapshotManager$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_GlobalSnapshotManager$stableprop|#static{}com_jakewharton_mosaic_GlobalSnapshotManager$stableprop[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop|#static{}com_jakewharton_mosaic_MosaicComposition$stableprop[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop|#static{}com_jakewharton_mosaic_MosaicNodeApplier$stableprop[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop|#static{}com_jakewharton_mosaic_Terminal$stableprop[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop|#static{}com_jakewharton_mosaic_TextPixel$stableprop[0] +final val com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop // com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop|#static{}com_jakewharton_mosaic_TextSurface$stableprop[0] + +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/aspectRatio(kotlin/Float, kotlin/Boolean = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/aspectRatio|aspectRatio@com.jakewharton.mosaic.modifier.Modifier(kotlin.Float;kotlin.Boolean){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/background(com.jakewharton.mosaic.ui/Color): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/background|background@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.Color){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/defaultMinSize(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/defaultMinSize|defaultMinSize@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/drawBehind(kotlin/Function1): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/drawBehind|drawBehind@com.jakewharton.mosaic.modifier.Modifier(kotlin.Function1){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/fillMaxHeight(kotlin/Float = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/fillMaxHeight|fillMaxHeight@com.jakewharton.mosaic.modifier.Modifier(kotlin.Float){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/fillMaxSize(kotlin/Float = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/fillMaxSize|fillMaxSize@com.jakewharton.mosaic.modifier.Modifier(kotlin.Float){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/fillMaxWidth(kotlin/Float = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/fillMaxWidth|fillMaxWidth@com.jakewharton.mosaic.modifier.Modifier(kotlin.Float){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/height(kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/height|height@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/heightIn(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/heightIn|heightIn@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/layout(kotlin/Function3): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/layout|layout@com.jakewharton.mosaic.modifier.Modifier(kotlin.Function3){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/offset(kotlin/Function0): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/offset|offset@com.jakewharton.mosaic.modifier.Modifier(kotlin.Function0){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/offset(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/offset|offset@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/onKeyEvent(kotlin/Function1): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/onKeyEvent|onKeyEvent@com.jakewharton.mosaic.modifier.Modifier(kotlin.Function1){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/onPreviewKeyEvent(kotlin/Function1): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/onPreviewKeyEvent|onPreviewKeyEvent@com.jakewharton.mosaic.modifier.Modifier(kotlin.Function1){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/padding(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/padding|padding@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/padding(kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/padding|padding@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/padding(kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/padding|padding@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredHeight(kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredHeight|requiredHeight@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredHeightIn(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredHeightIn|requiredHeightIn@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredSize(com.jakewharton.mosaic.ui.unit/IntSize): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredSize|requiredSize@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.unit.IntSize){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredSize(kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredSize|requiredSize@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredSize(kotlin/Int, kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredSize|requiredSize@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredSizeIn(kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredSizeIn|requiredSizeIn@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredWidth(kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredWidth|requiredWidth@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/requiredWidthIn(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/requiredWidthIn|requiredWidthIn@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/size(com.jakewharton.mosaic.ui.unit/IntSize): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/size|size@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.unit.IntSize){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/size(kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/size|size@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/size(kotlin/Int, kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/size|size@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/sizeIn(kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/sizeIn|sizeIn@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/width(kotlin/Int): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/width|width@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/widthIn(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/widthIn|widthIn@com.jakewharton.mosaic.modifier.Modifier(kotlin.Int;kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/wrapContentHeight(com.jakewharton.mosaic.ui/Alignment.Vertical = ..., kotlin/Boolean = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/wrapContentHeight|wrapContentHeight@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.Alignment.Vertical;kotlin.Boolean){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/wrapContentSize(com.jakewharton.mosaic.ui/Alignment = ..., kotlin/Boolean = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/wrapContentSize|wrapContentSize@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.Alignment;kotlin.Boolean){}[0] +final fun (com.jakewharton.mosaic.modifier/Modifier).com.jakewharton.mosaic.layout/wrapContentWidth(com.jakewharton.mosaic.ui/Alignment.Horizontal = ..., kotlin/Boolean = ...): com.jakewharton.mosaic.modifier/Modifier // com.jakewharton.mosaic.layout/wrapContentWidth|wrapContentWidth@com.jakewharton.mosaic.modifier.Modifier(com.jakewharton.mosaic.ui.Alignment.Horizontal;kotlin.Boolean){}[0] +final fun (com.jakewharton.mosaic.ui.unit/Constraints).com.jakewharton.mosaic.ui.unit/constrain(com.jakewharton.mosaic.ui.unit/Constraints): com.jakewharton.mosaic.ui.unit/Constraints // com.jakewharton.mosaic.ui.unit/constrain|constrain@com.jakewharton.mosaic.ui.unit.Constraints(com.jakewharton.mosaic.ui.unit.Constraints){}[0] +final fun (com.jakewharton.mosaic.ui.unit/Constraints).com.jakewharton.mosaic.ui.unit/constrain(com.jakewharton.mosaic.ui.unit/IntSize): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic.ui.unit/constrain|constrain@com.jakewharton.mosaic.ui.unit.Constraints(com.jakewharton.mosaic.ui.unit.IntSize){}[0] +final fun (com.jakewharton.mosaic.ui.unit/Constraints).com.jakewharton.mosaic.ui.unit/constrainHeight(kotlin/Int): kotlin/Int // com.jakewharton.mosaic.ui.unit/constrainHeight|constrainHeight@com.jakewharton.mosaic.ui.unit.Constraints(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.ui.unit/Constraints).com.jakewharton.mosaic.ui.unit/constrainWidth(kotlin/Int): kotlin/Int // com.jakewharton.mosaic.ui.unit/constrainWidth|constrainWidth@com.jakewharton.mosaic.ui.unit.Constraints(kotlin.Int){}[0] +final fun (com.jakewharton.mosaic.ui.unit/Constraints).com.jakewharton.mosaic.ui.unit/isSatisfiedBy(com.jakewharton.mosaic.ui.unit/IntSize): kotlin/Boolean // com.jakewharton.mosaic.ui.unit/isSatisfiedBy|isSatisfiedBy@com.jakewharton.mosaic.ui.unit.Constraints(com.jakewharton.mosaic.ui.unit.IntSize){}[0] +final fun (com.jakewharton.mosaic.ui.unit/Constraints).com.jakewharton.mosaic.ui.unit/offset(kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.ui.unit/Constraints // com.jakewharton.mosaic.ui.unit/offset|offset@com.jakewharton.mosaic.ui.unit.Constraints(kotlin.Int;kotlin.Int){}[0] +final fun <#A: kotlin/Any?> com.jakewharton.mosaic.ui/Static(androidx.compose.runtime.snapshots/SnapshotStateList<#A>, kotlin/Function3<#A, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int) // com.jakewharton.mosaic.ui/Static|Static(androidx.compose.runtime.snapshots.SnapshotStateList<0:0>;kotlin.Function3<0:0,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int){0§}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Fill$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Fill$stableprop_getter|com_jakewharton_mosaic_layout_DrawStyle_Fill$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Stroke$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_DrawStyle_Stroke$stableprop_getter|com_jakewharton_mosaic_layout_DrawStyle_Stroke$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_KeyEvent$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_KeyEvent$stableprop_getter|com_jakewharton_mosaic_layout_KeyEvent$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNode$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNode$stableprop_getter|com_jakewharton_mosaic_layout_MosaicNode$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNodeLayer$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_MosaicNodeLayer$stableprop_getter|com_jakewharton_mosaic_layout_MosaicNodeLayer$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_NotMeasured$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_NotMeasured$stableprop_getter|com_jakewharton_mosaic_layout_NotMeasured$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_Placeable$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_Placeable$stableprop_getter|com_jakewharton_mosaic_layout_Placeable$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_TextCanvasDrawScope$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.layout/com_jakewharton_mosaic_layout_TextCanvasDrawScope$stableprop_getter|com_jakewharton_mosaic_layout_TextCanvasDrawScope$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.modifier/com_jakewharton_mosaic_modifier_CombinedModifier$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.modifier/com_jakewharton_mosaic_modifier_CombinedModifier$stableprop_getter|com_jakewharton_mosaic_modifier_CombinedModifier$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.text/AnnotatedString(kotlin/String, com.jakewharton.mosaic.text/SpanStyle): com.jakewharton.mosaic.text/AnnotatedString // com.jakewharton.mosaic.text/AnnotatedString|AnnotatedString(kotlin.String;com.jakewharton.mosaic.text.SpanStyle){}[0] +final fun com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString$stableprop_getter|com_jakewharton_mosaic_text_AnnotatedString$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedStringTextLayout$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedStringTextLayout$stableprop_getter|com_jakewharton_mosaic_text_AnnotatedStringTextLayout$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Builder$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Builder$stableprop_getter|com_jakewharton_mosaic_text_AnnotatedString_Builder$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Range$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_AnnotatedString_Range$stableprop_getter|com_jakewharton_mosaic_text_AnnotatedString_Range$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_SpanStyle$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_SpanStyle$stableprop_getter|com_jakewharton_mosaic_text_SpanStyle$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_StringTextLayout$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_StringTextLayout$stableprop_getter|com_jakewharton_mosaic_text_StringTextLayout$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_TextLayout$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.text/com_jakewharton_mosaic_text_TextLayout$stableprop_getter|com_jakewharton_mosaic_text_TextLayout$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui.unit/Constraints(kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ...): com.jakewharton.mosaic.ui.unit/Constraints // com.jakewharton.mosaic.ui.unit/Constraints|Constraints(kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui.unit/IntOffset(kotlin/Int, kotlin/Int): com.jakewharton.mosaic.ui.unit/IntOffset // com.jakewharton.mosaic.ui.unit/IntOffset|IntOffset(kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui.unit/IntSize(kotlin/Int, kotlin/Int): com.jakewharton.mosaic.ui.unit/IntSize // com.jakewharton.mosaic.ui.unit/IntSize|IntSize(kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Box(com.jakewharton.mosaic.modifier/Modifier?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Box|Box(com.jakewharton.mosaic.modifier.Modifier?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Box(com.jakewharton.mosaic.modifier/Modifier?, com.jakewharton.mosaic.ui/Alignment?, kotlin/Boolean, kotlin/Function3, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Box|Box(com.jakewharton.mosaic.modifier.Modifier?;com.jakewharton.mosaic.ui.Alignment?;kotlin.Boolean;kotlin.Function3;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Color(kotlin/Float, kotlin/Float, kotlin/Float): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color|Color(kotlin.Float;kotlin.Float;kotlin.Float){}[0] +final fun com.jakewharton.mosaic.ui/Color(kotlin/Int, kotlin/Int, kotlin/Int): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/Color|Color(kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Column(com.jakewharton.mosaic.modifier/Modifier?, com.jakewharton.mosaic.ui/Arrangement.Vertical?, com.jakewharton.mosaic.ui/Alignment.Horizontal?, kotlin/Function3, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Column|Column(com.jakewharton.mosaic.modifier.Modifier?;com.jakewharton.mosaic.ui.Arrangement.Vertical?;com.jakewharton.mosaic.ui.Alignment.Horizontal?;kotlin.Function3;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Filler(kotlin/Char, com.jakewharton.mosaic.modifier/Modifier?, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/TextStyle, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Filler|Filler(kotlin.Char;com.jakewharton.mosaic.modifier.Modifier?;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Filler(kotlin/Int, com.jakewharton.mosaic.modifier/Modifier?, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/TextStyle, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Filler|Filler(kotlin.Int;com.jakewharton.mosaic.modifier.Modifier?;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Layout(kotlin/Function2, com.jakewharton.mosaic.modifier/Modifier?, kotlin/Function0?, com.jakewharton.mosaic.layout/MeasurePolicy, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Layout|Layout(kotlin.Function2;com.jakewharton.mosaic.modifier.Modifier?;kotlin.Function0?;com.jakewharton.mosaic.layout.MeasurePolicy;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Row(com.jakewharton.mosaic.modifier/Modifier?, com.jakewharton.mosaic.ui/Arrangement.Horizontal?, com.jakewharton.mosaic.ui/Alignment.Vertical?, kotlin/Function3, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Row|Row(com.jakewharton.mosaic.modifier.Modifier?;com.jakewharton.mosaic.ui.Arrangement.Horizontal?;com.jakewharton.mosaic.ui.Alignment.Vertical?;kotlin.Function3;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Spacer(com.jakewharton.mosaic.modifier/Modifier?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Spacer|Spacer(com.jakewharton.mosaic.modifier.Modifier?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Text(com.jakewharton.mosaic.text/AnnotatedString, com.jakewharton.mosaic.modifier/Modifier?, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/TextStyle, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Text|Text(com.jakewharton.mosaic.text.AnnotatedString;com.jakewharton.mosaic.modifier.Modifier?;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/Text(kotlin/String, com.jakewharton.mosaic.modifier/Modifier?, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/Color, com.jakewharton.mosaic.ui/TextStyle, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.jakewharton.mosaic.ui/Text|Text(kotlin.String;com.jakewharton.mosaic.modifier.Modifier?;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.Color;com.jakewharton.mosaic.ui.TextStyle;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement$stableprop_getter|com_jakewharton_mosaic_ui_Arrangement$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_Absolute$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_Absolute$stableprop_getter|com_jakewharton_mosaic_ui_Arrangement_Absolute$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_SpacedAligned$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_Arrangement_SpacedAligned$stableprop_getter|com_jakewharton_mosaic_ui_Arrangement_SpacedAligned$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment$stableprop_getter|com_jakewharton_mosaic_ui_BiasAlignment$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Horizontal$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Horizontal$stableprop_getter|com_jakewharton_mosaic_ui_BiasAlignment_Horizontal$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Vertical$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BiasAlignment_Vertical$stableprop_getter|com_jakewharton_mosaic_ui_BiasAlignment_Vertical$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BoxMeasurePolicy$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_BoxMeasurePolicy$stableprop_getter|com_jakewharton_mosaic_ui_BoxMeasurePolicy$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_ColumnScopeInstance$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_ColumnScopeInstance$stableprop_getter|com_jakewharton_mosaic_ui_ColumnScopeInstance$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_CrossAxisAlignment$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_CrossAxisAlignment$stableprop_getter|com_jakewharton_mosaic_ui_CrossAxisAlignment$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_DefaultIntrinsicMeasurable$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_DefaultIntrinsicMeasurable$stableprop_getter|com_jakewharton_mosaic_ui_DefaultIntrinsicMeasurable$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_HorizontalAlignModifier$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_HorizontalAlignModifier$stableprop_getter|com_jakewharton_mosaic_ui_HorizontalAlignModifier$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_IntrinsicsMeasureScope$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_IntrinsicsMeasureScope$stableprop_getter|com_jakewharton_mosaic_ui_IntrinsicsMeasureScope$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_LayoutWeightModifier$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_LayoutWeightModifier$stableprop_getter|com_jakewharton_mosaic_ui_LayoutWeightModifier$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_NoContentMeasureScope$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_NoContentMeasureScope$stableprop_getter|com_jakewharton_mosaic_ui_NoContentMeasureScope$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasureHelperResult$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasureHelperResult$stableprop_getter|com_jakewharton_mosaic_ui_RowColumnMeasureHelperResult$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurePolicy$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurePolicy$stableprop_getter|com_jakewharton_mosaic_ui_RowColumnMeasurePolicy$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurementHelper$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnMeasurementHelper$stableprop_getter|com_jakewharton_mosaic_ui_RowColumnMeasurementHelper$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnParentData$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowColumnParentData$stableprop_getter|com_jakewharton_mosaic_ui_RowColumnParentData$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowScopeInstance$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_RowScopeInstance$stableprop_getter|com_jakewharton_mosaic_ui_RowScopeInstance$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_VerticalAlignModifier$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic.ui/com_jakewharton_mosaic_ui_VerticalAlignModifier$stableprop_getter|com_jakewharton_mosaic_ui_VerticalAlignModifier$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_AnsiRendering$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_AnsiRendering$stableprop_getter|com_jakewharton_mosaic_AnsiRendering$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_DebugRendering$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_DebugRendering$stableprop_getter|com_jakewharton_mosaic_DebugRendering$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_GlobalSnapshotManager$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_GlobalSnapshotManager$stableprop_getter|com_jakewharton_mosaic_GlobalSnapshotManager$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicComposition$stableprop_getter|com_jakewharton_mosaic_MosaicComposition$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_MosaicNodeApplier$stableprop_getter|com_jakewharton_mosaic_MosaicNodeApplier$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_Terminal$stableprop_getter|com_jakewharton_mosaic_Terminal$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_TextPixel$stableprop_getter|com_jakewharton_mosaic_TextPixel$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop_getter(): kotlin/Int // com.jakewharton.mosaic/com_jakewharton_mosaic_TextSurface$stableprop_getter|com_jakewharton_mosaic_TextSurface$stableprop_getter(){}[0] +final fun com.jakewharton.mosaic/renderMosaic(kotlin/Function2): kotlin/String // com.jakewharton.mosaic/renderMosaic|renderMosaic(kotlin.Function2){}[0] +final fun com.jakewharton.mosaic/runMosaicBlocking(kotlin/Function2) // com.jakewharton.mosaic/runMosaicBlocking|runMosaicBlocking(kotlin.Function2){}[0] +final inline fun (com.jakewharton.mosaic.ui/Color).com.jakewharton.mosaic.ui/takeOrElse(kotlin/Function0): com.jakewharton.mosaic.ui/Color // com.jakewharton.mosaic.ui/takeOrElse|takeOrElse@com.jakewharton.mosaic.ui.Color(kotlin.Function0){}[0] +final inline fun (com.jakewharton.mosaic.ui/TextStyle).com.jakewharton.mosaic.ui/takeOrElse(kotlin/Function0): com.jakewharton.mosaic.ui/TextStyle // com.jakewharton.mosaic.ui/takeOrElse|takeOrElse@com.jakewharton.mosaic.ui.TextStyle(kotlin.Function0){}[0] +final inline fun <#A: kotlin/Any> (com.jakewharton.mosaic.text/AnnotatedString.Builder).com.jakewharton.mosaic.text/withStyle(com.jakewharton.mosaic.text/SpanStyle, kotlin/Function1): #A // com.jakewharton.mosaic.text/withStyle|withStyle@com.jakewharton.mosaic.text.AnnotatedString.Builder(com.jakewharton.mosaic.text.SpanStyle;kotlin.Function1){0§}[0] +final inline fun com.jakewharton.mosaic.text/buildAnnotatedString(kotlin/Function1): com.jakewharton.mosaic.text/AnnotatedString // com.jakewharton.mosaic.text/buildAnnotatedString|buildAnnotatedString(kotlin.Function1){}[0] +final suspend fun com.jakewharton.mosaic/runMosaic(kotlin/Function2) // com.jakewharton.mosaic/runMosaic|runMosaic(kotlin.Function2){}[0] diff --git a/mosaic-runtime/build.gradle b/mosaic-runtime/build.gradle index 88b85e14..d018e8b4 100644 --- a/mosaic-runtime/build.gradle +++ b/mosaic-runtime/build.gradle @@ -2,11 +2,20 @@ apply plugin: 'org.jetbrains.kotlin.multiplatform' apply plugin: 'org.jetbrains.kotlin.plugin.compose' apply from: "$rootDir/addAllTargets.gradle" apply from: "$rootDir/publish.gradle" -apply plugin: 'org.jetbrains.dokka' apply plugin: 'dev.drewhamilton.poko' kotlin { - applyDefaultHierarchyTemplate() + applyDefaultHierarchyTemplate { + it.common { + it.group("native") { + it.group("posix") { + it.group("linux") {} + it.group("macos") {} + } + } + } + } + explicitApi() sourceSets { @@ -14,7 +23,8 @@ kotlin { dependencies { api libs.compose.runtime api libs.kotlinx.coroutines.core - implementation libs.mordant + implementation libs.finalizationHook + implementation libs.mordant.core implementation libs.codepoints } } @@ -29,6 +39,7 @@ kotlin { jvmMain { dependencies { implementation libs.jansi + implementation libs.mordant.jvmJna } } } diff --git a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/ansi.kt b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/ansi.kt index 75f8dfb9..cc41f631 100644 --- a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/ansi.kt +++ b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/ansi.kt @@ -15,6 +15,9 @@ internal const val ansiReset = "${CSI}0" internal const val clearLine = "${CSI}K" internal const val cursorUp = "${CSI}F" +internal const val cursorHide = "$CSI?25l" +internal const val cursorShow = "$CSI?25h" + internal const val ansiSeparator = ";" internal const val ansiClosingCharacter = "m" diff --git a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/blocking.kt b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/blocking.kt deleted file mode 100644 index 556a297d..00000000 --- a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/blocking.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.jakewharton.mosaic - -import androidx.compose.runtime.Composable -import kotlinx.coroutines.runBlocking - -public fun runMosaicBlocking(content: @Composable () -> Unit) { - runBlocking { - runMosaic(content) - } -} diff --git a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/layout/KeyModifier.kt b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/layout/KeyModifier.kt new file mode 100644 index 00000000..ff124732 --- /dev/null +++ b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/layout/KeyModifier.kt @@ -0,0 +1,65 @@ +package com.jakewharton.mosaic.layout + +import androidx.compose.runtime.Immutable +import com.jakewharton.mosaic.modifier.Modifier +import dev.drewhamilton.poko.Poko + +public interface KeyModifier : Modifier.Element { + /** + * This function is called when a [KeyEvent] is received by this node during the downward pass. + * It gives ancestors of a focused component the chance to intercept an event. Return true to + * stop propagation of this event. If you return false, the event will be sent to this + * [KeyModifier]'s child. If none of the children consume the event, it will be sent + * back up to the root using the [onKeyEvent] function. + */ + public fun onPreKeyEvent(event: KeyEvent): Boolean + + /** + * This function is called when a [KeyEvent] is received by this node during the upward pass. + * While implementing this callback, return true to stop propagation of this event. If you + * return false, the key event will be sent to this [KeyModifier]'s parent. + */ + public fun onKeyEvent(event: KeyEvent): Boolean +} + +@[Immutable Poko] +public class KeyEvent( + public val key: String, + public val alt: Boolean = false, + public val ctrl: Boolean = false, + public val shift: Boolean = false, +) + +/** + * Adding this [modifier][Modifier] to the [modifier][Modifier] parameter of a component will allow + * it to intercept key events. + * + * @param onPreviewKeyEvent This callback is invoked when the user interacts with the + * keyboard. It gives ancestors of a focused component the chance to intercept a [KeyEvent]. + * Return true to stop propagation of this event. If you return false, the key event will be sent + * to this [onPreviewKeyEvent]'s child. If none of the children consume the event, it will be sent + * back up to the root [KeyModifier] using the `onKeyEvent` callback. + */ +public fun Modifier.onPreviewKeyEvent( + onPreviewKeyEvent: (event: KeyEvent) -> Boolean, +): Modifier = this then KeyModifierElement(onPreviewKeyEvent, null) + +/** + * Adding this [modifier][Modifier] to the [modifier][Modifier] parameter of a component will allow + * it to intercept key events. + * + * @param onKeyEvent This callback is invoked when the user interacts with the keyboard. + * While implementing this callback, return true to stop propagation of this event. If you return + * false, the key event will be sent to this [onKeyEvent]'s parent. + */ +public fun Modifier.onKeyEvent( + onKeyEvent: (event: KeyEvent) -> Boolean, +): Modifier = this then KeyModifierElement(null, onKeyEvent) + +private class KeyModifierElement( + val onPreEvent: ((KeyEvent) -> Boolean)?, + val onEvent: ((KeyEvent) -> Boolean)?, +) : KeyModifier { + override fun onPreKeyEvent(event: KeyEvent) = onPreEvent?.invoke(event) ?: false + override fun onKeyEvent(event: KeyEvent) = onEvent?.invoke(event) ?: false +} diff --git a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/layout/Node.kt b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/layout/Node.kt index 881dda16..499d9f77 100644 --- a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/layout/Node.kt +++ b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/layout/Node.kt @@ -62,6 +62,10 @@ internal abstract class MosaicNodeLayer( next?.drawTo(canvas) } + open fun sendKeyEvent(keyEvent: KeyEvent): Boolean { + return next?.sendKeyEvent(keyEvent) ?: false + } + override fun minIntrinsicWidth(height: Int): Int { return next?.minIntrinsicWidth(height) ?: 0 } @@ -107,6 +111,8 @@ internal class MosaicNode( is DrawModifier -> DrawLayer(element, nextLayer) + is KeyModifier -> KeyLayer(element, nextLayer) + is ParentDataModifier -> { parentData = element.modifyParentData(parentData) nextLayer @@ -154,6 +160,10 @@ internal class MosaicNode( onStaticDraw?.invoke() } + fun sendKeyEvent(keyEvent: KeyEvent): Boolean { + return topLayer.sendKeyEvent(keyEvent) + } + override fun minIntrinsicWidth(height: Int): Int { return topLayer.minIntrinsicWidth(height) } @@ -188,6 +198,15 @@ private class BottomLayer( } } + override fun sendKeyEvent(keyEvent: KeyEvent): Boolean { + for (child in node.children) { + if (child.sendKeyEvent(keyEvent)) { + return true + } + } + return false + } + override fun minIntrinsicWidth(height: Int): Int { return node.measurePolicy.run { minIntrinsicWidth(node.children, height) } } @@ -249,3 +268,13 @@ private class DrawLayer( canvas.translationY = oldY } } + +private class KeyLayer( + private val element: KeyModifier, + private val lowerLayer: MosaicNodeLayer, +) : MosaicNodeLayer(lowerLayer, false) { + override fun sendKeyEvent(keyEvent: KeyEvent) = + element.onPreKeyEvent(keyEvent) || + lowerLayer.sendKeyEvent(keyEvent) || + element.onKeyEvent(keyEvent) +} diff --git a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/mosaic.kt b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/mosaic.kt index 8cb2b96c..e04a1fd3 100644 --- a/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/mosaic.kt +++ b/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/mosaic.kt @@ -12,7 +12,12 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.snapshots.ObserverHandle import androidx.compose.runtime.snapshots.Snapshot import androidx.compose.runtime.withFrameNanos +import com.github.ajalt.mordant.input.RawModeScope +import com.github.ajalt.mordant.input.enterRawMode +import com.github.ajalt.mordant.platform.MultiplatformSystem import com.github.ajalt.mordant.terminal.Terminal as MordantTerminal +import com.jakewharton.finalization.withFinalizationHook +import com.jakewharton.mosaic.layout.KeyEvent import com.jakewharton.mosaic.layout.MosaicNode import com.jakewharton.mosaic.ui.AnsiLevel import com.jakewharton.mosaic.ui.BoxMeasurePolicy @@ -20,15 +25,21 @@ import com.jakewharton.mosaic.ui.unit.IntSize import kotlin.concurrent.Volatile import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext +import kotlin.time.Duration.Companion.milliseconds import kotlin.time.ExperimentalTime import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO import kotlinx.coroutines.Job import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED +import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.consumeEach -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking /** * True for a debug-like output that renders each "frame" on its own with a timestamp delta. @@ -40,39 +51,67 @@ internal fun renderMosaicNode(content: @Composable () -> Unit): MosaicNode { val mosaicComposition = MosaicComposition( coroutineScope = CoroutineScope(EmptyCoroutineContext), terminalState = MordantTerminal().toMutableState(), + keyEvents = Channel(), onDrawing = {}, ) mosaicComposition.setContent(content) mosaicComposition.cancel() - return mosaicComposition.applier.root + return mosaicComposition.rootNode } public fun renderMosaic(content: @Composable () -> Unit): String { return createRendering().render(renderMosaicNode(content)).toString() } +public fun runMosaicBlocking(content: @Composable () -> Unit) { + runBlocking { + runMosaic(content) + } +} + public suspend fun runMosaic(content: @Composable () -> Unit) { - coroutineScope { - val terminal = MordantTerminal() - val rendering = createRendering(terminal.info.ansiLevel.toMosaicAnsiLevel()) - val terminalState = terminal.toMutableState() - val mosaicComposition = MosaicComposition( - coroutineScope = this, - terminalState = terminalState, - onDrawing = { rootNode -> - platformDisplay(rendering.render(rootNode)) - }, - ) - mosaicComposition.sendFrames() - mosaicComposition.scope.updateTerminalInfo(terminal, terminalState) - mosaicComposition.setContent(content) - mosaicComposition.awaitComplete() + val mordantTerminal = MordantTerminal() + val rendering = createRendering(mordantTerminal.terminalInfo.ansiLevel.toMosaicAnsiLevel()) + val terminalState = mordantTerminal.toMutableState() + val keyEvents = Channel(UNLIMITED) + + val rawMode = if (MultiplatformSystem.readEnvironmentVariable("MOSAIC_RAW_MODE") != "false") { + // In theory this call could fail, so perform it before any additional control sequences. + mordantTerminal.enterRawMode() + } else { + null } + + platformDisplay(cursorHide) + + withFinalizationHook( + hook = { + platformDisplay(cursorShow) + rawMode?.close() + }, + block = { + val mosaicComposition = MosaicComposition( + coroutineScope = this, + terminalState = terminalState, + keyEvents = keyEvents, + onDrawing = { rootNode -> + platformDisplay(rendering.render(rootNode)) + }, + ) + mosaicComposition.sendFrames() + mosaicComposition.scope.updateTerminalInfo(mordantTerminal, terminalState) + rawMode?.let { rawMode -> + mosaicComposition.scope.readRawModeKeys(rawMode, keyEvents) + } + mosaicComposition.setContent(content) + mosaicComposition.awaitComplete() + }, + ) } private fun MordantTerminal.toMutableState(): MutableState { return mutableStateOf( - Terminal(size = IntSize(info.width, info.height)), + Terminal(size = IntSize(size.width, size.height)), ) } @@ -89,22 +128,36 @@ private fun CoroutineScope.updateTerminalInfo(terminal: MordantTerminal, termina launch { while (true) { val currentTerminalInfo = terminalInfo.value - if (terminal.info.updateTerminalSize() && - ( - currentTerminalInfo.size.width != terminal.info.width || - currentTerminalInfo.size.height != terminal.info.height - ) + val newSize = terminal.updateSize() + if (currentTerminalInfo.size.width != newSize.width || + currentTerminalInfo.size.height != newSize.height ) { - terminalInfo.value = Terminal(size = IntSize(terminal.info.width, terminal.info.height)) + terminalInfo.value = Terminal(size = IntSize(newSize.width, newSize.height)) } delay(50L) } } } +private fun CoroutineScope.readRawModeKeys(rawMode: RawModeScope, keyEvents: Channel) { + launch(Dispatchers.IO) { + while (isActive) { + val keyboardEvent = rawMode.readKeyOrNull(10.milliseconds) ?: continue + val keyEvent = KeyEvent( + key = keyboardEvent.key, + alt = keyboardEvent.alt, + ctrl = keyboardEvent.ctrl, + shift = keyboardEvent.shift, + ) + keyEvents.trySend(keyEvent) + } + } +} + internal class MosaicComposition( coroutineScope: CoroutineScope, private val terminalState: State, + private val keyEvents: ReceiveChannel, private val onDrawing: (MosaicNode) -> Unit, ) { private val job = Job(coroutineScope.coroutineContext[Job]) @@ -112,7 +165,8 @@ internal class MosaicComposition( private val composeContext: CoroutineContext = coroutineScope.coroutineContext + job + clock val scope = CoroutineScope(composeContext) - val applier = MosaicNodeApplier(::doLayout) + private val applier = MosaicNodeApplier(::doLayout) + val rootNode = applier.root private val recomposer = Recomposer(composeContext) private val composition = Composition(applier, recomposer) @@ -190,7 +244,18 @@ internal class MosaicComposition( fun sendFrames(): Job { return scope.launch { + val ctrlC = KeyEvent("c", ctrl = true) + while (true) { + // Drain any pending key events before triggering the frame. + while (true) { + val keyEvent = keyEvents.tryReceive().getOrNull() ?: break + val keyHandled = rootNode.sendKeyEvent(keyEvent) + if (!keyHandled && keyEvent == ctrlC) { + cancel() + } + } + clock.sendFrame(0L) // Frame time value is not used by Compose runtime. delay(50L) } diff --git a/mosaic-runtime/src/commonTest/kotlin/com/jakewharton/mosaic/TestMosaicComposition.kt b/mosaic-runtime/src/commonTest/kotlin/com/jakewharton/mosaic/TestMosaicComposition.kt index 9834a12d..0115ef84 100644 --- a/mosaic-runtime/src/commonTest/kotlin/com/jakewharton/mosaic/TestMosaicComposition.kt +++ b/mosaic-runtime/src/commonTest/kotlin/com/jakewharton/mosaic/TestMosaicComposition.kt @@ -3,6 +3,7 @@ package com.jakewharton.mosaic import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf +import com.jakewharton.mosaic.layout.KeyEvent import com.jakewharton.mosaic.layout.MosaicNode import com.jakewharton.mosaic.ui.AnsiLevel import com.jakewharton.mosaic.ui.unit.IntSize @@ -10,6 +11,7 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.withTimeout @@ -36,6 +38,8 @@ internal interface TestMosaicComposition { fun changeTerminalSize(width: Int, height: Int) + fun sendKeyEvent(keyEvent: KeyEvent) + suspend fun awaitNodeSnapshot(duration: Duration = 1.seconds): MosaicNode suspend fun awaitRenderSnapshot(duration: Duration = 1.seconds): String @@ -67,7 +71,9 @@ private class RealTestMosaicComposition( Terminal(size = initialTerminalSize), ) - val mosaicComposition = MosaicComposition(coroutineScope, terminalState) { rootNode -> + private val keyEvents = Channel(UNLIMITED) + + val mosaicComposition = MosaicComposition(coroutineScope, terminalState, keyEvents) { rootNode -> nodeSnapshots.trySend(rootNode) val stringRender = if (withAnsi) { rendering.render(rootNode).toString() @@ -91,6 +97,10 @@ private class RealTestMosaicComposition( terminalState.value = Terminal(size = IntSize(width, height)) } + override fun sendKeyEvent(keyEvent: KeyEvent) { + keyEvents.trySend(keyEvent) + } + override suspend fun awaitNodeSnapshot(duration: Duration): MosaicNode { return awaitSnapshot(duration) { nodeSnapshots.receive() } } diff --git a/mosaic-terminal/.gitignore b/mosaic-terminal/.gitignore new file mode 100644 index 00000000..a10d403f --- /dev/null +++ b/mosaic-terminal/.gitignore @@ -0,0 +1,3 @@ +.zig-cache +zig-out +src/jvmMain/resources diff --git a/mosaic-terminal/README.md b/mosaic-terminal/README.md new file mode 100644 index 00000000..48186345 --- /dev/null +++ b/mosaic-terminal/README.md @@ -0,0 +1,14 @@ +# Mosaic Terminal + +Low-level TTY manipulation and parsing library. + + +## Prerequisites + +The JVM target requires native libraries which are built outside Gradle using Zig 0.13.0. + +After downloading or installing Zig, in the `mosaic-terminal/` directory run: +``` +zig build -p src/jvmMain/resources/jni +``` +to create them. diff --git a/mosaic-terminal/api/mosaic-terminal.api b/mosaic-terminal/api/mosaic-terminal.api new file mode 100644 index 00000000..883a8a85 --- /dev/null +++ b/mosaic-terminal/api/mosaic-terminal.api @@ -0,0 +1,5 @@ +public final class com/jakewharton/mosaic/terminal/Tty { + public static final field INSTANCE Lcom/jakewharton/mosaic/terminal/Tty; + public final fun enableRawMode ()Ljava/lang/AutoCloseable; +} + diff --git a/mosaic-terminal/api/mosaic-terminal.klib.api b/mosaic-terminal/api/mosaic-terminal.klib.api new file mode 100644 index 00000000..b4a8c54a --- /dev/null +++ b/mosaic-terminal/api/mosaic-terminal.klib.api @@ -0,0 +1,11 @@ +// Klib ABI Dump +// Targets: [linuxArm64, linuxX64, macosArm64, macosX64, mingwX64] +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: true +// - Show declarations: true + +// Library unique name: +final object com.jakewharton.mosaic.terminal/Tty { // com.jakewharton.mosaic.terminal/Tty|null[0] + final fun enableRawMode(): kotlin/AutoCloseable // com.jakewharton.mosaic.terminal/Tty.enableRawMode|enableRawMode(){}[0] +} diff --git a/mosaic-terminal/build.gradle b/mosaic-terminal/build.gradle new file mode 100644 index 00000000..79e2ddac --- /dev/null +++ b/mosaic-terminal/build.gradle @@ -0,0 +1,53 @@ +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget + +import static co.touchlab.cklib.gradle.CompileToBitcode.Language.C + +apply plugin: 'org.jetbrains.kotlin.multiplatform' +apply from: "$rootDir/addAllTargets.gradle" +apply from: "$rootDir/publish.gradle" +apply plugin: 'co.touchlab.cklib' + +kotlin { + explicitApi() + + jvm { + compilations.main.compileTaskProvider.configure { + doFirst { + def files = project.fileTree('src/jvmMain/resources').files + if (files.size() != 6) { + throw new RuntimeException( + "Missing native libraries. Run `zig build -p src/jvmMain/resources/jni`. Found: $files", + ) + } + } + } + } + + sourceSets { + commonTest { + dependencies { + implementation libs.kotlin.test + implementation libs.assertk + } + } + } + + targets.withType(KotlinNativeTarget).configureEach { + compilations.main.cinterops { + create('mosaic') { + header(file('src/c/mosaic.h')) + packageName('com.jakewharton.mosaic.terminal') + } + } + } + + compilerOptions.freeCompilerArgs.add('-Xexpect-actual-classes') +} + +cklib { + config.kotlinVersion = libs.versions.kotlin.get() + create('mosaic', file('src/c'), ['main']) { + it.srcDirs = files('src/c') + it.language = C + } +} diff --git a/mosaic-terminal/build.zig b/mosaic-terminal/build.zig new file mode 100644 index 00000000..14e37faf --- /dev/null +++ b/mosaic-terminal/build.zig @@ -0,0 +1,58 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) !void { + // The Windows builds create a .lib file in the lib/ directory which we don't need. + const deleteLib = b.addRemoveDirTree(b.getInstallPath(.prefix, "lib")); + b.getInstallStep().dependOn(&deleteLib.step); + + setupMosaicTarget(b, &deleteLib.step, .linux, .aarch64, "arm64"); + setupMosaicTarget(b, &deleteLib.step, .linux, .x86_64, "x86_64"); + setupMosaicTarget(b, &deleteLib.step, .macos, .aarch64, "aarch64"); + setupMosaicTarget(b, &deleteLib.step, .macos, .x86_64, "x86_64"); + setupMosaicTarget(b, &deleteLib.step, .windows, .aarch64, "arm64"); + setupMosaicTarget(b, &deleteLib.step, .windows, .x86_64, "x86_64"); +} + +fn setupMosaicTarget(b: *std.Build, step: *std.Build.Step, tag: std.Target.Os.Tag, arch: std.Target.Cpu.Arch, dir: []const u8) void { + const lib = b.addSharedLibrary(.{ + .name = "mosaic", + .target = b.resolveTargetQuery(.{ + .cpu_arch = arch, + .os_tag = tag, + }), + .optimize = .ReleaseSmall, + }); + + lib.linkLibC(); + + lib.addIncludePath(b.path("src/c")); + lib.addIncludePath(b.path("src/jvmMain/include/share")); + lib.addIncludePath( + switch (tag) { + .windows => b.path("src/jvmMain/include/windows"), + else => b.path("src/jvmMain/include/unix"), + } + ); + + // TODO Tree-walk these two dirs for all C files. + lib.addCSourceFiles(.{ + .files = &.{ + "src/c/mosaic-rawMode-posix.c", + "src/c/mosaic-rawMode-windows.c", + "src/jvmMain/jni/mosaic-jni.c", + }, + .flags = &.{ + "-std=gnu99", + }, + }); + + const install = b.addInstallArtifact(lib, .{ + .dest_dir = .{ + .override = .{ + .custom = dir, + }, + }, + }); + + step.dependOn(&install.step); +} diff --git a/mosaic-terminal/src/c/cutils.h b/mosaic-terminal/src/c/cutils.h new file mode 100644 index 00000000..96a18646 --- /dev/null +++ b/mosaic-terminal/src/c/cutils.h @@ -0,0 +1,7 @@ +#ifndef CUTILS_H +#define CUTILS_H + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#endif // CUTILS_H diff --git a/mosaic-terminal/src/c/mosaic-rawMode-posix.c b/mosaic-terminal/src/c/mosaic-rawMode-posix.c new file mode 100644 index 00000000..0cd61765 --- /dev/null +++ b/mosaic-terminal/src/c/mosaic-rawMode-posix.c @@ -0,0 +1,63 @@ +#include "mosaic.h" + +#if defined(__APPLE__) || defined(__linux__) + +#include "cutils.h" +#include +#include +#include +#include +#include + +rawModeResult enterRawMode() { + rawModeResult result = {}; + + struct termios *saved = calloc(1, sizeof(struct termios)); + if (unlikely(saved == NULL)) { + goto ret; + } + + if (unlikely(tcgetattr(STDIN_FILENO, saved) != 0)) { + result.error = errno; + goto err; + } + + struct termios current = (*saved); + + // Flags as defined by "Raw mode" section of https://linux.die.net/man/3/termios + current.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | ISTRIP | IXON | PARMRK); + current.c_oflag &= ~(OPOST); + // Setting ECHONL should be useless here, but it is what is documented for cfmakeraw. + current.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); + current.c_cflag &= ~(CSIZE | PARENB); + current.c_cflag |= (CS8); + + current.c_cc[VMIN] = 1; + current.c_cc[VTIME] = 0; + + if (unlikely(tcsetattr(STDIN_FILENO, TCSAFLUSH, ¤t) != 0)) { + result.error = errno; + // Try to restore the saved config. + tcsetattr(STDIN_FILENO, TCSAFLUSH, saved); + goto err; + } + + result.saved = saved; + + ret: + return result; + + err: + free(saved); + goto ret; +} + +platformError exitRawMode(rawModeConfig *saved) { + int result = unlikely(tcsetattr(STDIN_FILENO, TCSAFLUSH, saved) != 0) + ? errno + : 0; + free(saved); + return result; +} + +#endif diff --git a/mosaic-terminal/src/c/mosaic-rawMode-windows.c b/mosaic-terminal/src/c/mosaic-rawMode-windows.c new file mode 100644 index 00000000..46d71c6c --- /dev/null +++ b/mosaic-terminal/src/c/mosaic-rawMode-windows.c @@ -0,0 +1,102 @@ +#include "mosaic.h" + +#if defined(WIN32) + +#include "cutils.h" +#include + +typedef struct rawModeConfigWindows { + DWORD input_mode; + DWORD output_mode; + UINT output_code_page; +} rawModeConfigWindows; + +rawModeResult enterRawMode() { + rawModeResult result = {}; + + HANDLE stdin = GetStdHandle(STD_INPUT_HANDLE); + if (unlikely(stdin == INVALID_HANDLE_VALUE)) { + result.error = GetLastError(); + goto ret; + } + HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (unlikely(stdout == INVALID_HANDLE_VALUE)) { + result.error = GetLastError(); + goto ret; + } + + rawModeConfigWindows *saved = malloc(sizeof(rawModeConfigWindows)); + if (unlikely(saved == NULL)) { + goto ret; + } + + if (unlikely(GetConsoleMode(stdin, &saved->input_mode) == 0)) { + result.error = GetLastError(); + goto err; + } + if (unlikely(GetConsoleMode(stdout, &saved->output_mode) == 0)) { + result.error = GetLastError(); + goto err; + } + if (unlikely((saved->output_code_page = GetConsoleOutputCP()) == 0)) { + result.error = GetLastError(); + goto err; + } + + if (unlikely(SetConsoleMode(stdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS) == 0)) { + result.error = GetLastError(); + goto err; + } + if (unlikely(SetConsoleMode(stdout, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN | ENABLE_LVB_GRID_WORLDWIDE) == 0)) { + result.error = GetLastError(); + SetConsoleMode(stdin, saved->input_mode); + goto err; + } + if (unlikely(SetConsoleOutputCP(65001 /* UTF-8 */) == 0)) { + result.error = GetLastError(); + SetConsoleMode(stdin, saved->input_mode); + SetConsoleMode(stdout, saved->input_mode); + goto err; + } + + result.saved = saved; + + ret: + return result; + + err: + free(saved); + goto ret; +} + +platformError exitRawMode(rawModeConfig *saved) { + platformError result = 0; + + HANDLE stdin = GetStdHandle(STD_INPUT_HANDLE); + if (unlikely(stdin == INVALID_HANDLE_VALUE)) { + result = GetLastError(); + goto done; + } + HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (unlikely(stdout == INVALID_HANDLE_VALUE)) { + result = GetLastError(); + goto done; + } + + // Try to restore all three properties even if some fail. + if (unlikely(SetConsoleMode(stdin, saved->input_mode) == 0)) { + result = GetLastError(); + } + if (unlikely(SetConsoleMode(stdout, saved->output_mode) == 0 && result == 0)) { + result = GetLastError(); + } + if (unlikely(SetConsoleOutputCP(saved->output_code_page) == 0 && result == 0)) { + result = GetLastError(); + } + + done: + free(saved); + return result; +} + +#endif diff --git a/mosaic-terminal/src/c/mosaic.h b/mosaic-terminal/src/c/mosaic.h new file mode 100644 index 00000000..e65da9bb --- /dev/null +++ b/mosaic-terminal/src/c/mosaic.h @@ -0,0 +1,28 @@ +#ifndef MOSAIC_H +#define MOSAIC_H + +#if defined(__APPLE__) || defined(__linux__) + +#include + +typedef struct termios rawModeConfig; +typedef unsigned int platformError; + +#elif defined(WIN32) + +#include + +typedef struct rawModeConfigWindows rawModeConfig; +typedef DWORD platformError; + +#endif + +typedef struct rawModeResult { + rawModeConfig* saved; + platformError error; +} rawModeResult; + +rawModeResult enterRawMode(); +platformError exitRawMode(rawModeConfig *saved); + +#endif // MOSAIC_H diff --git a/mosaic-terminal/src/commonMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt b/mosaic-terminal/src/commonMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt new file mode 100644 index 00000000..254c54a5 --- /dev/null +++ b/mosaic-terminal/src/commonMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt @@ -0,0 +1,16 @@ +package com.jakewharton.mosaic.terminal + +public expect object Tty { + /** + * Save the current terminal settings and enter "raw" mode. + * + * Raw mode is described as "input is available character by character, echoing is disabled, + * and all special processing of terminal input and output characters is disabled." + * + * The saved settings can be restored by calling [close][AutoCloseable.close] on + * the returned instance. + * + * See [`termios(3)`](https://linux.die.net/man/3/termios) for more information. + */ + public fun enableRawMode(): AutoCloseable +} diff --git a/mosaic-terminal/src/jvmMain/include/LICENSE b/mosaic-terminal/src/jvmMain/include/LICENSE new file mode 100644 index 00000000..8b400c7a --- /dev/null +++ b/mosaic-terminal/src/jvmMain/include/LICENSE @@ -0,0 +1,347 @@ +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must be licensed for +everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands interactively when run, + you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms +of this License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above + on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code +distributed need not include anything that is normally distributed (in either +source or binary form) with the major components (compiler, kernel, and so on) +of the operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or +any work based on the Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by +third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software Foundation. +If the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER +OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes + with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free + software, and you are welcome to redistribute it under certain conditions; + type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL + +Certain source files distributed by Oracle America and/or its affiliates are +subject to the following clarification and special exception to the GPL, but +only where Oracle has expressly included in the particular source file's header +the words "Oracle designates this particular file as subject to the "Classpath" +exception as provided by Oracle in the LICENSE file that accompanied this code." + + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. diff --git a/mosaic-terminal/src/jvmMain/include/share/jni.h b/mosaic-terminal/src/jvmMain/include/share/jni.h new file mode 100644 index 00000000..c85da1bc --- /dev/null +++ b/mosaic-terminal/src/jvmMain/include/share/jni.h @@ -0,0 +1,2001 @@ +/* + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef _JAVASOFT_JNI_H_ +#define _JAVASOFT_JNI_H_ + +#include +#include + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#include "jni_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* Return values from jobjectRefType */ +typedef enum _jobjectType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + + +#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); + + /* New JNI 1.6 Features */ + + jobjectRefType (JNICALL *GetObjectRefType) + (JNIEnv* env, jobject obj); + + /* Module Features */ + + jobject (JNICALL *GetModule) + (JNIEnv* env, jclass clazz); + + /* Virtual threads */ + + jboolean (JNICALL *IsVirtualThread) + (JNIEnv* env, jobject obj); +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + const jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + jobjectRefType GetObjectRefType(jobject obj) { + return functions->GetObjectRefType(this, obj); + } + + /* Module Features */ + + jobject GetModule(jclass clazz) { + return functions->GetModule(this, clazz); + } + + /* Virtual threads */ + + jboolean IsVirtualThread(jobject obj) { + return functions->IsVirtualThread(this, obj); + } + +#endif /* __cplusplus */ +}; + +/* + * optionString may be any option accepted by the JVM, or one of the + * following: + * + * -D= Set a system property. + * -verbose[:class|gc|jni] Enable verbose output, comma-separated. E.g. + * "-verbose:class" or "-verbose:gc,class" + * Standard names include: gc, class, and jni. + * All nonstandard (VM-specific) names must begin + * with "X". + * vfprintf extraInfo is a pointer to the vfprintf hook. + * exit extraInfo is a pointer to the exit hook. + * abort extraInfo is a pointer to the abort hook. + */ +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +/* These will be VM-specific. */ + +#define JDK1_2 +#define JDK1_4 + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +/* Defined by native libraries. */ +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 +#define JNI_VERSION_1_8 0x00010008 +#define JNI_VERSION_9 0x00090000 +#define JNI_VERSION_10 0x000a0000 +#define JNI_VERSION_19 0x00130000 +#define JNI_VERSION_20 0x00140000 +#define JNI_VERSION_21 0x00150000 + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JNI_H_ */ diff --git a/mosaic-terminal/src/jvmMain/include/unix/jni_md.h b/mosaic-terminal/src/jvmMain/include/unix/jni_md.h new file mode 100644 index 00000000..6e583da7 --- /dev/null +++ b/mosaic-terminal/src/jvmMain/include/unix/jni_md.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef JNIEXPORT + #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #ifdef ARM + #define JNIEXPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIEXPORT __attribute__((visibility("default"))) + #endif + #else + #define JNIEXPORT + #endif +#endif + +#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) + #ifdef ARM + #define JNIIMPORT __attribute__((externally_visible,visibility("default"))) + #else + #define JNIIMPORT __attribute__((visibility("default"))) + #endif +#else + #define JNIIMPORT +#endif + +#define JNICALL + +typedef int jint; +#ifdef _LP64 +typedef long jlong; +#else +typedef long long jlong; +#endif + +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/mosaic-terminal/src/jvmMain/include/windows/jni_md.h b/mosaic-terminal/src/jvmMain/include/windows/jni_md.h new file mode 100644 index 00000000..f7954219 --- /dev/null +++ b/mosaic-terminal/src/jvmMain/include/windows/jni_md.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#ifndef JNIEXPORT + #define JNIEXPORT __declspec(dllexport) +#endif +#define JNIIMPORT __declspec(dllimport) +#define JNICALL __stdcall + +typedef int jint; +typedef long long jlong; +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/mosaic-terminal/src/jvmMain/jni/mosaic-jni.c b/mosaic-terminal/src/jvmMain/jni/mosaic-jni.c new file mode 100644 index 00000000..53e0a1bb --- /dev/null +++ b/mosaic-terminal/src/jvmMain/jni/mosaic-jni.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include "cutils.h" + +JNIEXPORT jlong JNICALL +Java_com_jakewharton_mosaic_terminal_Tty_enterRawMode(JNIEnv *env, jclass type) { + rawModeResult result = enterRawMode(); + if (unlikely(result.error)) { + jclass ise = (*env)->FindClass(env, "java/lang/IllegalStateException"); + char *message = malloc(40 * sizeof(char)); + if (message) { + sprintf(message, "Unable to enable raw mode: %i", result.error); + // This throw can fail, but the only condition that should cause that is OOM which + // will occur from returning 0 (which is otherwise ignored if the throw succeeds). + (*env)->ThrowNew(env, ise, message); + } + return 0; + } + return (jlong) result.saved; +} + +JNIEXPORT int JNICALL +Java_com_jakewharton_mosaic_terminal_Tty_exitRawMode(JNIEnv *env, jclass type, jlong ptr) { + return exitRawMode((rawModeConfig*)ptr); +} diff --git a/mosaic-terminal/src/jvmMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt b/mosaic-terminal/src/jvmMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt new file mode 100644 index 00000000..55453ea6 --- /dev/null +++ b/mosaic-terminal/src/jvmMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt @@ -0,0 +1,66 @@ +package com.jakewharton.mosaic.terminal + +import java.io.IOException +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.StandardCopyOption.REPLACE_EXISTING +import java.util.Locale.US + +public actual object Tty { + init { + loadNativeLibrary("mosaic") + } + + public actual fun enableRawMode(): AutoCloseable { + val savedConfig = enterRawMode() + if (savedConfig == 0L) throw OutOfMemoryError() + return RawMode(savedConfig) + } + + private class RawMode( + private val savedPtr: Long, + ) : AutoCloseable { + override fun close() { + val error = exitRawMode(savedPtr) + check(error == 0) { "Unable to exit raw mode: $error" } + } + } + + @JvmStatic + private external fun enterRawMode(): Long + + @JvmStatic + private external fun exitRawMode(savedConfig: Long): Int + + @Suppress( + // Only loading from our own JAR contents. + "UnsafeDynamicallyLoadedCode", + // Preserving copy/paste! + "SameParameterValue", + ) + private fun loadNativeLibrary(name: String) { + val osName = System.getProperty("os.name").lowercase(US) + val osArch = System.getProperty("os.arch").lowercase(US) + val nativeLibraryJarPath = "/jni/$osArch/" + when { + "linux" in osName -> "lib$name.so" + "mac" in osName -> "lib$name.dylib" + "windows" in osName -> "$name.dll" + else -> throw IllegalStateException("Unsupported OS: $osName $osArch") + } + val nativeLibraryUrl = Tty::class.java.getResource(nativeLibraryJarPath) + ?: throw IllegalStateException("Unable to read $nativeLibraryJarPath from JAR") + val nativeLibraryFile: Path + try { + nativeLibraryFile = Files.createTempFile(name, null) + + // File-based deleteOnExit() uses a special internal shutdown hook that always runs last. + nativeLibraryFile.toFile().deleteOnExit() + nativeLibraryUrl.openStream().use { nativeLibrary -> + Files.copy(nativeLibrary, nativeLibraryFile, REPLACE_EXISTING) + } + } catch (e: IOException) { + throw RuntimeException("Unable to extract native library from JAR", e) + } + System.load(nativeLibraryFile.toAbsolutePath().toString()) + } +} diff --git a/mosaic-terminal/src/nativeMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt b/mosaic-terminal/src/nativeMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt new file mode 100644 index 00000000..c912a946 --- /dev/null +++ b/mosaic-terminal/src/nativeMain/kotlin/com/jakewharton/mosaic/terminal/Tty.kt @@ -0,0 +1,25 @@ +package com.jakewharton.mosaic.terminal + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.useContents + +@OptIn(ExperimentalForeignApi::class) +public actual object Tty { + public actual fun enableRawMode(): AutoCloseable { + val savedConfig = enterRawMode().useContents { + check(error == 0U) { "Unable to enable raw mode: $error" } + saved ?: throw OutOfMemoryError() + } + return RawMode(savedConfig) + } + + private class RawMode( + private val savedConfig: CPointer, + ) : AutoCloseable { + override fun close() { + val error = exitRawMode(savedConfig) + check(error.toInt() == 0) { "Unable to exit raw mode: $error" } + } + } +} diff --git a/publish.gradle b/publish.gradle index 15fc84fb..3536e507 100644 --- a/publish.gradle +++ b/publish.gradle @@ -1,5 +1,6 @@ -apply plugin: "com.vanniktech.maven.publish" -apply plugin: "binary-compatibility-validator" +apply plugin: 'com.vanniktech.maven.publish' +apply plugin: 'org.jetbrains.kotlinx.binary-compatibility-validator' +apply plugin: 'org.jetbrains.dokka' publishing { repositories { @@ -9,3 +10,11 @@ publishing { } } } + +apiValidation { + klib.enabled = true + + // We run API checks on a Mac where all possible Kotlin targets are available. + // Setting this to true will allow us to catch when targets are removed. + klib.strictValidation = System.getenv("CI") == "true" +} diff --git a/samples/counter/build.gradle b/samples/counter/build.gradle index 58a0a6a9..5fe654c3 100644 --- a/samples/counter/build.gradle +++ b/samples/counter/build.gradle @@ -1,6 +1,6 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget -import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType apply plugin: 'org.jetbrains.kotlin.multiplatform' apply plugin: 'org.jetbrains.kotlin.plugin.compose' @@ -23,6 +23,11 @@ kotlin { targets.withType(KotlinNativeTarget).configureEach { target -> target.binaries.executable { entryPoint = 'example.main' + if (buildType == NativeBuildType.DEBUG) { + linkTaskProvider.configure { + enabled = false + } + } } } diff --git a/samples/counter/demo.gif b/samples/counter/demo.gif index eddcb7bd..5018070f 100644 Binary files a/samples/counter/demo.gif and b/samples/counter/demo.gif differ diff --git a/samples/jest/demo.gif b/samples/jest/demo.gif index e8edfccb..8c0bf040 100644 Binary files a/samples/jest/demo.gif and b/samples/jest/demo.gif differ diff --git a/samples/robot/build.gradle b/samples/robot/build.gradle index 113813c5..bf66cb2a 100644 --- a/samples/robot/build.gradle +++ b/samples/robot/build.gradle @@ -1,12 +1,39 @@ -apply plugin: 'org.jetbrains.kotlin.jvm' +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType + +apply plugin: 'org.jetbrains.kotlin.multiplatform' apply plugin: 'org.jetbrains.kotlin.plugin.compose' +apply from: "$rootDir/addAllTargets.gradle" apply plugin: 'application' application { mainClass = 'example.RobotKt' } -dependencies { - implementation projects.mosaicRuntime - implementation 'org.jline:jline:3.26.3' +kotlin { + sourceSets { + commonMain { + dependencies { + implementation projects.mosaicRuntime + } + } + } + + targets.withType(KotlinNativeTarget).configureEach { target -> + target.binaries.executable { + entryPoint = 'example.main' + if (buildType == NativeBuildType.DEBUG) { + linkTaskProvider.configure { + enabled = false + } + } + } + } + + //noinspection ConfigurationAvoidance Cannot mutate this after buildscript evaluation. + targets.withType(KotlinJvmTarget) { + // Needed for 'application' plugin. + withJava() + } } diff --git a/samples/robot/demo.gif b/samples/robot/demo.gif index 4ca0d52f..3df56887 100644 Binary files a/samples/robot/demo.gif and b/samples/robot/demo.gif differ diff --git a/samples/robot/src/main/kotlin/example/robot.kt b/samples/robot/src/commonMain/kotlin/example/robot.kt similarity index 66% rename from samples/robot/src/main/kotlin/example/robot.kt rename to samples/robot/src/commonMain/kotlin/example/robot.kt index fc6a22ba..fc566e40 100644 --- a/samples/robot/src/main/kotlin/example/robot.kt +++ b/samples/robot/src/commonMain/kotlin/example/robot.kt @@ -3,12 +3,15 @@ package example import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import com.jakewharton.mosaic.layout.DrawStyle +import com.jakewharton.mosaic.layout.KeyEvent import com.jakewharton.mosaic.layout.drawBehind import com.jakewharton.mosaic.layout.height import com.jakewharton.mosaic.layout.offset +import com.jakewharton.mosaic.layout.onKeyEvent import com.jakewharton.mosaic.layout.padding import com.jakewharton.mosaic.layout.size import com.jakewharton.mosaic.modifier.Modifier @@ -18,10 +21,7 @@ import com.jakewharton.mosaic.ui.Column import com.jakewharton.mosaic.ui.Spacer import com.jakewharton.mosaic.ui.Text import com.jakewharton.mosaic.ui.unit.IntOffset -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.isActive -import kotlinx.coroutines.withContext -import org.jline.terminal.TerminalBuilder +import kotlinx.coroutines.awaitCancellation private const val worldWidth = 20 private const val worldHeight = 10 @@ -35,8 +35,21 @@ private const val robotHeight = 1 fun main() = runMosaicBlocking { var x by remember { mutableIntStateOf(0) } var y by remember { mutableIntStateOf(0) } + var exit by remember { mutableStateOf(false) } - Column { + Column( + modifier = Modifier.onKeyEvent { + when (it) { + KeyEvent("ArrowUp") -> y = (y - 1).coerceAtLeast(0) + KeyEvent("ArrowDown") -> y = (y + 1).coerceAtMost(worldHeight - robotHeight) + KeyEvent("ArrowLeft") -> x = (x - 1).coerceAtLeast(0) + KeyEvent("ArrowRight") -> x = (x + 1).coerceAtMost(worldWidth - robotWidth) + KeyEvent("q") -> exit = true + else -> return@onKeyEvent false + } + true + }, + ) { Text("Use arrow keys to move the face. Press “q” to exit.") Text("Position: $x, $y Robot: $robotWidth, $robotHeight World: $worldWidth, $worldHeight") Spacer(Modifier.height(1)) @@ -50,31 +63,9 @@ fun main() = runMosaicBlocking { } } - LaunchedEffect(Unit) { - withContext(Dispatchers.IO) { - val terminal = TerminalBuilder.terminal() - terminal.enterRawMode() - val reader = terminal.reader() - - while (isActive) { - // TODO https://github.com/JakeWharton/mosaic/issues/10 - when (reader.read()) { - 'q'.code -> break - - 27 -> { - when (reader.read()) { - 91, 79 -> { - when (reader.read()) { - 65 -> y = (y - 1).coerceAtLeast(0) - 66 -> y = (y + 1).coerceAtMost(worldHeight - robotHeight) - 67 -> x = (x + 1).coerceAtMost(worldWidth - robotWidth) - 68 -> x = (x - 1).coerceAtLeast(0) - } - } - } - } - } - } + if (!exit) { + LaunchedEffect(Unit) { + awaitCancellation() } } } diff --git a/samples/rrtop/build.gradle b/samples/rrtop/build.gradle index b0125f29..8a0b61b3 100644 --- a/samples/rrtop/build.gradle +++ b/samples/rrtop/build.gradle @@ -9,5 +9,4 @@ application { dependencies { implementation projects.mosaicRuntime implementation 'org.jetbrains.kotlinx:kotlinx-datetime:0.6.1' - implementation 'org.jline:jline:3.26.3' } diff --git a/samples/rrtop/src/main/kotlin/example/RrtopApp.kt b/samples/rrtop/src/main/kotlin/example/RrtopApp.kt index 8de8c0b2..0d32eb2a 100644 --- a/samples/rrtop/src/main/kotlin/example/RrtopApp.kt +++ b/samples/rrtop/src/main/kotlin/example/RrtopApp.kt @@ -2,13 +2,14 @@ package example import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import com.jakewharton.mosaic.LocalTerminal +import com.jakewharton.mosaic.layout.KeyEvent import com.jakewharton.mosaic.layout.background import com.jakewharton.mosaic.layout.fillMaxWidth import com.jakewharton.mosaic.layout.height +import com.jakewharton.mosaic.layout.onKeyEvent import com.jakewharton.mosaic.layout.padding import com.jakewharton.mosaic.layout.width import com.jakewharton.mosaic.modifier.Modifier @@ -18,17 +19,11 @@ import com.jakewharton.mosaic.text.withStyle import com.jakewharton.mosaic.ui.Alignment import com.jakewharton.mosaic.ui.Box import com.jakewharton.mosaic.ui.Text -import example.common.Key -import example.common.key -import example.common.keyEventFlow -import example.common.utf16CodePoint import example.screens.CmdScreen import example.screens.MainScreen import example.screens.RawScreen import example.screens.SlowScreen import example.screens.StatScreen -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext @Composable fun RrtopApp(rrtopViewModel: RrtopViewModel, colorsPalette: RrtopColorsPalette) { @@ -39,7 +34,21 @@ fun RrtopApp(rrtopViewModel: RrtopViewModel, colorsPalette: RrtopColorsPalette) modifier = Modifier .width(terminal.size.width) .height(terminal.size.height - 1) // subtraction of one is necessary, because there is a line with a cursor at the bottom, which moves up all the content - .background(LocalRrtopColorsPalette.current.mainBg), + .background(LocalRrtopColorsPalette.current.mainBg) + .onKeyEvent { + when (it) { + KeyEvent("ArrowLeft") -> rrtopViewModel.onArrowLeftPress() + KeyEvent("ArrowRight") -> rrtopViewModel.onArrowRightPress() + KeyEvent("Tab") -> rrtopViewModel.onTabPress() + + KeyEvent("q"), + KeyEvent("Q"), + -> rrtopViewModel.onQPress() + + else -> return@onKeyEvent false + } + true + }, ) { when (rrtopUiState.currentScreen) { RrtopUiState.Screen.Main -> MainScreen( @@ -73,23 +82,6 @@ fun RrtopApp(rrtopViewModel: RrtopViewModel, colorsPalette: RrtopColorsPalette) ) } } - - LaunchedEffect(Unit) { - withContext(Dispatchers.IO) { - keyEventFlow.collect { keyEvent -> - when (keyEvent.key) { - Key.DirectionLeft -> rrtopViewModel.onArrowLeftPress() - Key.DirectionRight -> rrtopViewModel.onArrowRightPress() - Key.Tab -> rrtopViewModel.onTabPress() - Key.Type -> { - if (keyEvent.utf16CodePoint == 'q'.code || keyEvent.utf16CodePoint == 'Q'.code) { - rrtopViewModel.onQPress() - } - } - } - } - } - } } @Composable diff --git a/samples/rrtop/src/main/kotlin/example/common/Key.kt b/samples/rrtop/src/main/kotlin/example/common/Key.kt deleted file mode 100644 index 059c8cae..00000000 --- a/samples/rrtop/src/main/kotlin/example/common/Key.kt +++ /dev/null @@ -1,117 +0,0 @@ -package example.common - -@JvmInline -value class Key(val keyCode: Int) { - companion object { - /** Unknown key. */ - val Unknown: Key = Key(0) - - /** Special key for detecting text input. */ - val Type: Key = Key(1) - - /** - * Up Arrow Key / Directional Pad Up key. - */ - val DirectionUp: Key = Key(2) - - /** - * Down Arrow Key / Directional Pad Down key. - */ - val DirectionDown: Key = Key(3) - - /** - * Left Arrow Key / Directional Pad Left key. - */ - val DirectionLeft: Key = Key(4) - - /** - * Right Arrow Key / Directional Pad Right key. - */ - val DirectionRight: Key = Key(5) - - /** - * Home Movement key. - * - * Used for scrolling or moving the cursor around to the start of a line - * or to the top of a list. - */ - val MoveHome: Key = Key(6) - - /** - * End Movement key. - * - * Used for scrolling or moving the cursor around to the end of a line - * or to the bottom of a list. - */ - val MoveEnd: Key = Key(7) - - /** - * Insert key. - * - * Toggles insert / overwrite edit mode. - */ - val Insert: Key = Key(8) - - /** - * Backspace key. - * - * Deletes characters before the insertion point, unlike [Delete]. - */ - val Backspace: Key = Key(9) - - /** - * Delete key. - * - * Deletes characters ahead of the insertion point, unlike [Backspace]. - */ - val Delete: Key = Key(10) - - /** Page Up key. */ - val PageUp: Key = Key(11) - - /** Page Down key. */ - val PageDown: Key = Key(12) - - /** Tab key. */ - val Tab: Key = Key(13) - - /** Enter key. */ - val Enter: Key = Key(14) - - /** F1 key. */ - val F1: Key = Key(15) - - /** F2 key. */ - val F2: Key = Key(16) - - /** F3 key. */ - val F3: Key = Key(17) - - /** F4 key. */ - val F4: Key = Key(18) - - /** F5 key. */ - val F5: Key = Key(19) - - /** F6 key. */ - val F6: Key = Key(20) - - /** F7 key. */ - val F7: Key = Key(21) - - /** F8 key. */ - val F8: Key = Key(22) - - /** F9 key. */ - val F9: Key = Key(23) - - /** F10 key. */ - val F10: Key = Key(24) - - /** F11 key. */ - val F11: Key = Key(25) - - /** F12 key. */ - val F12: Key = Key(26) - } -} diff --git a/samples/rrtop/src/main/kotlin/example/common/KeyEvent.kt b/samples/rrtop/src/main/kotlin/example/common/KeyEvent.kt deleted file mode 100644 index 9b2a6604..00000000 --- a/samples/rrtop/src/main/kotlin/example/common/KeyEvent.kt +++ /dev/null @@ -1,35 +0,0 @@ -package example.common - -fun KeyEvent(key: Key, utf16CodePoint: Int = 0): KeyEvent { - return KeyEvent(key.keyCode.toLong().shl(32) or (utf16CodePoint.toLong() and 0xFFFFFFFF)) -} - -@JvmInline -value class KeyEvent internal constructor(@PublishedApi internal val packed: Long) - -/** - * The key that was pressed. - */ -@Suppress("NOTHING_TO_INLINE") -inline val KeyEvent.key: Key - get() = Key(packed.shr(32).toInt()) - -/** - * The UTF16 value corresponding to the key event that was pressed. The unicode character - * takes into account any meta keys that are pressed (eg. Pressing shift results in capital - * alphabets). The UTF16 value uses the - * [U+n notation][http://www.unicode.org/reports/tr27/#notation] of the Unicode Standard. - * - * An [Int] is used instead of a [Char] so that we can support supplementary characters. The - * Unicode Standard allows for characters whose representation requires more than 16 bits. - * The range of legal code points is U+0000 to U+10FFFF, known as Unicode scalar value. - * - * The set of characters from U+0000 to U+FFFF is sometimes referred to as the Basic - * Multilingual Plane (BMP). Characters whose code points are greater than U+FFFF are called - * supplementary characters. In this representation, supplementary characters are represented - * as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the - * second from the low-surrogates range (\uDC00-\uDFFF). - */ -@Suppress("NOTHING_TO_INLINE") -inline val KeyEvent.utf16CodePoint: Int - get() = packed.and(0xFFFFFFFF).toInt() diff --git a/samples/rrtop/src/main/kotlin/example/common/keyEventFlow.kt b/samples/rrtop/src/main/kotlin/example/common/keyEventFlow.kt deleted file mode 100644 index 3ba41ba8..00000000 --- a/samples/rrtop/src/main/kotlin/example/common/keyEventFlow.kt +++ /dev/null @@ -1,122 +0,0 @@ -package example.common - -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.isActive -import org.jline.terminal.TerminalBuilder - -private val terminalReader by lazy { - val terminal = TerminalBuilder.terminal() - terminal.enterRawMode() - terminal.reader() -} - -val keyEventFlow: Flow = flow { - while (currentCoroutineContext().isActive) { - val firstInput = terminalReader.read() - if (firstInput == '\u001B'.code) { - val secondInput = terminalReader.read() - if (secondInput == '['.code || secondInput == 'O'.code) { - val thirdInput = terminalReader.read() - when (val thirdInputChar = thirdInput.toChar()) { - 'A' -> emit(KeyEvent(Key.DirectionUp)) - 'B' -> emit(KeyEvent(Key.DirectionDown)) - 'C' -> emit(KeyEvent(Key.DirectionRight)) - 'D' -> emit(KeyEvent(Key.DirectionLeft)) - 'F' -> emit(KeyEvent(Key.MoveHome)) - 'H' -> emit(KeyEvent(Key.MoveEnd)) - 'P' -> emit(KeyEvent(Key.F1)) - 'Q' -> emit(KeyEvent(Key.F2)) - 'R' -> emit(KeyEvent(Key.F3)) - 'S' -> emit(KeyEvent(Key.F4)) - else -> { - if (thirdInputChar in '1'..'6') { - val fourthInput = terminalReader.read() - val fourthInputChar = fourthInput.toChar() - if (fourthInputChar == '~') { - when (thirdInputChar) { - '1' -> emit(KeyEvent(Key.MoveHome)) - '2' -> emit(KeyEvent(Key.Insert)) - '3' -> emit(KeyEvent(Key.Delete)) - '4' -> emit(KeyEvent(Key.MoveEnd)) - '5' -> emit(KeyEvent(Key.PageUp)) - '6' -> emit(KeyEvent(Key.PageDown)) - else -> emit(KeyEvent(Key.Unknown)) - } - } else { - when (thirdInputChar) { - '1' -> when (fourthInputChar) { - '5' -> { - terminalReader.read() - emit(KeyEvent(Key.F5)) - } - '7' -> { - terminalReader.read() - emit(KeyEvent(Key.F6)) - } - '8' -> { - terminalReader.read() - emit(KeyEvent(Key.F7)) - } - '9' -> { - terminalReader.read() - emit(KeyEvent(Key.F8)) - } - else -> emit(KeyEvent(Key.Unknown)) - } - '2' -> when (fourthInputChar) { - '0' -> { - terminalReader.read() - emit(KeyEvent(Key.F9)) - } - '1' -> { - terminalReader.read() - emit(KeyEvent(Key.F10)) - } - '3' -> { - terminalReader.read() - emit(KeyEvent(Key.F11)) - } - '4' -> { - terminalReader.read() - emit(KeyEvent(Key.F12)) - } - else -> emit(KeyEvent(Key.Unknown)) - } - else -> emit(KeyEvent(Key.Unknown)) - } - } - } else { - emit(KeyEvent(Key.Unknown)) - } - } - } - } - } else { - val firstInputChar = firstInput.toChar() - if (firstInputChar.isISOControl()) { - when (firstInputChar) { - '\u0008', '\u007F' -> emit(KeyEvent(Key.Backspace)) - '\u0009' -> emit(KeyEvent(Key.Tab)) - '\u000D' -> emit(KeyEvent(Key.Enter)) - else -> emit(KeyEvent(Key.Unknown, firstInput)) - } - } else if (firstInputChar.isLetterOrDigit() || firstInputChar.isWhitespace()) { - emit(KeyEvent(Key.Type, firstInputChar.code)) - } else if (firstInputChar.isHighSurrogate()) { - val secondInput = terminalReader.read() - val secondInputChar = secondInput.toChar() - if (secondInputChar.isLowSurrogate()) { - emit(KeyEvent(Key.Type, "$firstInputChar$secondInputChar".codePointAt(0))) - } else { - emit(KeyEvent(Key.Unknown)) - } - } else if (firstInputChar.isDefined()) { - emit(KeyEvent(Key.Type, firstInput)) - } else { - emit(KeyEvent(Key.Unknown, firstInput)) - } - } - } -} diff --git a/settings.gradle b/settings.gradle index f31aae1e..f8d8562c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ rootProject.name = 'mosaic' include ':mosaic-runtime' +include ':mosaic-terminal' include ':samples:counter' include ':samples:demo' @@ -8,4 +9,6 @@ include ':samples:jest' include ':samples:robot' include ':samples:rrtop' +include ':tools:raw-mode-echo' + enableFeaturePreview('TYPESAFE_PROJECT_ACCESSORS') diff --git a/tools/raw-mode-echo/build.gradle b/tools/raw-mode-echo/build.gradle new file mode 100644 index 00000000..6b05e163 --- /dev/null +++ b/tools/raw-mode-echo/build.gradle @@ -0,0 +1,36 @@ +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType + +apply plugin: 'org.jetbrains.kotlin.multiplatform' +apply from: "$rootDir/addAllTargets.gradle" +apply plugin: 'application' + +application { + mainClass = 'example.Main' +} + +kotlin { + // Needed for 'application' plugin. + jvm().withJava() + + sourceSets { + commonMain { + dependencies { + implementation projects.mosaicTerminal + implementation libs.clikt + implementation libs.finalizationHook + } + } + } + + targets.withType(KotlinNativeTarget).configureEach { target -> + target.binaries.executable { + entryPoint = 'example.main' + if (buildType == NativeBuildType.DEBUG) { + linkTaskProvider.configure { + enabled = false + } + } + } + } +} diff --git a/tools/raw-mode-echo/src/commonMain/kotlin/example/input.kt b/tools/raw-mode-echo/src/commonMain/kotlin/example/input.kt new file mode 100644 index 00000000..b26ba38f --- /dev/null +++ b/tools/raw-mode-echo/src/commonMain/kotlin/example/input.kt @@ -0,0 +1,3 @@ +package example + +internal expect fun stdinRead(bytes: ByteArray, offset: Int, length: Int): Int diff --git a/tools/raw-mode-echo/src/commonMain/kotlin/example/main.kt b/tools/raw-mode-echo/src/commonMain/kotlin/example/main.kt new file mode 100644 index 00000000..785f5899 --- /dev/null +++ b/tools/raw-mode-echo/src/commonMain/kotlin/example/main.kt @@ -0,0 +1,90 @@ +@file:JvmName("Main") + +package example + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.options.flag +import com.github.ajalt.clikt.parameters.options.option +import com.jakewharton.finalization.withFinalizationHook +import com.jakewharton.mosaic.terminal.Tty +import kotlin.jvm.JvmName +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking + +fun main(vararg args: String) = RawModeEchoCommand().main(args) + +@OptIn(ExperimentalStdlibApi::class) +private class RawModeEchoCommand : CliktCommand("raw-mode-echo") { + private val all by option().flag() + private val focusEvents by option().flag() + private val kittyKeyEvents by option().flag() + private val mouseEvents by option().flag() + private val inBandResize by option().flag() + private val bracketedPaste by option().flag() + private val colorQuery by option().flag() + + override fun run() = runBlocking { + val values = Channel(UNLIMITED) + launch(Dispatchers.IO) { + val buffer = ByteArray(1024) + while (isActive) { + val read = stdinRead(buffer, 0, 1024) + val hex = buffer.toHexString(endIndex = read) + values.trySend(hex) + if (hex == "03") { + values.close() + break + } + } + } + + val rawMode = Tty.enableRawMode() + withFinalizationHook( + hook = { + rawMode.close() + print("\u001b[?1003l") // Any-event disable + print("\u001b[?1004l") // Focus disable + print("\u001b[?2004l") // Bracketed paste disable + print("\u001b[?2048l") // In-band resize disable + print("\u001b[?25h") // Cursor enable + }, + block = { + print("\u001b[?25l") // Cursor disable + print("\u001b[c") // Primary device attrs + print("\u001b[=c") // Tertiary device attrs + print("\u001b[5n") // Device status report + print("\u001b[>0q") // xterm version + if (all || focusEvents) { + print("\u001b[?1004\$p") // Focus query + print("\u001b[?1004h") // Focus enable + } + if (all || kittyKeyEvents) { + print("\u001b[?u") // Kitty keyboard enable + } + if (all || mouseEvents) { + print("\u001b[?1003h") // Any-event enable + } + if (all || inBandResize) { + print("\u001b[?2048\$p") // In-band resize query + print("\u001b[?2048h") // In-band resize enable + } + if (all || bracketedPaste) { + print("\u001b[?2004h") // Bracketed paste enable + } + if (all || colorQuery) { + print("\u001b[?996n") // Color scheme request + } + + for (value in values) { + print(value) + print("\r\n") + } + }, + ) + } +} diff --git a/tools/raw-mode-echo/src/jvmMain/kotlin/example/input.kt b/tools/raw-mode-echo/src/jvmMain/kotlin/example/input.kt new file mode 100644 index 00000000..c636eefe --- /dev/null +++ b/tools/raw-mode-echo/src/jvmMain/kotlin/example/input.kt @@ -0,0 +1,5 @@ +package example + +internal actual fun stdinRead(bytes: ByteArray, offset: Int, length: Int): Int { + return System.`in`.read(bytes, offset, length) +} diff --git a/tools/raw-mode-echo/src/nativeMain/kotlin/example/input.kt b/tools/raw-mode-echo/src/nativeMain/kotlin/example/input.kt new file mode 100644 index 00000000..0d69149b --- /dev/null +++ b/tools/raw-mode-echo/src/nativeMain/kotlin/example/input.kt @@ -0,0 +1,16 @@ +package example + +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.UnsafeNumber +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.usePinned +import platform.posix.STDIN_FILENO +import platform.posix.read + +@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class) +internal actual fun stdinRead(bytes: ByteArray, offset: Int, length: Int): Int { + return bytes.usePinned { pin -> + read(STDIN_FILENO, pin.addressOf(offset), length.convert()).convert() + } +}