├── .github └── workflows │ ├── build-and-publish-debian-image.yml │ ├── build-and-publish-fedora-image.yml │ ├── build-on-debian.yml │ ├── build-on-fedora.yml │ ├── build-on-ubuntu.yml │ └── build-on-windows.yml ├── .gitignore ├── .run └── examples.run.xml ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── build.gradle.kts ├── ci ├── build-on-remote.sh ├── buildLibrary.sh ├── debian │ ├── Dockerfile │ └── clone-and-build.sh ├── fedora │ ├── Dockerfile │ └── clone-and-build.sh ├── reinstallToMavenLocal.sh └── ubuntu │ ├── Dockerfile │ └── clone-and-build.sh ├── doc ├── c-libraries.uxf ├── concepts.md ├── gen │ ├── README.md │ ├── alias_table.md │ ├── callback_table.md │ ├── enum_table.md │ ├── size_table.md │ └── structure_table.md ├── macos.md ├── overview.html ├── screenshot.png ├── shell.nix └── windows.md ├── examples ├── build.gradle.kts └── src │ └── main │ ├── java │ └── examples │ │ ├── App.java │ │ ├── DemoInterface.java │ │ ├── GioStreams.java │ │ ├── GlibLoop.java │ │ ├── GlibSettings.java │ │ ├── HelloWorld.java │ │ ├── HugeList.java │ │ ├── ImageBridge.java │ │ ├── dnd │ │ └── DragAndDrop.java │ │ ├── geoclue │ │ └── WhereAmI.java │ │ ├── gstreamer │ │ ├── GtkSink.java │ │ └── HelloWorld.java │ │ ├── gtk4_demo │ │ ├── Accordion.java │ │ ├── AppLauncher.java │ │ ├── HeaderBarSample.java │ │ ├── LinksSample.java │ │ ├── PangoTextMask.java │ │ ├── Picker.java │ │ └── Pixbufs.java │ │ ├── gtk4_tutorial │ │ ├── CustomDrawing.java │ │ ├── ExampleApplication.java │ │ ├── HelloWorld.java │ │ └── UiBuilderExample.java │ │ └── libadwaita │ │ ├── README.md │ │ ├── demo │ │ ├── AdwDemoPageAbout.java │ │ ├── AdwDemoPageAvatar.java │ │ ├── AdwDemoPageButtons.java │ │ ├── AdwDemoPageCarousel.java │ │ ├── AdwDemoPageClamp.java │ │ ├── AdwDemoPageDialogs.java │ │ ├── AdwDemoPageFlap.java │ │ ├── AdwDemoPageLeaflet.java │ │ ├── AdwDemoPageLists.java │ │ ├── AdwDemoPageToasts.java │ │ ├── AdwDemoPageViewSwitcher.java │ │ ├── AdwDemoPageWelcome.java │ │ ├── AdwDemoPreferencesWindow.java │ │ ├── AdwDemoWindow.java │ │ ├── AdwFlapDemoWindow.java │ │ ├── AdwViewSwitcherDemoWindow.java │ │ ├── AdwaitaDemo.java │ │ ├── animations │ │ │ ├── AdwDemoPageAnimations.java │ │ │ └── AnimationsUtil.java │ │ ├── styles │ │ │ ├── AdwDemoPageStyles.java │ │ │ └── AdwStyleDemoWindow.java │ │ └── tab_view │ │ │ ├── AdwDemoPageTabView.java │ │ │ ├── AdwTabViewDemoPage.java │ │ │ └── AdwTabViewDemoWindow.java │ │ ├── demo_simple │ │ └── AdwaitaDemo.java │ │ ├── example │ │ └── HelloWorld.java │ │ └── layout │ │ └── SplitViewDemo.java │ └── resources │ ├── GTK.svg │ ├── adw_demo │ ├── adw-demo-page-about.ui │ ├── adw-demo-page-animations.ui │ ├── adw-demo-page-avatar.ui │ ├── adw-demo-page-buttons.ui │ ├── adw-demo-page-carousel.ui │ ├── adw-demo-page-clamp.ui │ ├── adw-demo-page-dialogs.ui │ ├── adw-demo-page-flap.ui │ ├── adw-demo-page-leaflet.ui │ ├── adw-demo-page-list.ui │ ├── adw-demo-page-lists.ui │ ├── adw-demo-page-styles.ui │ ├── adw-demo-page-tab-view.ui │ ├── adw-demo-page-toasts.ui │ ├── adw-demo-page-view-switcher.ui │ ├── adw-demo-page-welcome.ui │ ├── adw-demo-preferences-window.ui │ ├── adw-demo-window.ui │ ├── adw-flap-demo-window.ui │ ├── adw-style-demo-window.ui │ ├── adw-tab-view-demo-page.ui │ ├── adw-tab-view-demo-window.ui │ ├── adw-view-switcher-demo-window.ui │ ├── adwaita-demo.gresources.gresource │ ├── adwaita-demo.gresources.xml │ ├── compile-resources.sh │ ├── data │ │ ├── org.gnome.Adwaita1.Demo-symbolic.svg │ │ ├── org.gnome.Adwaita1.Demo.Source.svg │ │ └── org.gnome.Adwaita1.Demo.svg │ ├── icons │ │ ├── org.example.Typeset.Source.svg │ │ └── scalable │ │ │ ├── actions │ │ │ ├── avatar-delete-symbolic.svg │ │ │ ├── avatar-save-symbolic.svg │ │ │ ├── clock-alarm-symbolic.svg │ │ │ ├── clock-stopwatch-symbolic.svg │ │ │ ├── clock-timer-symbolic.svg │ │ │ ├── clock-world-symbolic.svg │ │ │ ├── gesture-touchpad-swipe-back-symbolic-rtl.svg │ │ │ ├── gesture-touchpad-swipe-back-symbolic.svg │ │ │ ├── gesture-touchscreen-swipe-back-symbolic-rtl.svg │ │ │ ├── gesture-touchscreen-swipe-back-symbolic.svg │ │ │ ├── preferences-window-layout-symbolic.svg │ │ │ ├── preferences-window-search-symbolic.svg │ │ │ ├── row-copy-symbolic.svg │ │ │ ├── row-forbidden-symbolic.svg │ │ │ ├── row-preferences-symbolic.svg │ │ │ ├── row-shutdown-symbolic.svg │ │ │ ├── style-classes-symbolic.svg │ │ │ ├── tab-new-symbolic.svg │ │ │ ├── view-sidebar-end-symbolic-rtl.svg │ │ │ ├── view-sidebar-end-symbolic.svg │ │ │ ├── view-sidebar-start-symbolic-rtl.svg │ │ │ ├── view-sidebar-start-symbolic.svg │ │ │ ├── widget-about-symbolic.svg │ │ │ ├── widget-banner-symbolic.svg │ │ │ ├── widget-carousel-symbolic.svg │ │ │ ├── widget-clamp-symbolic.svg │ │ │ ├── widget-dialog-symbolic.svg │ │ │ ├── widget-flap-symbolic.svg │ │ │ ├── widget-leaflet-symbolic.svg │ │ │ ├── widget-list-symbolic.svg │ │ │ ├── widget-tab-view-symbolic.svg │ │ │ ├── widget-toast-symbolic.svg │ │ │ └── widget-view-switcher-symbolic.svg │ │ │ ├── apps │ │ │ ├── org.example.Typeset.svg │ │ │ └── org.gnome.Boxes.svg │ │ │ └── status │ │ │ ├── dark-mode-symbolic.svg │ │ │ ├── light-mode-symbolic.svg │ │ │ ├── tab-audio-muted-symbolic.svg │ │ │ └── tab-audio-playing-symbolic.svg │ ├── style-dark.css │ └── style.css │ ├── builder-example │ └── window.ui │ ├── css_accordion │ └── css_accordion.css │ ├── example-application │ ├── menu.ui │ ├── preferences.ui │ └── window.ui │ └── pixbufs │ ├── apple-red.png │ ├── background.jpg │ ├── gnome-applets.png │ ├── gnome-calendar.png │ ├── gnome-foot.png │ ├── gnome-gimp.png │ ├── gnome-gmush.png │ ├── gnome-gsame.png │ └── gnu-keys.png ├── generator ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── ch │ │ │ └── bailu │ │ │ └── gtk │ │ │ ├── App.kt │ │ │ ├── Configuration.kt │ │ │ ├── Directories.kt │ │ │ ├── builder │ │ │ ├── AliasBuilder.kt │ │ │ ├── BuilderInterface.kt │ │ │ └── ModelBuilder.kt │ │ │ ├── config │ │ │ ├── DocUrl.kt │ │ │ ├── GtkDocUrl.kt │ │ │ └── StaticUrl.kt │ │ │ ├── log │ │ │ ├── DebugPrint.kt │ │ │ └── Logable.kt │ │ │ ├── model │ │ │ ├── FieldModel.kt │ │ │ ├── ImplementsModel.kt │ │ │ ├── MethodModel.kt │ │ │ ├── Model.kt │ │ │ ├── NamespaceModel.kt │ │ │ ├── ParameterModel.kt │ │ │ ├── StructureModel.kt │ │ │ ├── compose │ │ │ │ ├── ClassComposer.kt │ │ │ │ ├── CodeComposer.kt │ │ │ │ ├── InterfaceComposer.kt │ │ │ │ └── PackageComposer.kt │ │ │ ├── filter │ │ │ │ ├── Filter.kt │ │ │ │ └── ModelList.kt │ │ │ ├── list │ │ │ │ └── ModelLists.kt │ │ │ └── type │ │ │ │ ├── CType.kt │ │ │ │ ├── CTypeConverter.kt │ │ │ │ ├── CallbackType.kt │ │ │ │ ├── ClassType.kt │ │ │ │ ├── JavaType.kt │ │ │ │ ├── NamespaceType.kt │ │ │ │ ├── StructureType.kt │ │ │ │ └── Type.kt │ │ │ ├── parser │ │ │ ├── Parser.kt │ │ │ └── tag │ │ │ │ ├── AliasTag.kt │ │ │ │ ├── CallbackTag.kt │ │ │ │ ├── DocTag.kt │ │ │ │ ├── DocumentTag.kt │ │ │ │ ├── EnumerationTag.kt │ │ │ │ ├── FieldTag.kt │ │ │ │ ├── IgnoreTag.kt │ │ │ │ ├── MemberTag.kt │ │ │ │ ├── MethodTag.kt │ │ │ │ ├── NamedWithDocTag.kt │ │ │ │ ├── NamespaceTag.kt │ │ │ │ ├── ParameterTag.kt │ │ │ │ ├── RepositoryTag.kt │ │ │ │ ├── StructureTag.kt │ │ │ │ ├── Tag.kt │ │ │ │ ├── TagList.kt │ │ │ │ ├── TagWithParent.kt │ │ │ │ └── TypeTag.kt │ │ │ ├── table │ │ │ ├── AliasTable.kt │ │ │ ├── CallbackTable.kt │ │ │ ├── EnumTable.kt │ │ │ ├── NamespaceTable.kt │ │ │ ├── PrimitivesTable.kt │ │ │ ├── ReservedTokenTable.kt │ │ │ ├── SizeTable.kt │ │ │ ├── StructureTable.kt │ │ │ ├── ValueTable.kt │ │ │ └── WrapperTable.kt │ │ │ ├── validator │ │ │ └── Validator.kt │ │ │ └── writer │ │ │ ├── Append.kt │ │ │ ├── CodeWriter.kt │ │ │ ├── Names.kt │ │ │ ├── TextWriter.kt │ │ │ ├── java │ │ │ ├── JavaApiWriter.kt │ │ │ ├── JavaImpWriter.kt │ │ │ └── PackageWriter.kt │ │ │ └── java_doc │ │ │ ├── JavaDoc.kt │ │ │ ├── JavaDocEmpty.kt │ │ │ ├── JavaDocHtml.kt │ │ │ ├── JavaDocPlain.kt │ │ │ └── JavaDocWriter.kt │ └── resources │ │ ├── cairo-custom.gir │ │ └── gir │ │ ├── Adw-1.gir │ │ ├── GLib-2.0.gir │ │ ├── GObject-2.0.gir │ │ ├── Gdk-4.0.gir │ │ ├── GdkPixbuf-2.0.gir │ │ ├── Geoclue-2.0.gir │ │ ├── Gio-2.0.gir │ │ ├── Graphene-1.0.gir │ │ ├── Gsk-4.0.gir │ │ ├── Gst-1.0.gir │ │ ├── Gtk-4.0.gir │ │ ├── Pango-1.0.gir │ │ └── PangoCairo-1.0.gir │ └── test │ └── kotlin │ └── ch │ └── bailu │ └── gtk │ ├── TestAlias.kt │ ├── TestDocWriter.kt │ ├── TestPrimitivesTable.kt │ ├── TestTypeModel.kt │ └── writer │ └── TestNames.kt ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── java-gtk ├── build.gradle.kts └── src │ ├── main │ ├── java │ │ └── ch │ │ │ └── bailu │ │ │ └── gtk │ │ │ ├── gobject │ │ │ └── ObjectClassExtended.java │ │ │ ├── gtk │ │ │ ├── FileChooserDialogExtended.java │ │ │ ├── ValueFactory.java │ │ │ └── WidgetClassExtended.java │ │ │ ├── lib │ │ │ ├── bridge │ │ │ │ ├── Bytes.java │ │ │ │ ├── CSS.java │ │ │ │ ├── GResource.java │ │ │ │ ├── Image.java │ │ │ │ ├── InputStreamBridge.java │ │ │ │ ├── JavaStreams.java │ │ │ │ ├── ListIndex.java │ │ │ │ ├── Matrix.java │ │ │ │ ├── UiBuilder.java │ │ │ │ └── package-info.java │ │ │ ├── handler │ │ │ │ ├── CallbackHandler.java │ │ │ │ ├── ClassHandler.java │ │ │ │ ├── SignalHandler.java │ │ │ │ ├── action │ │ │ │ │ ├── ActionHandler.java │ │ │ │ │ └── ActionHandlerMap.java │ │ │ │ └── package-info.java │ │ │ ├── jna │ │ │ │ ├── AdwLib.java │ │ │ │ ├── GObjectLib.java │ │ │ │ ├── LibraryList.java │ │ │ │ └── Loader.java │ │ │ └── util │ │ │ │ ├── IDGen.java │ │ │ │ ├── JavaResource.java │ │ │ │ ├── MMap.java │ │ │ │ ├── SizeLog.java │ │ │ │ └── package-info.java │ │ │ └── type │ │ │ ├── Array.java │ │ │ ├── Bytes.java │ │ │ ├── Dbl.java │ │ │ ├── Flt.java │ │ │ ├── Imp.java │ │ │ ├── ImpBytes.java │ │ │ ├── ImpDbl.java │ │ │ ├── ImpFlt.java │ │ │ ├── ImpInt.java │ │ │ ├── ImpStr.java │ │ │ ├── Int.java │ │ │ ├── Int64.java │ │ │ ├── Interface.java │ │ │ ├── Outsider.java │ │ │ ├── Package.java │ │ │ ├── Pointer.java │ │ │ ├── PointerCastInterface.java │ │ │ ├── PointerContainer.java │ │ │ ├── PointerInterface.java │ │ │ ├── PropertyHolder.java │ │ │ ├── Record.java │ │ │ ├── Str.java │ │ │ ├── Strs.java │ │ │ ├── Type.java │ │ │ ├── Util.java │ │ │ ├── Wrapper.java │ │ │ ├── exception │ │ │ └── AllocationError.java │ │ │ ├── gobject │ │ │ └── TypeSystem.java │ │ │ └── package-info.java │ └── resources │ │ └── jna │ │ └── loader.properties │ └── test │ ├── java │ └── ch │ │ └── bailu │ │ └── gtk │ │ ├── TestBytes.java │ │ ├── TestCCall.java │ │ ├── TestCPointer.java │ │ ├── TestDbl.java │ │ ├── TestFlt.java │ │ ├── TestGBytes.java │ │ ├── TestGObject.java │ │ ├── TestGdkRectangle.java │ │ ├── TestInt.java │ │ ├── TestIntrospection.java │ │ ├── TestListIndex.java │ │ ├── TestPropertyAccess.java │ │ ├── TestStr.java │ │ ├── TestSurface.java │ │ ├── TestTypeQuery.java │ │ ├── lib │ │ └── bridge │ │ │ └── InputStreamBridgeTest.java │ │ └── type │ │ └── TestPointer.java │ └── resources │ ├── GTK.svg │ └── test.txt ├── jitpack.yml └── settings.gradle.kts /.github/workflows/build-and-publish-debian-image.yml: -------------------------------------------------------------------------------- 1 | name: Create and publish Debian build image 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-and-push-image: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: read 11 | packages: write 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v2 16 | 17 | - name: Log in to the container registry 18 | uses: docker/login-action@v1 19 | with: 20 | registry: ghcr.io 21 | username: ${{ github.actor }} 22 | password: ${{ secrets.GITHUB_TOKEN }} 23 | 24 | - name: Extract metadata (tags, labels) 25 | id: meta 26 | uses: docker/metadata-action@v2 27 | with: 28 | images: ghcr.io/bailuk/java-gtk/gtk4-debian 29 | 30 | - name: Build and push build image 31 | uses: docker/build-push-action@v2 32 | with: 33 | context: ci/debian 34 | push: true 35 | tags: ghcr.io/bailuk/java-gtk/gtk4-debian:latest,${{ steps.meta.outputs.tags }} 36 | labels: ${{ steps.meta.outputs.labels }} 37 | -------------------------------------------------------------------------------- /.github/workflows/build-and-publish-fedora-image.yml: -------------------------------------------------------------------------------- 1 | name: Create and publish Fedora build image 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-and-push-image: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: read 11 | packages: write 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v2 16 | 17 | - name: Log in to the container registry 18 | uses: docker/login-action@v1 19 | with: 20 | registry: ghcr.io 21 | username: ${{ github.actor }} 22 | password: ${{ secrets.GITHUB_TOKEN }} 23 | 24 | - name: Extract metadata (tags, labels) 25 | id: meta 26 | uses: docker/metadata-action@v2 27 | with: 28 | images: ghcr.io/bailuk/java-gtk/gtk4-fedora 29 | 30 | - name: Build and push build image 31 | uses: docker/build-push-action@v2 32 | with: 33 | context: ci/fedora 34 | push: true 35 | tags: ghcr.io/bailuk/java-gtk/gtk4-fedora:latest,${{ steps.meta.outputs.tags }} 36 | labels: ${{ steps.meta.outputs.labels }} 37 | -------------------------------------------------------------------------------- /.github/workflows/build-on-debian.yml: -------------------------------------------------------------------------------- 1 | name: Build on Debian 2 | 3 | on: 4 | push: 5 | branches: [ main, stage ] 6 | pull_request: 7 | branches: [ main, stage ] 8 | workflow_dispatch: 9 | 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | container: 16 | image: ghcr.io/bailuk/java-gtk/gtk4-debian:latest 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: Accept permission 24 | run: git config --global --add safe.directory /__w/java-gtk/java-gtk 25 | 26 | - name: Display tags 27 | run: git tag 28 | 29 | - name: Display version 30 | run: ./gradlew cV 31 | 32 | - name: Generate source code 33 | run: ./gradlew generate 34 | 35 | - name: Build library 36 | run: ./gradlew build 37 | 38 | - name: Upload artifact 39 | uses: actions/upload-artifact@v4 40 | with: 41 | name: java-gtk 42 | path: java-gtk/build/libs/* 43 | if-no-files-found: error 44 | -------------------------------------------------------------------------------- /.github/workflows/build-on-fedora.yml: -------------------------------------------------------------------------------- 1 | name: Build on Fedora 2 | 3 | on: 4 | push: 5 | branches: [ main, stage ] 6 | pull_request: 7 | branches: [ main, stage ] 8 | workflow_dispatch: 9 | 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | container: 16 | image: ghcr.io/bailuk/java-gtk/gtk4-fedora:latest 17 | 18 | steps: 19 | - name: Checkout repository 20 | uses: actions/checkout@v3 21 | with: 22 | fetch-depth: 0 23 | 24 | - name: Accept permission 25 | run: git config --global --add safe.directory /__w/java-gtk/java-gtk 26 | 27 | - name: Display tags 28 | run: git tag 29 | 30 | - name: Display version 31 | run: ./gradlew cV 32 | 33 | - name: Generate source code 34 | run: ./gradlew generate 35 | 36 | - name: Build library 37 | run: ./gradlew build 38 | 39 | - name: Upload artifact 40 | uses: actions/upload-artifact@v4 41 | with: 42 | name: java-gtk 43 | path: java-gtk/build/libs/* 44 | if-no-files-found: error 45 | -------------------------------------------------------------------------------- /.github/workflows/build-on-ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: Build on Ubuntu 2 | 3 | on: 4 | push: 5 | branches: 6 | - '*' 7 | - '!main' 8 | workflow_dispatch: 9 | 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | with: 19 | fetch-depth: 0 20 | 21 | - name: Set up JDK 11 22 | uses: actions/setup-java@v3 23 | with: 24 | distribution: 'zulu' 25 | java-version: 11 26 | 27 | - name: Version 28 | run: ./gradlew cV 29 | 30 | - name: Generate source code 31 | run: ./gradlew generate 32 | 33 | - name: Install GTK-4 34 | run: | 35 | sudo apt-get update 36 | sudo apt-get install -y libgtk-4-1 37 | 38 | - name: Build library 39 | run: ./gradlew build 40 | -------------------------------------------------------------------------------- /.github/workflows/build-on-windows.yml: -------------------------------------------------------------------------------- 1 | name: Build on Windows 2 | 3 | on: 4 | push: 5 | branches: [ main, stage ] 6 | pull_request: 7 | branches: [ main, stage ] 8 | workflow_dispatch: 9 | 10 | env: 11 | JAVA_TOOL_OPTIONS: '-Dfile.encoding=UTF8 -Djava-gtk.headless=true' 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: windows-latest 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | with: 22 | fetch-depth: 0 23 | 24 | - name: Set up JDK 25 | uses: actions/setup-java@v3 26 | with: 27 | distribution: 'zulu' 28 | java-version: 17 29 | 30 | - name: Set up MSYS2 31 | uses: msys2/setup-msys2@v2 32 | with: 33 | msystem: MINGW64 34 | update: true 35 | install: mingw-w64-x86_64-gtk4 36 | 37 | - name: Generate source code 38 | run: ./gradlew generate 39 | 40 | - name: Build library 41 | shell: msys2 {0} 42 | run: ./gradlew build 43 | 44 | - name: Upload generator test reports 45 | if: always() 46 | uses: actions/upload-artifact@v4 47 | with: 48 | name: generator-reports 49 | path: | 50 | generator/build/reports/* 51 | generator/build/*.out 52 | 53 | - name: Upload library test reports 54 | if: always() 55 | uses: actions/upload-artifact@v4 56 | with: 57 | name: library-reports 58 | path: | 59 | java-gtk/build/reports/* 60 | **/*.log 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Generated 2 | /javadoc 3 | 4 | # From https://gist.github.com/dedunumax/54e82214715e35439227 5 | 6 | ## Java 7 | .mtj.tmp/ 8 | *.class 9 | *.jar 10 | *.war 11 | *.ear 12 | *.nar 13 | hs_err_pid* 14 | 15 | ## Gradle 16 | bin/ 17 | build/ 18 | .gradle 19 | .gradletasknamecache 20 | gradle-app.setting 21 | !gradle-wrapper.jar 22 | 23 | ## IntelliJ 24 | out/ 25 | .idea/ 26 | .idea_modules/ 27 | *.iml 28 | *.ipr 29 | *.iws 30 | 31 | ## Eclipse 32 | .settings/ 33 | tmp/ 34 | .metadata 35 | .classpath 36 | .project 37 | *.tmp 38 | *.bak 39 | *.swp 40 | *~.nib 41 | local.properties 42 | .loadpath 43 | .factorypath 44 | 45 | ## NetBeans 46 | nbproject/private/ 47 | nbbuild/ 48 | dist/ 49 | nbdist/ 50 | nbactions.xml 51 | nb-configuration.xml 52 | 53 | ## Visual Studio Code 54 | .vscode/ 55 | .code-workspace 56 | 57 | ## OS X 58 | .DS_Store 59 | 60 | ## nix-shell 61 | /shell.nix 62 | 63 | # Development 64 | todo/ 65 | /ci/qemu/ 66 | -------------------------------------------------------------------------------- /.run/examples.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 - 2025 Lukas Bai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | /** 3 | * https://github.com/allegro/axion-release-plugin 4 | * 5 | * Current build version 6 | * ./gradlew cV 7 | * 8 | */ 9 | id ("pl.allegro.tech.build.axion-release") version "1.18.18" 10 | } 11 | 12 | project.version = scmVersion.version 13 | -------------------------------------------------------------------------------- /ci/build-on-remote.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # build this project on a remote device via ssh 4 | # usage: ./build-on-remote.sh host 5 | 6 | test -f gradlew || cd .. 7 | 8 | host=$1 9 | arch=`ssh ${host} uname -m` 10 | 11 | echo "build on ${host} for ${arch}" 12 | 13 | ssh ${host} "test -d git || mkdir git" || exit 1 14 | scp ci/debian/clone-and-build.sh mobian:git || exit 1 15 | ssh ${host} "chmod +x git/clone-and-build.sh" || exit 1 16 | ssh ${host} "cd git && ./clone-and-build.sh 3" || exit 1 17 | -------------------------------------------------------------------------------- /ci/buildLibrary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # use `make` instead 4 | # 5 | # compile and build library 6 | 7 | test -f gradlew || cd .. 8 | 9 | echo 10 | echo "Build java archives" 11 | ./gradlew -q java-gtk:build || exit 1 12 | find java-gtk/ -name *.jar 13 | -------------------------------------------------------------------------------- /ci/debian/Dockerfile: -------------------------------------------------------------------------------- 1 | # Creates an image containing everything to build this project 2 | # Based on https://hub.docker.com/_/debian/ 3 | 4 | # podman build -t build-on-debian . 5 | # podman run -it --name build-on-debian build-on-debian 6 | # -> ./clone-and-build.sh 7 | 8 | 9 | FROM docker.io/debian:trixie 10 | LABEL version="0.7.0" 11 | 12 | ENV JAVA_TOOL_OPTIONS "-Dfile.encoding=UTF-8" 13 | 14 | COPY clone-and-build.sh clone-and-build.sh 15 | RUN chmod +x clone-and-build.sh 16 | 17 | RUN apt-get -y update 18 | RUN apt-get -y upgrade 19 | RUN apt-get -y install git 20 | RUN apt-get -y install openjdk-21-jdk-headless 21 | RUN apt-get -y install libgtk-4-1 22 | RUN apt-get -y install libadwaita-1-0 23 | RUN apt-get -y clean 24 | -------------------------------------------------------------------------------- /ci/debian/clone-and-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | test -d java-gtk || git clone "https://github.com/bailuk/java-gtk.git" || exit 1 4 | 5 | cd java-gtk || exit 1 6 | git pull || exit 1 7 | 8 | ./gradlew generate || exit 1 9 | ./gradlew build 10 | -------------------------------------------------------------------------------- /ci/fedora/Dockerfile: -------------------------------------------------------------------------------- 1 | # A fedora based build image 2 | # Based on https://hub.docker.com/_/fedora/ 3 | 4 | # podman build -f Dockerfile -t build-on-fedora 5 | # podman run -it --name build-on-fedora build-on-fedora:latest 6 | # => ./clone-and-build.sh 7 | 8 | FROM docker.io/fedora:39 9 | LABEL version="0.5.0" 10 | 11 | ENV JAVA_TOOL_OPTIONS "-Dfile.encoding=UTF8" 12 | ENV JAVA_HOME "/lib/jvm/jre" 13 | 14 | COPY clone-and-build.sh clone-and-build.sh 15 | RUN chmod +x clone-and-build.sh 16 | 17 | RUN dnf -y upgrade 18 | RUN dnf -y install java-17-openjdk 19 | RUN dnf -y install java-17-openjdk-devel 20 | RUN dnf -y install git 21 | RUN dnf -y install gtk4 22 | RUN dnf -y install libadwaita 23 | RUN dnf -y clean all 24 | -------------------------------------------------------------------------------- /ci/fedora/clone-and-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | test -d java-gtk || git clone "https://github.com/bailuk/java-gtk.git" || exit 1 4 | 5 | cd java-gtk || exit 1 6 | git pull || exit 1 7 | 8 | ./gradlew generate || exit 1 9 | ./gradlew build 10 | -------------------------------------------------------------------------------- /ci/reinstallToMavenLocal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # use `make install` instead 4 | 5 | test -f gradlew || cd .. 6 | 7 | repoDir="${HOME}/.m2/repository/ch/bailu/java-gtk/" 8 | 9 | echo 10 | echo "Remove 'java-gtk' from local Maven repository" 11 | rm -r ${repoDir} 12 | 13 | echo 14 | echo "Install 'java-gtk' to local Maven repository" 15 | ./gradlew -q publishToMavenLocal || exit 1 16 | find ${repoDir} 17 | -------------------------------------------------------------------------------- /ci/ubuntu/Dockerfile: -------------------------------------------------------------------------------- 1 | # A Ubuntu based build image 2 | # 3 | # This should be as identical as possible with the official GitHub Actions Ubuntu image 4 | # https://github.com/actions/runner-images 5 | # 6 | # Based on https://hub.docker.com/_/ubuntu/ 7 | 8 | # podman build -f Dockerfile -t build-on-ubuntu 9 | # podman run -it --name build-on-ubuntu build-on-ubuntu:latest 10 | # => ./clone-and-build.sh 11 | 12 | FROM docker.io/ubuntu:latest 13 | LABEL version="0.1.0" 14 | 15 | ENV JAVA_TOOL_OPTIONS "-Dfile.encoding=UTF8" 16 | 17 | COPY clone-and-build.sh clone-and-build.sh 18 | RUN chmod +x clone-and-build.sh 19 | 20 | RUN apt-get -y update 21 | RUN apt-get -y upgrade 22 | RUN apt-get -y install git 23 | RUN apt-get -y install openjdk-11-jdk-headless 24 | RUN apt-get -y install libgtk-4-1 25 | RUN apt-get -y clean 26 | -------------------------------------------------------------------------------- /ci/ubuntu/clone-and-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | test -d java-gtk || git clone "https://github.com/bailuk/java-gtk.git" || exit 1 4 | 5 | cd java-gtk || exit 1 6 | git pull || exit 1 7 | 8 | ./gradlew generate || exit 1 9 | ./gradlew build 10 | -------------------------------------------------------------------------------- /doc/concepts.md: -------------------------------------------------------------------------------- 1 | # Types 2 | 3 | ## Pointer 4 | 5 | `Pointer` is the base class for all Generated Types (GObject Classes, GObject Records and GObject Interfaces) and 6 | the base class for Wrapper Types (Int, Byte, Str ...) 7 | 8 | `Pointer` holds a `PointerContainer` and `PointerContainer` holds a `long` that contains a c/native pointer. 9 | Any java-gtk type is just a c-pointer with an API. 10 | 11 | `Pointer` and `PointerContainer` implement `PointerInterface`. `PointerInterface` provides casting functions 12 | to cast between different Pointer types: `cast()`, `asPointer()`, `asCPointer()`, `asJnaPointer()` 13 | 14 | `Pointer` is also derived from `Type`, which offers static variants of this type casting functions. 15 | 16 | See 'Interfaces' for an example 17 | 18 | ## Casting 19 | 20 | `cast()` returns a `PointerContainer`, any sub class of `Pointer` offers a constructor taking a `PointerContainer` as 21 | parameter. 22 | 23 | This allows for casting between java-gtk types. 24 | 25 | Of course type casting should only be applied if both types are compatible, like for accessing the implementing class 26 | of an interface. The static `cast()` function (of `Type`) can be used to get a `PointerContainer` from other pointer representation (c-pointer, JnaPointer). 27 | 28 | See 'Interfaces' for an example 29 | 30 | ## Interfaces 31 | 32 | GObject interfaces are represented by separate classes. Generated GObject Classes offer `asInterfaceName()` functions to 33 | access their interface APIs. 34 | 35 | In this Example widget, buildable und button reference the same object: 36 | 37 | ```java 38 | // access Buildable interface of Button (Widget) 39 | Widget widget = new Button(); 40 | 41 | Buildable buildable = widget.asBuildable(); 42 | Str id = buildable.getBuildableId() // access interface API 43 | 44 | // cast back to button 45 | Button button = new Button(buildable.cast()); 46 | button.setLabel("ID: " + id.toString()); 47 | ``` 48 | -------------------------------------------------------------------------------- /doc/gen/README.md: -------------------------------------------------------------------------------- 1 | # ch.bailu.gtk.Configuration 2 | 3 | ## Namespaces 4 | 5 | | GIR File | Library | Documentation 6 | |----------|---------|-------------- 7 | | GObject-2.0.gir | gobject-2.0 | [https://docs.gtk.org/](https://docs.gtk.org/) 8 | | Gtk-4.0.gir | gtk-4 | [https://docs.gtk.org/](https://docs.gtk.org/) 9 | | Gio-2.0.gir | gio-2.0 | [https://docs.gtk.org/](https://docs.gtk.org/) 10 | | Gdk-4.0.gir | gtk-4 | [https://docs.gtk.org/](https://docs.gtk.org/) 11 | | Gsk-4.0.gir | gtk-4 | [https://docs.gtk.org/](https://docs.gtk.org/) 12 | | Graphene-1.0.gir | graphene-1.0 | [https://ebassi.github.io/graphene/docs/](https://ebassi.github.io/graphene/docs/) 13 | | PangoCairo-1.0.gir | pangocairo-1.0 | [https://docs.gtk.org/](https://docs.gtk.org/) 14 | | cairo-custom.gir | cairo | [https://www.cairographics.org/manual/](https://www.cairographics.org/manual/) 15 | | GLib-2.0.gir | glib-2.0 | [https://docs.gtk.org/](https://docs.gtk.org/) 16 | | Pango-1.0.gir | pango-1.0 | [https://docs.gtk.org/](https://docs.gtk.org/) 17 | | GdkPixbuf-2.0.gir | gdk_pixbuf-2.0 | [https://docs.gtk.org/](https://docs.gtk.org/) 18 | | Geoclue-2.0.gir | geoclue-2 | [https://www.freedesktop.org/software/geoclue/docs/libgeoclue/](https://www.freedesktop.org/software/geoclue/docs/libgeoclue/) 19 | | Adw-1.gir | adwaita-1 | [https://gnome.pages.gitlab.gnome.org/libadwaita/doc/](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/) 20 | | Gst-1.0.gir | gstreamer-1.0 | [https://gstreamer.freedesktop.org/documentation/gstreamer/gi-index.html](https://gstreamer.freedesktop.org/documentation/gstreamer/gi-index.html) 21 | 22 | ## Tables 23 | 24 | - [structure_table.md](structure_table.md) 25 | - [alias_table.md](alias_table.md) 26 | - [callback_table.md](callback_table.md) 27 | - [enum_table.md](enum_table.md) 28 | - [size_table.md](size_table.md) 29 | 30 | --- 31 | **Autogenerated**. Run `./gradlew generate-update-doc` to update in [/doc/gen](/doc/gen) 32 | -------------------------------------------------------------------------------- /doc/gen/alias_table.md: -------------------------------------------------------------------------------- 1 | # ch.bailu.gtk.table.AliasTable 2 | 3 | | From | To 4 | |--------------------------------|--- 5 | | gst.BufferMapInfo | gst.MapInfo 6 | | gst.ClockID | gst.gpointer 7 | | glib.RecMutexLocker | glib.none 8 | | glib.Strv | glib.utf8 9 | | glib.Quark | glib.guint32 10 | | pango.LayoutRun | pango.GlyphItem 11 | | gst.ElementFactoryListType | gst.guint64 12 | | gst.MemoryMapInfo | gst.MapInfo 13 | | gobject.Type | gobject.gsize 14 | | gst.ClockTimeDiff | gst.gint64 15 | | gobject.SignalCMarshaller | gobject.ClosureMarshal 16 | | glib.MutexLocker | glib.none 17 | | glib.RWLockWriterLocker | glib.none 18 | | gtk.Allocation | gdk.Rectangle 19 | | glib.String | glib.GString 20 | | glib.DateDay | glib.guint8 21 | | pango.Glyph | pango.guint32 22 | | glib.MainContextPusher | glib.none 23 | | gobject.SignalCVaMarshaller | gobject.VaClosureMarshal 24 | | glib.Pid | glib.gint 25 | | glib.RefString | glib.gchar 26 | | gst.ClockTime | gst.guint64 27 | | glib.Time | glib.gint32 28 | | pango.GlyphUnit | pango.gint32 29 | | glib.DateYear | glib.guint16 30 | | glib.RWLockReaderLocker | glib.none 31 | | glib.TimeSpan | glib.gint64 32 | 33 | --- 34 | **Autogenerated**. Run `./gradlew generate-update-doc` to update in [/doc/gen](/doc/gen) 35 | -------------------------------------------------------------------------------- /doc/gen/size_table.md: -------------------------------------------------------------------------------- 1 | # ch.bailu.gtk.table.SizeTable 2 | 3 | | Type | Size 4 | |--------------------------------|----- 5 | | gobject.TypeInterface | 16 6 | | gobject.TypeClass | 8 7 | 8 | --- 9 | **Autogenerated**. Run `./gradlew generate-update-doc` to update in [/doc/gen](/doc/gen) 10 | -------------------------------------------------------------------------------- /doc/macos.md: -------------------------------------------------------------------------------- 1 | # Using java-gtk on MacOS 2 | 3 | ## Install GTK libraries 4 | 5 | [Setting up GTK for Mac OS ](https://www.gtk.org/docs/installations/macos/) 6 | 7 | ## Running a java-gtk application 8 | 9 | On MacOS the main thread of a java-gtk application needs to be thread 0. 10 | In order to start the application on the correct thread the option `-XstartOnFirstThread` needs to be passed to the JVM 11 | 12 | Example: `./gradlew run -Dorg.gradle.jvmargs="-XstartOnFirstThread"` 13 | -------------------------------------------------------------------------------- /doc/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | GTK 4 bindings for Java 5 |

6 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /doc/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/doc/screenshot.png -------------------------------------------------------------------------------- /doc/shell.nix: -------------------------------------------------------------------------------- 1 | # Development environment with nix-shell 2 | { pkgs ? import {} 3 | }: 4 | pkgs.mkShell { 5 | name="java-gtk"; 6 | buildInputs = [ 7 | pkgs.git 8 | pkgs.jdk21_headless # Non headless is linked against gtk3 and does therefore not work 9 | pkgs.gtk4 10 | ]; 11 | shellHook = '' 12 | LD_LIBRARY_PATH=${pkgs.gtk4.outPath}/lib 13 | LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.glib.out.outPath}/lib 14 | LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.gdk-pixbuf.outPath}/lib 15 | LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.cairo.outPath}/lib 16 | LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.pango.out.outPath}/lib 17 | LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${pkgs.libadwaita.outPath}/lib 18 | export LD_LIBRARY_PATH 19 | echo "./gradlew generate && ./gradlew build && ./gradlew run" 20 | ''; 21 | } 22 | -------------------------------------------------------------------------------- /examples/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | application 3 | } 4 | repositories { 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | implementation(project(":java-gtk")) 10 | } 11 | 12 | application { 13 | val example = "examples.App" 14 | mainClass.set(example) 15 | } 16 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/DemoInterface.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import ch.bailu.gtk.gtk.Window; 4 | import ch.bailu.gtk.type.Str; 5 | 6 | public interface DemoInterface { 7 | Window runDemo(); 8 | Str getTitle(); 9 | Str getDescription(); 10 | } 11 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/GioStreams.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import ch.bailu.gtk.type.exception.AllocationError; 4 | import ch.bailu.gtk.gio.DataInputStream; 5 | import ch.bailu.gtk.gio.File; 6 | import ch.bailu.gtk.type.Str; 7 | 8 | /** 9 | * https://www.packtpub.com/product/gnome-3-application-development-beginner-s-guide/9781849519427 10 | */ 11 | public class GioStreams { 12 | public GioStreams() { 13 | var file = File.newForUri(new Str("https://docs.gtk.org/gio/class.IOStream.html")); 14 | 15 | try { 16 | var stream = file.read(null); 17 | var inputStream = new DataInputStream(stream); 18 | 19 | var data = inputStream.readUpto(new Str(""),0, null,null); 20 | System.out.println(data.toString()); 21 | 22 | data.destroy(); 23 | stream.close(null); 24 | } catch (AllocationError allocationError) { 25 | allocationError.printStackTrace(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/GlibLoop.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | import ch.bailu.gtk.glib.GlibConstants; 5 | import ch.bailu.gtk.glib.MainLoop; 6 | 7 | public class GlibLoop { 8 | private final MainLoop loop; 9 | static int timers = 0; 10 | 11 | public static void main(String[] args) { 12 | new GlibLoop(); 13 | } 14 | 15 | 16 | public GlibLoop() { 17 | loop = new MainLoop(Glib.mainContextDefault(), false); 18 | new Timer("Timer one", 777); 19 | new Timer("Timer two", 1024); 20 | loop.run(); 21 | } 22 | 23 | private class Timer { 24 | private int count = 10; 25 | 26 | public Timer(String name, int interval) { 27 | int result = Glib.timeoutAdd(interval, (cb, user_data) -> { 28 | if (count > 0) { 29 | System.out.println(name + ": timeout " + count-- + " received"); 30 | return GlibConstants.SOURCE_CONTINUE; 31 | } else { 32 | System.out.println(name + ": done"); 33 | return remove(); 34 | } 35 | }, null); 36 | 37 | if (result > 0) timers++; 38 | } 39 | 40 | public boolean remove() { 41 | if (--timers == 0) { 42 | loop.quit(); 43 | } 44 | return GlibConstants.SOURCE_REMOVE; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/GlibSettings.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import ch.bailu.gtk.gio.Settings; 4 | import ch.bailu.gtk.gtk.Box; 5 | import ch.bailu.gtk.gtk.Label; 6 | import ch.bailu.gtk.gtk.Orientation; 7 | import ch.bailu.gtk.gtk.Window; 8 | import ch.bailu.gtk.type.Str; 9 | 10 | /** 11 | * https://wiki.gnome.org/Apps/DconfEditor 12 | * 13 | * 14 | */ 15 | public class GlibSettings implements DemoInterface { 16 | private static final Str TITLE = new Str("Load settings (GlibSettings)"); 17 | private static final Str SETTINGS = new Str("org.gnome.desktop.background"); 18 | private static final Str ENTRY = new Str("picture-uri"); 19 | 20 | @Override 21 | public Window runDemo() { 22 | var window = new Window(); 23 | var box = new Box(Orientation.VERTICAL, 5); 24 | box.setMarginBottom(5); 25 | box.setMarginEnd(5); 26 | box.setMarginStart(5); 27 | box.setMarginTop(5); 28 | 29 | var label = new Label(SETTINGS); 30 | box.append(label); 31 | 32 | label = new Label(ENTRY); 33 | box.append(label); 34 | 35 | Str response = loadEntry(); 36 | label = new Label(response); 37 | box.append(label); 38 | response.destroy(); 39 | 40 | window.setChild(box); 41 | return window; 42 | } 43 | 44 | Str loadEntry() { 45 | var settings = new Settings(SETTINGS); 46 | if (settings.isNotNull()) { 47 | Str str = settings.getString(ENTRY); 48 | if (str.isNotNull()) { 49 | System.out.println(str); 50 | return str; 51 | } 52 | } 53 | return new Str("error"); 54 | } 55 | 56 | @Override 57 | public Str getTitle() { 58 | return TITLE; 59 | } 60 | 61 | @Override 62 | public Str getDescription() { 63 | return TITLE; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import ch.bailu.gtk.gio.ApplicationFlags; 4 | import ch.bailu.gtk.gtk.Application; 5 | import ch.bailu.gtk.gtk.ApplicationWindow; 6 | import ch.bailu.gtk.gtk.Button; 7 | import ch.bailu.gtk.type.Strs; 8 | 9 | public class HelloWorld { 10 | public static void main(String[] args) { 11 | var app = new Application("com.example.GtkApplication", 12 | ApplicationFlags.FLAGS_NONE); 13 | 14 | app.onActivate(() -> { 15 | // Create a new window 16 | var window = new ApplicationWindow(app); 17 | 18 | // Create a new button 19 | var button = new Button(); 20 | 21 | // Set button label 22 | button.setLabel("Hello, World!"); 23 | 24 | // When the button is clicked, close the window 25 | button.onClicked(window::close); 26 | 27 | window.setChild(button); 28 | window.show(); 29 | }); 30 | 31 | // Start application main loop 32 | var result = app.run(args.length, new Strs(args)); 33 | 34 | // Terminate with exit code 35 | System.exit(result); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/dnd/DragAndDrop.java: -------------------------------------------------------------------------------- 1 | package examples.dnd; 2 | 3 | import ch.bailu.gtk.gdk.GdkConstants; 4 | import ch.bailu.gtk.gio.ApplicationFlags; 5 | import ch.bailu.gtk.gio.File; 6 | import ch.bailu.gtk.gtk.Application; 7 | import ch.bailu.gtk.gtk.ApplicationWindow; 8 | import ch.bailu.gtk.gtk.DropTarget; 9 | import ch.bailu.gtk.gtk.Label; 10 | import ch.bailu.gtk.type.Str; 11 | import ch.bailu.gtk.type.Strs; 12 | 13 | /** 14 | * https://docs.gtk.org/gtk4/drag-and-drop.html 15 | */ 16 | public class DragAndDrop { 17 | public final static Str ID = new Str("org.gtk.example.dnd"); 18 | 19 | public static void main(String[] args) { 20 | 21 | var app = new Application(ID, ApplicationFlags.FLAGS_NONE); 22 | app.onActivate(() -> { 23 | // Get and initialize application window 24 | var window = new ApplicationWindow(app); 25 | window.setTitle("Drag and drop demo"); 26 | window.setDefaultSize(400,300); 27 | 28 | // Create a label to display dropped files 29 | var label = new Label("Drop files here"); 30 | label.setHexpand(true); 31 | label.setVexpand(true); 32 | 33 | // Crate drop target 34 | var target = new DropTarget(File.getTypeID(), GdkConstants.ACTION_ALL); 35 | target.onDrop((value, x, y) -> { 36 | System.out.println("dropped"); 37 | var file = new File(value.getObject().cast()); 38 | label.setText(file.getBasename()); 39 | return true; 40 | }); 41 | 42 | // Make the label a drop target 43 | label.addController(target); 44 | 45 | // Compose and display 46 | window.setChild(label); 47 | window.show(); 48 | }); 49 | 50 | 51 | System.exit(app.run(args.length, new Strs(args))); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/gstreamer/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package examples.gstreamer; 2 | 3 | import ch.bailu.gtk.gst.Gst; 4 | import ch.bailu.gtk.gst.GstConstants; 5 | import ch.bailu.gtk.gst.MessageType; 6 | import ch.bailu.gtk.gst.State; 7 | import ch.bailu.gtk.type.Int; 8 | import ch.bailu.gtk.type.Pointer; 9 | import ch.bailu.gtk.type.Str; 10 | import ch.bailu.gtk.type.exception.AllocationError; 11 | 12 | /** 13 | * Basic tutorial 1: Hello world! 14 | */ 15 | public class HelloWorld { 16 | public static void main(String[] args) throws AllocationError { 17 | Gst.init(Int.NULL, Pointer.NULL); 18 | 19 | var url = new Str("playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm"); 20 | var pipeline = Gst.parseLaunch(url); 21 | pipeline.setState(State.PLAYING); 22 | 23 | var bus = pipeline.getBus(); 24 | var msg = bus.timedPopFiltered(GstConstants.CLOCK_TIME_NONE, MessageType.ERROR | MessageType.EOS); 25 | 26 | 27 | /* TODO: `Message` has a field `mini_object` with size 0. This is not supported. 28 | if (msg.getFieldType() == MessageType.ERROR) { 29 | System.err.println("An error occurred! Re-run with the GST_DEBUG=*:WARN environment variable set for more details."); 30 | } 31 | */ 32 | 33 | msg.destroy(); 34 | bus.unref(); 35 | pipeline.setState(State.NULL); 36 | pipeline.unref(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/gtk4_demo/Accordion.java: -------------------------------------------------------------------------------- 1 | package examples.gtk4_demo; 2 | 3 | import ch.bailu.gtk.gtk.Align; 4 | import ch.bailu.gtk.gtk.Box; 5 | import ch.bailu.gtk.gtk.Button; 6 | import ch.bailu.gtk.gtk.Orientation; 7 | import ch.bailu.gtk.gtk.Window; 8 | import ch.bailu.gtk.lib.bridge.CSS; 9 | import ch.bailu.gtk.type.Str; 10 | import examples.DemoInterface; 11 | 12 | public class Accordion implements DemoInterface { 13 | private static Str name = new Str("CSS Accordion"); 14 | 15 | @Override 16 | public Window runDemo() { 17 | var window = new Window(); 18 | window.setDefaultSize(600, 300); 19 | 20 | var container = new Box(Orientation.HORIZONTAL, 0); 21 | container.setHalign(Align.CENTER); 22 | container.setValign(Align.CENTER); 23 | 24 | container.append(Button.newWithLabelButton("This")); 25 | container.append(Button.newWithLabelButton("Is")); 26 | container.append(Button.newWithLabelButton("A")); 27 | container.append(Button.newWithLabelButton("CSS")); 28 | container.append(Button.newWithLabelButton("Accordion")); 29 | container.append(Button.newWithLabelButton(":-)")); 30 | 31 | window.setChild(container); 32 | 33 | try { 34 | CSS.addProviderRecursive(window, "/css_accordion/css_accordion.css"); 35 | } catch (Exception e) { 36 | System.err.println(e.getMessage()); 37 | } 38 | 39 | window.show(); 40 | return window; 41 | } 42 | 43 | @Override 44 | public Str getTitle() { 45 | return name; 46 | } 47 | 48 | @Override 49 | public Str getDescription() { 50 | return name; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/gtk4_demo/LinksSample.java: -------------------------------------------------------------------------------- 1 | package examples.gtk4_demo; 2 | 3 | import ch.bailu.gtk.gtk.Label; 4 | import ch.bailu.gtk.gtk.Window; 5 | import ch.bailu.gtk.type.Str; 6 | import examples.DemoInterface; 7 | 8 | public class LinksSample implements DemoInterface { 9 | 10 | private static final Str TITLE = new Str("Links"); 11 | private static final Str LABEL = new Str( 12 | "Some text may be marked up\n" + 14 | "as hyperlinks, which can be clicked\n" + 15 | "or activated via keynav\n" + 16 | "and they work fine with other markup, like when\n" + 17 | "searching on " + 18 | "Go" + 19 | "og" + 20 | "le" + 21 | "." 22 | ); 23 | 24 | @Override 25 | public Window runDemo() { 26 | var window = new Window(); 27 | Label label = new Label(LABEL); 28 | 29 | label.setUseMarkup(true); 30 | label.onActivateLink(uri -> { 31 | System.out.println("link clicked"); 32 | return false; 33 | }); 34 | window.setChild(label); 35 | label.show(); 36 | return window; 37 | } 38 | 39 | @Override 40 | public Str getTitle() { 41 | return TITLE; 42 | } 43 | 44 | @Override 45 | public Str getDescription() { 46 | return TITLE; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/gtk4_tutorial/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package examples.gtk4_tutorial; 2 | 3 | import ch.bailu.gtk.gio.ApplicationFlags; 4 | import ch.bailu.gtk.gtk.Application; 5 | import ch.bailu.gtk.gtk.ApplicationWindow; 6 | import ch.bailu.gtk.gtk.Button; 7 | import ch.bailu.gtk.gtk.Grid; 8 | import ch.bailu.gtk.type.Str; 9 | import ch.bailu.gtk.type.Strs; 10 | 11 | /** 12 | * https://docs.gtk.org/gtk4/getting_started.html 13 | */ 14 | public class HelloWorld { 15 | 16 | public HelloWorld(String[] args) { 17 | final var app = new Application(new Str("org.gtk.example"), ApplicationFlags.FLAGS_NONE); 18 | app.onActivate(() -> { 19 | final var window = new ApplicationWindow(app); 20 | 21 | window.setTitle(new Str("Window")); 22 | window.setDefaultSize(200,200); 23 | 24 | var grid = new Grid(); 25 | window.setChild(grid); 26 | 27 | var buttonHello = Button.newWithLabelButton(new Str("Hello")); 28 | buttonHello.onClicked(()->System.out.println("Hello")); 29 | grid.attach(buttonHello,0,0,1,1); 30 | 31 | var buttonWorld = Button.newWithLabelButton(new Str("World")); 32 | buttonWorld.onClicked(()->System.out.println("World")); 33 | grid.attach(buttonWorld,1,0,1,1); 34 | 35 | var buttonQuit = Button.newWithLabelButton(new Str("Quit")); 36 | buttonQuit.onClicked(()->window.destroy()); 37 | grid.attach(buttonQuit, 0,1,2,1); 38 | 39 | window.show(); 40 | }); 41 | app.run(args.length, new Strs(args)); 42 | app.unref(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/gtk4_tutorial/UiBuilderExample.java: -------------------------------------------------------------------------------- 1 | package examples.gtk4_tutorial; 2 | 3 | import java.io.IOException; 4 | 5 | import ch.bailu.gtk.type.exception.AllocationError; 6 | import ch.bailu.gtk.gtk.Application; 7 | import ch.bailu.gtk.gtk.Button; 8 | import ch.bailu.gtk.gtk.Window; 9 | import ch.bailu.gtk.lib.bridge.UiBuilder; 10 | import ch.bailu.gtk.type.Str; 11 | import examples.DemoInterface; 12 | 13 | public class UiBuilderExample implements DemoInterface { 14 | private static final Str TITLE = new Str("UI builder demo"); 15 | 16 | private final Application application; 17 | 18 | public UiBuilderExample(Application app) { 19 | this.application = app; 20 | } 21 | 22 | @Override 23 | public Window runDemo() { 24 | 25 | try { 26 | var builder = UiBuilder.fromResource("/builder-example/window.ui"); 27 | 28 | var window = new Window(builder.getObject("window")); 29 | window.setApplication(application); 30 | 31 | var button1 = new Button(builder.getObject("button1")); 32 | button1.onClicked(() -> System.out.println("Hello from button1")); 33 | 34 | var button2 = new Button(builder.getObject("button2")); 35 | button2.onClicked(() -> System.out.println("Hello from button2")); 36 | 37 | var quit = new Button(builder.getObject("quit")); 38 | quit.onClicked(window::close); 39 | 40 | return window; 41 | } catch (AllocationError | IOException e) { 42 | System.err.println(e.getMessage()); 43 | 44 | } 45 | return new Window(); 46 | } 47 | 48 | 49 | @Override 50 | public Str getTitle() { 51 | return TITLE; 52 | } 53 | 54 | @Override 55 | public Str getDescription() { 56 | return TITLE; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/README.md: -------------------------------------------------------------------------------- 1 | # libadwaita demo 2 | 3 | ## [demo_simple](demo_simple) 4 | 5 | Simple POC adwaita demo ported from [https://github.com/Northshore-Hero/libadwaita-demo](https://github.com/Northshore-Hero/libadwaita-demo) 6 | 7 | 8 | ## [demo](demo) 9 | 10 | Almost complete port of the official libadwaita demo [https://gitlab.gnome.org/GNOME/libadwaita/-/blob/main/demo](https://gitlab.gnome.org/GNOME/libadwaita/-/blob/main/demo) 11 | 12 | Demonstrates how typical patterns can be implemented in Java. 13 | 14 | Uses convenience methods from `java-gtk/src/main/java/ch/bailu/gtk/type/gobject/TypeSystem.java`, 15 | `java-gtk/src/main/java/ch/bailu/gtk/gobject/ObjectClassExtended.java` and `java-gtk/src/main/java/ch/bailu/gtk/gtk/WidgetClassExtended.java` 16 | 17 | *Resource loading* is done directly via Java Resources where possible and indirectly 18 | from a gresource file located in the `java/resources` directory file as a workaround. 19 | 20 | *Overloading of virtual functions* is not yet supported by the generated API. 21 | 22 | Demo can be executed by running the main function located here: [demo/AdwaitaDemo.java](demo/AdwaitaDemo.java) 23 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/AdwDemoPageButtons.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.type.Str; 6 | import ch.bailu.gtk.type.gobject.TypeSystem; 7 | 8 | public class AdwDemoPageButtons { 9 | private final static Str TYPE_NAME = new Str(AdwDemoPageButtons.class.getSimpleName()); 10 | 11 | private static long type = 0; 12 | public synchronized static long getTypeID() { 13 | if (type == 0) { 14 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 15 | var widgetClass = new WidgetClassExtended(g_class.cast()); 16 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-buttons.ui"); 17 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 18 | } 19 | return type; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/AdwDemoPageClamp.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.type.Str; 6 | import ch.bailu.gtk.type.gobject.TypeSystem; 7 | 8 | public class AdwDemoPageClamp extends Bin { 9 | private final static Str TYPE_NAME = new Str(AdwDemoPageClamp.class.getSimpleName()); 10 | 11 | private static long type = 0; 12 | public synchronized static long getTypeID() { 13 | if (type == 0) { 14 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 15 | var widgetClass = new WidgetClassExtended(g_class.cast()); 16 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-clamp.ui"); 17 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 18 | } 19 | return type; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/AdwDemoPageFlap.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.gtk.Window; 6 | import ch.bailu.gtk.type.PointerContainer; 7 | import ch.bailu.gtk.type.Str; 8 | import ch.bailu.gtk.type.gobject.TypeSystem; 9 | 10 | public class AdwDemoPageFlap extends Bin { 11 | private final static Str TYPE_NAME = new Str(AdwDemoPageFlap.class.getSimpleName()); 12 | private static long type = 0; 13 | 14 | private AdwDemoPageFlap(PointerContainer self) { 15 | super(self); 16 | } 17 | 18 | private void onRunDemo() { 19 | var window = new AdwFlapDemoWindow(); 20 | window.setTransientFor(new Window(this.getRoot().cast())); 21 | window.present(); 22 | } 23 | 24 | public synchronized static long getTypeID() { 25 | if (type == 0) { 26 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 27 | var widgetClass = new WidgetClassExtended(g_class.cast()); 28 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-flap.ui"); 29 | widgetClass.installAction("demo.run", null, (__self1, self, action_name, parameter) -> new AdwDemoPageFlap(self.cast()).onRunDemo()); 30 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 31 | } 32 | return type; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/AdwDemoPageLists.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.adw.Toast; 5 | import ch.bailu.gtk.gobject.Gobject; 6 | import ch.bailu.gtk.gobject.ObjectClassExtended; 7 | import ch.bailu.gtk.gtk.WidgetClassExtended; 8 | import ch.bailu.gtk.lib.handler.SignalHandler; 9 | import ch.bailu.gtk.type.Pointer; 10 | import ch.bailu.gtk.type.Str; 11 | import ch.bailu.gtk.type.gobject.TypeSystem; 12 | 13 | public class AdwDemoPageLists { 14 | private final static Str TYPE_NAME = new Str(AdwDemoPageLists.class.getSimpleName()); 15 | private static long type = 0; 16 | 17 | public synchronized static long getTypeID() { 18 | if (type == 0) { 19 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 20 | var widgetClass = new WidgetClassExtended(g_class.cast()); 21 | var objectClass = new ObjectClassExtended(g_class.cast()); 22 | 23 | final var signal = objectClass.signalNew(AdwDemoPageToasts.ADD_TOAST_SIGNAL, TypeSystem.GTYPE_NONE, Toast.getTypeID()); 24 | 25 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-list.ui"); 26 | widgetClass.bindTemplateCallback("entry_apply_cb", (SignalHandler.SignalCallback) self -> { 27 | final var toast = new Toast("Changes applied"); 28 | Gobject.signalEmit(Pointer.asPointer(self), signal, 0, toast.asCPointer()); 29 | }); 30 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 31 | } 32 | return type; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/AdwDemoPageViewSwitcher.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.gtk.Window; 6 | import ch.bailu.gtk.type.PointerContainer; 7 | import ch.bailu.gtk.type.Str; 8 | import ch.bailu.gtk.type.gobject.TypeSystem; 9 | 10 | public class AdwDemoPageViewSwitcher extends Bin { 11 | private final static Str TYPE_NAME = new Str(AdwDemoPageViewSwitcher.class.getSimpleName()); 12 | 13 | private static long type = 0; 14 | 15 | public AdwDemoPageViewSwitcher(PointerContainer pointer) { 16 | super(pointer); 17 | } 18 | 19 | 20 | public synchronized static long getTypeID() { 21 | if (type == 0) { 22 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 23 | var widgetClass = new WidgetClassExtended(g_class.cast()); 24 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-view-switcher.ui"); 25 | widgetClass.installAction("demo.run", null, (__self1, widget, action_name, parameter) -> new AdwDemoPageViewSwitcher(widget.cast()).runDemo()); 26 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 27 | } 28 | return type; 29 | } 30 | 31 | private void runDemo() { 32 | var window = new AdwViewSwitcherDemoWindow(); 33 | window.setTransientFor(new Window(getRoot().cast())); 34 | window.present(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/AdwDemoPageWelcome.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.type.Str; 6 | import ch.bailu.gtk.type.gobject.TypeSystem; 7 | 8 | public class AdwDemoPageWelcome extends Bin { 9 | private final static Str TYPE_NAME = new Str(AdwDemoPageWelcome.class.getSimpleName()); 10 | 11 | private static long type = 0; 12 | public synchronized static long getTypeID() { 13 | if (type == 0) { 14 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 15 | var widgetClass = new WidgetClassExtended(g_class.cast()); 16 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-welcome.ui"); 17 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 18 | } 19 | return type; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/AdwViewSwitcherDemoWindow.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo; 2 | 3 | import ch.bailu.gtk.adw.Window; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.type.Str; 6 | import ch.bailu.gtk.type.gobject.TypeSystem; 7 | 8 | public class AdwViewSwitcherDemoWindow extends Window { 9 | private final static Str TYPE_NAME = new Str(AdwViewSwitcherDemoWindow.class.getSimpleName()); 10 | private static long type = 0; 11 | 12 | public AdwViewSwitcherDemoWindow() { 13 | super(TypeSystem.newInstance(getTypeID())); 14 | } 15 | 16 | public synchronized static long getTypeID() { 17 | if (type == 0) { 18 | type = TypeSystem.registerClass(Window.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 19 | var widgetClass = new WidgetClassExtended(g_class.cast()); 20 | widgetClass.setTemplateOrExit("/adw_demo/adw-view-switcher-demo-window.ui"); 21 | }, (__self, instance, g_class) -> new Window(instance.cast()).initTemplate()); 22 | } 23 | return type; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/styles/AdwDemoPageStyles.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo.styles; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.gtk.Window; 6 | import ch.bailu.gtk.type.Str; 7 | import ch.bailu.gtk.type.gobject.TypeSystem; 8 | 9 | public class AdwDemoPageStyles { 10 | private final static Str TYPE_NAME = new Str(AdwDemoPageStyles.class.getSimpleName()); 11 | 12 | private static long type = 0; 13 | public synchronized static long getTypeID() { 14 | if (type == 0) { 15 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 16 | var widgetClass = new WidgetClassExtended(g_class.cast()); 17 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-styles.ui"); 18 | 19 | widgetClass.installAction("demo.run", null, (__self1, widget, action_name, parameter) -> { 20 | var window = new AdwStyleDemoWindow(); 21 | window.setTransientFor(new Window(widget.getRoot().cast())); 22 | window.present(); 23 | }); 24 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 25 | } 26 | return type; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/demo/tab_view/AdwDemoPageTabView.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.demo.tab_view; 2 | 3 | import ch.bailu.gtk.adw.Bin; 4 | import ch.bailu.gtk.gtk.WidgetClassExtended; 5 | import ch.bailu.gtk.gtk.Window; 6 | import ch.bailu.gtk.type.Str; 7 | import ch.bailu.gtk.type.gobject.TypeSystem; 8 | 9 | public class AdwDemoPageTabView extends Bin { 10 | private final static Str TYPE_NAME = new Str(AdwDemoPageTabView.class.getSimpleName()); 11 | 12 | private static long type = 0; 13 | 14 | public synchronized static long getTypeID() { 15 | if (type == 0) { 16 | type = TypeSystem.registerClass(Bin.getTypeID(), TYPE_NAME, 0, (__self, g_class, class_data) -> { 17 | var widgetClass = new WidgetClassExtended(g_class.cast()); 18 | System.err.println("Adw.TabOverview since: 1.3"); 19 | widgetClass.setTemplateOrExit("/adw_demo/adw-demo-page-tab-view.ui"); 20 | 21 | widgetClass.installAction("demo.run", null, (__self1, widget, action_name, parameter) -> { 22 | var window = new AdwTabViewDemoWindow(); 23 | window.setTransientFor(new Window(widget.getRoot().cast())); 24 | window.present(); 25 | }); 26 | }, (__self, instance, g_class) -> new Bin(instance.cast()).initTemplate()); 27 | } 28 | return type; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/src/main/java/examples/libadwaita/example/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package examples.libadwaita.example; 2 | 3 | import ch.bailu.gtk.adw.Application; 4 | import ch.bailu.gtk.adw.Bin; 5 | import ch.bailu.gtk.gtk.ApplicationWindow; 6 | import ch.bailu.gtk.gtk.Label; 7 | import ch.bailu.gtk.type.Str; 8 | import ch.bailu.gtk.type.Strs; 9 | 10 | public class HelloWorld { 11 | public static void main(String[] args) { 12 | var app = new Application(new Str("org.example.Hello"), 0); 13 | 14 | app.onActivate(() -> { 15 | var bin = new Bin(); 16 | var win = new ApplicationWindow(app); 17 | var label = new Label(new Str("Hello")); 18 | win.setTitle(new Str("Hello")); 19 | win.setDefaultSize(200, 200); 20 | win.setChild(bin); 21 | bin.setChild(label); 22 | win.present(); 23 | }); 24 | 25 | app.run(0, Strs.NULL); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /examples/src/main/resources/GTK.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-demo-page-about.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | 25 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-demo-page-dialogs.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | 25 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-demo-page-flap.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | 25 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-demo-page-styles.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | 25 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-demo-page-tab-view.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | 25 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-demo-page-view-switcher.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 24 | 25 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-demo-page-welcome.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adw-tab-view-demo-page.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/adwaita-demo.gresources.gresource: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/adw_demo/adwaita-demo.gresources.gresource -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/compile-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | glib-compile-resources adwaita-demo.gresources.xml 4 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/avatar-delete-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/avatar-save-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/preferences-window-search-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/row-copy-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/row-forbidden-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/row-preferences-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/row-shutdown-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/tab-new-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/view-sidebar-end-symbolic-rtl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/view-sidebar-end-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/view-sidebar-start-symbolic-rtl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/view-sidebar-start-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-about-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-banner-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-carousel-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-clamp-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-dialog-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-flap-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-tab-view-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-toast-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/actions/widget-view-switcher-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/status/light-mode-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/status/tab-audio-muted-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/icons/scalable/status/tab-audio-playing-symbolic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/style-dark.css: -------------------------------------------------------------------------------- 1 | #custom-button-1 { 2 | color: @red_1; 3 | } 4 | 5 | #custom-button-2 { 6 | color: @purple_1; 7 | } 8 | 9 | .tab-page-color-1 { 10 | background: shade(@blue_5, 0.7); 11 | } 12 | 13 | .tab-page-color-2 { 14 | background: shade(@green_5, 0.6); 15 | } 16 | 17 | .tab-page-color-3 { 18 | background: shade(@yellow_5, 0.5); 19 | } 20 | 21 | .tab-page-color-4 { 22 | background: shade(@orange_5, 0.6); 23 | } 24 | 25 | .tab-page-color-5 { 26 | background: shade(@red_5, 0.7); 27 | } 28 | 29 | .tab-page-color-6 { 30 | background: shade(@purple_5, 0.7); 31 | } 32 | 33 | .tab-page-color-7 { 34 | background: shade(@brown_5, 0.7); 35 | } 36 | 37 | .tab-page-color-8 { 38 | background: #363636; 39 | } 40 | -------------------------------------------------------------------------------- /examples/src/main/resources/adw_demo/style.css: -------------------------------------------------------------------------------- 1 | stacksidebar { 2 | border-left-width: 0px; 3 | border-right-width: 0px; 4 | } 5 | 6 | /* Mimic the status page. */ 7 | .avatar-page, 8 | .timed-animation-page { 9 | margin: 36px 12px; 10 | } 11 | 12 | .avatar-page > box > label.title, 13 | .timed-animation-page > box > label.title { 14 | margin-bottom: 12px; 15 | } 16 | 17 | .avatar-page > box > label.description { 18 | margin-bottom: 36px; 19 | } 20 | 21 | flowbox.inline flowboxchild { 22 | padding: 0; 23 | background: none; 24 | color: inherit; 25 | } 26 | 27 | #custom-button-1 { 28 | color: @red_3; 29 | } 30 | 31 | #custom-button-2 { 32 | color: @purple_3; 33 | } 34 | 35 | #custom-button-3 { 36 | color: white; 37 | background-color: @green_5; 38 | } 39 | 40 | #custom-button-4 { 41 | color: white; 42 | background-color: @orange_4; 43 | } 44 | 45 | #animation-sample { 46 | min-width: 30px; 47 | min-height: 30px; 48 | border-radius: 24px; 49 | background: linear-gradient(to bottom, @green_2, @green_5); 50 | } 51 | 52 | .tab-page-color-1 { 53 | background: shade(@blue_1, 1.2); 54 | } 55 | 56 | .tab-page-color-2 { 57 | background: shade(@green_1, 1.2); 58 | } 59 | 60 | .tab-page-color-3 { 61 | background: shade(@yellow_1, 1.2); 62 | } 63 | 64 | .tab-page-color-4 { 65 | background: shade(@orange_1, 1.2); 66 | } 67 | 68 | .tab-page-color-5 { 69 | background: shade(@red_1, 1.4); 70 | } 71 | 72 | .tab-page-color-6 { 73 | background: shade(@purple_1, 1.3); 74 | } 75 | 76 | .tab-page-color-7 { 77 | background: shade(@brown_1, 1.3); 78 | } 79 | 80 | .tab-page-color-8 { 81 | background: white; 82 | } 83 | -------------------------------------------------------------------------------- /examples/src/main/resources/builder-example/window.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Grid 5 | 6 | 7 | 8 | 9 | 10 | Button 1 11 | 12 | 13 | 0 14 | 15 | 0 16 | 17 | 18 | 19 | 20 | 21 | 22 | Button 2 23 | 24 | 25 | 1 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | 33 | Quit 34 | 35 | 36 | 0 37 | 38 | 1 39 | 2 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /examples/src/main/resources/css_accordion/css_accordion.css: -------------------------------------------------------------------------------- 1 | 2 | * { 3 | all: unset; 4 | } 5 | 6 | 7 | * { 8 | transition-property: color, background-color, border-color, background-image, padding, border-width; 9 | transition-duration: 1s; 10 | 11 | font: 20px Cantarell; 12 | } 13 | 14 | window { 15 | background: linear-gradient(153deg, #151515, #151515 5px, transparent 5px) 0 0, 16 | linear-gradient(333deg, #151515, #151515 5px, transparent 5px) 10px 5px, 17 | linear-gradient(153deg, #222, #222 5px, transparent 5px) 0 5px, 18 | linear-gradient(333deg, #222, #222 5px, transparent 5px) 10px 10px, 19 | linear-gradient(90deg, #1b1b1b, #1b1b1b 10px, transparent 10px), 20 | linear-gradient(#1d1d1d, #1d1d1d 25%, #1a1a1a 25%, #1a1a1a 50%, transparent 50%, transparent 75%, #242424 75%, #242424); 21 | background-color: #131313; 22 | background-size: 20px 20px; 23 | } 24 | 25 | button { 26 | color: black; 27 | background-color: #bbb; 28 | border-style: solid; 29 | border-width: 2px 0 2px 2px; 30 | border-color: #333; 31 | 32 | padding: 12px 4px; 33 | } 34 | 35 | button:first-child { 36 | border-radius: 5px 0 0 5px; 37 | } 38 | 39 | button:last-child { 40 | border-radius: 0 5px 5px 0; 41 | border-width: 2px; 42 | } 43 | 44 | button:hover { 45 | padding: 12px 48px; 46 | background-color: #4870bc; 47 | } 48 | 49 | button *:hover { 50 | color: white; 51 | } 52 | 53 | button:hover:active, 54 | button:active { 55 | background-color: #993401; 56 | } 57 | -------------------------------------------------------------------------------- /examples/src/main/resources/example-application/menu.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | _Words 7 | app.show-words 8 | 9 | 10 | _Preferences 11 | app.preferences 12 | 13 |
14 |
15 | 16 | _Quit 17 | app.quit 18 | 19 |
20 |
21 |
22 | -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/apple-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/apple-red.png -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/background.jpg -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/gnome-applets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/gnome-applets.png -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/gnome-calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/gnome-calendar.png -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/gnome-foot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/gnome-foot.png -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/gnome-gimp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/gnome-gimp.png -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/gnome-gmush.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/gnome-gmush.png -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/gnome-gsame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/gnome-gsame.png -------------------------------------------------------------------------------- /examples/src/main/resources/pixbufs/gnu-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/examples/src/main/resources/pixbufs/gnu-keys.png -------------------------------------------------------------------------------- /generator/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | plugins { 3 | java 4 | 5 | // https://kotlinlang.org/docs/gradle-configure-project.html 6 | kotlin("jvm") version "2.1.10" 7 | } 8 | 9 | repositories { 10 | mavenCentral() 11 | } 12 | 13 | dependencies { 14 | // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter 15 | testImplementation("org.junit.jupiter:junit-jupiter:5.12.1") 16 | 17 | // https://mvnrepository.com/artifact/net.sf.kxml/kxml2 18 | // xml parser implementation 19 | implementation("net.sf.kxml:kxml2:2.3.0") 20 | 21 | } 22 | 23 | testing { 24 | suites { 25 | val test by getting(JvmTestSuite::class) { 26 | useJUnitJupiter() 27 | } 28 | } 29 | } 30 | 31 | tasks.register("generate-update-doc", JavaExec::class) { 32 | description = "Generate source code from introspective files and update meta documentation" 33 | registerGeneratorTask(this) 34 | args(setOf("-l", "../doc/gen")) 35 | } 36 | 37 | tasks.register("generate", JavaExec::class) { 38 | description = "Generate source code from introspective files" 39 | registerGeneratorTask(this) 40 | } 41 | 42 | 43 | fun registerGeneratorTask(task: JavaExec) { 44 | task.dependsOn("build") 45 | description = "Generate source code from introspective files" 46 | task.classpath = sourceSets["main"].runtimeClasspath 47 | task.mainClass.set("ch.bailu.gtk.AppKt") 48 | task.args(setOf("-j", "${project.rootDir}/java-gtk/build/generated/src/main/java/ch/bailu/gtk/")) 49 | } 50 | 51 | tasks.compileJava { 52 | options.compilerArgs.add("-Xlint:deprecation") 53 | options.compilerArgs.add("-Xlint:unchecked") 54 | } 55 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/builder/AliasBuilder.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.builder 2 | 3 | import ch.bailu.gtk.NamespaceConfig 4 | import ch.bailu.gtk.model.type.NamespaceType 5 | import ch.bailu.gtk.parser.tag.* 6 | import ch.bailu.gtk.table.* 7 | import ch.bailu.gtk.table.AliasTable.convert 8 | 9 | 10 | class AliasBuilder : BuilderInterface{ 11 | private var namespace = "" 12 | 13 | override fun buildStructure(structure: StructureTag) { 14 | StructureTable.add(namespace, convert(namespace, structure.getName()), structure.getType.isNotEmpty(), structure.isTypeStructFor) 15 | } 16 | 17 | private fun convert(namespace: String, name: String): String { 18 | return convert(NamespaceType(namespace, name)).name 19 | } 20 | 21 | override fun buildNamespaceStart(namespace: NamespaceTag, namespaceConfig: NamespaceConfig) { 22 | this.namespace = namespace.getName().lowercase() 23 | NamespaceTable.add(this.namespace, namespaceConfig) 24 | } 25 | 26 | override fun buildNamespaceEnd() {} 27 | 28 | override fun buildAlias(aliasTag: AliasTag) { 29 | AliasTable.add(namespace, aliasTag.getName(), aliasTag.getTypeName()) 30 | } 31 | 32 | override fun buildEnumeration(enumeration: EnumerationTag) { 33 | EnumTable.add(NamespaceType(namespace, enumeration.getName())) 34 | EnumTable.add(NamespaceType(namespace, enumeration.type)) 35 | } 36 | 37 | override fun buildCallback(callbackTag: CallbackTag) { 38 | CallbackTable.add(namespace, callbackTag) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/builder/BuilderInterface.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.builder 2 | 3 | import ch.bailu.gtk.NamespaceConfig 4 | import ch.bailu.gtk.parser.tag.* 5 | import java.io.IOException 6 | 7 | interface BuilderInterface { 8 | @Throws(IOException::class) 9 | fun buildStructure(structure: StructureTag) 10 | fun buildNamespaceStart(namespace: NamespaceTag, namespaceConfig: NamespaceConfig) 11 | 12 | @Throws(IOException::class) 13 | fun buildNamespaceEnd() 14 | fun buildAlias(aliasTag: AliasTag) 15 | 16 | @Throws(IOException::class) 17 | fun buildEnumeration(enumeration: EnumerationTag) 18 | 19 | @Throws(IOException::class) 20 | fun buildCallback(callbackTag: CallbackTag) 21 | } 22 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/config/DocUrl.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.config 2 | 3 | import ch.bailu.gtk.model.StructureModel 4 | 5 | abstract class DocUrl { 6 | abstract fun getUrl(structureModel: StructureModel): String 7 | abstract fun getBaseUrl(): String 8 | } 9 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/config/GtkDocUrl.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.config 2 | 3 | import ch.bailu.gtk.model.StructureModel 4 | import ch.bailu.gtk.model.type.StructureType 5 | 6 | class GtkDocUrl(private val baseUrl: String, private val section: String): DocUrl() { 7 | 8 | override fun getUrl(structureModel: StructureModel): String { 9 | val type = getType(structureModel.structureType) 10 | 11 | return if ("" == type) { 12 | baseUrl 13 | } else { 14 | "${baseUrl}${section}/${type}.${structureModel.apiName}.html" 15 | } 16 | } 17 | 18 | override fun getBaseUrl(): String { 19 | return baseUrl 20 | } 21 | 22 | private fun getType(structureType: StructureType): String { 23 | return when { 24 | structureType.compare(StructureType.Types.RECORD) -> { 25 | "struct" 26 | } 27 | structureType.compare(StructureType.Types.CLASS) -> { 28 | "class" 29 | } 30 | structureType.compare(StructureType.Types.INTERFACE) -> { 31 | "iface" 32 | } 33 | structureType.compare(StructureType.Types.CALLBACK) -> { 34 | "callback" 35 | } 36 | else -> { 37 | "" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/config/StaticUrl.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.config 2 | 3 | import ch.bailu.gtk.model.StructureModel 4 | 5 | class StaticUrl(val url: String): DocUrl() { 6 | override fun getUrl(structureModel: StructureModel): String { 7 | return url 8 | } 9 | 10 | override fun getBaseUrl(): String { 11 | return url 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/log/DebugPrint.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.log 2 | 3 | import ch.bailu.gtk.model.Model 4 | import ch.bailu.gtk.model.type.Type 5 | import ch.bailu.gtk.parser.tag.TagWithParent 6 | 7 | object DebugPrint { 8 | 9 | fun colon(tag: TagWithParent, vararg strings: String): String { 10 | return colonList(tag::class.simpleName?: "", strings.toList(), "(", ")") 11 | } 12 | 13 | fun colon(model: Model, vararg strings: String): String { 14 | return colonList(model::class.simpleName?: "", strings.toList()) 15 | } 16 | 17 | fun colon(type: Type, vararg strings: String): String { 18 | return colonList(type.getDebugIdentifier(), strings.toList(), "{", "}") 19 | } 20 | 21 | private fun colonList(model: String, strings: List, open: String = "[", close : String = "]"): String { 22 | val builder = StringBuilder() 23 | builder.append(open).append(model) 24 | for (s in strings) { 25 | builder.append(':') 26 | builder.append(s) 27 | } 28 | return builder.append(close).toString() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/log/Logable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.log 2 | 3 | import java.io.Writer 4 | 5 | interface Logable { 6 | fun log(writer: Writer) 7 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/ImplementsModel.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model 2 | 3 | import ch.bailu.gtk.log.DebugPrint 4 | import ch.bailu.gtk.model.type.ClassType 5 | import ch.bailu.gtk.parser.tag.NamedWithDocTag 6 | 7 | /** 8 | * A class can implement interfaces: 9 | * 10 | */ 11 | class ImplementsModel(private val currentNamespace: String, tag: NamedWithDocTag): Model() { 12 | private val classType: ClassType = 13 | ClassType(currentNamespace, tag.getName(), tag.getName()) 14 | 15 | /** 16 | * API Type name including namespace if not current namespace 17 | */ 18 | val apiTypeName: String 19 | get() = classType.getApiTypeName(currentNamespace) 20 | 21 | /** 22 | * API Type name without namespace 23 | */ 24 | val name: String 25 | get() = classType.type.name 26 | 27 | init { 28 | setSupported("type-not-supported", classType.valid) 29 | } 30 | 31 | override fun toString(): String { 32 | return DebugPrint.colon(this, supportedState, classType.toString()) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/Model.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model 2 | 3 | abstract class Model { 4 | var isSupported = true 5 | private set 6 | 7 | var supportedState = "Supported" 8 | private set 9 | 10 | var isPublic = true 11 | private set 12 | 13 | var visibleState = "Public" 14 | private set 15 | 16 | fun setSupported(reason: String, supported: Boolean) { 17 | if (!supported) { 18 | if (isSupported) { 19 | isSupported = false 20 | supportedState = reason 21 | } else { 22 | supportedState += ":${reason}" 23 | } 24 | } 25 | } 26 | 27 | fun setPrivate(reason: String, private: Boolean) { 28 | if (private) { 29 | if (isPublic) { 30 | isPublic = false 31 | this.visibleState = reason 32 | } else { 33 | this.visibleState += ":${reason}" 34 | } 35 | } 36 | } 37 | 38 | fun setPublic(reason: String, public: Boolean) { 39 | setPrivate(reason, !public) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/NamespaceModel.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model 2 | 3 | import ch.bailu.gtk.Configuration 4 | import ch.bailu.gtk.NamespaceConfig 5 | import ch.bailu.gtk.model.type.NamespaceType 6 | import ch.bailu.gtk.parser.tag.MethodTag 7 | import ch.bailu.gtk.parser.tag.NamespaceTag 8 | import ch.bailu.gtk.parser.tag.ParameterTag 9 | import ch.bailu.gtk.table.NamespaceTable 10 | 11 | class NamespaceModel( 12 | val namespace: String = "", 13 | val library: String = "", 14 | val functions: List = ArrayList(), 15 | val constants: List = ArrayList(), 16 | val infoDocUrl: String = "", 17 | val infoGirFile: String = "", 18 | val infoNamespace: String = "", 19 | val infoVersion: String = "", 20 | val infoSharedLibrary: String = "" 21 | ) : Model() { 22 | 23 | 24 | constructor(tag: NamespaceTag, config: NamespaceConfig) : 25 | this( 26 | namespace = tag.getName().lowercase(), 27 | library = config.library, 28 | functions = tag.getFunctions(), 29 | constants = tag.getConstants(), 30 | infoDocUrl = config.docUrl.getBaseUrl(), 31 | infoVersion = tag.version, 32 | infoNamespace = tag.getName(), 33 | infoGirFile = config.girFile, 34 | infoSharedLibrary = tag.sharedLibrary 35 | ) { 36 | setSupported("unknown-namespace", NamespaceTable.contains(namespace)) 37 | } 38 | 39 | constructor(type: NamespaceType) : this(type.namespace) { 40 | setSupported("unknown-namespace", NamespaceTable.contains(namespace)) 41 | } 42 | 43 | val fullNamespace: String 44 | get() = if ("" == namespace) { 45 | Configuration.BASE_NAME_SPACE_NODOT 46 | } else { 47 | Configuration.BASE_NAME_SPACE_DOT + namespace 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/compose/ClassComposer.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.compose 2 | 3 | import ch.bailu.gtk.model.NamespaceModel 4 | import ch.bailu.gtk.model.StructureModel 5 | import ch.bailu.gtk.model.filter.filterCreateMallocConstructor 6 | import ch.bailu.gtk.model.list.ModelLists 7 | import ch.bailu.gtk.writer.CodeWriter 8 | 9 | class ClassComposer : CodeComposer() { 10 | 11 | override fun compose(writer: CodeWriter, namespaceModel: NamespaceModel, structureModel: StructureModel, models: ModelLists) { 12 | 13 | writer.writeClass(structureModel) 14 | 15 | models.callbacks.forEach { writer.writeCallback(structureModel, it) } 16 | models.signals.forEach { writer.writeCallback(structureModel, it, true) } 17 | 18 | writer.writeInternalConstructor(structureModel) 19 | 20 | if (structureModel.isRecord && models.fields.isNotEmpty()) { 21 | if (filterCreateMallocConstructor(structureModel)) { 22 | writer.writeMallocConstructor(structureModel) 23 | } 24 | 25 | writer.writeBeginStruct(structureModel, models.fields) 26 | models.fields.forEach { writer.writeField(structureModel, it) } 27 | writer.writeEndStruct() 28 | } 29 | 30 | writer.writeBeginInstance(namespaceModel) 31 | models.privateFactories.forEach { writer.writePrivateFactory(structureModel, it) } 32 | models.factories.forEach { writer.writeFactory(structureModel, it) } 33 | models.constructors.forEach { writer.writeConstructor(structureModel, it) } 34 | models.methods.forEach { writer.writeMethod(structureModel, it) } 35 | models.signals.forEach { writer.writeSignal(structureModel, it) } 36 | models.functions.forEach { writer.writeFunction(structureModel, it) } 37 | models.implements.forEach { writer.writeImplements(it)} 38 | writer.writeIntrospection(structureModel) 39 | writer.writeEndInstance() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/compose/CodeComposer.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.compose 2 | 3 | import ch.bailu.gtk.model.NamespaceModel 4 | import ch.bailu.gtk.model.StructureModel 5 | import ch.bailu.gtk.model.list.ModelLists 6 | import ch.bailu.gtk.model.type.StructureType 7 | import ch.bailu.gtk.writer.CodeWriter 8 | 9 | abstract class CodeComposer { 10 | 11 | companion object { 12 | fun factory(structureType: StructureType): CodeComposer { 13 | return if (structureType.isPackage) { 14 | PackageComposer() 15 | } else if (structureType.isClassType) { 16 | ClassComposer() 17 | } else { 18 | InterfaceComposer() 19 | } 20 | } 21 | } 22 | abstract fun compose(writer: CodeWriter, namespaceModel: NamespaceModel, structureModel: StructureModel, models: ModelLists) 23 | 24 | fun write(writer: CodeWriter, namespaceModel: NamespaceModel, structureModel: StructureModel, models: ModelLists) { 25 | writeStart(writer, structureModel) 26 | compose(writer, namespaceModel, structureModel, models) 27 | writeEnd(writer, structureModel, models) 28 | } 29 | 30 | private fun writeStart(writer: CodeWriter, structureModel: StructureModel) { 31 | writer.writeStart(structureModel, structureModel.nameSpaceModel) 32 | } 33 | 34 | fun writeEnd(writer: CodeWriter, structureModel: StructureModel, models: ModelLists) { 35 | writer.writeClassEnd() 36 | writer.writeDebugBegin(structureModel) 37 | for (m in models.unsupported) { 38 | writer.writeDebugUnsupported(m) 39 | } 40 | writer.writeDebugEnd() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/compose/InterfaceComposer.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.compose 2 | 3 | import ch.bailu.gtk.model.NamespaceModel 4 | import ch.bailu.gtk.model.StructureModel 5 | import ch.bailu.gtk.model.list.ModelLists 6 | import ch.bailu.gtk.writer.CodeWriter 7 | 8 | class InterfaceComposer : CodeComposer() { 9 | 10 | override fun compose(writer: CodeWriter, namespaceModel: NamespaceModel, structureModel: StructureModel, models: ModelLists) { 11 | writer.writeInterface(structureModel) 12 | for (p in models.constants) { 13 | writer.writeConstant(structureModel, p) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/compose/PackageComposer.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.compose 2 | 3 | import ch.bailu.gtk.model.NamespaceModel 4 | import ch.bailu.gtk.model.StructureModel 5 | import ch.bailu.gtk.model.list.ModelLists 6 | import ch.bailu.gtk.writer.CodeWriter 7 | 8 | class PackageComposer : CodeComposer() { 9 | 10 | override fun compose(writer: CodeWriter, namespaceModel: NamespaceModel, structureModel: StructureModel, models: ModelLists) { 11 | writer.writeClass(structureModel) 12 | for (cb in models.callbacks) { 13 | writer.writeCallback(structureModel, cb) 14 | } 15 | 16 | writer.writeBeginInstance(namespaceModel) 17 | for (m in models.functions) { 18 | writer.writeFunction(structureModel, m) 19 | } 20 | writer.writeEndInstance() 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/filter/Filter.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.filter 2 | 3 | import ch.bailu.gtk.model.MethodModel 4 | import ch.bailu.gtk.model.StructureModel 5 | 6 | /** 7 | * See [ch.bailu.gtk.table.ValueTable] for converted values 8 | */ 9 | fun filterValues(value: String): Boolean { 10 | return ("9223372036854775807" != value // G_MAXINT64 11 | && "-9223372036854775808" != value // G_MININT64 12 | && "86400000000" != value // TIME_SPAN_DAY 13 | && "3600000000" != value) // TIME_SPAN_HOUR 14 | } 15 | 16 | fun filterMethod(structureModel: StructureModel, methodModel: MethodModel): Boolean { 17 | if ("PrintUnixDialog" == structureModel.apiName && "getSettings" == methodModel.apiName) { 18 | return false 19 | } 20 | if ("ActionRow" == structureModel.apiName && "activate" == methodModel.apiName) { 21 | return false 22 | } 23 | if ("DataInputStream" == structureModel.apiName && "readByte" == methodModel.apiName) { 24 | return false // overrides function with different return type 25 | } 26 | return true 27 | } 28 | 29 | 30 | fun filterField(): Boolean { 31 | return true 32 | } 33 | 34 | fun filterCreateMallocConstructor(structureModel: StructureModel): Boolean { 35 | return structureModel.allFieldsAreSupported && !structureModel.disguised 36 | } 37 | 38 | fun filterParent(parent: String): String { 39 | if ("Object" == parent || "ch.bailu.gtk.gobject.Object" == parent) { 40 | return "ch.bailu.gtk.type.PropertyHolder" 41 | } 42 | return parent 43 | } 44 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/filter/ModelList.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.filter 2 | 3 | import ch.bailu.gtk.model.Model 4 | 5 | class ModelList(private val unsupported: ArrayList = ArrayList()) : java.util.ArrayList() { 6 | 7 | fun addIfSupported(model: T) { 8 | addIfSupported(model, model.isSupported) 9 | } 10 | 11 | fun addIfSupported(model: T, supported: Boolean) { 12 | if (supported) { 13 | add(model) 14 | } else { 15 | unsupported.add(model) 16 | } 17 | } 18 | 19 | override fun add(element: T): Boolean { 20 | return if (contains(element)) { 21 | false 22 | } else { 23 | super.add(element) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/list/ModelLists.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.list 2 | 3 | import ch.bailu.gtk.model.* 4 | import ch.bailu.gtk.model.filter.ModelList 5 | 6 | class ModelLists { 7 | 8 | val unsupported: ModelList = ModelList() 9 | val privateFactories = ModelList(unsupported) 10 | val factories = ModelList(unsupported) 11 | val constructors = ModelList(unsupported) 12 | val methods = ModelList(unsupported) 13 | val signals = ModelList(unsupported) 14 | val callbacks = ModelList(unsupported) 15 | val functions = ModelList(unsupported) 16 | val fields = ModelList(unsupported) 17 | val constants = ModelList(unsupported) 18 | val implements = ModelList(unsupported) 19 | 20 | fun addIfSupportedWithCallbacks(models: ModelList, methodModel: MethodModel) { 21 | models.addIfSupported(methodModel) 22 | if (methodModel.isSupported) { 23 | methodModel.callbackModel.forEach {callbacks.add(it)} 24 | } 25 | } 26 | 27 | fun hasNativeCalls(): Boolean { 28 | return methods.size > 0 || privateFactories.size > 0 || signals.size > 0 || fields.size > 0 || functions.size > 0 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/type/CType.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.type 2 | 3 | import ch.bailu.gtk.log.DebugPrint 4 | import java.util.regex.Pattern 5 | 6 | class CType(type: String) : Type() { 7 | companion object { 8 | private val P_CONST = Pattern.compile("^const [A-Za-z]+") 9 | private val P_POINTER = Pattern.compile(".*[A-Za-z]+\\*$") 10 | private val P_NOPOINTER = Pattern.compile(".*[A-Za-z]+$") 11 | } 12 | 13 | val type = if ("" == type) "void*" else type 14 | 15 | val isSinglePointer = P_POINTER.matcher(this.type).find() 16 | val isConst = P_CONST.matcher(this.type).find() 17 | val isDirectType = P_NOPOINTER.matcher(this.type).find() 18 | 19 | operator fun contains(type: String): Boolean { 20 | return this.type.contains(type) 21 | } 22 | 23 | override fun getDebugIdentifier(): String { 24 | return "c" 25 | } 26 | 27 | override fun toString(): String { 28 | return DebugPrint.colon(this, type) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/type/CTypeConverter.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.type 2 | 3 | import ch.bailu.gtk.parser.tag.ParameterTag 4 | import ch.bailu.gtk.table.EnumTable 5 | 6 | object CTypeConverter { 7 | private const val OUT_ENUM_C_TYPE = "gint*" 8 | private const val VARARG_TYPE = "..." 9 | 10 | fun toCTypeName(namespace: String, parameter: ParameterTag): String { 11 | return if (isOutEnum(namespace, parameter)) { 12 | OUT_ENUM_C_TYPE 13 | } else if (parameter.isVarargs) { 14 | VARARG_TYPE 15 | } else { 16 | parameter.getType() 17 | } 18 | } 19 | 20 | private fun isOutEnum(namespace: String, parameter: ParameterTag): Boolean { 21 | return !parameter.inDirection && EnumTable.isEnum(namespace, parameter) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/type/CallbackType.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.type 2 | 3 | import ch.bailu.gtk.log.DebugPrint 4 | import ch.bailu.gtk.parser.tag.CallbackTag 5 | import ch.bailu.gtk.table.AliasTable 6 | import ch.bailu.gtk.table.CallbackTable 7 | import ch.bailu.gtk.writer.Names 8 | 9 | class CallbackType(namespace: String, typeName: String): Type() { 10 | val type = AliasTable.convert(NamespaceType(namespace, typeName)) 11 | val callbackTag = CallbackTable[type.namespace, type.name] 12 | val valid: Boolean = callbackTag is CallbackTag 13 | 14 | fun getApiTypeName(namespace: String = ""): String { 15 | return Names.getApiTypeName(type, namespace) 16 | } 17 | 18 | override fun getDebugIdentifier(): String { 19 | return "cb" 20 | } 21 | 22 | override fun toString(): String { 23 | return DebugPrint.colon(this, type.name) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/type/JavaType.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.type 2 | 3 | import ch.bailu.gtk.log.DebugPrint 4 | import ch.bailu.gtk.table.PrimitivesTable 5 | 6 | /** 7 | * A Primitive java type. 8 | * Is valid if name is configured in [PrimitivesTable] 9 | */ 10 | class JavaType(typeName: String) : Type() { 11 | private var type = PrimitivesTable.convert(typeName) 12 | 13 | val valid: Boolean 14 | get () = type.isNotEmpty() 15 | 16 | fun getApiTypeName(): String { 17 | return type 18 | } 19 | 20 | fun isVoid(): Boolean { 21 | return "void" == type 22 | } 23 | 24 | override fun getDebugIdentifier(): String { 25 | return "j" 26 | } 27 | 28 | override fun toString(): String { 29 | return DebugPrint.colon(this, type) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/type/NamespaceType.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.type 2 | 3 | import java.util.* 4 | import java.util.regex.Pattern 5 | 6 | class NamespaceType(fallbackNamespace: String, typeName: String) { 7 | companion object { 8 | private val NAMESPACE = Pattern.compile("^([A-Za-z_]\\w+)\\.([A-Za-z_]\\w+)$") 9 | private val NONAMESPACE = Pattern.compile("^[A-Za-z_]\\w+$") 10 | 11 | val INVALID = NamespaceType("", "") 12 | } 13 | 14 | val namespace: String 15 | val name: String 16 | 17 | val valid: Boolean 18 | get() = name.isNotEmpty() 19 | 20 | init { 21 | var m = NAMESPACE.matcher(typeName) 22 | if (m.find()) { 23 | namespace = m.group(1).lowercase() 24 | name = m.group(2) 25 | } else { 26 | m = NONAMESPACE.matcher(typeName) 27 | if (m.find()) { 28 | namespace = fallbackNamespace.lowercase() 29 | name = typeName 30 | } else { 31 | namespace = "" 32 | name = "" 33 | } 34 | } 35 | } 36 | 37 | override fun hashCode(): Int { 38 | return Objects.hash(namespace, name) 39 | } 40 | 41 | override fun toString(): String { 42 | return "${namespace}.${name}" 43 | } 44 | 45 | override fun equals(other: Any?): Boolean { 46 | if (this === other) return true 47 | if (javaClass != other?.javaClass) return false 48 | 49 | other as NamespaceType 50 | 51 | if (namespace != other.namespace) return false 52 | if (name != other.name) return false 53 | 54 | return true 55 | } 56 | 57 | fun isCurrentNameSpace(currentNameSpace: String): Boolean { 58 | return namespace == currentNameSpace 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/model/type/Type.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.model.type 2 | 3 | abstract class Type { 4 | abstract fun getDebugIdentifier(): String 5 | } 6 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/AliasTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | class AliasTag(parent: TagWithParent): ParameterTag(parent) { 4 | 5 | override fun end() { 6 | getBuilder().buildAlias(this) 7 | } 8 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/CallbackTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | import java.io.IOException 4 | 5 | class CallbackTag(parent: TagWithParent): MethodTag(parent) { 6 | 7 | @Throws(IOException::class) 8 | override fun end() { 9 | getBuilder().buildCallback(this) 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/DocTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | class DocTag(parent: TagWithParent): TagWithParent(parent) { 4 | var aText = "" 5 | 6 | override fun getChild(name: String): TagWithParent { 7 | return ignore() 8 | } 9 | 10 | override fun setText(text: String) { 11 | this.aText = text 12 | } 13 | 14 | fun getText(): String { 15 | return aText 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/DocumentTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | import ch.bailu.gtk.NamespaceConfig 4 | import ch.bailu.gtk.builder.BuilderInterface 5 | 6 | class DocumentTag(private val builder: BuilderInterface, 7 | private val namespaceConfig: NamespaceConfig 8 | ): Tag() { 9 | 10 | override fun getBuilder(): BuilderInterface { 11 | return builder 12 | } 13 | 14 | override fun getNamespaceConfig(): NamespaceConfig { 15 | return namespaceConfig 16 | } 17 | 18 | override fun getChild(name: String): TagWithParent { 19 | if ("repository" == name) { 20 | return RepositoryTag(this) 21 | } 22 | return ignore() 23 | } 24 | 25 | override fun getParent(): Tag { 26 | return this 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/EnumerationTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | import java.io.IOException 4 | 5 | class EnumerationTag(parent: TagWithParent) : TypeTag(parent) { 6 | private val members = TagList() 7 | 8 | override fun getChild(name: String): TagWithParent { 9 | return if ("member" == name) { 10 | members.addTag(MemberTag(this)) 11 | } else super.getChild(name) 12 | } 13 | 14 | @Throws(IOException::class) 15 | override fun end() { 16 | getBuilder().buildEnumeration(this) 17 | } 18 | 19 | fun getMembers(): List { 20 | return members 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/FieldTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | class FieldTag(parent: TagWithParent) : ParameterTag(parent) { 4 | 5 | val method = MethodTag(this) 6 | var isMethod = false 7 | private set 8 | 9 | override fun getChild(name: String): TagWithParent { 10 | if ("callback" == name) { 11 | isMethod = true 12 | return method 13 | } 14 | return super.getChild(name) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/IgnoreTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | class IgnoreTag (parent: Tag) : TagWithParent(parent){ 4 | 5 | override fun getChild(name: String): TagWithParent { 6 | return ignore() 7 | } 8 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/MemberTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | class MemberTag(parent: TagWithParent) : ParameterTag(parent) { 4 | 5 | override fun getType(): String { 6 | return if ("" == super.getType()) "int" else super.getType() 7 | } 8 | 9 | override fun getName(): String { 10 | return super.getName().uppercase() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/NamedWithDocTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | open class NamedWithDocTag(parent: TagWithParent) : TagWithParent(parent){ 4 | private var name: String = "" 5 | private val docTag = DocTag(this) 6 | 7 | override fun getChild(name: String): TagWithParent { 8 | if ("doc" == name) { 9 | return docTag 10 | } 11 | return ignore() 12 | } 13 | 14 | override fun setAttribute(name: String, value: String) { 15 | if ("name" == name) { 16 | this.name = value 17 | } 18 | } 19 | 20 | open fun getName(): String { 21 | return name 22 | } 23 | 24 | fun getDoc(): String { 25 | return docTag.getText() 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/RepositoryTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | class RepositoryTag(parent: Tag) : TagWithParent(parent) { 4 | private val namespace = NamespaceTag(this) 5 | 6 | override fun getChild(name: String): TagWithParent { 7 | if ("namespace" == name) { 8 | return namespace 9 | } 10 | if ("package" == name) { 11 | return namespace.addPackage(NamedWithDocTag(this)) 12 | } 13 | if ("c:include" == name) { 14 | return namespace.addInclude(NamedWithDocTag(this)) 15 | } 16 | return ignore() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/Tag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | import ch.bailu.gtk.NamespaceConfig 4 | import ch.bailu.gtk.builder.BuilderInterface 5 | 6 | abstract class Tag { 7 | abstract fun getChild(name: String): TagWithParent 8 | 9 | open fun started() {} 10 | open fun end() {} 11 | 12 | open fun setText(text: String) {} 13 | open fun setAttribute(name: String, value: String) {} 14 | 15 | abstract fun getParent(): Tag 16 | 17 | abstract fun getBuilder(): BuilderInterface 18 | abstract fun getNamespaceConfig(): NamespaceConfig 19 | 20 | 21 | protected fun ignore(): IgnoreTag { 22 | return IgnoreTag(this) 23 | } 24 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/TagList.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | import java.util.* 4 | 5 | class TagList : ArrayList() { 6 | fun addTag(tag: T): TagWithParent { 7 | this.add(tag) 8 | return tag 9 | } 10 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/TagWithParent.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | import ch.bailu.gtk.NamespaceConfig 4 | import ch.bailu.gtk.builder.BuilderInterface 5 | 6 | abstract class TagWithParent (private var parent: Tag): Tag() { 7 | 8 | override fun getParent(): Tag { return parent} 9 | 10 | override fun getBuilder(): BuilderInterface { 11 | return parent.getBuilder() 12 | } 13 | 14 | override fun getNamespaceConfig() : NamespaceConfig { 15 | return parent.getNamespaceConfig() 16 | } 17 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/parser/tag/TypeTag.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.parser.tag 2 | 3 | open class TypeTag(parent: TagWithParent) : NamedWithDocTag(parent) { 4 | var type: String = "" 5 | private set 6 | 7 | override fun setAttribute(name: String, value: String) { 8 | if ("c:type" == name) { 9 | type = value 10 | } else { 11 | super.setAttribute(name, value) 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/AliasTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | import ch.bailu.gtk.log.Logable 4 | import ch.bailu.gtk.model.type.NamespaceType 5 | import java.io.Writer 6 | 7 | object AliasTable : Logable { 8 | val table: MutableMap = HashMap() 9 | 10 | init { 11 | add("glib", "String", "GString") 12 | } 13 | 14 | 15 | fun add(from: NamespaceType, to: NamespaceType) { 16 | table[from] = to 17 | } 18 | 19 | fun add(namespace: String, fromName: String, toName: String) { 20 | val from = NamespaceType(namespace, fromName) 21 | val to = NamespaceType(namespace, toName) 22 | add(from, to) 23 | } 24 | 25 | fun convert(fallbackNamespace: String, typeName: String): NamespaceType { 26 | return convert(NamespaceType(fallbackNamespace, typeName)) 27 | } 28 | 29 | fun convert(from: NamespaceType): NamespaceType { 30 | return table[from] ?: from 31 | } 32 | 33 | override fun log(writer: Writer) { 34 | writer.write("# ${AliasTable.javaClass.canonicalName}\n\n") 35 | writer.write("| From | To\n") 36 | writer.write("|--------------------------------|---\n") 37 | table.forEach { 38 | writer.write(String.format("| %-30s | %s\n", it.key, it.value)) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/CallbackTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | import ch.bailu.gtk.log.Logable 4 | import ch.bailu.gtk.parser.tag.CallbackTag 5 | import java.io.Writer 6 | 7 | object CallbackTable : Logable { 8 | private val table: MutableMap> = HashMap() 9 | 10 | fun add(namespace: String, callbackTag: CallbackTag) { 11 | getTable(namespace)[callbackTag.getName()] = callbackTag 12 | } 13 | 14 | private fun getTable(namespace: String): MutableMap { 15 | var result = table[namespace] 16 | if (result == null) { 17 | result = HashMap() 18 | table[namespace] = result 19 | } 20 | return result 21 | } 22 | 23 | operator fun get(namespace: String, name: String): CallbackTag? { 24 | return getTable(namespace)[name] 25 | } 26 | 27 | override fun log(writer: Writer) { 28 | writer.write("# ${CallbackTable.javaClass.canonicalName}\n") 29 | 30 | table.onEach { namespace -> 31 | writer.write("\n## ${namespace.key}\n\n") 32 | 33 | writer.write("| Name | Detailed\n") 34 | writer.write("|------------------------------------------|---------\n") 35 | namespace.value.forEach { 36 | writer.write(String.format("| %-40s | %s\n", it.key, it.value)) 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/EnumTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | import ch.bailu.gtk.model.type.NamespaceType 4 | import ch.bailu.gtk.log.Logable 5 | import ch.bailu.gtk.parser.tag.ParameterTag 6 | import java.io.Writer 7 | import java.util.* 8 | 9 | object EnumTable: Logable { 10 | private val table: MutableMap> = HashMap() 11 | 12 | fun add(type: NamespaceType) { 13 | if (type.valid) { 14 | getTable(type.namespace)[type.name] = type.name 15 | } 16 | } 17 | 18 | private fun getTable(namespace: String): MutableMap { 19 | var result = table[namespace] 20 | if (result == null) { 21 | result = HashMap() 22 | table[namespace] = result 23 | } 24 | return result 25 | } 26 | 27 | operator fun contains(type: NamespaceType): Boolean { 28 | return type.valid && getTable(type.namespace).containsKey(type.name) 29 | } 30 | 31 | fun isEnum(namespace: String, parameter: ParameterTag): Boolean { 32 | return isEnum(namespace, parameter.getTypeName()) || isEnum(namespace, parameter.getType()) 33 | } 34 | 35 | private fun isEnum(namespace: String, typeName: String): Boolean { 36 | return contains(NamespaceType(namespace, typeName)) 37 | } 38 | 39 | override fun log(writer: Writer) { 40 | writer.write("# ${EnumTable.javaClass.canonicalName}\n") 41 | 42 | table.onEach { namespace -> 43 | writer.write("\n## ${namespace.key}\n\n") 44 | 45 | writer.write("| Name\n") 46 | writer.write("| -----\n") 47 | 48 | namespace.value.forEach { 49 | writer.write(String.format("| %s\n", it.key)) 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/NamespaceTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | import ch.bailu.gtk.NamespaceConfig 4 | import java.util.* 5 | 6 | object NamespaceTable { 7 | private val table: MutableMap = HashMap() 8 | 9 | fun add(namespace: String, namespaceConfig: NamespaceConfig) { 10 | table[namespace.lowercase()] = namespaceConfig 11 | } 12 | 13 | operator fun contains(namespace: String): Boolean { 14 | return table.containsKey(namespace) 15 | } 16 | 17 | fun with(namespace: String, action: (NamespaceConfig) -> Unit) { 18 | val config = table.get(namespace) 19 | if (config != null) { 20 | action(config) 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/PrimitivesTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | import java.util.* 4 | 5 | object PrimitivesTable { 6 | 7 | private val table: MutableMap = HashMap(50) 8 | 9 | init { 10 | add("none", "void") 11 | add("void", "void") 12 | add("gboolean", "boolean") 13 | add("_Bool", "boolean") 14 | add("gint", "int") 15 | add("glong", "long") 16 | add("guint", "int") 17 | add("gdouble", "double") 18 | add("guint16", "int") 19 | add("gfloat", "float") 20 | add("guint32", "int") 21 | add("gssize", "long") 22 | add("gulong", "long") 23 | add("gsize", "long") 24 | add("GType", "long") 25 | add("guchar", "byte") 26 | add("gchar", "byte") 27 | add("gunichar", "byte") 28 | add("gint64", "long") 29 | add("gint32", "int") 30 | add("gint16", "int") 31 | add("gint8", "int") 32 | add("guint64", "long") 33 | add("guint32", "int") 34 | add("guint16", "int") 35 | add("guint8", "int") 36 | add("time_t", "long") 37 | add("long", "long") 38 | add("int", "int") 39 | add("double", "double") 40 | add("float", "float") 41 | add("const char*", "String") 42 | add("const gchar*", "String") 43 | add("...", "java.lang.Object...") 44 | add("GQuark", "int") 45 | add("GstClockTime", "long") 46 | } 47 | 48 | private fun add(cType: String, jType: String) { 49 | table[cType] = jType 50 | } 51 | 52 | operator fun contains(cType: String): Boolean { 53 | return table.containsKey(cType) 54 | } 55 | 56 | fun convert(cType: String): String { 57 | return table[cType] ?: "" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/ReservedTokenTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | object ReservedTokenTable { 4 | private val table: MutableMap = HashMap() 5 | 6 | init { 7 | add("package", "_package") 8 | add("native", "_native") 9 | add("continue", "_continue") 10 | add("double", "_double") 11 | add("int", "_int") 12 | add("new", "_new") 13 | add("default", "_default") 14 | add("private", "_private") 15 | add("...", "_ellipsis") 16 | add("interface", "_interface") 17 | add("false", "_false") 18 | add("true", "_true") 19 | add("toString", "toStr") 20 | add("wait", "doWait") 21 | } 22 | 23 | private fun add(reserved: String, replacement: String) { 24 | table[reserved] = replacement 25 | } 26 | 27 | fun convert(token: String): String { 28 | return table[token] ?: convertNumber(token) 29 | } 30 | 31 | private fun convertNumber(token: String): String { 32 | if (token.isNotEmpty() && token[0].isDigit()) { 33 | return "_$token" 34 | } 35 | return token 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/SizeTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | import ch.bailu.gtk.log.Logable 4 | import ch.bailu.gtk.model.type.NamespaceType 5 | import java.io.Writer 6 | 7 | object SizeTable: Logable { 8 | val table: MutableMap = HashMap() 9 | 10 | init { 11 | add("gobject", "TypeClass", 8) 12 | add("gobject", "TypeInterface", 16) 13 | } 14 | 15 | 16 | private fun add(type: NamespaceType, size: Int) { 17 | table[type] = size 18 | } 19 | 20 | private fun add(namespace: String, name: String, size: Int) { 21 | add(NamespaceType(namespace, name), size) 22 | } 23 | 24 | fun getSize(namespace: String, name: String): Int { 25 | return table.getOrDefault(NamespaceType(namespace, name),0) 26 | } 27 | 28 | fun isSizeKnown(namespaceType: NamespaceType): Boolean { 29 | return table.getOrDefault(namespaceType,0) > 0 30 | } 31 | 32 | override fun log(writer: Writer) { 33 | writer.write("# ${SizeTable.javaClass.canonicalName}\n\n") 34 | writer.write("| Type | Size\n") 35 | writer.write("|--------------------------------|-----\n") 36 | 37 | table.forEach { 38 | writer.write(String.format("| %-30s | %d\n", it.key, it.value)) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/table/ValueTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.table 2 | 3 | import java.util.HashMap 4 | 5 | /** 6 | * https://simonv.fr/TypesConvert/?integers 7 | * See [ch.bailu.gtk.model.filter.filterValues] for filtered values 8 | */ 9 | object ValueTable { 10 | 11 | private val table: MutableMap = HashMap(50) 12 | 13 | init { 14 | add("2147483649", "-2147483647") 15 | add("2147483650", "-2147483646") 16 | add("2147483651", "-2147483645") 17 | add("2147483652", "-2147483644") 18 | add("2147483653", "-2147483643") 19 | add("2147483654", "-2147483642") 20 | add("2147483655", "-2147483641") 21 | add("2147483656", "-2147483640") 22 | add("2147483648", "-2147483648") // G_MININT32 23 | add("4294967295", "-1") // G_MAXUINT32 24 | add("18446744073709551615", "-1") // Long variant 25 | } 26 | 27 | private fun add(original: String, converted: String) { 28 | table[original] = converted 29 | } 30 | 31 | operator fun contains(original: String): Boolean { 32 | return table.containsKey(original) 33 | } 34 | 35 | fun convert(original: String): String { 36 | return table[original] ?: original 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/validator/Validator.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.validator 2 | 3 | import ch.bailu.gtk.model.MethodModel 4 | import ch.bailu.gtk.model.Model 5 | 6 | object Validator { 7 | fun giveUp(reason: String, condition: Boolean) { 8 | if (condition) { 9 | giveUp(reason) 10 | } 11 | } 12 | 13 | fun giveUp(reason: String) { 14 | throw RuntimeException("Validator: $reason") 15 | } 16 | 17 | fun validMethodName(methodModel: MethodModel) { 18 | giveUp("Invalid method name ${methodModel.apiName}", methodModel.apiName == "Register") 19 | 20 | } 21 | 22 | fun validateAlias(apiName: String) { 23 | giveUp("Type not aliased $apiName", apiName.endsWith(".String")) 24 | } 25 | 26 | fun validateNotEmpty(name: String) { 27 | giveUp("Empty name", name.isEmpty()) 28 | } 29 | 30 | fun validateSupported(model: Model) { 31 | giveUp("Model not supported", !model.isSupported) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/writer/Append.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer; 2 | 3 | interface Append { 4 | fun a(o : String) : Append 5 | fun a(o : String, intent: Int) : Append 6 | } 7 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/writer/CodeWriter.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer 2 | 3 | import ch.bailu.gtk.model.* 4 | import ch.bailu.gtk.model.filter.ModelList 5 | 6 | 7 | interface CodeWriter { 8 | fun writeStart(structureModel : StructureModel, namespaceModel : NamespaceModel) 9 | 10 | fun writeClass(structureModel : StructureModel) 11 | fun writeInterface(structureModel : StructureModel) 12 | 13 | fun writeInternalConstructor(structureModel : StructureModel) 14 | fun writeConstructor(structureModel : StructureModel, methodModel : MethodModel) 15 | 16 | fun writeFactory(structureModel : StructureModel, methodModel : MethodModel) 17 | fun writePrivateFactory(structureModel : StructureModel, methodModel : MethodModel) 18 | 19 | fun writeConstant(structureModel: StructureModel, parameterModel : ParameterModel) 20 | fun writeMethod(structureModel : StructureModel, methodModel : MethodModel) 21 | 22 | fun writeSignal(structureModel : StructureModel, methodModel : MethodModel) 23 | fun writeField(structureModel : StructureModel, fieldModel : FieldModel) 24 | fun writeFunction(structureModel : StructureModel, methodModel : MethodModel) 25 | 26 | fun writeImplements(implementsModel: ImplementsModel) 27 | 28 | fun writeMallocConstructor(structureModel : StructureModel) 29 | fun writeCallback(structureModel: StructureModel, methodModel: MethodModel, isSignal: Boolean = false) 30 | 31 | fun writeIntrospection(structureModel: StructureModel) 32 | fun writeBeginStruct(structureModel : StructureModel, fields: ModelList) 33 | fun writeEndStruct() 34 | fun writeBeginInstance(namespaceModel: NamespaceModel) 35 | fun writeEndInstance() 36 | 37 | fun writeClassEnd() 38 | 39 | fun writeDebugBegin(structureModel: StructureModel) 40 | fun writeDebugEnd() 41 | fun writeDebugUnsupported(model : Model) 42 | } 43 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/writer/TextWriter.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer 2 | 3 | import java.io.Writer 4 | 5 | class TextWriter(private val writer : Writer) { 6 | private var space = 0 7 | 8 | fun a(text : String) : TextWriter { 9 | writer.append(text) 10 | return this 11 | } 12 | 13 | fun a(text : String, intent: Int) : TextWriter { 14 | writer.append(text.replaceIndent(" ".repeat(intent))) 15 | return nl() 16 | } 17 | 18 | fun start(i : Int) : TextWriter { 19 | space = Math.max(space, i) 20 | return nl(space) 21 | } 22 | 23 | fun end(i : Int) { 24 | space = i 25 | } 26 | 27 | fun nl(i : Int = 1): TextWriter { 28 | return a("\n".repeat(i)) 29 | } 30 | 31 | fun l(s : Int, text : String, e : Int) { 32 | start(s) 33 | a(text).nl() 34 | end(e) 35 | } 36 | } -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/writer/java/PackageWriter.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer.java 2 | 3 | import ch.bailu.gtk.model.NamespaceModel 4 | import ch.bailu.gtk.writer.Names 5 | import ch.bailu.gtk.writer.TextWriter 6 | import ch.bailu.gtk.writer.java_doc.JavaDoc 7 | 8 | class PackageWriter(private val out: TextWriter, val doc: JavaDoc) { 9 | 10 | fun write(namespaceModel: NamespaceModel) { 11 | writeDoc(namespaceModel) 12 | out.a("package ") 13 | out.a(namespaceModel.fullNamespace) 14 | out.a(";\n") 15 | } 16 | 17 | private fun writeDoc(namespaceModel: NamespaceModel) { 18 | doc.writeStart(0) 19 | doc.writeBlockPlain( 20 | """ 21 | Generated: ${namespaceModel.infoNamespace} ${namespaceModel.infoVersion} 22 |
API Reference Manual: ${namespaceModel.infoDocUrl}} 23 |
Functions class: {@link ${namespaceModel.fullNamespace}.${Names.getJavaClassName(namespaceModel.namespace)}} 24 |
Constants class: {@link ${namespaceModel.fullNamespace}.${Names.getJavaPackageConstantsInterfaceName(namespaceModel.namespace)}} 25 |
Generated from: ${namespaceModel.infoGirFile} 26 |
Shared library: ${namespaceModel.infoSharedLibrary} 27 |
Configured library: ${namespaceModel.library} 28 | """.trimIndent()) 29 | doc.writeDocEnd() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/writer/java_doc/JavaDoc.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer.java_doc 2 | 3 | import ch.bailu.gtk.model.MethodModel 4 | import ch.bailu.gtk.model.StructureModel 5 | import ch.bailu.gtk.writer.Append 6 | import java.io.Writer 7 | 8 | abstract class JavaDoc(val writer: Writer): Append { 9 | private var begin = "" 10 | private var space = "" 11 | private var intent = 0 12 | 13 | override fun a(o: String): Append { 14 | writer.append(o) 15 | return this 16 | } 17 | 18 | 19 | override fun a(o : String, intent: Int) : Append { 20 | writer.append(o.replaceIndent(" ".repeat(intent))) 21 | return this 22 | } 23 | 24 | 25 | abstract fun writeClassUrl(structureModel: StructureModel) 26 | abstract fun writeBlockPlain(doc: String) 27 | abstract fun writeBlock(doc: String) 28 | abstract fun writeParameter(methodModel: MethodModel) 29 | abstract fun writeReturn(methodModel: MethodModel) 30 | 31 | fun writeLine(line: String, nl: String = "") { 32 | a("${begin}${nl}${line}\n") 33 | } 34 | 35 | fun writeStart(intend: Int) { 36 | intent = intend 37 | space = " ".repeat(intent) 38 | begin = "$space * " 39 | 40 | a("${space}/**\n") 41 | } 42 | 43 | fun writeDocEnd() { 44 | a("${space}*/\n") 45 | } 46 | 47 | fun startLine(): Append { 48 | return a(begin) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/writer/java_doc/JavaDocEmpty.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer.java_doc 2 | 3 | import ch.bailu.gtk.model.MethodModel 4 | import ch.bailu.gtk.model.StructureModel 5 | import java.io.Writer 6 | 7 | class JavaDocEmpty(writer: Writer) : JavaDoc(writer) { 8 | override fun writeClassUrl(structureModel: StructureModel) {} 9 | override fun writeBlockPlain(doc: String) {} 10 | override fun writeBlock(doc: String) {} 11 | override fun writeParameter(methodModel: MethodModel) {} 12 | override fun writeReturn(methodModel: MethodModel) {} 13 | } 14 | -------------------------------------------------------------------------------- /generator/src/main/kotlin/ch/bailu/gtk/writer/java_doc/JavaDocPlain.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer.java_doc 2 | 3 | import ch.bailu.gtk.model.MethodModel 4 | import ch.bailu.gtk.model.StructureModel 5 | import ch.bailu.gtk.table.NamespaceTable 6 | import java.io.Writer 7 | 8 | class JavaDocPlain(writer: Writer): JavaDoc(writer) { 9 | 10 | override fun writeBlockPlain(doc: String) { 11 | writeBlock(doc) 12 | } 13 | 14 | override fun writeBlock(doc: String) { 15 | doc.lines().forEach { 16 | writeLine(it) 17 | } 18 | } 19 | 20 | override fun writeClassUrl(structureModel: StructureModel) { 21 | NamespaceTable.with(structureModel.nameSpaceModel.namespace) { 22 | writeLine(it.docUrl.getUrl(structureModel), "") 23 | } 24 | 25 | } 26 | 27 | override fun writeParameter(methodModel: MethodModel) { 28 | methodModel.parameters.forEach { 29 | writeDocParamLine(it.doc, "@param ${it.name}") 30 | } 31 | } 32 | 33 | override fun writeReturn(methodModel: MethodModel) { 34 | if (!methodModel.returnType.isVoid) { 35 | writeDocParamLine(methodModel.returnType.doc, "@return") 36 | } 37 | } 38 | 39 | 40 | private fun writeDocParamLine(doc: String, prefix: String) { 41 | startLine().a(prefix) 42 | doc.lines().forEach{a(" ").a(it)} 43 | a("\n") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /generator/src/test/kotlin/ch/bailu/gtk/TestAlias.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk 2 | 3 | import ch.bailu.gtk.model.type.NamespaceType 4 | import ch.bailu.gtk.table.AliasTable.add 5 | import ch.bailu.gtk.table.AliasTable.convert 6 | import org.junit.jupiter.api.Assertions 7 | import org.junit.jupiter.api.Test 8 | 9 | class TestAlias { 10 | @Test 11 | fun testAlias() { 12 | val from = NamespaceType("gtk", "Allocation") 13 | val to = NamespaceType("gdk", "Rectangle") 14 | add(from, to) 15 | val test = convert(from) 16 | Assertions.assertEquals("Rectangle", test.name) 17 | Assertions.assertEquals("gdk", test.namespace) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /generator/src/test/kotlin/ch/bailu/gtk/TestDocWriter.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk 2 | 3 | import org.junit.jupiter.api.Assertions 4 | import org.junit.jupiter.api.Test 5 | 6 | class TestDocWriter { 7 | @Test 8 | fun testEvenPre() { 9 | val doc = "Sets the maximum allowed length of the contents of the widget. If\n" + 10 | "the current contents are longer than the given length, then they\n" + 11 | "will be truncated to fit.\n" + 12 | "\n" + 13 | "This is equivalent to getting @entry's #GtkEntryBuffer and\n" + 14 | "calling gtk_entry_buffer_set_max_length() on it.\n" + 15 | "]|" 16 | 17 | 18 | Assertions.assertEquals(false, isEvenPre(doc)) 19 | } 20 | 21 | private fun isEvenPre(doc: String): Boolean { 22 | return if (count(doc, "|[") != count(doc, "]|")) { 23 | println("WARNING code tags are not even: \"${doc.replace('\n', ' ')}\"") 24 | false 25 | } else { 26 | true 27 | } 28 | } 29 | 30 | private fun count(doc: String, word: String): Int { 31 | var index = doc.indexOf(word) 32 | var count = 0 33 | 34 | while (index > -1) { 35 | count++ 36 | index = doc.indexOf(word, index+1) 37 | } 38 | return count 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /generator/src/test/kotlin/ch/bailu/gtk/TestPrimitivesTable.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk 2 | 3 | import ch.bailu.gtk.table.PrimitivesTable.contains 4 | import ch.bailu.gtk.table.PrimitivesTable.convert 5 | import org.junit.jupiter.api.Assertions 6 | import org.junit.jupiter.api.Test 7 | 8 | class TestPrimitivesTable { 9 | @Test 10 | fun test() { 11 | Assertions.assertEquals(true, contains("gdouble")) 12 | Assertions.assertEquals("double", convert("gdouble")) 13 | Assertions.assertEquals(true, contains("double")) 14 | Assertions.assertEquals("double", convert("double")) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /generator/src/test/kotlin/ch/bailu/gtk/writer/TestNames.kt: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.writer 2 | 3 | import org.junit.jupiter.api.Assertions.assertEquals 4 | import org.junit.jupiter.api.Test 5 | 6 | class TestNames { 7 | 8 | @Test 9 | fun testJavaMethodName() { 10 | assertEquals("cclosureMarshalBooleanBoxedBoxed", Names.getJavaMethodName("cclosure_marshal_BOOLEAN__BOXED_BOXED")) 11 | } 12 | 13 | @Test 14 | fun testCallbackName() { 15 | assertEquals("OnClassInitFunc", Names.getJavaCallbackInterfaceName("ClassInitFunc")) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bailuk/java-gtk/85529da01e518f401554c6b9d8caab20042ac22b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/gobject/ObjectClassExtended.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.gobject; 2 | 3 | import ch.bailu.gtk.lib.jna.GObjectLib; 4 | import ch.bailu.gtk.type.PointerContainer; 5 | import ch.bailu.gtk.type.Str; 6 | 7 | public class ObjectClassExtended extends ObjectClass { 8 | 9 | public ObjectClassExtended(PointerContainer g_class) { 10 | super(g_class); 11 | } 12 | 13 | public void onDispose(Object instance) { 14 | getFieldDispose().invoke(instance.asCPointer()); 15 | } 16 | 17 | public int signalNew(Str name, long returnType, Long... types) { 18 | return GObjectLib.INST().g_signal_new( 19 | name.asCPointer(), 20 | new TypeClass(cast()).getFieldGType(), 21 | SignalFlags.RUN_FIRST, 22 | 0, 23 | 0, 24 | 0, 25 | 0, 26 | returnType, 27 | types.length, 28 | (java.lang.Object[]) types); 29 | } 30 | 31 | public ObjectClassExtended getParentClass() { 32 | final var typeClass = new TypeClass(cast()); 33 | return new ObjectClassExtended(typeClass.peekParent().cast()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/gtk/ValueFactory.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.gtk; 2 | 3 | import ch.bailu.gtk.gobject.Object; 4 | import ch.bailu.gtk.gobject.Value; 5 | import ch.bailu.gtk.type.Int; 6 | import ch.bailu.gtk.type.Record; 7 | import ch.bailu.gtk.type.Str; 8 | 9 | public class ValueFactory { 10 | // TODO: This should come from SizeTable.kt 11 | private static final int VALUE_SIZE = 24; 12 | 13 | public static Value initValue(long typeID) { 14 | return new Value(new Record(VALUE_SIZE).cast()).init(typeID); 15 | } 16 | 17 | public static Value toValue(Str str) { 18 | var result = initValue(Str.getTypeID()); 19 | result.setString(str); 20 | return result; 21 | } 22 | 23 | public static Value toValue(String str) { 24 | var result = initValue(Str.getTypeID()); 25 | result.setString(str); 26 | return result; 27 | } 28 | 29 | public static Value toValue(int value) { 30 | var result = initValue(Int.getTypeID()); 31 | result.setInt(value); 32 | return result; 33 | } 34 | 35 | public static Value toValue(Object obj) { 36 | var result = initValue(Object.getTypeID()); 37 | result.setObject(obj); 38 | return result; 39 | } 40 | 41 | public static Value toValue(boolean value) { 42 | var result = initValue(Int.getBooleanTypeID()); 43 | result.setBoolean(value); 44 | return result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/gtk/WidgetClassExtended.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.gtk; 2 | 3 | import com.sun.jna.Callback; 4 | 5 | import java.io.IOException; 6 | 7 | import ch.bailu.gtk.lib.util.JavaResource; 8 | import ch.bailu.gtk.type.PointerContainer; 9 | import ch.bailu.gtk.type.Str; 10 | 11 | public class WidgetClassExtended extends WidgetClass { 12 | 13 | public WidgetClassExtended(PointerContainer g_class) { 14 | super(g_class); 15 | } 16 | 17 | public void bindTemplateCallback(String name, Callback cb) { 18 | JnaWidgetClass.INST().gtk_widget_class_bind_template_callback_full(asCPointer(), new Str(name).asCPointer(), cb); 19 | } 20 | 21 | public void setTemplateOrExit(String resource) { 22 | try { 23 | setTemplate(new JavaResource(resource).asBytes()); 24 | } catch (IOException e) { 25 | e.printStackTrace(); 26 | System.exit(1); 27 | } 28 | } 29 | 30 | @FunctionalInterface 31 | public interface SizeAllocateCallback extends com.sun.jna.Callback { 32 | void invoke(long widget, int widht, int height, int baseline); 33 | } 34 | 35 | public void overrideSizeAllocate(SizeAllocateCallback cp) { 36 | System.out.println("TODO implement overrideSizeAllocate"); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/bridge/Bytes.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.bridge; 2 | 3 | import ch.bailu.gtk.type.PointerContainer; 4 | import ch.bailu.gtk.type.Int64; 5 | import ch.bailu.gtk.type.Pointer; 6 | 7 | public class Bytes extends ch.bailu.gtk.glib.Bytes { 8 | public Bytes(PointerContainer pointer) { 9 | super(pointer); 10 | } 11 | 12 | public Bytes(byte[] bytes) { 13 | super(new ch.bailu.gtk.type.Bytes(bytes), bytes.length); 14 | } 15 | 16 | public Bytes(ch.bailu.gtk.type.Bytes bytes) { 17 | super(createFromWrapper(bytes)); 18 | } 19 | 20 | 21 | private static PointerContainer createFromWrapper(ch.bailu.gtk.type.Bytes bytes) { 22 | bytes.throwIfNull(); 23 | if (bytes.getSize() < 1) { 24 | bytes.throwNullPointerException("size == " + bytes.getSize()); 25 | } 26 | 27 | return new ch.bailu.gtk.glib.Bytes(new Pointer(bytes.cast()), bytes.getSize()).cast(); 28 | } 29 | 30 | 31 | private ch.bailu.gtk.type.Bytes toBytesWrapper() { 32 | var size = new Int64(); 33 | var data = getData(size); 34 | var result = new ch.bailu.gtk.type.Bytes(new PointerContainer(data.asCPointer()), (int) size.get()); 35 | size.destroy(); 36 | return result; 37 | } 38 | 39 | 40 | public byte[] toBytes(int start, int end) { 41 | return toBytesWrapper().toBytes(start, end); 42 | } 43 | 44 | public byte[] toBytes() { 45 | return toBytesWrapper().toBytes(); 46 | } 47 | 48 | public byte getByte(int i) { 49 | return toBytesWrapper().getByte(i); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/bridge/GResource.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.bridge; 2 | 3 | import java.io.IOException; 4 | 5 | import ch.bailu.gtk.gio.Resource; 6 | import ch.bailu.gtk.lib.util.JavaResource; 7 | import ch.bailu.gtk.type.Bytes; 8 | import ch.bailu.gtk.type.exception.AllocationError; 9 | 10 | public class GResource { 11 | 12 | /** 13 | * Load a gresource bundle from java resources path and register it 14 | * See {@link ch.bailu.gtk.gio.Resource} for documentation on how to generate 15 | * gresource bundles. 16 | * 17 | * @param path absolute path to gresource: "/gresource/app.gresource" 18 | */ 19 | public static void loadAndRegister(String path) { 20 | try (var stream = (new JavaResource(path).asStream())) { 21 | var bytes = new Bytes(stream.readAllBytes()); 22 | var resource = Resource.newFromDataResource(ch.bailu.gtk.glib.Bytes.newStaticBytes(bytes, bytes.getLength())); 23 | resource.register(); 24 | } catch (IOException | AllocationError e) { 25 | System.err.println("Load gresource failed for '" + path + "'"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/bridge/Matrix.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.bridge; 2 | 3 | import java.awt.geom.AffineTransform; 4 | 5 | public class Matrix { 6 | 7 | 8 | /** 9 | * Translate awt.geom.AffineTransform to cairo.Matrix 10 | * 11 | * names and relations: 12 | * flatmatrix[0] m00 xx scaleX 13 | * flatmatrix[1] m10 yx shearY 14 | * flatmatrix[2] m01 xy shearX 15 | * flatmatrix[3] m11 yy scaleY 16 | */ 17 | public static ch.bailu.gtk.cairo.Matrix toCairoMatrix(AffineTransform transform) { 18 | var matrix = new ch.bailu.gtk.cairo.Matrix(); 19 | matrix.init( 20 | transform.getScaleX(), 21 | transform.getShearY(), 22 | transform.getShearX(), 23 | transform.getScaleY(), 24 | transform.getTranslateX(), 25 | transform.getTranslateY()); 26 | return matrix; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/bridge/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Util classes that facilitate integrating the java-gtk api into java 3 | * programs 4 | */ 5 | package ch.bailu.gtk.lib.bridge; 6 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/handler/ClassHandler.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.handler; 2 | 3 | import java.io.PrintStream; 4 | import java.util.HashMap; 5 | 6 | import ch.bailu.gtk.lib.util.SizeLog; 7 | import ch.bailu.gtk.type.Int; 8 | import ch.bailu.gtk.type.Pointer; 9 | 10 | public class ClassHandler { 11 | private final static HashMap map = new HashMap<>(); 12 | private static final SizeLog sizeLog = new SizeLog(ClassHandler.class.getSimpleName()); 13 | 14 | 15 | private final String name; 16 | private final Pointer instance; 17 | 18 | public ClassHandler(String key) { 19 | instance = new Int(); 20 | name = key; 21 | } 22 | 23 | public Pointer getInstance() { 24 | return instance; 25 | } 26 | 27 | public static ClassHandler get(String key) { 28 | synchronized (map) { 29 | if (map.containsKey(key)) { 30 | return map.get(key); 31 | } else { 32 | var result = new ClassHandler(key); 33 | map.put(key, result); 34 | sizeLog.log(map.size()); 35 | return result; 36 | } 37 | } 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return Long.toHexString(instance.asCPointer()) + " " + instance + " " + name; 43 | } 44 | 45 | public static void dump(PrintStream out) { 46 | out.println("_"); 47 | out.println(ClassHandler.class.getSimpleName()); 48 | out.println("=".repeat(ClassHandler.class.getSimpleName().length())); 49 | out.println(map.size()); 50 | map.keySet().forEach((key)-> out.println(map.get(key))); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/handler/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Manage GTK and JNA resources 3 | */ 4 | package ch.bailu.gtk.lib.handler; 5 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/jna/AdwLib.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.jna; 2 | 3 | import com.sun.jna.Library; 4 | 5 | public class AdwLib { 6 | 7 | private static AdwLib.Instance _INST = null; 8 | 9 | public static AdwLib.Instance INST() { 10 | if (_INST == null) { 11 | _INST = Loader.load("adwaita-1", AdwLib.Instance.class); 12 | } 13 | return _INST; 14 | } 15 | 16 | public interface Instance extends Library { 17 | // TODO enum types are not yet supported by API 18 | long adw_leaflet_transition_type_get_type(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/jna/GObjectLib.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.jna; 2 | 3 | import com.sun.jna.Callback; 4 | import com.sun.jna.Library; 5 | import com.sun.jna.Structure; 6 | 7 | public class GObjectLib { 8 | private static Instance _INST = null; 9 | 10 | public static final int GTYPE_INTERFACE_SIZE = 16; 11 | 12 | @Structure.FieldOrder({"g_iface", "get_item_type", "get_n_items", "get_item"}) 13 | private static class GListModelInterface extends Structure { 14 | 15 | public GListModelInterface(long _self) { 16 | super(ch.bailu.gtk.type.Pointer.asJnaPointer(_self)); 17 | } 18 | 19 | public byte[] g_iface = new byte[GTYPE_INTERFACE_SIZE]; 20 | public Callback get_item_type; 21 | public Callback get_n_items; 22 | public Callback get_item; 23 | } 24 | 25 | public static Instance INST() { 26 | if (_INST == null) { 27 | _INST = Loader.load("gobject-2.0", Instance.class); 28 | } 29 | return _INST; 30 | } 31 | 32 | public interface Instance extends Library { 33 | long g_signal_connect_data(long instance, String detailed_signal, Callback cb, long data, long destroy_data, int flag); 34 | void g_signal_handler_disconnect (long instance, long handler_id); 35 | int g_signal_new(long signal_name, long itype, int singal_flags, int class_offset, long accumulator, long accu_data, long c_marshaller, long return_type, int n_params, Object ... objects); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/jna/LibraryList.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.jna; 2 | 3 | import java.util.HashMap; 4 | import java.util.TreeSet; 5 | 6 | public class LibraryList { 7 | private final HashMap> libraries = new HashMap<>(); 8 | 9 | public boolean addInitial(String libraryName) { 10 | if (!libraries.containsKey(libraryName)) { 11 | addSingle(libraryName, libraryName); 12 | return true; 13 | } 14 | return false; 15 | } 16 | 17 | public void addSingle(String libraryName, String lib) { 18 | TreeSet set = new TreeSet<>(); 19 | set.add(lib); 20 | libraries.put(libraryName, set); 21 | } 22 | 23 | public TreeSet get(String libraryName) { 24 | return libraries.get(libraryName); 25 | } 26 | 27 | public void clear(String libraryName) { 28 | libraries.put(libraryName, new TreeSet<>()); 29 | } 30 | 31 | public void add(String libraryName, String lib) { 32 | if (libraries.containsKey(libraryName)) { 33 | libraries.get(libraryName).add(lib); 34 | } 35 | } 36 | 37 | public int size(String libraryName) { 38 | if (libraries.containsKey(libraryName)) { 39 | return libraries.get(libraryName).size(); 40 | } 41 | return 0; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/util/IDGen.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.util; 2 | 3 | public class IDGen { 4 | private long next = 0; 5 | public synchronized long gen() { 6 | return next++; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/util/MMap.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.util; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Set; 8 | 9 | public class MMap { 10 | private Map > map = new HashMap<>(); 11 | 12 | public synchronized void put(K1 k1, K2 k2, V v) { 13 | if (!containsKey(k1)) { 14 | map.put(k1, new HashMap<>()); 15 | } 16 | get(k1).put(k2, v); 17 | } 18 | 19 | private boolean containsKey(K1 k1) { 20 | return map.containsKey(k1); 21 | } 22 | 23 | public synchronized V get(K1 k1, K2 k2) { 24 | if (containsKey(k1)) { 25 | return get(k1).get(k2); 26 | } 27 | return null; 28 | } 29 | 30 | private Map get(K1 k1) { 31 | return map.get(k1); 32 | } 33 | 34 | public synchronized void remove(K1 k1) { 35 | map.remove(k1); 36 | } 37 | 38 | public synchronized void remove(K1 k1, K2 k2) { 39 | if (containsKey(k1)) { 40 | get(k1).remove(k2); 41 | if (get(k1).isEmpty()) { 42 | remove(k1); 43 | } 44 | } 45 | } 46 | 47 | 48 | public synchronized Collection getValues(K1 k1) { 49 | if (containsKey(k1)) { 50 | return get(k1).values(); 51 | } 52 | return Collections.emptySet(); 53 | } 54 | 55 | public synchronized long size() { 56 | return map.values().stream().mapToLong(Map::size).sum(); 57 | } 58 | 59 | public Set keySet() { 60 | return map.keySet(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/util/SizeLog.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.util; 2 | 3 | public class SizeLog { 4 | 5 | private final String label; 6 | private long lastLog = System.currentTimeMillis(); 7 | private long lastSize = 0; 8 | 9 | public SizeLog(String label) { 10 | this.label = label; 11 | } 12 | 13 | public void log(long size) { 14 | long now = System.currentTimeMillis(); 15 | 16 | if (now - lastLog > 5000) { 17 | if (lastSize != size) { 18 | System.out.println("R::" + this.label + ": " + size); 19 | } 20 | lastLog = now; 21 | lastSize = size; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/lib/util/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Util class that have no dependencies to GTK libraries 3 | */ 4 | package ch.bailu.gtk.lib.util; 5 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Array.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | public abstract class Array extends Wrapper { 6 | private final static int SIZE_UNKNOWN = -1; 7 | 8 | 9 | private int length; 10 | private final int bytes; 11 | 12 | public Array(PointerContainer pointer, int bytes, int length) { 13 | super(pointer); 14 | this.bytes = bytes; 15 | if (pointer.isNull()) { 16 | this.length = 0; 17 | } else { 18 | this.length = length; 19 | } 20 | } 21 | 22 | @Override 23 | public void destroy() { 24 | if (length != 0) { 25 | Glib.free(asPointer()); 26 | length = 0; 27 | } 28 | } 29 | 30 | public int getLength() { 31 | return length; 32 | } 33 | 34 | public int getSize() { 35 | if (length < 0) { 36 | return -1; 37 | } 38 | return length * bytes; 39 | } 40 | 41 | public void checkLimit(int index) { 42 | if (isSizeKnown() && !isWithinLimit(index)) { 43 | throw new IndexOutOfBoundsException("length: " + length + " index: " + index); 44 | } 45 | } 46 | 47 | private boolean isWithinLimit(int index) { 48 | return index < length && index >= 0; 49 | } 50 | 51 | public boolean isSizeKnown() { 52 | return length != SIZE_UNKNOWN; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Flt.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | public class Flt extends Array { 4 | 5 | public Flt(float f) { 6 | this(createFlt(f), 1); 7 | } 8 | public Flt() { 9 | this(createFlt(0),1); 10 | } 11 | public Flt(PointerContainer pointer, int length) { 12 | super(pointer, Float.BYTES, length); 13 | } 14 | public Flt(PointerContainer pointer) { 15 | super(pointer, Float.BYTES, 0); 16 | } 17 | public Flt(float[] values) { 18 | super(createFloatArray(values), Float.BYTES, values.length); 19 | } 20 | 21 | 22 | public void setAt(int index, float value) { 23 | throwIfNull(); 24 | checkLimit(index); 25 | ImpFlt.setAt(asCPointer(), index, value); 26 | } 27 | 28 | 29 | public float getAt(int index) { 30 | throwIfNull(); 31 | checkLimit(index); 32 | return ImpFlt.getAt(asCPointer(), index); 33 | } 34 | 35 | private static PointerContainer createFloatArray(float[] values) { 36 | if (values.length > 0) { 37 | return new PointerContainer(ImpFlt.createFloatArray(values)); 38 | } 39 | return PointerContainer.NULL; 40 | } 41 | 42 | private static PointerContainer createFlt(float value) { 43 | return new PointerContainer(ImpFlt.createFlt(value)); 44 | } 45 | 46 | public static Flt create(float value) { 47 | return new Flt(createFlt(value)); 48 | } 49 | 50 | public void set(float i) { 51 | setAt(0,i); 52 | } 53 | 54 | public float get() { 55 | return getAt(0); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Imp.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | public class Imp { 6 | public static long createPointerArray(long[] pointers) { 7 | long size = (long) pointers.length * Long.BYTES; 8 | Pointer result = Glib.malloc(size); 9 | Pointer.asJnaPointer(result).write(0, pointers, 0, pointers.length); 10 | return result.asCPointer(); 11 | } 12 | 13 | public static long allocate(long size) { 14 | var result = Glib.malloc0(size); 15 | return result.asCPointer(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/ImpBytes.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | class ImpBytes { 6 | public static long createBytes(int size) { 7 | var result = Glib.malloc0(size); 8 | return result.asCPointer(); 9 | } 10 | 11 | public static long createBytes(byte[] bytes) { 12 | var result = Glib.malloc(bytes.length); 13 | result.asJnaPointer().write(0, bytes, 0, bytes.length); 14 | 15 | return result.asCPointer(); 16 | } 17 | 18 | public static long createBytes(byte[] bytes, byte terminate) { 19 | var result = Glib.malloc(bytes.length+1); 20 | result.asJnaPointer().write(0, bytes, 0, bytes.length); 21 | result.asJnaPointer().setByte(bytes.length, terminate); 22 | 23 | return result.asCPointer(); 24 | } 25 | 26 | public static byte getByte(long cPointer, int index) { 27 | com.sun.jna.Pointer pointer = Pointer.asJnaPointer(cPointer); 28 | return pointer.getByte(index); 29 | } 30 | 31 | public static void setByte(long cPointer, int index, byte value) { 32 | com.sun.jna.Pointer pointer = Pointer.asJnaPointer(cPointer); 33 | pointer.setByte(index, value); 34 | } 35 | 36 | public static byte[] toBytes(long cPointer, int start, int size) { 37 | byte[] result = new byte[size]; 38 | 39 | com.sun.jna.Pointer pointer = Pointer.asJnaPointer(cPointer); 40 | pointer.read(start, result, 0, size); 41 | return result; 42 | } 43 | 44 | public static void setInt(long cPointer, int index, int value) { 45 | com.sun.jna.Pointer pointer = Pointer.asJnaPointer(cPointer); 46 | pointer.setInt(index, value); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/ImpDbl.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | class ImpDbl { 6 | 7 | public static long createDoubleArray(double[] doubles) { 8 | var result = Glib.malloc((long) doubles.length * Double.BYTES); 9 | result.asJnaPointer().write(0, doubles, 0, doubles.length); 10 | return result.asCPointer(); 11 | } 12 | 13 | public static long createDoubleArrayFromFloats(float[] floats) { 14 | var result = Glib.malloc((long) floats.length * Double.BYTES); 15 | com.sun.jna.Pointer p = result.asJnaPointer(); 16 | for (int i = 0; i< floats.length; i++) { 17 | p.setDouble((long) i *Double.BYTES, floats[i]); 18 | } 19 | return result.asCPointer(); 20 | 21 | } 22 | 23 | public static void setAt(long cPointer, int index, double value) { 24 | Pointer.asJnaPointer(cPointer).setDouble((long) index * Double.BYTES, value); 25 | } 26 | 27 | public static long createDbl(double value) { 28 | var result = Glib.malloc(Double.BYTES); 29 | result.asJnaPointer().setDouble(0, value); 30 | return result.asCPointer(); 31 | } 32 | 33 | public static double getAt(long cPointer, int index) { 34 | return Pointer.asJnaPointer(cPointer).getDouble((long) index * Double.BYTES); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/ImpFlt.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | class ImpFlt { 6 | public static void setAt(long cPointer, int index, float value) { 7 | Pointer.asJnaPointer(cPointer).setFloat((long) index * Float.BYTES, value); 8 | } 9 | 10 | public static long createFlt(float value) { 11 | var result = Glib.malloc(Float.BYTES); 12 | result.asJnaPointer().setFloat(0, value); 13 | return result.asCPointer(); 14 | } 15 | 16 | public static float getAt(long cPointer, int index) { 17 | return Pointer.asJnaPointer(cPointer).getFloat((long) index * Float.BYTES); 18 | } 19 | 20 | 21 | public static long createFloatArray(float[] floats) { 22 | var result = Glib.malloc((long) floats.length * Float.BYTES); 23 | com.sun.jna.Pointer p = result.asJnaPointer(); 24 | for (int i = 0; i< floats.length; i++) { 25 | p.setFloat((long) i * Float.BYTES, floats[i]); 26 | } 27 | return result.asCPointer(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/ImpInt.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | class ImpInt { 6 | 7 | public static long createInt(int value) { 8 | var result = Glib.malloc(Integer.BYTES); 9 | result.asJnaPointer().setInt(0, value); 10 | return result.asCPointer(); 11 | } 12 | 13 | public static void set(long cPointer, int value) { 14 | Pointer.asJnaPointer(cPointer).setInt(0, value); 15 | } 16 | 17 | public static int get(long cPointer) { 18 | return Pointer.asJnaPointer(cPointer).getInt(0); 19 | } 20 | 21 | 22 | public static long createLong(long value) { 23 | var result = Glib.malloc(Long.BYTES); 24 | result.asJnaPointer().setLong(0, value); 25 | return result.asCPointer(); 26 | } 27 | 28 | public static void setLong(long cPointer, long value) { 29 | Pointer.asJnaPointer(cPointer).setLong(0, value); 30 | } 31 | 32 | public static long getLong(long cPointer) { 33 | return Pointer.asJnaPointer(cPointer).getLong(0); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/ImpStr.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | 5 | class ImpStr { 6 | public static String toString(long pointer) { 7 | return Pointer.asJnaPointer(pointer).getString(0, StandardCharsets.UTF_8.name()); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Int.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | public class Int extends Wrapper { 6 | 7 | public final static Int NULL = new Int(new PointerContainer(0)); 8 | 9 | private boolean created; // prevent double destroy 10 | 11 | public Int(int value) { 12 | this(createInt(value)); 13 | } 14 | 15 | public Int() { 16 | this(createInt(0)); 17 | } 18 | 19 | public Int(PointerContainer pointer) { 20 | super(pointer); 21 | created = pointer.isNotNull(); 22 | } 23 | 24 | 25 | private static PointerContainer createInt(int value) { 26 | return new PointerContainer(ImpInt.createInt(value)); 27 | } 28 | 29 | public static Int create(int value) { 30 | return new Int(createInt(value)); 31 | } 32 | 33 | public void set(boolean b) { 34 | set( (b) ? 1 : 0); 35 | } 36 | 37 | public void set(int i) { 38 | ImpInt.set(asCPointer(), i); 39 | } 40 | 41 | public int get() { 42 | return ImpInt.get(asCPointer()); 43 | } 44 | 45 | public boolean is() { 46 | return get() != 0; 47 | } 48 | 49 | @Override 50 | public void destroy() { 51 | if (created) { 52 | Glib.free(asPointer()); 53 | created = false; 54 | } 55 | } 56 | 57 | public static int getTypeID() { 58 | return 24; // G_TYPE_INT 59 | } 60 | 61 | public static long getBooleanTypeID() { 62 | return 20; // G_TYPE_BOOLEAN 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Int64.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | /** 6 | * https://www.w3schools.com/java/java_data_types.asp 7 | */ 8 | public class Int64 extends Wrapper { 9 | private boolean created; 10 | 11 | public Int64() { 12 | this(createLong(0)); 13 | } 14 | 15 | public Int64(PointerContainer pointer) { 16 | super(pointer); 17 | created = pointer.isNotNull(); 18 | } 19 | 20 | 21 | private static PointerContainer createLong(long value) { 22 | return new PointerContainer(ImpInt.createLong(value)); 23 | } 24 | 25 | public static Int64 create(long value) { 26 | return new Int64(createLong(value)); 27 | } 28 | 29 | public void set(long i) { 30 | ImpInt.setLong(asCPointer(), i); 31 | } 32 | 33 | public long get() { 34 | return ImpInt.getLong(asCPointer()); 35 | } 36 | 37 | @Override 38 | public void destroy() { 39 | if (created) { 40 | Glib.free(asPointer()); 41 | created = false; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Interface.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | /** 4 | * Base class for gobject interfaces 5 | */ 6 | public class Interface extends PropertyHolder { 7 | 8 | public Interface(PointerContainer pointer) { 9 | super(pointer); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Outsider.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | /** 4 | * Unknown type. Type is in a external library 5 | */ 6 | public class Outsider extends Pointer { 7 | public Outsider(PointerContainer pointer) { 8 | super(pointer); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Package.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | /** 4 | * Base type for package functions class 5 | */ 6 | public class Package extends Type {} 7 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/PointerCastInterface.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import java.util.Objects; 4 | 5 | public interface PointerCastInterface { 6 | static void throwIfNull(PointerInterface pointer) { 7 | Objects.requireNonNull(pointer, "pointer == null"); 8 | pointer.throwIfNull(); 9 | } 10 | 11 | static long asCPointerNotNull(PointerInterface pointer) { 12 | throwIfNull(pointer); 13 | return pointer.asCPointer(); 14 | } 15 | 16 | static long asCPointer(PointerInterface pointer) { 17 | if (pointer == null) { 18 | return 0; 19 | } else { 20 | return pointer.asCPointer(); 21 | } 22 | } 23 | 24 | static long asCPointer(com.sun.jna.Pointer p) { 25 | return com.sun.jna.Pointer.nativeValue(p); 26 | } 27 | 28 | static com.sun.jna.Pointer asJnaPointer(PointerInterface p) { 29 | return asJnaPointer(p.asCPointer()); 30 | } 31 | 32 | 33 | static com.sun.jna.Pointer asJnaPointer(long p) { 34 | return new com.sun.jna.Pointer(p); 35 | } 36 | 37 | static Pointer asPointer(com.sun.jna.Pointer jnaPointer) { 38 | return new Pointer(cast(jnaPointer)); 39 | } 40 | 41 | static Pointer asPointer(long cPointer) { 42 | return new Pointer(cast(cPointer)); 43 | } 44 | 45 | static PointerContainer cast(long p) { 46 | return new PointerContainer(p); 47 | } 48 | 49 | static PointerContainer cast(com.sun.jna.Pointer p) { 50 | return new PointerContainer(asCPointer(p)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/PointerContainer.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | public class PointerContainer implements PointerInterface { 4 | public final static PointerContainer NULL = new PointerContainer(0); 5 | 6 | private final long cPointer; 7 | 8 | public PointerContainer(long pointer) { 9 | this.cPointer = pointer; 10 | } 11 | 12 | @Override 13 | public final long asCPointer() { 14 | return cPointer; 15 | } 16 | 17 | @Override 18 | public int hashCode() { 19 | return Long.valueOf(cPointer).hashCode(); 20 | } 21 | 22 | @Override 23 | public boolean equals(Object obj) { 24 | if (obj == this) { 25 | return true; 26 | } else if (obj == null) { 27 | return cPointer == 0; 28 | } else if (obj instanceof PointerInterface) { 29 | return ((PointerInterface)obj).asCPointer() == cPointer; 30 | } else if (obj instanceof Number) { 31 | return cPointer == ((Number) obj).longValue(); 32 | } 33 | return false; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return String.valueOf(cPointer); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/PointerInterface.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | public interface PointerInterface { 4 | long asCPointer(); 5 | 6 | default boolean isNull() { 7 | return asCPointer() == 0; 8 | } 9 | default boolean isNotNull() { 10 | return asCPointer() != 0; 11 | } 12 | 13 | default void throwIfNull() { 14 | Type.throwIfNull(this); 15 | } 16 | 17 | default long asCPointerNotNull() { 18 | throwIfNull(); 19 | return asCPointer(); 20 | } 21 | 22 | default com.sun.jna.Pointer asJnaPointer() { 23 | return Type.asJnaPointer(asCPointer()); 24 | } 25 | 26 | default PointerContainer cast() { 27 | return new PointerContainer(asCPointer()); 28 | } 29 | 30 | default Pointer asPointer() { 31 | return new Pointer(cast()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Record.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import ch.bailu.gtk.glib.Glib; 4 | 5 | /** 6 | * Record: a structure that is not based on gobject 7 | * 8 | */ 9 | public class Record extends Pointer { 10 | 11 | /** 12 | * Creates an empty record of specified size. 13 | * Allocates heap of specified size and initializes memory to 0. 14 | * @param size size to allocate 15 | */ 16 | public Record(int size) { 17 | super(Glib.malloc0(size).cast()); 18 | } 19 | 20 | public Record(PointerContainer pointer) { 21 | super(pointer); 22 | } 23 | 24 | /** 25 | * Frees resources. 26 | * Free memory allocated for this record. 27 | * Object is invalid afterwards and should not be accessed. 28 | */ 29 | public void destroy() { 30 | Glib.free(asPointer()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Str.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | 5 | public class Str extends Bytes { 6 | public final static Str NULL = new Str(PointerContainer.NULL); 7 | 8 | public Str(PointerContainer pointer) { 9 | super(pointer); 10 | } 11 | 12 | /** 13 | * Allocate a null terminated string in the c heap. 14 | * Copy str to allocated string. 15 | * @param str Java string to copy to c heap 16 | */ 17 | public Str(String str) { 18 | super(str.getBytes(StandardCharsets.UTF_8), (byte)0); 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | if (asCPointer() == 0) { 24 | return ""; 25 | } 26 | return ImpStr.toString(asCPointer()); 27 | } 28 | 29 | public static int getTypeID() { 30 | return 64; // G_TYPE_STRING 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Type.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * Base Type for all c types and type like structures: Record, Class, Wrapper, Package, Interface... 7 | * Holds all static type cast functions 8 | */ 9 | public abstract class Type { 10 | public static void throwIfNull(PointerInterface pointer) { 11 | Objects.requireNonNull(pointer, "pointer == null"); 12 | pointer.throwIfNull(); 13 | } 14 | 15 | public static long asCPointerNotNull(PointerInterface pointer) { 16 | //TODO throwIfNull(pointer); 17 | return pointer.asCPointer(); 18 | } 19 | 20 | public static long asCPointer(PointerInterface pointer) { 21 | if (pointer == null) { 22 | return 0; 23 | } else { 24 | return pointer.asCPointer(); 25 | } 26 | } 27 | 28 | public static long asCPointer(com.sun.jna.Pointer p) { 29 | return com.sun.jna.Pointer.nativeValue(p); 30 | } 31 | 32 | public static com.sun.jna.Pointer asJnaPointer(PointerInterface p) { 33 | return asJnaPointer(p.asCPointer()); 34 | } 35 | 36 | 37 | public static com.sun.jna.Pointer asJnaPointer(long p) { 38 | return new com.sun.jna.Pointer(p); 39 | } 40 | 41 | public static Pointer asPointer(com.sun.jna.Pointer jnaPointer) { 42 | return new Pointer(cast(jnaPointer)); 43 | } 44 | 45 | public static Pointer asPointer(long cPointer) { 46 | return new Pointer(cast(cPointer)); 47 | } 48 | 49 | public static PointerContainer cast(long p) { 50 | return new PointerContainer(p); 51 | } 52 | 53 | public static PointerContainer cast(com.sun.jna.Pointer p) { 54 | return new PointerContainer(asCPointer(p)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /java-gtk/src/main/java/ch/bailu/gtk/type/Util.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | public class Util { 4 | 5 | public static long[] toPointerArray(Pointer[] pointers) { 6 | long[] result = new long[pointers.length]; 7 | 8 | for (int i=0; i 4 | * Representation of native C types (wrapper types) for GTK Api calls and subtypes for API class hierarchy. 5 | */ 6 | package ch.bailu.gtk.type; 7 | -------------------------------------------------------------------------------- /java-gtk/src/main/resources/jna/loader.properties: -------------------------------------------------------------------------------- 1 | # Alternative library names: 2 | # key: default library name as set in 'generator/src/main/kotlin/ch/bailu/gtk/Configuration.kt' 3 | # value: comma separated list with additional names 4 | # 5 | gtk-4=libgtk-4-1,libgtk-4 6 | gio-2.0=libgio-2.0-0,libgio-2.0 7 | gobject-2.0=libgobject-2.0-0,libgobject-2.0 8 | pangocairo-1.0=libpangocairo-1.0-0,libpangocairo-1.0 9 | cairo=libcairo-2,libcairo 10 | glib-2.0=libglib-2.0-0,libglib-2.0 11 | pango-1.0=libpango-1.0-0,libpango-1.0 12 | gdk_pixbuf-2.0=libgdk_pixbuf-2.0-0,libgdk_pixbuf-2.0 13 | adwaita-1=libadwaita-1-0,libadwaita-1 14 | gstreamer-1.0=libgstreamer-1.0-0,libgstreamer-1.0 15 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestBytes.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import ch.bailu.gtk.type.Bytes; 8 | import ch.bailu.gtk.type.PointerContainer; 9 | 10 | public class TestBytes { 11 | 12 | 13 | @Test 14 | public void testBytes() { 15 | byte[] buffer = new byte[200]; 16 | buffer[0]=42; 17 | buffer[199]=99; 18 | 19 | Bytes bytesA = new Bytes(buffer); 20 | 21 | 22 | assertEquals(200, bytesA.getSize()); 23 | assertEquals(42, bytesA.getByte(0)); 24 | assertEquals(99, bytesA.getByte(199)); 25 | 26 | bytesA.setByte(199, (byte) 98); 27 | assertEquals(98, bytesA.getByte(199)); 28 | 29 | bytesA.destroy(); 30 | assertEquals(0, bytesA.getSize()); 31 | 32 | 33 | Bytes bytesB = new Bytes(new byte[0]); 34 | assertEquals(0, bytesB.getSize()); 35 | bytesB.destroy(); 36 | } 37 | 38 | @Test 39 | public void testNullBytes() { 40 | Bytes bytes = new Bytes(PointerContainer.NULL); 41 | assertEquals(0, bytes.getSize()); 42 | assertEquals(0, bytes.getLength()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestCPointer.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertFalse; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import ch.bailu.gtk.type.PointerContainer; 9 | 10 | public class TestCPointer { 11 | 12 | @Test 13 | public void testCPointer() { 14 | assertTrue(PointerContainer.NULL.isNull()); 15 | assertFalse(PointerContainer.NULL.isNotNull()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestDbl.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import ch.bailu.gtk.type.Dbl; 8 | 9 | public class TestDbl { 10 | 11 | 12 | @Test 13 | public void testDbl() { 14 | Dbl d = new Dbl(); 15 | assertEquals(0d, d.get()); 16 | 17 | d.set(290.99); 18 | assertEquals(290.99, d.get()); 19 | 20 | d.set(Double.MAX_VALUE); 21 | assertEquals(Double.MAX_VALUE, d.get()); 22 | 23 | d.set(Double.MIN_VALUE); 24 | assertEquals(Double.MIN_VALUE, d.get()); 25 | } 26 | 27 | @Test 28 | public void testDbls() { 29 | Dbl d = new Dbl(new double[] {4d,Double.MAX_VALUE,6d,7d,0d,-1d}); 30 | Dbl f = new Dbl(new float[] {4f,Float.MAX_VALUE,7f,0f,-1f}); 31 | 32 | assertEquals(6, d.getLength()); 33 | assertEquals(5, f.getLength()); 34 | 35 | assertEquals(Double.MAX_VALUE, d.getAt(1)); 36 | assertEquals(Float.MAX_VALUE, f.getAt(1)); 37 | assertEquals(-1f, f.getAt(f.getLength()-1)); 38 | 39 | d.destroy(); 40 | f.destroy(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestFlt.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import ch.bailu.gtk.type.Flt; 8 | 9 | public class TestFlt { 10 | @Test 11 | public void testFlt() { 12 | Flt flt = new Flt(); 13 | assertEquals(0f, flt.get()); 14 | 15 | flt.set(290.99f); 16 | assertEquals(290.99f, flt.get()); 17 | 18 | flt.set(Float.MAX_VALUE); 19 | assertEquals(Float.MAX_VALUE, flt.get()); 20 | 21 | flt.destroy(); 22 | } 23 | 24 | @Test 25 | public void testFlts() { 26 | Flt flts = new Flt(new float[] {4f,Float.MAX_VALUE,7f,0f,-1f}); 27 | 28 | assertEquals(5, flts.getLength()); 29 | assertEquals(Float.MAX_VALUE, flts.getAt(1)); 30 | assertEquals(-1f, flts.getAt(flts.getLength()-1)); 31 | 32 | flts.destroy(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestGBytes.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import ch.bailu.gtk.lib.bridge.Bytes; 8 | 9 | public class TestGBytes { 10 | 11 | @Test 12 | public void testBytes() { 13 | byte[] buffer = new byte[200]; 14 | buffer[0]=42; 15 | buffer[199]=99; 16 | 17 | Bytes bytesA = new Bytes(buffer); 18 | 19 | assertEquals(200, bytesA.getSize()); 20 | assertEquals(42, bytesA.getByte(0)); 21 | assertEquals(99, bytesA.getByte(199)); 22 | bytesA.unref(); 23 | 24 | Bytes bytesB = new Bytes(new byte[0]); 25 | assertEquals(0, bytesB.getSize()); 26 | bytesB.unref(); 27 | 28 | Bytes bytesC = new Bytes(new byte[]{4,5,0}); 29 | byte[] res = bytesC.toBytes(); 30 | assertEquals(3, res.length); 31 | assertEquals(4, res[0]); 32 | assertEquals(5, res[1]); 33 | assertEquals(0, res[2]); 34 | bytesC.unref(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestGObject.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import ch.bailu.gtk.gobject.Gobject; 4 | import ch.bailu.gtk.type.Str; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.*; 8 | 9 | public class TestGObject { 10 | 11 | @Test void testGObject() { 12 | assertTrue(Gobject.signalIsValidName(new Str("activate"))); 13 | assertFalse(Gobject.signalIsValidName(new Str("äctivate"))); 14 | assertEquals((20) << (2), ch.bailu.gtk.gobject.Object.getTypeID()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestGdkRectangle.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertFalse; 5 | import static org.junit.jupiter.api.Assertions.assertTrue; 6 | 7 | import org.junit.jupiter.api.Test; 8 | 9 | import ch.bailu.gtk.gdk.Rectangle; 10 | 11 | public class TestGdkRectangle { 12 | 13 | @Test public void testRectangle() { 14 | Rectangle r1 = new Rectangle(); 15 | 16 | assertEquals(0, r1.getFieldX()); 17 | assertEquals(0, r1.getFieldY()); 18 | assertEquals(0, r1.getFieldWidth()); 19 | assertEquals(0, r1.getFieldHeight()); 20 | 21 | r1.setFieldY(5); 22 | r1.setFieldWidth(10); 23 | assertEquals(5, r1.getFieldY()); 24 | assertEquals(10, r1.getFieldWidth()); 25 | 26 | Rectangle r2 = new Rectangle(); 27 | r2.setFieldY(5); 28 | r2.setFieldWidth(10); 29 | 30 | assertTrue(r1.equal(r2)); 31 | 32 | r2.setFieldHeight(2); 33 | assertEquals(2, r2.getFieldHeight()); 34 | assertFalse(r1.equal(r2)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestInt.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import ch.bailu.gtk.type.Int; 6 | import ch.bailu.gtk.type.Int64; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | 10 | public class TestInt { 11 | 12 | @Test 13 | public void testInt() { 14 | var a = new Int(); 15 | assertEquals(0, a.get()); 16 | 17 | a.set(290); 18 | assertEquals(290, a.get()); 19 | 20 | a.set(Integer.MAX_VALUE); 21 | assertEquals(Integer.MAX_VALUE, a.get()); 22 | 23 | a.set(Integer.MIN_VALUE); 24 | assertEquals(Integer.MIN_VALUE, a.get()); 25 | a.destroy(); 26 | 27 | var b = Int.create(-1); 28 | assertEquals(-1, b.get()); 29 | b.destroy(); 30 | } 31 | 32 | @Test 33 | public void testInt64() { 34 | var a = new Int64(); 35 | assertEquals(0L, a.get()); 36 | 37 | a.set(290); 38 | assertEquals(290L, a.get()); 39 | 40 | a.set(Long.MAX_VALUE); 41 | assertEquals(Long.MAX_VALUE, a.get()); 42 | 43 | a.set(Long.MIN_VALUE); 44 | assertEquals(Long.MIN_VALUE, a.get()); 45 | a.destroy(); 46 | 47 | var b = Int64.create(-1L); 48 | assertEquals(-1L, b.get()); 49 | b.destroy(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestIntrospection.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import ch.bailu.gtk.gobject.InitiallyUnowned; 9 | import ch.bailu.gtk.gobject.InitiallyUnownedClass; 10 | import ch.bailu.gtk.gobject.Object; 11 | import ch.bailu.gtk.gobject.ObjectClass; 12 | import ch.bailu.gtk.gtk.Widget; 13 | import ch.bailu.gtk.gtk.WidgetClass; 14 | 15 | public class TestIntrospection { 16 | @Test 17 | void testTypeSize() { 18 | assertTrue(ObjectClass.getInstanceSize()>0); 19 | assertEquals(Object.getTypeSize().classSize, ObjectClass.getInstanceSize()); 20 | 21 | assertTrue(WidgetClass.getInstanceSize()>0); 22 | assertEquals(Widget.getTypeSize().classSize, WidgetClass.getInstanceSize()); 23 | 24 | assertEquals(Widget.getParentTypeSize().instanceSize, InitiallyUnowned.getInstanceSize()); 25 | assertEquals(Widget.getParentTypeSize().classSize, InitiallyUnownedClass.getInstanceSize()); 26 | assertEquals(Widget.getParentTypeSize().classSize, InitiallyUnowned.getTypeSize().classSize); 27 | assertEquals(Widget.getParentTypeSize().instanceSize, InitiallyUnowned.getTypeSize().instanceSize); 28 | } 29 | 30 | @Test 31 | void testTypeId() { 32 | assertEquals(Widget.getParentTypeID(), InitiallyUnowned.getTypeID()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestListIndex.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import ch.bailu.gtk.lib.bridge.ListIndex; 9 | import ch.bailu.gtk.gio.ListModel; 10 | import ch.bailu.gtk.gtk.SelectionModel; 11 | import ch.bailu.gtk.gtk.SingleSelection; 12 | 13 | public class TestListIndex { 14 | 15 | 16 | @Test 17 | public void testListIndex() { 18 | ListIndex listIndex = new ListIndex(5); 19 | assertEquals(5, listIndex.getSize()); 20 | assertEquals(0, listIndex.getIndex()); 21 | listIndex.setIndex(2); 22 | assertEquals(2, listIndex.getIndex()); 23 | 24 | var listModel = new ListModel(listIndex.cast()); 25 | assertEquals(1, new ListIndex(listModel.getItem(1).cast()).getIndex()); 26 | assertEquals(1, new ListIndex(listModel.getObject(1).cast()).getIndex()); 27 | 28 | listIndex.setSize(10); 29 | assertEquals(10, listModel.getNItems()); 30 | 31 | var singleSelection = new SingleSelection(listModel); 32 | assertEquals(0, singleSelection.getSelected()); 33 | listIndex.setSize(10); 34 | 35 | singleSelection.setSelected(3); 36 | assertEquals(3,singleSelection.getSelected()); 37 | 38 | var selectionModel = new SelectionModel(singleSelection.cast()); 39 | selectionModel.selectItem(4, true); 40 | assertTrue(selectionModel.isSelected(4)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/TestTypeQuery.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import ch.bailu.gtk.gobject.Gobject; 8 | import ch.bailu.gtk.gobject.TypeQuery; 9 | import ch.bailu.gtk.type.gobject.TypeSystem; 10 | 11 | public class TestTypeQuery { 12 | 13 | public static final int GOBJECT_INSTANCE_SIZE = 24; 14 | public static final int GOBJECT_CLASS_SIZE = 136; 15 | 16 | @Test 17 | public void test() { 18 | var type = ch.bailu.gtk.gobject.Object.getTypeID(); 19 | var typeQuery = new TypeQuery(); 20 | Gobject.typeQuery(type, typeQuery); 21 | typeQuery.getFieldType(); 22 | assertEquals(type, typeQuery.getFieldType()); 23 | assertEquals((20) << (2), typeQuery.getFieldType()); 24 | 25 | assertEquals(GOBJECT_CLASS_SIZE, typeQuery.getFieldClassSize()); 26 | assertEquals(GOBJECT_INSTANCE_SIZE, typeQuery.getFieldInstanceSize()); 27 | 28 | assertEquals(TypeSystem.getTypeSize(type).classSize, typeQuery.getFieldClassSize()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/lib/bridge/InputStreamBridgeTest.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.lib.bridge; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.io.IOException; 9 | 10 | import ch.bailu.gtk.gdkpixbuf.Pixbuf; 11 | import ch.bailu.gtk.gobject.Object; 12 | import ch.bailu.gtk.lib.util.JavaResource; 13 | import ch.bailu.gtk.type.Bytes; 14 | import ch.bailu.gtk.type.Str; 15 | import ch.bailu.gtk.type.exception.AllocationError; 16 | 17 | public class InputStreamBridgeTest { 18 | 19 | @Test 20 | public void testInputStreamBridge() throws AllocationError, IOException { 21 | System.out.println("Class Size: " + Object.getTypeSize().classSize); 22 | 23 | 24 | try (java.io.InputStream inputStream = new JavaResource("/test.txt").asStream()) { 25 | var inputStreamBridge = new InputStreamBridge(inputStream); 26 | 27 | var buffer = new Bytes(10); 28 | 29 | var count = (int)inputStreamBridge.read(buffer,buffer.getLength(), null); 30 | buffer.setByte(count, (byte)0); 31 | 32 | assertEquals(4, count, "resources/test.txt must not contain new line"); 33 | assertEquals("test", new Str(buffer.cast()).toString()); 34 | inputStreamBridge.unref(); 35 | } 36 | } 37 | 38 | @Test 39 | public void testReadImage() throws IOException, AllocationError { 40 | final var inputStreamBridge = new InputStreamBridge(new JavaResource("/GTK.svg").asStream()); 41 | final var pixbuf = Pixbuf.newFromStreamAtScalePixbuf(inputStreamBridge, -1, -1, true, null); 42 | assertEquals(89, pixbuf.getWidth()); 43 | assertEquals(96, pixbuf.getHeight()); 44 | assertTrue(inputStreamBridge.close(null)); 45 | inputStreamBridge.unref(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java-gtk/src/test/java/ch/bailu/gtk/type/TestPointer.java: -------------------------------------------------------------------------------- 1 | package ch.bailu.gtk.type; 2 | 3 | import static org.junit.jupiter.api.Assertions.assertEquals; 4 | import static org.junit.jupiter.api.Assertions.assertFalse; 5 | import static org.junit.jupiter.api.Assertions.assertTrue; 6 | 7 | import org.junit.jupiter.api.Test; 8 | 9 | public class TestPointer { 10 | 11 | @Test 12 | void testPointer() { 13 | assertEquals(45L, new Pointer(Type.cast(45L)).asCPointer()); 14 | assertEquals(999L, Type.cast(new Pointer(Type.cast(999L)).asJnaPointer()).asCPointer()); 15 | 16 | var pointer1 = Pointer.NULL; 17 | var pointer2 = new Pointer(Type.cast(0)); 18 | 19 | assertTrue(pointer1.equals(pointer1)); 20 | assertTrue(pointer1.equals(null)); 21 | assertTrue(pointer1.equals(pointer2)); 22 | assertTrue(pointer1.equals(0L)); 23 | assertTrue(pointer1.equals(0f)); 24 | 25 | var pointer3 = new Pointer(Type.cast(123)); 26 | var pointer4 = new Pointer(pointer3.cast()); 27 | assertFalse(pointer3.equals(pointer1)); 28 | assertTrue(pointer3.equals(pointer4)); 29 | assertTrue(pointer3.equals(123L)); 30 | assertFalse(pointer3.equals(124L)); 31 | assertTrue(pointer3.equals(123f)); 32 | assertTrue(pointer3.equals(Type.cast(123))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java-gtk/src/test/resources/GTK.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /java-gtk/src/test/resources/test.txt: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk11 3 | install: 4 | - ./gradlew -q generator:generate 5 | - ./gradlew -q java-gtk:build java-gtk:publishToMavenLocal -xtest 6 | env: 7 | MYVAR: "custom environment variable" 8 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "java-gtk" 2 | 3 | include("generator") 4 | include("java-gtk") 5 | include("examples") 6 | --------------------------------------------------------------------------------