Skip to content

Commit

Permalink
Merge branch 'termux:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
airidosas252 authored Nov 13, 2024
2 parents 24d153e + 354acbd commit a664316
Show file tree
Hide file tree
Showing 74 changed files with 5,052 additions and 1,152 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/debug_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
with:
submodules: recursive
- name: Validation
uses: gradle/wrapper-validation-action@v3
uses: gradle/actions/wrapper-validation@v4

- name: Java setup
uses: actions/setup-java@v4
Expand All @@ -52,8 +52,6 @@ jobs:
run: ./gradlew assembleDebug
- name: Build companion package
run: ./build_termux_package
- name: Copy loader to target directory
run: cp ./shell-loader/build/outputs/apk/debug/shell-loader-debug.apk ./app/build/outputs/apk/debug/shell-loader-nightly.apk
- name: Store app-arm64-v8a-debug
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -89,7 +87,6 @@ jobs:
with:
name: termux-companion packages
path: |
./app/build/outputs/apk/debug/shell-loader-nightly.apk
./app/build/outputs/apk/debug/termux-x11-*-all.deb
./app/build/outputs/apk/debug/termux-x11-*-any.pkg.tar.xz
Expand All @@ -114,6 +111,5 @@ jobs:
Based on ${{ github.sha }}
files: |
./app/build/outputs/apk/debug/app-*-debug.apk
./app/build/outputs/apk/debug/shell-loader-nightly.apk
./app/build/outputs/apk/debug/termux-x11-*-all.deb
./app/build/outputs/apk/debug/termux-x11-*-any.pkg.tar.xz
2 changes: 1 addition & 1 deletion .github/workflows/update-wrapper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ jobs:
submodules: recursive

- name: Update Gradle Wrapper
uses: gradle-update/update-gradle-wrapper-action@v1
uses: gradle-update/update-gradle-wrapper-action@v2
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,6 @@
[submodule "app/src/main/cpp/bzip2"]
path = app/src/main/cpp/bzip2
url = https://gitlab.com/bzip2/bzip2
[submodule "app/src/main/cpp/OpenXR-SDK"]
path = app/src/main/cpp/OpenXR-SDK
url = https://github.com/KhronosGroup/OpenXR-SDK.git
50 changes: 46 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ or
Just like any other X server.

## Setup Instructions
Application runs only on Android 8+ devices.
For this one you must enable the `x11-repo` repository can be done by executing `pkg install x11-repo` command
Termux:X11 requres Android 8 or later. It consists of an Android app and a companion termux package, and you must install both.

For X applications to work, you must install Termux-x11 companion package. You can do that by downloading an artifact from [last successful build](https://github.com/termux/termux-x11/actions/workflows/debug_build.yml) and installing `termux-x11-*-debug.apk` (according to device `architecture`, universal if you are doubting) and `*.deb` (if you use termux with `pkg`) or `*.tar.xz` (if you use termux with `pacman`) files from `termux-companion packages` artifact (do not try to install `shell-loader-nightly.apk` as Android application, it is not intended to be installed, it is only for chroot users).
Or you can install nightly companion package from repositories with `pkg in x11-repo && pkg in termux-x11-nightly`
The Android app is available via the [nightly release tag](https://github.com/termux/termux-x11/releases/tag/nightly) of this repository. Download and install the `app-$ARCHITECTURE-debug.apk` matching your device's CPU architecture. (You can choose `app-universal-debug.apk` if you are not sure which architecture to pick, and it'll use a few extra MB of storage.)

The companion termux package is available from the termux graphical repository. You can ensure it's enabled and install this package with `pkg i x11-repo && pkg i termux-x11-nightly`. If you need to, you can also download a `.deb` or `*.tar.xz` from the same nightly release tag as above.

Finally, most people will want to use a desktop environment with Termux:X11. If you don't know what that means or don't know which one to pick, run `pkg i xfce` (also from `x11-repo`) to install a good one to start with. The rest of these instructions will assume that your goal is to run an XFCE desktop, or that you can modify the instructions as you follow them for your actual goal.

## Running Graphical Applications
You can start your desired graphical application by doing:
Expand All @@ -48,6 +50,14 @@ You may replace `xfce4-session` if you use other than Xfce
~ $ termux-x11 :1 -xstartup "xfce4-session"
```

Also you can do
```
export TERMUX_X11_XSTARTUP="xfce4-session"
termux-x11 :1
```
In this case you can same TERMUX_X11_XSTARTUP somewhere in `.bashrc` or other script and not type it every time you invoke termux-x11.


If you're done using Termux:X11 just simply exit it through it's notification drawer by expanding the Termux:X11 notification then "Exit"
But you should pay attention that `termux-x11` command is still running and can not be killed this way.

Expand All @@ -71,12 +81,28 @@ If you plan to use the program with chroot or unshare, you must to run it as roo
This directory must be accessible from the shell from which you launch termux-x11, i.e. it must be in the same SELinux context, same mount namespace, and so on.
Also you must set `XKB_CONFIG_ROOT` environment variable pointing to container's `/usr/share/X11/xkb` directory, otherwise you will have `xkbcomp`-related errors.
You can get loader for nightly build from an artifact of [last successful build](https://github.com/termux/termux-x11/actions/workflows/debug_build.yml)
Do not forget to disable SELinux
```
setenforce 0
export TMPDIR=/path/to/chroot/container/tmp
export CLASSPATH=$(/system/bin/pm path com.termux.x11 | cut -d: -f2)
/system/bin/app_process / com.termux.x11.CmdEntryPoint :0
```

### Force stopping X server (running in termux background, not an activity)

termux-x11's X server runs in process with name "app_process", not "termux-x11". But you can kill it by searching "com.termux.x11" in commandline.
So killing it will look like
```
pkill -f com.termux.x11
```

### Closing Android activity (running in foreground, not X server)

```
am broadcast -a com.termux.x11.ACTION_STOP -p com.termux.x11
```

### Logs
If you need to obtain logs from the `com.termux.x11` application,
set the `TERMUX_X11_DEBUG` environment variable to 1, like this:
Expand Down Expand Up @@ -151,6 +177,22 @@ Also you can start `termux-x11` with `-dpi` option.
~ $ termux-x11 :1 -xstartup "xfce4-session" -dpi 120
```

## Changing, dumping and restoring preferences from commandline

It is possible to change preferences of termux-x11 from command line.
`termux-x11-nightly` package contains `termux-x11-preference` tool which can be used like
```shell
termux-x11-preference [list] {key:value} [{key2:value2}]..."
```
Use `termux-x11-preference` to dump current preference.
Use `termux-x11-preference > file` to dump current preferences to file.
Use `termux-x11-preferences < file` to restore preferences from file.
Use `termux-x11-preferences "fullscreen"="false" "showAdditionalKbd"="true"` to disable fullscreen and enable additional key bar. The full list of preferences you can modify is available with `termux-x11-preference list` command. You can specify one or more preferences here.
Termux:X11 activity should be available in background or foreground, otherwise `termux-x11-preferences` tool will hang indefinitely.
In the case if there is `Store preferences for secondary displays separately` preference active `termux-x11-preference` will use/modify preferences of display where Termux:X11 activity is currently opened.
## Using with 3rd party apps
It is possible to use Termux:X11 with 3rd party apps.
Check how `shell-loader/src/main/java/com/termux/x11/Loader.java` works.
Expand Down
67 changes: 63 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ apply plugin: 'com.android.application'

android {
namespace 'com.termux.x11'
//noinspection GrDeprecatedAPIUsage
compileSdkVersion 34
defaultConfig {
applicationId "com.termux.x11"
minSdkVersion 26
targetSdkVersion 34
versionCode 14
versionName "1.03.00"
versionCode 15
def commit= 'git rev-parse --verify --short HEAD'.execute().text.trim()
def version = "1.03.01"
versionName "${version}-${commit.length()==1?"nongit":commit}-${(new Date()).format("dd.MM.yy")}"
buildConfigField "String", "COMMIT", "\"" + ("git rev-parse HEAD\n".execute().getText().trim() ?: (System.getenv('CURRENT_COMMIT') ?: "NO_COMMIT")) + "\""
}

Expand Down Expand Up @@ -46,8 +49,64 @@ android {

dependencies {
//noinspection DifferentStdlibGradleVersion
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.23"
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.21"
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.6'
implementation 'androidx.preference:preference:1.2.1'
compileOnly project(':shell-loader:stub')
}
afterEvaluate {
tasks.register("generatePrefs") {
//noinspection UnnecessaryQualifiedReference
def xml = groovy.xml.DOMBuilder.parse((new StringReader(file('src/main/res/xml/preferences.xml').text)))
def preferenceNodes = xml.documentElement.getElementsByTagName("*")
def preferences = []

for (int i = 0; i < preferenceNodes.length; i++) {
def node = preferenceNodes.item(i)
if (node.nodeName == 'EditTextPreference' && node.getAttribute("app:key") != "extra_keys_config")
preferences << [ type: 'String', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue") ]
else if (node.nodeName == 'SeekBarPreference')
preferences << [ type: 'Int', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue") ]
else if (node.nodeName == 'ListPreference') {
def entries = node.getAttribute("app:entries")
def values = node.getAttribute("app:entryValues")
preferences << [type: 'List', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue"),
entries: entries.substring(7, entries.length()), values: values.substring(7, values.length())]
}
else if (node.nodeName == 'SwitchPreferenceCompat')
preferences << [ type: 'Boolean', key: node.getAttribute("app:key"), default: node.getAttribute("app:defaultValue") ]
}

def out = file('build/generated/java/com/termux/x11/Prefs.java')
out.getParentFile().exists() || out.getParentFile().mkdirs()
out.delete()
out.createNewFile()

out << 'package com.termux.x11;\n'
out << 'import java.util.HashMap;\n'
out << 'import android.content.Context;\n'
out << 'import com.termux.x11.utils.TermuxX11ExtraKeys;\n'
out << '\n'
out << 'public class Prefs extends LoriePreferences.PrefsProto {\n'
preferences.each {
if (it.type == 'Int' || it.type == 'Boolean')
out << " public final ${it.type}Preference ${it.key} = new ${it.type}Preference(\"${it.key}\", ${it.default});\n"
else if (it.type == 'String')
out << " public final StringPreference ${it.key} = new StringPreference(\"${it.key}\", \"${it.default}\");\n"
else if (it.type == 'List')
out << " public final ${it.type}Preference ${it.key} = new ${it.type}Preference(\"${it.key}\", \"${it.default}\", R.array.${it.entries}, R.array.${it.values});\n"
}
out << ' public final StringPreference extra_keys_config = new StringPreference("extra_keys_config", TermuxX11ExtraKeys.DEFAULT_IVALUE_EXTRA_KEYS);\n'
out << ' public final HashMap<String, Preference> keys = new HashMap<>() {{\n'
preferences.each { out << ' put("' + it.key + '", ' + it.key + ');\n' }
out << ' put("extra_keys_config", extra_keys_config);\n'
out << ' }};\n'
out << '\n'
out << ' public Prefs(Context ctx) {\n'
out << ' super(ctx);\n'
out << ' }\n'
out << '}\n'
}
android.sourceSets.main.java.srcDirs += 'build/generated/java'
preBuild.dependsOn generatePrefs
}
19 changes: 19 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<uses-feature android:name="android.hardware.vr.headtracking" android:required="false" />
<uses-feature android:name="com.oculus.feature.PASSTHROUGH" android:required="false" />
<uses-feature android:name="oculus.software.handtracking" android:required="false" />
<uses-feature android:name="oculus.software.overlay_keyboard" android:required="false" />

<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
Expand Down Expand Up @@ -37,6 +42,20 @@
</intent-filter>
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />
</activity>
<activity
android:name=".XrActivity"
android:configChanges="density|orientation|screenSize|keyboard|keyboardHidden|uiMode"
android:exported="true"
android:launchMode="singleTask"
android:resizeableActivity="false"
android:screenOrientation="landscape"
android:process=":vr_process">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="com.oculus.intent.category.VR" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:theme="@style/Theme.AppCompat.DayNight"
android:excludeFromRecents="true"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/aidl/com/termux/x11/ICmdEntryInterface.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.termux.x11;

// This interface is used by utility on termux side.
interface ICmdEntryInterface {
void windowChanged(in Surface surface);
void windowChanged(in Surface surface, String name);
ParcelFileDescriptor getXConnection();
ParcelFileDescriptor getLogcatOutput();
}
20 changes: 19 additions & 1 deletion app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ set(test_compile_options
"-fno-strict-aliasing"
"-Wno-unused-but-set-variable"
"-Wno-unused-parameter"
"-Wno-unused-variable")
"-Wno-unused-variable"
"-Wno-unused-function"
"-Wno-missing-prototypes"
"-Wno-macro-redefined"
"-Wno-uninitialized"
"-Wno-shadow")

set(CMAKE_REQUIRED_QUIET_OLD ${CMAKE_REQUIRED_QUIET})
set(CMAKE_REQUIRED_QUIET 1)
Expand All @@ -75,3 +80,16 @@ set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_OLD})
foreach(project xorgproto fontenc md pixman tirpc xshmfence Xdmcp Xau Xfont2 xkbcomp xserver)
include(recipes/${project}.cmake)
endforeach()

if(${ANDROID_ABI} MATCHES "arm64-v8a")
add_subdirectory(OpenXR-SDK)
add_library(XRio SHARED
"xrio/android.c"
"xrio/engine.c"
"xrio/framebuffer.c"
"xrio/input.c"
"xrio/math.c"
"xrio/renderer.c")
target_link_options(XRio PRIVATE "-Wl,--as-needed" "-Wl,--no-undefined" "-fvisibility=hidden")
target_link_libraries(XRio "-Wl,--whole-archive" "-Wl,--no-whole-archive" android log EGL GLESv2 openxr_loader)
endif()
1 change: 1 addition & 0 deletions app/src/main/cpp/OpenXR-SDK
Submodule OpenXR-SDK added at f90488
2 changes: 1 addition & 1 deletion app/src/main/cpp/libfontenc
Submodule libfontenc updated from 68300c to 92a85f
2 changes: 1 addition & 1 deletion app/src/main/cpp/libx11
Submodule libx11 updated from fc5ec8 to a46558
2 changes: 1 addition & 1 deletion app/src/main/cpp/libxdmcp
Submodule libxdmcp updated from 7f5677 to 1192d3
2 changes: 1 addition & 1 deletion app/src/main/cpp/libxtrans
Submodule libxtrans updated from c4262e to 3b3a3b
Loading

0 comments on commit a664316

Please sign in to comment.