diff --git a/app/build.gradle b/app/build.gradle index bff33ac..fc88de0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "com.vectras.vm" minSdk minApi targetSdk targetApi - versionCode 155 - versionName "4.4.8" + versionCode 156 + versionName "4.4.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true diff --git a/app/src/main/java/com/vectras/vm/ExportRomActivity.java b/app/src/main/java/com/vectras/vm/ExportRomActivity.java index 617d7bd..1fe8531 100644 --- a/app/src/main/java/com/vectras/vm/ExportRomActivity.java +++ b/app/src/main/java/com/vectras/vm/ExportRomActivity.java @@ -166,6 +166,9 @@ public class ExportRomActivity extends AppCompatActivity { vmConfigMap.put("battery", current.battery); + vmConfigMap.put("mouse", current.mouse); + vmConfigMap.put("keyboard", current.keyboard); + boolean isUsingDiskInQemuExtraParams = VMManager.isHaveADisk(current.itemExtra); if (FileUtils.isFileExists(current.itemPath)) { @@ -219,6 +222,8 @@ public class ExportRomActivity extends AppCompatActivity { vmConfigMap.put("isUseUefi", current.isUseUefi); vmConfigMap.put("isUseDefaultBios", current.isUseDefaultBios); + vmConfigMap.put("accel", current.accel); + vmConfigMap.put("qemu", VmFileManager.pathToTextMark(this, current.vmID, current.itemExtra)); vmConfigMap.put("arch", current.itemArch); diff --git a/app/src/main/java/com/vectras/vm/StartVM.java b/app/src/main/java/com/vectras/vm/StartVM.java index bad04d4..9d02063 100644 --- a/app/src/main/java/com/vectras/vm/StartVM.java +++ b/app/src/main/java/com/vectras/vm/StartVM.java @@ -131,6 +131,17 @@ public class StartVM { } } + String inputDevicesParams = ""; + String mouse = Objects.requireNonNull(VMCreatorSelector.getMouse(activity, vmData.mouse).get("value")).toString(); + if (!mouse.isEmpty()) { + inputDevicesParams += " -device " + mouse; + } + String keyboard = Objects.requireNonNull(VMCreatorSelector.getKeyboard(activity, vmData.keyboard).get("value")).toString(); + if (!keyboard.isEmpty()) { + inputDevicesParams += " -device " + keyboard; + } + if (!inputDevicesParams.isEmpty() && !ParamManager.hasUsb(extraParams)) inputDevicesParams = " -usb" + inputDevicesParams; + String graphicsParams = ""; String graphics = Objects.requireNonNull(VMCreatorSelector.getGraphicsCard(activity, vmData.graphicCard).get("value")).toString(); if (!graphics.isEmpty()) { @@ -172,7 +183,13 @@ public class StartVM { bootParams = " -boot " + bootFromParams + (!bootFromParams.isEmpty() && !showBootMenuParams.isEmpty() ? "," : "") + showBootMenuParams + " "; } - extraParams = machineParams + cpuParams + memoryParams + bootParams + graphicsParams + networkParams + soundParams + " " + extraParams; + String accelParams = ""; + String accel = Objects.requireNonNull(VMCreatorSelector.getAccel(activity, vmData.accel).get("value")).toString(); + if (!accel.isEmpty()) { + accelParams = " -accel " + ((vmData.accel > 1 && !DeviceUtils.is64bit()) ? Objects.requireNonNull(VMCreatorSelector.getAccel(activity, 1).get("value")).toString() : accel); + } + + extraParams = machineParams + inputDevicesParams + cpuParams + memoryParams + bootParams + graphicsParams + networkParams + soundParams + accelParams + " " + extraParams; return env(activity, extraParams, vmData.itemPath, false); } diff --git a/app/src/main/java/com/vectras/vm/VMManager.java b/app/src/main/java/com/vectras/vm/VMManager.java index a973bbd..f61c709 100644 --- a/app/src/main/java/com/vectras/vm/VMManager.java +++ b/app/src/main/java/com/vectras/vm/VMManager.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Objects; +import java.util.PropertyPermission; import java.util.Random; public class VMManager { @@ -904,8 +905,16 @@ public class VMManager { public static void requestKillAllQemuProcess(Activity activity, Runnable runnable) { DialogUtils.twoDialog(activity, activity.getString(R.string.do_you_want_to_kill_all_qemu_processes), activity.getString(R.string.all_running_vms_will_be_forcibly_shut_down), activity.getString(R.string.kill_all), activity.getString(R.string.cancel), true, R.drawable.power_settings_new_24px, true, () -> { - killallqemuprocesses(activity); + ProgressDialog progressDialog = new ProgressDialog(activity); + progressDialog.setText(activity.getString(R.string.shutting_down)); + progressDialog.show(); + new Thread(() -> { + killallqemuprocesses(activity); + activity.runOnUiThread(() -> { + progressDialog.reset(); if (runnable != null) runnable.run(); + }); + }).start(); }, null, null); } diff --git a/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java b/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java index 0947bd4..85b365f 100644 --- a/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java +++ b/app/src/main/java/com/vectras/vm/creator/VMCreatorActivity.java @@ -30,9 +30,11 @@ import com.vectras.qemu.MainSettingsManager; import com.vectras.vm.AppConfig; import com.vectras.vm.R; import com.vectras.vm.creator.configs.ListManager; +import com.vectras.vm.creator.editor.AccelerationConfigsDialog; import com.vectras.vm.creator.editor.AdvancedConfigsDialog; import com.vectras.vm.creator.editor.BoardConfigsDialog; import com.vectras.vm.creator.editor.GraphicsConfigsDialog; +import com.vectras.vm.creator.editor.InputDevicesConfigsDialog; import com.vectras.vm.creator.editor.NetworkConfigsDialog; import com.vectras.vm.creator.editor.SoundConfigsDialog; import com.vectras.vm.creator.utils.CreatorUtils; @@ -210,6 +212,15 @@ public class VMCreatorActivity extends AppCompatActivity { dialog.show(getSupportFragmentManager(), "board_configs_dialog"); }); + binding.lnInputDevices.setOnClickListener(v -> { + save(); + + InputDevicesConfigsDialog dialog = new InputDevicesConfigsDialog(); + dialog.setConfigs(current); + dialog.setOnDismiss(this::loadConfig); + dialog.show(getSupportFragmentManager(), "input_devices_configs_dialog"); + }); + binding.lnStorage.setOnClickListener(v -> { save(); @@ -255,6 +266,15 @@ public class VMCreatorActivity extends AppCompatActivity { dialog.show(getSupportFragmentManager(), "sound_configs_dialog"); }); + binding.lnAcceleration.setOnClickListener(v -> { + save(); + + AccelerationConfigsDialog dialog = new AccelerationConfigsDialog(); + dialog.setConfigs(current); + dialog.setOnDismiss(this::loadConfig); + dialog.show(getSupportFragmentManager(), "acceleration_configs_dialog"); + }); + binding.lnAdvanced.setOnClickListener(v -> { save(); @@ -524,26 +544,9 @@ public class VMCreatorActivity extends AppCompatActivity { } private void setDefault() { - String defQemuParams; - if (DeviceUtils.is64bit()) { - defQemuParams = switch (MainSettingsManager.getArch(this)) { - case "ARM64" -> - "-accel tcg,thread=multi -device nec-usb-xhci -device usb-kbd -device usb-mouse"; - case "PPC" -> "-M mac99 -accel tcg,thread=multi"; - default -> - "-accel tcg,thread=multi -usb -device usb-tablet"; - }; - } else { - defQemuParams = switch (MainSettingsManager.getArch(this)) { - case "ARM64" -> - "-device nec-usb-xhci -device usb-kbd -device usb-mouse"; - case "PPC" -> "-M mac99"; - default -> - "-usb -device usb-tablet"; - }; - } + current = new DataMainRoms(); + binding.title.setText(getString(R.string.new_vm)); - current.itemExtra = defQemuParams; String currentArch = MainSettingsManager.getArch(this); @@ -565,6 +568,9 @@ public class VMCreatorActivity extends AppCompatActivity { // ENSONIQ AudioPCI ES1370 : Intel HD Audio Controller (ich6) current.soundCard = currentArch.equals(MainSettingsManager.PPC_ARCH) ? 5 : 2; + + // TCG (multi-threaded) : TCG (single-threaded) + current.accel = DeviceUtils.is64bit() ? 2 : 1; } private void checkVMID() { @@ -601,14 +607,14 @@ public class VMCreatorActivity extends AppCompatActivity { DialogUtils.oneDialog(this, getString(R.string.oops), getString(R.string.need_set_name), getString(R.string.ok), true, R.drawable.error_96px, true, null, null); } else { String _contentDialog = ""; - if (current.itemExtra.isEmpty()) { - _contentDialog = getResources().getString(R.string.qemu_params_is_empty); - } +// if (current.itemExtra.isEmpty()) { +// _contentDialog = getResources().getString(R.string.qemu_params_is_empty); +// } if (isAllDriveEmpty() && !VMManager.isHaveADisk(current.itemExtra)) { - if (!_contentDialog.isEmpty()) { - _contentDialog += "\n\n"; - } +// if (!_contentDialog.isEmpty()) { +// _contentDialog += "\n\n"; +// } _contentDialog += getResources().getString(R.string.you_have_not_added_any_storage_devices); } diff --git a/app/src/main/java/com/vectras/vm/creator/configs/ListManager.java b/app/src/main/java/com/vectras/vm/creator/configs/ListManager.java index 9c7218a..4dd9a29 100644 --- a/app/src/main/java/com/vectras/vm/creator/configs/ListManager.java +++ b/app/src/main/java/com/vectras/vm/creator/configs/ListManager.java @@ -5,6 +5,7 @@ import android.content.Context; import com.vectras.qemu.MainSettingsManager; import com.vectras.vm.R; import com.vectras.vm.utils.CpuHelper; +import com.vectras.vm.utils.DeviceUtils; import com.vectras.vm.utils.UniversalPickerDialog; import java.util.ArrayList; @@ -280,4 +281,27 @@ public class ListManager { UniversalPickerDialog.putToList(list, context.getString(R.string.ati), "ati-vga"); return list; } + + public static ArrayList> mouseTypes(Context context) { + ArrayList> list = new ArrayList<>(); + UniversalPickerDialog.putToList(list, context.getString(R.string.ps_2), ""); + UniversalPickerDialog.putToList(list, context.getString(R.string.usb), "usb-mouse"); + UniversalPickerDialog.putToList(list, context.getString(R.string.usb_tablet), "usb-tablet"); + return list; + } + + public static ArrayList> keyboardTypes(Context context) { + ArrayList> list = new ArrayList<>(); + UniversalPickerDialog.putToList(list, context.getString(R.string.ps_2), ""); + UniversalPickerDialog.putToList(list, context.getString(R.string.usb), "usb-kbd"); + return list; + } + + public static ArrayList> accelTypes(Context context) { + ArrayList> list = new ArrayList<>(); + UniversalPickerDialog.putToList(list, context.getString(R.string.none), ""); + UniversalPickerDialog.putToList(list, context.getString(R.string.tcg_single_thread), "tcg,thread=single"); + if (DeviceUtils.is64bit()) UniversalPickerDialog.putToList(list, context.getString(R.string.tcg_multi_thread), "tcg,thread=multi"); + return list; + } } diff --git a/app/src/main/java/com/vectras/vm/creator/editor/AccelerationConfigsDialog.java b/app/src/main/java/com/vectras/vm/creator/editor/AccelerationConfigsDialog.java new file mode 100644 index 0000000..a74fc44 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/creator/editor/AccelerationConfigsDialog.java @@ -0,0 +1,112 @@ +package com.vectras.vm.creator.editor; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import com.vectras.vm.R; +import com.vectras.vm.creator.utils.EditorUtils; +import com.vectras.vm.creator.utils.VMCreatorSelector; +import com.vectras.vm.databinding.CreatorAccelerationDialogBinding; +import com.vectras.vm.main.vms.DataMainRoms; +import com.vectras.vm.utils.DialogUtils; + +import java.util.Objects; + +public class AccelerationConfigsDialog extends BottomSheetDialogFragment { + final String TAG = "AccelerationConfigsDialog"; + + String vmId; + DataMainRoms configs; + + boolean isSave = true; + + public void setConfigs(DataMainRoms configs) { + this.configs = configs; + if (configs != null) { + vmId = configs.vmID; + } + } + + CreatorAccelerationDialogBinding binding; + + @NonNull + @Override + public BottomSheetDialog onCreateDialog(Bundle savedInstanceState) { + // This can happen after the app is freed from memory and then reopened. + if (configs == null) { + isSave = false; + if (savedInstanceState == null) DialogUtils.oopsDialog(requireActivity(), getString(R.string.something_went_wrong)); + dismiss(); + return EditorUtils.getDummyDialog(requireActivity()); + } + + binding = CreatorAccelerationDialogBinding.inflate(getLayoutInflater()); + + BottomSheetDialog dialog = new BottomSheetDialog(requireActivity()); + dialog.setContentView(binding.getRoot()); + + initialize(); + + dialog.setOnShowListener(d -> { + BottomSheetBehavior behavior = dialog.getBehavior(); + behavior.setState(BottomSheetBehavior.STATE_EXPANDED); + behavior.setSkipCollapsed(true); + }); + + return dialog; + } + + AccelerationConfigsDialogCallback callback; + + public void setOnDismiss(AccelerationConfigsDialogCallback callback) { + this.callback = callback; + } + + public interface AccelerationConfigsDialogCallback { + void onDismiss(DataMainRoms configs); + } + + public void onDismiss(@NonNull DialogInterface dialogInterface) { + super.onDismiss(dialogInterface); + if (callback != null && isSave) { + save(); + callback.onDismiss(configs); + } + } + + // Auto save. + public void onPause() { + super.onPause(); + if (callback != null && isSave) { + save(); + callback.onDismiss(configs); + } + } + + private void initialize() { + if (!isAdded()) return; + + binding.sbvType.setOnClickListener(v -> VMCreatorSelector.accel(requireActivity(), configs.accel, ((position, name, value) -> { + configs.accel = position; + binding.sbvType.setSubtitle(name); + }))); + + load(); + } + + private void load() { + if (!isAdded()) return; + + binding.sbvType.setSubtitle(Objects.requireNonNull(VMCreatorSelector.getAccel(requireActivity(), configs.accel).get("name")).toString()); + } + + private void save() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/creator/editor/BoardConfigsDialog.java b/app/src/main/java/com/vectras/vm/creator/editor/BoardConfigsDialog.java index 4746a3c..90f719a 100644 --- a/app/src/main/java/com/vectras/vm/creator/editor/BoardConfigsDialog.java +++ b/app/src/main/java/com/vectras/vm/creator/editor/BoardConfigsDialog.java @@ -36,6 +36,7 @@ public class BoardConfigsDialog extends BottomSheetDialogFragment { boolean isSave = true; int availableMemory = Integer.MAX_VALUE; + int warningMemory = Integer.MAX_VALUE; public void setConfigs(DataMainRoms configs) { this.configs = configs; @@ -58,6 +59,9 @@ public class BoardConfigsDialog extends BottomSheetDialogFragment { } availableMemory = RamInfo.vectrasMemory(requireActivity()); + warningMemory = availableMemory / 100 * 80; + if (availableMemory - warningMemory >= 1024) warningMemory = availableMemory / 100 * 90; + if (availableMemory - warningMemory >= 1024) warningMemory = availableMemory / 100 * 95; binding = CreatorBoardDialogBinding.inflate(getLayoutInflater()); @@ -168,7 +172,7 @@ public class BoardConfigsDialog extends BottomSheetDialogFragment { public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(Editable editable) { - if (!editable.toString().isEmpty() && Integer.parseInt(editable.toString()) > (availableMemory / 100 * 80)) { + if (!editable.toString().isEmpty() && Integer.parseInt(editable.toString()) >= warningMemory) { binding.cpiMemory.setError(getString(R.string.capacity_too_large)); } else { binding.cpiMemory.setError(null); diff --git a/app/src/main/java/com/vectras/vm/creator/editor/InputDevicesConfigsDialog.java b/app/src/main/java/com/vectras/vm/creator/editor/InputDevicesConfigsDialog.java new file mode 100644 index 0000000..fa87912 --- /dev/null +++ b/app/src/main/java/com/vectras/vm/creator/editor/InputDevicesConfigsDialog.java @@ -0,0 +1,118 @@ +package com.vectras.vm.creator.editor; + +import android.content.DialogInterface; +import android.os.Bundle; +import android.widget.FrameLayout; + +import androidx.annotation.NonNull; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.BottomSheetDialog; +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; +import com.vectras.vm.R; +import com.vectras.vm.creator.utils.EditorUtils; +import com.vectras.vm.creator.utils.VMCreatorSelector; +import com.vectras.vm.databinding.CreatorInputDevicesDialogBinding; +import com.vectras.vm.main.vms.DataMainRoms; +import com.vectras.vm.utils.DialogUtils; + +import java.util.Objects; + +public class InputDevicesConfigsDialog extends BottomSheetDialogFragment { + final String TAG = "InputDevicesConfigsDialog"; + + String vmId; + DataMainRoms configs; + + boolean isSave = true; + + public void setConfigs(DataMainRoms configs) { + this.configs = configs; + if (configs != null) { + vmId = configs.vmID; + } + } + + CreatorInputDevicesDialogBinding binding; + + @NonNull + @Override + public BottomSheetDialog onCreateDialog(Bundle savedInstanceState) { + // This can happen after the app is freed from memory and then reopened. + if (configs == null) { + isSave = false; + if (savedInstanceState == null) DialogUtils.oopsDialog(requireActivity(), getString(R.string.something_went_wrong)); + dismiss(); + return EditorUtils.getDummyDialog(requireActivity()); + } + + binding = CreatorInputDevicesDialogBinding.inflate(getLayoutInflater()); + + BottomSheetDialog dialog = new BottomSheetDialog(requireActivity()); + dialog.setContentView(binding.getRoot()); + + initialize(); + + dialog.setOnShowListener(d -> { + BottomSheetBehavior behavior = dialog.getBehavior(); + behavior.setState(BottomSheetBehavior.STATE_EXPANDED); + behavior.setSkipCollapsed(true); + }); + + return dialog; + } + + InputDevicesConfigsDialogCallback callback; + + public void setOnDismiss(InputDevicesConfigsDialogCallback callback) { + this.callback = callback; + } + + public interface InputDevicesConfigsDialogCallback { + void onDismiss(DataMainRoms configs); + } + + public void onDismiss(@NonNull DialogInterface dialogInterface) { + super.onDismiss(dialogInterface); + if (callback != null && isSave) { + save(); + callback.onDismiss(configs); + } + } + + // Auto save. + public void onPause() { + super.onPause(); + if (callback != null && isSave) { + save(); + callback.onDismiss(configs); + } + } + + private void initialize() { + if (!isAdded()) return; + + binding.sbvMouse.setOnClickListener(v -> VMCreatorSelector.mouse(requireActivity(), configs.mouse, ((position, name, value) -> { + configs.mouse = position; + binding.sbvMouse.setSubtitle(name); + }))); + + binding.sbvKeyboard.setOnClickListener(v -> VMCreatorSelector.keyboard(requireActivity(), configs.keyboard, ((position, name, value) -> { + configs.keyboard = position; + binding.sbvKeyboard.setSubtitle(name); + }))); + + load(); + } + + private void load() { + if (!isAdded()) return; + + binding.sbvMouse.setSubtitle(Objects.requireNonNull(VMCreatorSelector.getMouse(requireActivity(), configs.mouse).get("name")).toString()); + binding.sbvKeyboard.setSubtitle(Objects.requireNonNull(VMCreatorSelector.getKeyboard(requireActivity(), configs.keyboard).get("name")).toString()); + } + + private void save() { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/creator/utils/VMCreatorSelector.java b/app/src/main/java/com/vectras/vm/creator/utils/VMCreatorSelector.java index 123378c..151a5b1 100644 --- a/app/src/main/java/com/vectras/vm/creator/utils/VMCreatorSelector.java +++ b/app/src/main/java/com/vectras/vm/creator/utils/VMCreatorSelector.java @@ -70,6 +70,22 @@ public class VMCreatorSelector { return ListManager.networkCards(context).get(position); } + public static void mouse(Activity activity, int position, UniversalPickerDialog.UniversalPickerDialogCallback callback) { + showDialog(activity, ListManager.mouseTypes(activity), position, callback, activity.getString(R.string.types)); + } + + public static HashMap getMouse(Context context, int position) { + return ListManager.mouseTypes(context).get(position); + } + + public static void keyboard(Activity activity, int position, UniversalPickerDialog.UniversalPickerDialogCallback callback) { + showDialog(activity, ListManager.keyboardTypes(activity), position, callback, activity.getString(R.string.types)); + } + + public static HashMap getKeyboard(Context context, int position) { + return ListManager.keyboardTypes(context).get(position); + } + public static void soundCard(Activity activity, int position, UniversalPickerDialog.UniversalPickerDialogCallback callback) { showDialog(activity, ListManager.soundCards(activity), position, callback, activity.getString(R.string.cards)); } @@ -86,6 +102,14 @@ public class VMCreatorSelector { showDialog(activity, ListManager.bootFrom(activity), position, callback, activity.getString(R.string.boot_from)); } + public static void accel(Activity activity, int position, UniversalPickerDialog.UniversalPickerDialogCallback callback) { + showDialog(activity, ListManager.accelTypes(activity), position, callback, activity.getString(R.string.types)); + } + + public static HashMap getAccel(Context context, int position) { + return ListManager.accelTypes(context).get(position); + } + public static void showDialog(Activity activity, ArrayList> list, int position, UniversalPickerDialog.UniversalPickerDialogCallback callback, String title) { UniversalPickerDialog.show(activity, list, position, callback, title); } diff --git a/app/src/main/java/com/vectras/vm/main/vms/DataMainRoms.java b/app/src/main/java/com/vectras/vm/main/vms/DataMainRoms.java index 07bb14f..ebf3068 100644 --- a/app/src/main/java/com/vectras/vm/main/vms/DataMainRoms.java +++ b/app/src/main/java/com/vectras/vm/main/vms/DataMainRoms.java @@ -67,6 +67,12 @@ public class DataMainRoms { public boolean sharedFolder; + // Input devices + + public int mouse; + + public int keyboard; + // Graphics public int graphicCard; @@ -91,6 +97,10 @@ public class DataMainRoms { public boolean isUseDefaultBios = true; + // Acceleration + + public int accel; + // Advanced @SerializedName( diff --git a/app/src/main/java/com/vectras/vm/manager/ParamManager.java b/app/src/main/java/com/vectras/vm/manager/ParamManager.java index 0570677..ae53170 100644 --- a/app/src/main/java/com/vectras/vm/manager/ParamManager.java +++ b/app/src/main/java/com/vectras/vm/manager/ParamManager.java @@ -18,4 +18,8 @@ public class ParamManager { public static boolean hasMemory(String param) { return Pattern.compile("(? vncCanvas.setAlpha(value / 100)); diff --git a/app/src/main/java/com/vectras/vm/settings/SettingsData.java b/app/src/main/java/com/vectras/vm/settings/SettingsData.java index 516783f..a90bc45 100644 --- a/app/src/main/java/com/vectras/vm/settings/SettingsData.java +++ b/app/src/main/java/com/vectras/vm/settings/SettingsData.java @@ -26,6 +26,14 @@ public class SettingsData { set(context, "opengl", value); } + public static void x11Bubble(Context context, boolean value) { + set(context, "x11_bubble", value); + } + + public static boolean x11Bubble(Context context) { + return get(context, "x11_bubble"); + } + // Core public static boolean get(Context context, String key) { diff --git a/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java b/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java index 99bb08c..c14a471 100644 --- a/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java +++ b/app/src/main/java/com/vectras/vm/settings/X11DisplaySettingsActivity.java @@ -38,9 +38,10 @@ public class X11DisplaySettingsActivity extends AppCompatActivity { private void initialize() { binding.swEnabled.setChecked(MainSettingsManager.getVmUi(this).equals("X11")); binding.swRunQemuWithXterm.setChecked(MainSettingsManager.getRunQemuWithXterm(this)); + binding.swUseExternal.setChecked(MainSettingsManager.getExternalX11(this)); binding.swUseSdl.setChecked(MainSettingsManager.getUseSdl(this)); binding.swUseOpengl.setChecked(SettingsData.opengl(this)); - binding.swUseExternal.setChecked(MainSettingsManager.getExternalX11(this)); + binding.swBubble.setChecked(SettingsData.x11Bubble(this)); binding.swEnabled.setOnCheckedChangeListener((buttonView, isChecked) -> { MainSettingsManager.setVmUi(this, isChecked ? "X11" : "VNC"); @@ -54,9 +55,9 @@ public class X11DisplaySettingsActivity extends AppCompatActivity { } else { if (PackageUtils.isInstalled("com.termux.x11", this)) { Intent intent = new Intent(); - intent.setClassName("com.termux.x11", "com.termux.x11.MainActivity"); + intent.setClassName("com.termux.x11", "com.termux.x11.LoriePreferences"); + intent.setAction(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); startActivity(intent); } else { DialogUtils.needInstallTermuxX11(this); @@ -64,6 +65,9 @@ public class X11DisplaySettingsActivity extends AppCompatActivity { } }); + binding.swUseExternal.setOnCheckedChangeListener((buttonView, isChecked) -> MainSettingsManager.setExternalX11(this, isChecked)); + binding.lnUseExternal.setOnClickListener(v -> binding.swUseExternal.toggle()); + binding.swRunQemuWithXterm.setOnCheckedChangeListener((buttonView, isChecked) -> MainSettingsManager.setRunQemuWithXterm(this, isChecked)); binding.lnRunQemuWithXterm.setOnClickListener(v -> binding.swRunQemuWithXterm.toggle()); @@ -73,8 +77,8 @@ public class X11DisplaySettingsActivity extends AppCompatActivity { binding.swUseOpengl.setOnCheckedChangeListener((buttonView, isChecked) -> SettingsData.opengl(this, isChecked)); binding.lnUseOpengl.setOnClickListener(v -> binding.swUseOpengl.toggle()); - binding.swUseExternal.setOnCheckedChangeListener((buttonView, isChecked) -> MainSettingsManager.setExternalX11(this, isChecked)); - binding.lnUseExternal.setOnClickListener(v -> binding.swUseExternal.toggle()); + binding.swBubble.setOnCheckedChangeListener((buttonView, isChecked) -> SettingsData.x11Bubble(this, isChecked)); + binding.lnBubble.setOnClickListener(v -> binding.swBubble.toggle()); binding.lnTurnipZink.setOnClickListener(v -> startActivity(new Intent(this, TurnipZinkSetupWizardActivity.class))); @@ -86,10 +90,11 @@ public class X11DisplaySettingsActivity extends AppCompatActivity { private void uiController(boolean isEnabled) { binding.lnAllOptions.setAlpha(isEnabled ? 1f : 0.5f); binding.lnPreferences.setEnabled(isEnabled); + binding.lnUseExternal.setEnabled(isEnabled); binding.lnRunQemuWithXterm.setEnabled(isEnabled); binding.lnUseSdl.setEnabled(isEnabled); binding.lnUseOpengl.setEnabled(isEnabled); - binding.lnUseExternal.setEnabled(isEnabled); + binding.lnBubble.setEnabled(isEnabled); binding.lnTurnipZink.setEnabled(isEnabled); } } \ No newline at end of file diff --git a/app/src/main/java/com/vectras/vm/x11/AddIn.java b/app/src/main/java/com/vectras/vm/x11/AddIn.java index 8851cf5..860634f 100644 --- a/app/src/main/java/com/vectras/vm/x11/AddIn.java +++ b/app/src/main/java/com/vectras/vm/x11/AddIn.java @@ -46,6 +46,7 @@ import com.vectras.vm.manager.VmControllerDialog; import com.vectras.vm.manager.VmFileManager; import com.vectras.vm.manager.VmListManager; import com.vectras.vm.manager.VmPicker; +import com.vectras.vm.settings.SettingsData; import com.vectras.vm.sound.StreamAudio; import com.vectras.vm.utils.DialogUtils; import com.vectras.vm.utils.UIUtils; @@ -161,7 +162,9 @@ public class AddIn { ControlersOptionsFragment newFragment = new ControlersOptionsFragment(); newFragment.binding = binding.controlsfragment; newFragment.show(ft, "Controllers"); - newFragment.setOnDismiss = () -> binding.lnBubbleContainer.setVisibility(bindingControls.mainControl.getVisibility() == View.GONE ? View.VISIBLE : View.GONE); + + if (SettingsData.x11Bubble(activity)) + newFragment.setOnDismiss = () -> binding.lnBubbleContainer.setVisibility(bindingControls.mainControl.getVisibility() == View.GONE ? View.VISIBLE : View.GONE); }); @@ -557,14 +560,15 @@ public class AddIn { } public void handleOnBack() { - if (bindingControls.mainControl.getVisibility() == View.GONE) { + if (bindingControls.mainControl.getVisibility() == View.GONE && !SettingsData.x11Bubble(activity)) { bindingControls.mainControl.setVisibility(View.VISIBLE); - - } else if (streamAudio != null) { - if (!VmAudioManager.currentVmId.equals(Config.vmID)) - streamAudio.setCross(null); - if (streamAudio.isPlaying()) streamAudio.stop(); } else { + if (streamAudio != null) { + if (!VmAudioManager.currentVmId.equals(Config.vmID)) + streamAudio.setCross(null); + if (streamAudio.isPlaying()) streamAudio.stop(); + } + activity.finish(); } } diff --git a/app/src/main/java/com/vectras/vm/x11/LorieView.java b/app/src/main/java/com/vectras/vm/x11/LorieView.java index 972e3b6..bcf598a 100644 --- a/app/src/main/java/com/vectras/vm/x11/LorieView.java +++ b/app/src/main/java/com/vectras/vm/x11/LorieView.java @@ -505,6 +505,11 @@ public class LorieView extends SurfaceView implements InputStub { @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { + X11Activity.getInstance().onBackPressed(); + return true; + } + if (imeBuggyKeys.contains(event.getKeyCode())) { // IME does not handle/send events for some keys correctly correctly. // So we should send key release manually in the case if IME will not send it... @@ -522,6 +527,11 @@ public class LorieView extends SurfaceView implements InputStub { @Override public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { + X11Activity.getInstance().onBackPressed(); + return true; + } + if (imeBuggyKeys.contains(event.getKeyCode())) { // remove messages we posted in dispatchKeyEventPreIme int action = event.getAction(); diff --git a/app/src/main/java/com/vectras/vm/x11/X11Activity.java b/app/src/main/java/com/vectras/vm/x11/X11Activity.java index 59b2572..91bec1f 100644 --- a/app/src/main/java/com/vectras/vm/x11/X11Activity.java +++ b/app/src/main/java/com/vectras/vm/x11/X11Activity.java @@ -112,7 +112,7 @@ public class X11Activity extends AppCompatActivity { Log.e("X11Activity", "Something went wrong while we extracted connection details from binder.", e); } } else if (ACTION_STOP.equals(intent.getAction())) { - finishAffinity(); + finish(); } else if (ACTION_PREFERENCES_CHANGED.equals(intent.getAction())) { Log.d("X11Activity", "preference: " + intent.getStringExtra("key")); if (!"additionalKbdVisible".equals(intent.getStringExtra("key"))) @@ -158,7 +158,7 @@ public class X11Activity extends AppCompatActivity { return instance; } - AddIn addIn; + public AddIn addIn; ActivityX11Binding binding; @@ -261,6 +261,13 @@ public class X11Activity extends AppCompatActivity { addIn.initialize(binding); } + @Override + protected void onNewIntent(@NonNull Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + onReceiveConnection(intent); + } + @Override protected void onDestroy() { unregisterReceiver(receiver); diff --git a/app/src/main/java/com/vectras/vm/x11/input/TouchInputHandler.java b/app/src/main/java/com/vectras/vm/x11/input/TouchInputHandler.java index 8094ca4..e24d327 100644 --- a/app/src/main/java/com/vectras/vm/x11/input/TouchInputHandler.java +++ b/app/src/main/java/com/vectras/vm/x11/input/TouchInputHandler.java @@ -480,7 +480,7 @@ public class TouchInputHandler { return noAction; switch(pref.asList().get()) { - case "toggle soft keyboard": return (key, down) -> { if (down) X11Activity.toggleKeyboardVisibility(mActivity); }; + //case "toggle soft keyboard": return (key, down) -> { if (down) X11Activity.toggleKeyboardVisibility(mActivity); }; case "toggle additional key bar": return (key, down) -> { if (down) mActivity.toggleExtraKeys(); }; case "open preferences": return (key, down) -> { if (down) mActivity.startActivity(new Intent(mActivity, LoriePreferences.class) {{ setAction(Intent.ACTION_MAIN); }}); }; case "release pointer and keyboard capture": return (key, down) -> { if (down) setCapturingEnabled(false); }; diff --git a/app/src/main/jniLibs/arm64-v8a/libXlorie.so b/app/src/main/jniLibs/arm64-v8a/libXlorie.so index 1f0293b..10d62d6 100644 Binary files a/app/src/main/jniLibs/arm64-v8a/libXlorie.so and b/app/src/main/jniLibs/arm64-v8a/libXlorie.so differ diff --git a/app/src/main/jniLibs/armeabi-v7a/libXlorie.so b/app/src/main/jniLibs/armeabi-v7a/libXlorie.so index 47f67a2..ebd4ad9 100644 Binary files a/app/src/main/jniLibs/armeabi-v7a/libXlorie.so and b/app/src/main/jniLibs/armeabi-v7a/libXlorie.so differ diff --git a/app/src/main/jniLibs/x86/libXlorie.so b/app/src/main/jniLibs/x86/libXlorie.so index 804d5cc..fa8b713 100644 Binary files a/app/src/main/jniLibs/x86/libXlorie.so and b/app/src/main/jniLibs/x86/libXlorie.so differ diff --git a/app/src/main/jniLibs/x86_64/libXlorie.so b/app/src/main/jniLibs/x86_64/libXlorie.so index f962443..5d6515e 100644 Binary files a/app/src/main/jniLibs/x86_64/libXlorie.so and b/app/src/main/jniLibs/x86_64/libXlorie.so differ diff --git a/app/src/main/res/layout-v24/activity_x11.xml b/app/src/main/res/layout-v24/activity_x11.xml new file mode 100644 index 0000000..4a63294 --- /dev/null +++ b/app/src/main/res/layout-v24/activity_x11.xml @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +