Xorg: launch xserver

This commit is contained in:
zt515
2017-12-02 00:16:01 +08:00
parent 4b6b707e33
commit 136ba9bc63
10 changed files with 937 additions and 905 deletions

View File

@ -138,7 +138,9 @@ public class Globals {
public static boolean MultitouchGesturesUsed[] = new boolean[4]; public static boolean MultitouchGesturesUsed[] = new boolean[4];
public static int MultitouchGestureSensitivity = 1; public static int MultitouchGestureSensitivity = 1;
public static int TouchscreenCalibration[] = new int[4]; public static int TouchscreenCalibration[] = new int[4];
public static String DataDir = new String(""); public static String DataDir = "/data/data/io.neoterm/files/usr/share/xorg-neoterm";
public static String UnSecureDataDir = "/data/data/io.neoterm/files/usr/share/xorg-neoterm";
public static String HomeDir = "/data/data/io.neoterm/files/home";
public static boolean VideoLinearFilter = true; public static boolean VideoLinearFilter = true;
public static boolean MultiThreadedVideo = false; public static boolean MultiThreadedVideo = false;

View File

@ -14,4 +14,8 @@ public class NeoGLView extends DemoGLSurfaceView {
public void callNativeScreenKeyboardShown(int shown) { public void callNativeScreenKeyboardShown(int shown) {
nativeScreenKeyboardShown(shown); nativeScreenKeyboardShown(shown);
} }
public void callNativeScreenVisibleRect(int x, int y, int w, int h) {
nativeScreenVisibleRect(x, y, w, h);
}
} }

View File

@ -0,0 +1,13 @@
package io.neoterm;
import io.neoterm.xorg.NeoXorgViewClient;
/**
* @author kiva
*/
public class NeoXorgSettings {
public static void init(NeoXorgViewClient client) {
Settings.Load(client);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import io.neoterm.Globals import io.neoterm.Globals
import io.neoterm.NeoXorgSettings
import io.neoterm.R import io.neoterm.R
import io.neoterm.frontend.component.NeoComponent import io.neoterm.frontend.component.NeoComponent
import io.neoterm.frontend.logging.NLog import io.neoterm.frontend.logging.NLog
@ -66,7 +67,7 @@ class SessionComponent : NeoComponent {
return result return result
} }
private fun checkLibrariesLoaded() { private fun checkLibrariesLoaded(): Boolean {
if (!IS_LIBRARIES_LOADED) { if (!IS_LIBRARIES_LOADED) {
synchronized(SessionComponent::class.java) { synchronized(SessionComponent::class.java) {
if (!IS_LIBRARIES_LOADED) { if (!IS_LIBRARIES_LOADED) {
@ -74,6 +75,7 @@ class SessionComponent : NeoComponent {
} }
} }
} }
return IS_LIBRARIES_LOADED
} }
} }
@ -88,7 +90,10 @@ class SessionComponent : NeoComponent {
fun createSession(context: Context, parameter: XParameter): XSession { fun createSession(context: Context, parameter: XParameter): XSession {
if (context is Activity) { if (context is Activity) {
checkLibrariesLoaded() if (!checkLibrariesLoaded()) {
throw RuntimeException("Cannot load libraries!")
}
return XSession(context, XSessionData()) return XSession(context, XSessionData())
} }
throw RuntimeException("Creating X sessions requires Activity, but got Context") throw RuntimeException("Creating X sessions requires Activity, but got Context")

View File

@ -24,7 +24,7 @@ import java.util.*
* @author kiva * @author kiva
*/ */
class XSession constructor(private val mActivity: Activity, private val sessionData: XSessionData) : NeoXorgViewClient { class XSession constructor(private val mActivity: Activity, val mSessionData: XSessionData) : NeoXorgViewClient {
var mSessionName = ""; var mSessionName = "";
init { init {
@ -33,20 +33,42 @@ class XSession constructor(private val mActivity: Activity, private val sessionD
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
} }
if (sessionData.audioThread == null) { mSessionData.client = this
sessionData.audioThread = NeoAudioThread(this) NeoXorgSettings.init(this)
if (mSessionData.audioThread == null) {
mSessionData.audioThread = NeoAudioThread(this)
} }
} }
fun onPause() {
mSessionData.isPaused = true
if (mSessionData.glView != null) {
mSessionData.glView?.onPause()
}
}
fun onDestroy() {
if (mSessionData.glView != null) {
mSessionData.glView?.exitApp()
}
}
fun onResume() {
if (mSessionData.glView != null) {
mSessionData.glView?.onResume()
}
mSessionData.isPaused = false
}
override fun getContext() = mActivity override fun getContext() = mActivity
override fun isKeyboardWithoutTextInputShown() = sessionData.keyboardWithoutTextInputShown override fun isKeyboardWithoutTextInputShown() = mSessionData.keyboardWithoutTextInputShown
override fun isPaused() = sessionData.isPaused override fun isPaused() = mSessionData.isPaused
override fun runOnUiThread(runnable: Runnable?) = mActivity.runOnUiThread(runnable) override fun runOnUiThread(runnable: Runnable?) = mActivity.runOnUiThread(runnable)
override fun getGLView() = sessionData.glView override fun getGLView() = mSessionData.glView
override fun getWindow() = mActivity.window!! override fun getWindow() = mActivity.window!!
@ -56,14 +78,14 @@ class XSession constructor(private val mActivity: Activity, private val sessionD
val inputManager = mActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val inputManager = mActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (!isKeyboardWithoutTextInputShown) { if (!isKeyboardWithoutTextInputShown) {
sessionData.keyboardWithoutTextInputShown = true mSessionData.keyboardWithoutTextInputShown = true
runOnUiThread(Runnable { runOnUiThread(Runnable {
if (keyboard == 0) { if (keyboard == 0) {
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0) inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
inputManager.showSoftInput(glView, InputMethodManager.SHOW_FORCED) inputManager.showSoftInput(glView, InputMethodManager.SHOW_FORCED)
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
} else { } else {
if (sessionData.screenKeyboard != null) if (mSessionData.screenKeyboard != null)
return@Runnable return@Runnable
val builtinKeyboard = BuiltInKeyboardView(mActivity, null) val builtinKeyboard = BuiltInKeyboardView(mActivity, null)
@ -159,17 +181,17 @@ class XSession constructor(private val mActivity: Activity, private val sessionD
override fun onKey(p1: Int, p2: IntArray) {} override fun onKey(p1: Int, p2: IntArray) {}
}) })
sessionData.screenKeyboard = builtinKeyboard mSessionData.screenKeyboard = builtinKeyboard
val layout = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM) val layout = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM)
sessionData.videoLayout!!.addView(sessionData.screenKeyboard, layout) mSessionData.videoLayout!!.addView(mSessionData.screenKeyboard, layout)
} }
}) })
} else { } else {
sessionData.keyboardWithoutTextInputShown = false mSessionData.keyboardWithoutTextInputShown = false
runOnUiThread { runOnUiThread {
if (sessionData.screenKeyboard != null) { if (mSessionData.screenKeyboard != null) {
sessionData.videoLayout!!.removeView(sessionData.screenKeyboard) mSessionData.videoLayout!!.removeView(mSessionData.screenKeyboard)
sessionData.screenKeyboard = null mSessionData.screenKeyboard = null
} }
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
inputManager.hideSoftInputFromWindow(glView!!.windowToken, 0) inputManager.hideSoftInputFromWindow(glView!!.windowToken, 0)
@ -179,23 +201,23 @@ class XSession constructor(private val mActivity: Activity, private val sessionD
} }
override fun setScreenKeyboardHintMessage(hideMessage: String?) { override fun setScreenKeyboardHintMessage(hideMessage: String?) {
sessionData.screenKeyboardHintMessage = hideMessage mSessionData.screenKeyboardHintMessage = hideMessage
if (sessionData.screenKeyboard is EditText) { if (mSessionData.screenKeyboard is EditText) {
runOnUiThread { runOnUiThread {
val editText = sessionData.screenKeyboard as EditText? val editText = mSessionData.screenKeyboard as EditText?
editText?.hint = hideMessage ?: mActivity.getString(R.string.text_edit_click_here) editText?.hint = hideMessage ?: mActivity.getString(R.string.text_edit_click_here)
} }
} }
} }
override fun isScreenKeyboardShown() = sessionData.screenKeyboard != null override fun isScreenKeyboardShown() = mSessionData.screenKeyboard != null
override fun showScreenKeyboard(oldText: String?) { override fun showScreenKeyboard(oldText: String?) {
if (Globals.CompatibilityHacksTextInputEmulatesHwKeyboard) { if (Globals.CompatibilityHacksTextInputEmulatesHwKeyboard) {
showScreenKeyboardWithoutTextInputField(Globals.TextInputKeyboard) showScreenKeyboardWithoutTextInputField(Globals.TextInputKeyboard)
return return
} }
if (sessionData.screenKeyboard != null) if (mSessionData.screenKeyboard != null)
return return
val screenKeyboard = EditText(mActivity, null, val screenKeyboard = EditText(mActivity, null,
@ -203,7 +225,7 @@ class XSession constructor(private val mActivity: Activity, private val sessionD
android.R.style.TextAppearance_Material_Widget_EditText android.R.style.TextAppearance_Material_Widget_EditText
else android.R.style.TextAppearance_Widget_EditText) else android.R.style.TextAppearance_Widget_EditText)
val hint = sessionData.screenKeyboardHintMessage val hint = mSessionData.screenKeyboardHintMessage
screenKeyboard.hint = hint ?: mActivity.getString(R.string.text_edit_click_here) screenKeyboard.hint = hint ?: mActivity.getString(R.string.text_edit_click_here)
screenKeyboard.setText(oldText) screenKeyboard.setText(oldText)
screenKeyboard.setSelection(screenKeyboard.text.length) screenKeyboard.setSelection(screenKeyboard.text.length)
@ -213,8 +235,8 @@ class XSession constructor(private val mActivity: Activity, private val sessionD
if (isRunningOnOUYA && Globals.TvBorders) if (isRunningOnOUYA && Globals.TvBorders)
screenKeyboard.setPadding(100, 100, 100, 100) // Bad bad HDMI TVs all have cropped borders screenKeyboard.setPadding(100, 100, 100, 100) // Bad bad HDMI TVs all have cropped borders
sessionData.screenKeyboard = screenKeyboard mSessionData.screenKeyboard = screenKeyboard
sessionData.videoLayout!!.addView(sessionData.screenKeyboard) mSessionData.videoLayout!!.addView(mSessionData.screenKeyboard)
screenKeyboard.inputType = InputType.TYPE_CLASS_TEXT screenKeyboard.inputType = InputType.TYPE_CLASS_TEXT
screenKeyboard.isFocusableInTouchMode = true screenKeyboard.isFocusableInTouchMode = true
@ -236,19 +258,19 @@ class XSession constructor(private val mActivity: Activity, private val sessionD
if (isKeyboardWithoutTextInputShown) if (isKeyboardWithoutTextInputShown)
showScreenKeyboardWithoutTextInputField(Globals.TextInputKeyboard) showScreenKeyboardWithoutTextInputField(Globals.TextInputKeyboard)
if (sessionData.screenKeyboard == null || sessionData.screenKeyboard !is EditText) if (mSessionData.screenKeyboard == null || mSessionData.screenKeyboard !is EditText)
return return
synchronized(sessionData.textInput) { synchronized(mSessionData.textInput) {
val text = (sessionData.screenKeyboard as EditText).text.toString() val text = (mSessionData.screenKeyboard as EditText).text.toString()
for (i in 0 until text.length) { for (i in 0 until text.length) {
NeoRenderer.callNativeTextInput(text[i].toInt(), text.codePointAt(i)) NeoRenderer.callNativeTextInput(text[i].toInt(), text.codePointAt(i))
} }
} }
NeoRenderer.callNativeTextInputFinished() NeoRenderer.callNativeTextInputFinished()
inputManager.hideSoftInputFromWindow(sessionData.screenKeyboard!!.windowToken, 0) inputManager.hideSoftInputFromWindow(mSessionData.screenKeyboard!!.windowToken, 0)
sessionData.videoLayout!!.removeView(sessionData.screenKeyboard) mSessionData.videoLayout!!.removeView(mSessionData.screenKeyboard)
sessionData.screenKeyboard = null mSessionData.screenKeyboard = null
glView!!.isFocusableInTouchMode = true glView!!.isFocusableInTouchMode = true
glView!!.isFocusable = true glView!!.isFocusable = true
glView!!.requestFocus() glView!!.requestFocus()

View File

@ -8,17 +8,17 @@ import de.mrapp.android.tabswitcher.Tab
* @author kiva * @author kiva
*/ */
open class NeoTab(title: CharSequence) : Tab(title) { open class NeoTab(title: CharSequence) : Tab(title) {
fun onPause() {} open fun onPause() {}
fun onResume() {} open fun onResume() {}
fun onStart() {} open fun onStart() {}
fun onStop() {} open fun onStop() {}
fun onWindowFocusChanged(hasFocus: Boolean) {} open fun onWindowFocusChanged(hasFocus: Boolean) {}
fun onDestroy() {} open fun onDestroy() {}
fun onConfigurationChanged(newConfig: Configuration) {} open fun onConfigurationChanged(newConfig: Configuration) {}
} }

View File

@ -1,19 +1,22 @@
package io.neoterm.ui.term.tab package io.neoterm.ui.term.tab
import android.content.Context import android.content.Context
import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout
import de.mrapp.android.tabswitcher.Tab import de.mrapp.android.tabswitcher.Tab
import de.mrapp.android.tabswitcher.TabSwitcher import de.mrapp.android.tabswitcher.TabSwitcher
import de.mrapp.android.tabswitcher.TabSwitcherDecorator import de.mrapp.android.tabswitcher.TabSwitcherDecorator
import io.neoterm.Globals
import io.neoterm.NeoGLView
import io.neoterm.R import io.neoterm.R
import io.neoterm.component.color.ColorSchemeComponent import io.neoterm.component.color.ColorSchemeComponent
import io.neoterm.frontend.session.shell.client.TermCompleteListener
import io.neoterm.frontend.completion.listener.OnAutoCompleteListener
import io.neoterm.frontend.component.ComponentManager import io.neoterm.frontend.component.ComponentManager
import io.neoterm.frontend.preference.NeoPreference import io.neoterm.frontend.logging.NLog
import io.neoterm.frontend.terminal.TerminalView import io.neoterm.frontend.terminal.TerminalView
import io.neoterm.frontend.terminal.eks.ExtraKeysView import io.neoterm.frontend.terminal.eks.ExtraKeysView
import io.neoterm.ui.term.NeoTermActivity import io.neoterm.ui.term.NeoTermActivity
@ -28,6 +31,8 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
private val VIEW_TYPE_X = 2 private val VIEW_TYPE_X = 2
} }
private fun setViewLayerType(view: View?) = view?.setLayerType(View.LAYER_TYPE_NONE, null)
override fun onInflateView(inflater: LayoutInflater, parent: ViewGroup?, viewType: Int): View { override fun onInflateView(inflater: LayoutInflater, parent: ViewGroup?, viewType: Int): View {
return when (viewType) { return when (viewType) {
VIEW_TYPE_TERM -> { VIEW_TYPE_TERM -> {
@ -60,13 +65,63 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
} }
VIEW_TYPE_X -> { VIEW_TYPE_X -> {
val xtab = tab as XSessionTab toolbar.visibility = View.GONE
bindXSessionView(tab) bindXSessionView(tab as XSessionTab)
} }
} }
} }
private fun bindXSessionView(tab: XSessionTab) { private fun bindXSessionView(tab: XSessionTab) {
val sessionData = tab.sessionData ?: return
if (sessionData.videoLayout == null) {
val videoLayout = findViewById<FrameLayout>(R.id.xorg_video_layout)
sessionData.videoLayout = videoLayout
setViewLayerType(videoLayout)
}
val videoLayout = sessionData.videoLayout!!
if (sessionData.glView == null) {
Thread {
sessionData.client?.runOnUiThread {
sessionData.glView = NeoGLView(sessionData.client)
sessionData.glView?.isFocusableInTouchMode = true
sessionData.glView?.isFocusable = true
sessionData.glView?.requestFocus()
setViewLayerType(sessionData.glView)
videoLayout.addView(sessionData.glView,
FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT))
if (Globals.HideSystemMousePointer
&& android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
sessionData.glView?.pointerIcon =
android.view.PointerIcon.getSystemIcon(context,
android.view.PointerIcon.TYPE_NULL)
}
val r = Rect()
videoLayout.getWindowVisibleDisplayFrame(r)
sessionData.glView?.callNativeScreenVisibleRect(r.left, r.top, r.right, r.bottom)
videoLayout.viewTreeObserver.addOnGlobalLayoutListener({
val r = Rect()
videoLayout.getWindowVisibleDisplayFrame(r)
val heightDiff = videoLayout.rootView.height - videoLayout.height // Take system bar into consideration
val widthDiff = videoLayout.rootView.width - videoLayout.width // Nexus 5 has system bar at the right side
Log.v("SDL", "Main window visible region changed: " + r.left + ":" + r.top + ":" + r.width() + ":" + r.height())
videoLayout.postDelayed({
sessionData.glView?.callNativeScreenVisibleRect(r.left + widthDiff, r.top + heightDiff, r.width(), r.height())
}, 300)
videoLayout.postDelayed({
sessionData.glView?.callNativeScreenVisibleRect(r.left + widthDiff, r.top + heightDiff, r.width(), r.height())
}, 600)
})
}
}.start()
}
} }
private fun bindTerminalView(tab: Tab, view: TerminalView?, extraKeysView: ExtraKeysView?) { private fun bindTerminalView(tab: Tab, view: TerminalView?, extraKeysView: ExtraKeysView?) {
@ -105,9 +160,9 @@ class NeoTabDecorator(val context: NeoTermActivity) : TabSwitcherDecorator() {
} }
} }
private fun createAutoCompleteListener(view: TerminalView): OnAutoCompleteListener? { // private fun createAutoCompleteListener(view: TerminalView): OnAutoCompleteListener? {
return TermCompleteListener(view) // return TermCompleteListener(view)
} // }
override fun getViewTypeCount(): Int { override fun getViewTypeCount(): Int {
return 2 return 2

View File

@ -1,5 +1,6 @@
package io.neoterm.ui.term.tab package io.neoterm.ui.term.tab
import android.content.res.Configuration
import io.neoterm.frontend.session.xorg.XSession import io.neoterm.frontend.session.xorg.XSession
/** /**
@ -7,4 +8,35 @@ import io.neoterm.frontend.session.xorg.XSession
*/ */
class XSessionTab(title: CharSequence) : NeoTab(title) { class XSessionTab(title: CharSequence) : NeoTab(title) {
var session: XSession? = null var session: XSession? = null
val sessionData
get() = session?.mSessionData
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (!hasFocus) {
onPause()
} else {
onResume()
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
session?.updateScreenOrientation()
}
override fun onPause() {
session?.onPause()
super.onPause()
}
override fun onDestroy() {
super.onDestroy()
session?.onDestroy()
}
override fun onResume() {
super.onResume()
session?.onResume()
}
} }

View File

@ -3,10 +3,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <FrameLayout
android:layout_centerInParent="true" android:id="@+id/xorg_video_layout"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:text="Hello X Server! Comming soon."/> android:layout_centerInParent="true" />
</RelativeLayout> </RelativeLayout>