mirror of
https://github.com/xoureldeen/Vectras-VM-Android.git
synced 2026-07-09 17:28:54 +00:00
4.2.5
- Fixed an issue with the confusing virtual machine control dialog box. - Fixed the frozen virtual machine startup dialog box. - Added marking of content containing advertisements. - Added select and display of the virtual machine control dialog box to the built-in X11 screen. - Removed the quick software launch shortcut button from the built-in X11 screen. - Added a blur effect to the built-in X11 screen. - Several minor interface improvements. - Bugs fixed.
This commit is contained in:
parent
6dbf2f711e
commit
a227f5b8a6
27 changed files with 391 additions and 98 deletions
|
|
@ -12,8 +12,8 @@ android {
|
|||
applicationId "com.vectras.vm"
|
||||
minSdk minApi
|
||||
targetSdk targetApi
|
||||
versionCode 128
|
||||
versionName "4.2.4"
|
||||
versionCode 129
|
||||
versionName "4.2.5"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@
|
|||
android:exported="false"
|
||||
android:label="@string/mini_tools" />
|
||||
<activity
|
||||
android:name=".RomInfo"
|
||||
android:name=".store.RomInfo"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
|
|
|
|||
|
|
@ -189,8 +189,8 @@ public class RfbProto {
|
|||
class VectrasOutputStream {
|
||||
|
||||
OutputStream os;
|
||||
HandlerThread rfbQueueThread = null;
|
||||
Handler handler = null;
|
||||
HandlerThread rfbQueueThread;
|
||||
Handler handler;
|
||||
|
||||
public VectrasOutputStream(OutputStream sos) {
|
||||
os = sos;
|
||||
|
|
@ -203,14 +203,11 @@ public class RfbProto {
|
|||
public void write(final int data) throws IOException {
|
||||
final int data0 = data;
|
||||
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sos.write(data0);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
handler.post(() -> {
|
||||
try {
|
||||
sos.write(data0);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -218,16 +215,13 @@ public class RfbProto {
|
|||
public void write(final byte[] bytes) throws IOException {
|
||||
final byte [] buffer0 = java.util.Arrays.copyOf(bytes, bytes.length);
|
||||
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sos.write(buffer0);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Error while sending VNC data");
|
||||
if(Config.debug)
|
||||
e.printStackTrace();
|
||||
}
|
||||
handler.post(() -> {
|
||||
try {
|
||||
sos.write(buffer0);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Error while sending VNC data");
|
||||
if(Config.debug)
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -237,14 +231,11 @@ public class RfbProto {
|
|||
final int offset0 = offset;
|
||||
final int count0 = count;
|
||||
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sos.write(buffer0, offset0, count0);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
handler.post(() -> {
|
||||
try {
|
||||
sos.write(buffer0, offset0, count0);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -370,8 +361,19 @@ public class RfbProto {
|
|||
try {
|
||||
os.close();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
Log.e(TAG, "Error while closing VectrasOutputStream", ex);
|
||||
}
|
||||
|
||||
if (localSocket != null) {
|
||||
try {
|
||||
localSocket.close();
|
||||
closed = true;
|
||||
Log.v(TAG, "RFB local socket closed");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error while closing RFB local socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (sock != null) {
|
||||
try {
|
||||
sock.close();
|
||||
|
|
@ -385,7 +387,7 @@ public class RfbProto {
|
|||
|
||||
} */
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "Error while closing RFB socket", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1202,6 +1202,8 @@ public class MainVNCActivity extends VncCanvasActivity {
|
|||
}
|
||||
});
|
||||
|
||||
bindingControls.btnVmManager.setVisibility(View.GONE);
|
||||
|
||||
bindingDesktopControls.rightClickBtn.setOnClickListener(v -> {
|
||||
try {
|
||||
MotionEvent e = MotionEvent.obtain(1000, 1000, MotionEvent.ACTION_DOWN, vncCanvas.mouseX, vncCanvas.mouseY,
|
||||
|
|
|
|||
|
|
@ -842,15 +842,22 @@ public class VMManager {
|
|||
|
||||
public static boolean isVMRunning(Context context, String vmID) {
|
||||
String result = Terminal.executeShellCommandWithResult("ps -e", context);
|
||||
if (result.contains(Config.getCacheDir() + "/" + vmID + "/qmpsocket")) {
|
||||
Log.d("VMManager.isThisVMRunning", "Yes");
|
||||
if (result.contains(" -qmp unix:" + Config.getLocalQMPSocketPath(vmID))) {
|
||||
Log.d("VMManager.isThisVMRunning", "Yes.\n\n" + result);
|
||||
return true;
|
||||
} else {
|
||||
Log.d("VMManager.isThisVMRunning", "No");
|
||||
Log.d("VMManager.isThisVMRunning", "No.\n\n" + result);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVMRunning(String vmID) {
|
||||
File qmpSocket = new File(Config.getLocalQMPSocketPath(vmID));
|
||||
boolean exists = qmpSocket.exists();
|
||||
Log.d("VMManager.isThisVMRunning", exists ? "Yes" : "No");
|
||||
return exists;
|
||||
}
|
||||
|
||||
public static boolean isQemuRunning(Activity activity) {
|
||||
Terminal vterm = new Terminal(activity);
|
||||
vterm.executeShellCommand2("ps -e", false, activity);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import com.vectras.qemu.MainSettingsManager;
|
|||
import com.vectras.vm.AppConfig;
|
||||
import com.vectras.vm.Fragment.CreateImageDialogFragment;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.RomInfo;
|
||||
import com.vectras.vm.store.RomInfo;
|
||||
import com.vectras.vm.SplashActivity;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.main.vms.DataMainRoms;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import com.bumptech.glide.Glide;
|
|||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.vectras.qemu.Config;
|
||||
import com.vectras.vm.creator.VMCreatorActivity;
|
||||
import com.vectras.vm.ExportRomActivity;
|
||||
import com.vectras.vm.R;
|
||||
|
|
@ -30,6 +31,8 @@ import java.io.File;
|
|||
public class RomOptionsDialog {
|
||||
public static void show(Activity activity, int position, DataMainRoms vmConfig) {
|
||||
if (VMManager.isVMRunning(activity, vmConfig.vmID)) {
|
||||
Config.vmID = vmConfig.vmID;
|
||||
|
||||
VmControllerDialog vmControllerDialog = new VmControllerDialog();
|
||||
vmControllerDialog.streamAudio = VmAudioManager.streamAudio;
|
||||
vmControllerDialog.position = position;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ public class StartVmDialog {
|
|||
QmpSender.shutdown();
|
||||
new Handler(Looper.getMainLooper()).post(callBack::onStop);
|
||||
|
||||
final int MAX_TRY = 10;
|
||||
int triedCount = 0;
|
||||
|
||||
boolean isVmRuning = VMManager.isVMRunning(activity, vmId);
|
||||
|
||||
while (isVmRuning) {
|
||||
|
|
@ -96,7 +99,9 @@ public class StartVmDialog {
|
|||
|
||||
QmpSender.shutdown();
|
||||
|
||||
if (!isVmRuning || VMManager.isQemuStopedWithError) {
|
||||
if (!isVmRuning || VMManager.isQemuStopedWithError || triedCount == MAX_TRY) {
|
||||
if (triedCount < MAX_TRY) FileUtils.delete(Config.getLocalQMPSocketPath(vmId));
|
||||
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
isShuttingDown = false;
|
||||
dismiss();
|
||||
|
|
@ -110,6 +115,8 @@ public class StartVmDialog {
|
|||
} catch (InterruptedException ignored) {
|
||||
|
||||
}
|
||||
|
||||
triedCount++;
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -35,4 +35,5 @@ public class DataRoms {
|
|||
public String id;
|
||||
@SerializedName("vecid")
|
||||
public String vecid;
|
||||
public boolean containsAds;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.RomInfo;
|
||||
import com.vectras.vm.store.RomInfo;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -76,10 +76,13 @@ public class RomStoreHomeAdpater extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
intent.putExtra("id", current.id);
|
||||
intent.putExtra("vecid", current.vecid);
|
||||
intent.putExtra("isRomInfo", true);
|
||||
intent.putExtra("containsAds", current.containsAds);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
|
||||
myHolder.textAvail.setText(context.getString(R.string.available) + (current.containsAds ? " • " + context.getString(R.string.contains_ads) : ""));
|
||||
} else {
|
||||
myHolder.textAvail.setText(context.getString(R.string.unavailable));
|
||||
myHolder.textAvail.setText(context.getString(R.string.unavailable) + (current.containsAds ? " • " + context.getString(R.string.contains_ads) : ""));
|
||||
myHolder.textAvail.setTextColor(Color.RED);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.RomInfo;
|
||||
import com.vectras.vm.store.RomInfo;
|
||||
import com.vectras.vm.main.romstore.DataRoms;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
|
|
@ -77,10 +77,12 @@ public class SoftwareStoreHomeAdapter extends RecyclerView.Adapter<RecyclerView.
|
|||
intent.putExtra("id", current.id);
|
||||
intent.putExtra("vecid", current.vecid);
|
||||
intent.putExtra("isRomInfo", false);
|
||||
intent.putExtra("containsAds", current.containsAds);
|
||||
context.startActivity(intent);
|
||||
});
|
||||
myHolder.textAvail.setText(context.getString(R.string.available) + (current.containsAds ? " • " + context.getString(R.string.contains_ads) : ""));
|
||||
} else {
|
||||
myHolder.textAvail.setText(context.getString(R.string.unavailable));
|
||||
myHolder.textAvail.setText(context.getString(R.string.unavailable) + (current.containsAds ? " • " + context.getString(R.string.contains_ads) : ""));
|
||||
myHolder.textAvail.setTextColor(Color.RED);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import com.vectras.vm.utils.DialogUtils;
|
|||
import com.vectras.vm.utils.FileUtils;
|
||||
import com.vectras.vm.utils.ProgressDialog;
|
||||
import com.vectras.vm.utils.StreamAudio;
|
||||
import com.vectras.vm.x11.X11Activity;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -121,7 +122,8 @@ public class VmControllerDialog extends DialogFragment {
|
|||
binding.lnSwitch.setOnClickListener(v -> {
|
||||
if (isAdded()) {
|
||||
VmPicker vmPicker = new VmPicker(requireActivity());
|
||||
vmPicker.currentVmId= Config.vmID;
|
||||
vmPicker.currentVmId = Config.vmID;
|
||||
vmPicker.title = getString(R.string.switch_to);
|
||||
vmPicker.listVm = list;
|
||||
vmPicker.pick((position, name, value) -> {
|
||||
if (Config.vmID.equals(value)) return;
|
||||
|
|
@ -182,7 +184,7 @@ public class VmControllerDialog extends DialogFragment {
|
|||
dismiss();
|
||||
});
|
||||
|
||||
if (isAdded() && (!(requireActivity() instanceof MainVNCActivity))) {
|
||||
if (isAdded() && (!(requireActivity() instanceof MainVNCActivity)) && (!(requireActivity() instanceof X11Activity))) {
|
||||
if (streamAudio == null)
|
||||
streamAudio = new StreamAudio(requireActivity().getApplicationContext());
|
||||
if (!streamAudio.isPlaying()) VmAudioManager.set(Config.vmID);
|
||||
|
|
@ -191,11 +193,16 @@ public class VmControllerDialog extends DialogFragment {
|
|||
if (streamAudio == null ||
|
||||
!isAdded() ||
|
||||
audioFileSize == 0 ||
|
||||
(isAdded() && (!(requireActivity() instanceof MainVNCActivity)) && !VmAudioManager.currentVmId.equals(Config.vmID))
|
||||
(isAdded() && (!(requireActivity() instanceof MainVNCActivity)) && !(requireActivity() instanceof X11Activity) && !VmAudioManager.currentVmId.equals(Config.vmID))
|
||||
) {
|
||||
binding.lnMute.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (!streamAudio.isPlaying()) {
|
||||
if (isAdded() && requireActivity() instanceof X11Activity) {
|
||||
if (!streamAudio.getFile().equals(VmFileManager.findAudioRaw(getContext(), Config.vmID)) || !streamAudio.isPlaying()) {
|
||||
binding.ivMute.setImageResource(R.drawable.volume_up_24px);
|
||||
binding.tvMute.setText(R.string.unmute);
|
||||
}
|
||||
} else if (!streamAudio.isPlaying()) {
|
||||
binding.ivMute.setImageResource(R.drawable.volume_up_24px);
|
||||
binding.tvMute.setText(R.string.unmute);
|
||||
}
|
||||
|
|
@ -491,7 +498,21 @@ public class VmControllerDialog extends DialogFragment {
|
|||
}
|
||||
|
||||
private void mute() {
|
||||
if (streamAudio.isPlaying()) {
|
||||
if (isAdded() && requireActivity() instanceof X11Activity) {
|
||||
if (streamAudio.isPlaying() && streamAudio.getFile().equals(VmFileManager.findAudioRaw(getContext(), Config.vmID))) {
|
||||
streamAudio.stop();
|
||||
binding.ivMute.setImageResource(R.drawable.volume_up_24px);
|
||||
binding.tvMute.setText(R.string.unmute);
|
||||
} else {
|
||||
if (!streamAudio.getFile().equals(VmFileManager.findAudioRaw(getContext(), Config.vmID))) {
|
||||
streamAudio.stop();
|
||||
streamAudio.setFile(VmFileManager.findAudioRaw(getContext(), Config.vmID));
|
||||
}
|
||||
streamAudio.play();
|
||||
binding.ivMute.setImageResource(R.drawable.volume_off_24px);
|
||||
binding.tvMute.setText(R.string.mute);
|
||||
}
|
||||
} else if (streamAudio.isPlaying()) {
|
||||
streamAudio.stop();
|
||||
binding.ivMute.setImageResource(R.drawable.volume_up_24px);
|
||||
binding.tvMute.setText(R.string.unmute);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,21 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
|
||||
public class VmListManager {
|
||||
public static ArrayList<HashMap<String, Object>> getAllVmForPickRunningNoVncSocketOnly(Context context) {
|
||||
ArrayList<HashMap<String, Object>> listVm = getAllVmForPickRunningOnly(context);
|
||||
ArrayList<HashMap<String, Object>> list = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < listVm.size(); i++) {
|
||||
if (!FileUtils.isFileExists(Config.getLocalVNCSocketPath(Objects.requireNonNull(listVm.get(i).get("value")).toString()))) {
|
||||
list.add(listVm.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static ArrayList<HashMap<String, Object>> getAllVmForPickRunningVncSocketOnly(Context context) {
|
||||
ArrayList<HashMap<String, Object>> listVm = getAllVmForPick(context);
|
||||
ArrayList<HashMap<String, Object>> listVm = getAllVmForPickRunningOnly(context);
|
||||
ArrayList<HashMap<String, Object>> list = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < listVm.size(); i++) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.app.Activity;
|
|||
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.creator.VMCreatorSelector;
|
||||
import com.vectras.vm.utils.UniversalPickerDialog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -12,8 +13,9 @@ import java.util.Objects;
|
|||
public class VmPicker {
|
||||
public boolean isRunningOnly;
|
||||
public String currentVmId = "";
|
||||
public String title;
|
||||
private Activity activity;
|
||||
ArrayList<HashMap<String, Object>> listVm;
|
||||
public ArrayList<HashMap<String, Object>> listVm;
|
||||
|
||||
public interface VMPickerCallback {
|
||||
void onSelected(int position, String name, String vmId);
|
||||
|
|
@ -39,11 +41,11 @@ public class VmPicker {
|
|||
}
|
||||
}
|
||||
|
||||
VMCreatorSelector.showDialog(
|
||||
UniversalPickerDialog.show(
|
||||
activity,
|
||||
list,
|
||||
position,
|
||||
(callback::onSelected),
|
||||
activity.getString(R.string.switch_to));
|
||||
title == null || title.isEmpty() ? activity.getString(R.string.vm_picker) : title);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.vectras.vm;
|
||||
package com.vectras.vm.store;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
|
|
@ -22,6 +22,9 @@ import com.anbui.elephant.interaction.Interaction;
|
|||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.vectras.vm.ImagePrvActivity;
|
||||
import com.vectras.vm.R;
|
||||
import com.vectras.vm.VMManager;
|
||||
import com.vectras.vm.creator.VMCreatorActivity;
|
||||
import com.vectras.vm.databinding.ActivityRomInfoBinding;
|
||||
import com.vectras.vm.utils.DialogUtils;
|
||||
|
|
@ -177,9 +180,15 @@ public class RomInfo extends AppCompatActivity {
|
|||
if (getIntent().hasExtra("title")) {
|
||||
binding.textName.setText(getIntent().getStringExtra("title"));
|
||||
}
|
||||
|
||||
if (getIntent().hasExtra("shortdesc")) {
|
||||
binding.textSize.setText(getIntent().getStringExtra("shortdesc"));
|
||||
}
|
||||
|
||||
if (getIntent().hasExtra("containsAds")) {
|
||||
binding.tvContainsAds.setVisibility(getIntent().getBooleanExtra("containsAds", false) ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
if (getIntent().hasExtra("desc")) {
|
||||
binding.descTxt.setText(getIntent().getStringExtra("desc"));
|
||||
}
|
||||
|
|
@ -38,6 +38,10 @@ public class StreamAudio {
|
|||
filePath = path;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
public void setCross(StreamAudio streamAudio) {
|
||||
cross = streamAudio;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class UniversalPickerDialog {
|
|||
public RecyclerviewAdapter(Activity activity, AlertDialog alertDialog, ArrayList<HashMap<String, Object>> arr, int position, UniversalPickerDialogCallback callback) {
|
||||
this.activity = activity;
|
||||
data = arr;
|
||||
currentPosition = position > -1 ? position : 0;
|
||||
currentPosition = position;
|
||||
dialog = alertDialog;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
|||
import static android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.RenderEffect;
|
||||
import android.graphics.Shader;
|
||||
import android.os.Looper;
|
||||
|
||||
import static android.view.InputDevice.KEYBOARD_TYPE_ALPHABETIC;
|
||||
|
|
@ -30,7 +32,11 @@ import com.vectras.vm.databinding.GameControlsBinding;
|
|||
import com.vectras.vm.main.core.MainStartVM;
|
||||
import com.vectras.vm.manager.QmpSender;
|
||||
import com.vectras.vm.manager.VmAudioManager;
|
||||
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.utils.DialogUtils;
|
||||
import com.vectras.vm.utils.StreamAudio;
|
||||
import com.vectras.vm.utils.UIUtils;
|
||||
|
||||
|
|
@ -94,6 +100,8 @@ import com.vectras.vm.x11.utils.X11ToolbarViewPager;
|
|||
import com.vectras.vm.R;
|
||||
import com.vectras.vterm.Terminal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
|
@ -410,41 +418,41 @@ public class X11Activity extends AppCompatActivity implements View.OnApplyWindow
|
|||
}
|
||||
});
|
||||
|
||||
bindingControls.btnPrograms.setOnClickListener(v -> {
|
||||
Dialog dialog = new Dialog(this);
|
||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
dialog.setContentView(R.layout.dialog_programs);
|
||||
Objects.requireNonNull(dialog.getWindow()).setBackgroundDrawableResource(android.R.color.transparent);
|
||||
|
||||
WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes();
|
||||
layoutParams.alpha = 1f;
|
||||
dialog.getWindow().setAttributes(layoutParams);
|
||||
|
||||
ImageButton termBtn = dialog.findViewById(R.id.btnTerminal);
|
||||
ImageButton vkCubeBtn = dialog.findViewById(R.id.btnVkCube);
|
||||
ImageButton glxGearsBtn = dialog.findViewById(R.id.btnGlxGears);
|
||||
|
||||
termBtn.setOnClickListener(v1 -> {
|
||||
new Terminal(this).executeShellCommand2("xfce4-terminal", false, this);
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
glxGearsBtn.setOnClickListener(v1 -> {
|
||||
new Terminal(this).executeShellCommand2("glxgears", false, this);
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
vkCubeBtn.setOnClickListener(v1 -> {
|
||||
new Terminal(this).executeShellCommand2("vkcube", false, this);
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
try {
|
||||
dialog.show();
|
||||
} catch (WindowManager.BadTokenException e) {
|
||||
Log.e(TAG, "Failed to show dialog", e);
|
||||
}
|
||||
});
|
||||
// bindingControls.btnPrograms.setOnClickListener(v -> {
|
||||
// Dialog dialog = new Dialog(this);
|
||||
// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
// dialog.setContentView(R.layout.dialog_programs);
|
||||
// Objects.requireNonNull(dialog.getWindow()).setBackgroundDrawableResource(android.R.color.transparent);
|
||||
//
|
||||
// WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes();
|
||||
// layoutParams.alpha = 1f;
|
||||
// dialog.getWindow().setAttributes(layoutParams);
|
||||
//
|
||||
// ImageButton termBtn = dialog.findViewById(R.id.btnTerminal);
|
||||
// ImageButton vkCubeBtn = dialog.findViewById(R.id.btnVkCube);
|
||||
// ImageButton glxGearsBtn = dialog.findViewById(R.id.btnGlxGears);
|
||||
//
|
||||
// termBtn.setOnClickListener(v1 -> {
|
||||
// new Terminal(this).executeShellCommand2("xfce4-terminal", false, this);
|
||||
// dialog.dismiss();
|
||||
// });
|
||||
//
|
||||
// glxGearsBtn.setOnClickListener(v1 -> {
|
||||
// new Terminal(this).executeShellCommand2("glxgears", false, this);
|
||||
// dialog.dismiss();
|
||||
// });
|
||||
//
|
||||
// vkCubeBtn.setOnClickListener(v1 -> {
|
||||
// new Terminal(this).executeShellCommand2("vkcube", false, this);
|
||||
// dialog.dismiss();
|
||||
// });
|
||||
//
|
||||
// try {
|
||||
// dialog.show();
|
||||
// } catch (WindowManager.BadTokenException e) {
|
||||
// Log.e(TAG, "Failed to show dialog", e);
|
||||
// }
|
||||
// });
|
||||
|
||||
bindingGameControls.upGameBtn.setOnTouchListener((v, event) -> {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
|
|
@ -517,12 +525,21 @@ public class X11Activity extends AppCompatActivity implements View.OnApplyWindow
|
|||
bindingGameControls.xBtn.setOnClickListener(v -> keyDownUp(KEYCODE_X));
|
||||
bindingGameControls.ctrlGameBtn.setOnClickListener(v -> keyDownUp(KEYCODE_CTRL_LEFT));
|
||||
bindingGameControls.spaceBtn.setOnClickListener(v -> keyDownUp(KEYCODE_SPACE));
|
||||
|
||||
bindingControls.btnVterm.setOnClickListener(v -> {
|
||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
// Create and show the dialog.
|
||||
LoggerDialogFragment newFragment = new LoggerDialogFragment();
|
||||
newFragment.show(ft, "Logger");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
if (newFragment.getDialog() == null) return;
|
||||
blurLayout();
|
||||
newFragment.getDialog().setOnDismissListener(d -> unBlurLayout());
|
||||
}
|
||||
});
|
||||
|
||||
bindingControls.shutdownBtn.setOnClickListener(v -> finish());
|
||||
|
||||
bindingControls.kbdBtn.setOnClickListener(v -> new Handler(Looper.getMainLooper()).postDelayed(() -> toggleKeyboardVisibility(X11Activity.this), 200));
|
||||
|
|
@ -533,6 +550,8 @@ public class X11Activity extends AppCompatActivity implements View.OnApplyWindow
|
|||
newFragment.binding = binding.controlsfragment;
|
||||
newFragment.show(ft, "Controllers");
|
||||
});
|
||||
|
||||
|
||||
bindingControls.btnSettings
|
||||
.setOnClickListener(
|
||||
(l) ->
|
||||
|
|
@ -542,6 +561,9 @@ public class X11Activity extends AppCompatActivity implements View.OnApplyWindow
|
|||
setAction(Intent.ACTION_MAIN);
|
||||
}
|
||||
}));
|
||||
|
||||
bindingControls.btnVmManager.setOnClickListener(v -> vmController());
|
||||
|
||||
bindingDesktopControls.upBtn.setOnTouchListener((v, event) -> {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
sendKey(KEYCODE_DPAD_UP, false);
|
||||
|
|
@ -1486,4 +1508,72 @@ public class X11Activity extends AppCompatActivity implements View.OnApplyWindow
|
|||
Config.setDefault();
|
||||
finish();
|
||||
}
|
||||
|
||||
private void vmController() {
|
||||
ArrayList<HashMap<String, Object>> list = VmListManager.getAllVmForPickRunningNoVncSocketOnly(this);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
DialogUtils.oopsDialog(this, getString(R.string.no_vms_are_available));
|
||||
} else if (list.size() == 1) {
|
||||
Config.vmID = Objects.requireNonNull(list.get(0).get("value")).toString();
|
||||
|
||||
VmControllerDialog vmControllerDialog = new VmControllerDialog();
|
||||
vmControllerDialog.streamAudio = streamAudio;
|
||||
vmControllerDialog.show(getSupportFragmentManager(), "VmControllerDialog");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
blurLayout();
|
||||
vmControllerDialog.setOnDismissCallback(this::unBlurLayout);
|
||||
}
|
||||
} else {
|
||||
VmPicker vmPicker = new VmPicker(this);
|
||||
vmPicker.currentVmId = "";
|
||||
vmPicker.listVm = list;
|
||||
vmPicker.pick((position, name, value) -> {
|
||||
if (position < 0) {
|
||||
DialogUtils.oopsDialog(this, getString(R.string.no_vms_are_available));
|
||||
return;
|
||||
}
|
||||
|
||||
Config.vmID = value;
|
||||
|
||||
VmControllerDialog vmControllerDialog = new VmControllerDialog();
|
||||
vmControllerDialog.streamAudio = streamAudio;
|
||||
vmControllerDialog.show(getSupportFragmentManager(), "VmControllerDialog");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
getSupportFragmentManager().executePendingTransactions();
|
||||
blurLayout();
|
||||
vmControllerDialog.setOnDismissCallback(this::unBlurLayout);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
boolean isBlurring;
|
||||
|
||||
private void blurLayout() {
|
||||
if (isBlurring || !MainSettingsManager.getBlurEffect(this)) return;
|
||||
isBlurring = true;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
RenderEffect blurEffect = RenderEffect.createBlurEffect(
|
||||
25f, 25f,
|
||||
Shader.TileMode.CLAMP
|
||||
);
|
||||
binding.main.setRenderEffect(blurEffect);
|
||||
binding.lorieView.setRenderEffect(blurEffect);
|
||||
}
|
||||
}
|
||||
|
||||
private void unBlurLayout() {
|
||||
if (!isBlurring) return;
|
||||
isBlurring = false;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
binding.main.setRenderEffect(null);
|
||||
binding.lorieView.setRenderEffect(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
app/src/main/res/drawable/gamepad_24px.xml
Normal file
10
app/src/main/res/drawable/gamepad_24px.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M480,306L480,306L480,306L480,306L480,306ZM654,480L654,480L654,480L654,480L654,480ZM306,480L306,480L306,480L306,480L306,480ZM480,654L480,654L480,654L480,654L480,654ZM480,420L360,300L360,80L600,80L600,300L480,420ZM660,600L540,480L660,360L880,360L880,600L660,600ZM80,600L80,360L300,360L420,480L300,600L80,600ZM360,880L360,660L480,540L600,660L600,880L360,880ZM480,306L520,266L520,160L440,160L440,266L480,306ZM160,520L266,520L306,480L266,440L160,440L160,520ZM440,800L520,800L520,694L480,654L440,694L440,800ZM694,520L800,520L800,440L694,440L654,480L694,520Z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/stack_24px.xml
Normal file
10
app/src/main/res/drawable/stack_24px.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M240,560L240,640L160,640Q127,640 103.5,616.5Q80,593 80,560L80,160Q80,127 103.5,103.5Q127,80 160,80L560,80Q593,80 616.5,103.5Q640,127 640,160L640,240L560,240L560,160Q560,160 560,160Q560,160 560,160L160,160Q160,160 160,160Q160,160 160,160L160,560Q160,560 160,560Q160,560 160,560L240,560ZM400,880Q367,880 343.5,856.5Q320,833 320,800L320,400Q320,367 343.5,343.5Q367,320 400,320L800,320Q833,320 856.5,343.5Q880,367 880,400L880,800Q880,833 856.5,856.5Q833,880 800,880L400,880ZM400,800L800,800Q800,800 800,800Q800,800 800,800L800,400Q800,400 800,400Q800,400 800,400L400,400Q400,400 400,400Q400,400 400,400L400,800Q400,800 400,800Q400,800 400,800ZM600,600Q600,600 600,600Q600,600 600,600L600,600Q600,600 600,600Q600,600 600,600L600,600Q600,600 600,600Q600,600 600,600L600,600Q600,600 600,600Q600,600 600,600Z"/>
|
||||
</vector>
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="com.vectras.vm.RomInfo">
|
||||
tools:context="com.vectras.vm.store.RomInfo">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
|
|
@ -96,6 +96,14 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="size"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_contains_ads"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/contains_ads"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
|
|
|||
|
|
@ -84,7 +84,17 @@
|
|||
android:layout_marginRight="8dp"
|
||||
android:background="@drawable/controls_button"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:src="@drawable/round_settings_24"
|
||||
android:src="@drawable/settings_24px"
|
||||
app:tint="?attr/colorPrimary" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btn_vm_manager"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="8dp"
|
||||
android:background="@drawable/controls_button"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:src="@drawable/stack_24px"
|
||||
app:tint="?attr/colorPrimary" />
|
||||
|
||||
<ImageButton
|
||||
|
|
@ -95,7 +105,9 @@
|
|||
android:background="@drawable/controls_button"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:src="@drawable/apps_24px"
|
||||
app:tint="?attr/colorPrimary" />
|
||||
app:tint="?attr/colorPrimary"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/btnQmp"
|
||||
|
|
@ -104,7 +116,7 @@
|
|||
android:layout_marginRight="8dp"
|
||||
android:background="@drawable/controls_button"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:src="@drawable/round_terminal_24"
|
||||
android:src="@drawable/terminal_24px"
|
||||
app:tint="?attr/colorPrimary" />
|
||||
|
||||
<ImageButton
|
||||
|
|
@ -124,7 +136,7 @@
|
|||
android:layout_marginRight="8dp"
|
||||
android:background="@drawable/controls_button"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:src="@drawable/round_games_24"
|
||||
android:src="@drawable/gamepad_24px"
|
||||
app:tint="?attr/colorPrimary" />
|
||||
|
||||
<ImageButton
|
||||
|
|
@ -134,7 +146,7 @@
|
|||
android:layout_marginLeft="0dp"
|
||||
android:background="@drawable/controls_button"
|
||||
android:backgroundTint="?attr/colorPrimary"
|
||||
android:src="@drawable/round_keyboard_24"
|
||||
android:src="@drawable/keyboard_24px"
|
||||
app:tint="?attr/colorPrimary" />
|
||||
|
||||
<ImageButton
|
||||
|
|
|
|||
|
|
@ -592,6 +592,7 @@
|
|||
<string name="in_system_settings">Ở cài đặt hệ thống.</string>
|
||||
<string name="missing_packages">Một số gói đang bị thiếu</string>
|
||||
<string name="missing_packages_content">Đây là những gói đang bị thiếu và bạn nên cài đặt chúng:</string>
|
||||
<string name="contains_ads">Có chứa quảng cáo</string>
|
||||
|
||||
<!--======================TERMUX STRINGS====================-->
|
||||
<string name="application_name" translatable="false">Vterm</string>
|
||||
|
|
|
|||
|
|
@ -604,6 +604,7 @@
|
|||
<string name="missing_packages">Missing packages</string>
|
||||
<string name="missing_packages_content">These are the missing packages that you should install:</string>
|
||||
<string name="x11_general_setting_note">You need to restart the app when switching between built-in and external.</string>
|
||||
<string name="contains_ads">Contains ads</string>
|
||||
|
||||
|
||||
<!--======================TERMUX STRINGS====================-->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue