Skip to content

Commit

Permalink
box and wine initial support
Browse files Browse the repository at this point in the history
  • Loading branch information
Cateners committed Nov 30, 2023
1 parent 2a19c5e commit b342855
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 110 deletions.
Binary file modified assets/patch.tar.gz
Binary file not shown.
15 changes: 9 additions & 6 deletions extra/cross/install-box
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,23 @@ sudo apt reinstall -y libc6-dev

mkdir $HOME/.local/share/tiny/cross

rm -rf $HOME/.local/share/tiny/tmp
mkdir $HOME/.local/share/tiny/tmp
cd $HOME/.local/share/tiny/tmp

git clone https://github.com/ptitSeb/box86
git clone https://mirror.ghproxy.com/https://github.com/ptitSeb/box86
if [ $? -ne 0 ]; then
git clone https://mirror.ghproxy.com/https://github.com/ptitSeb/box86
git clone https://github.com/ptitSeb/box86
if [ $? -ne 0 ]; then
rm -rf $HOME/.local/share/tiny/tmp
echo '仓库克隆失败...退出安装...'
exit
fi
fi

git clone https://github.com/ptitSeb/box64
git clone https://mirror.ghproxy.com/https://github.com/ptitSeb/box64
if [ $? -ne 0 ]; then
git clone https://mirror.ghproxy.com/https://github.com/ptitSeb/box64
git clone https://github.com/ptitSeb/box64
if [ $? -ne 0 ]; then
rm -rf $HOME/.local/share/tiny/tmp
echo '仓库克隆失败...退出安装...'
Expand All @@ -35,17 +36,19 @@ cd box86
mkdir build
cd build
cmake .. -DARM64=1 -DBAD_SIGNAL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
make
make -j
cd ../..
mv box86/build/box86 ../cross
mv box86/x86lib ../cross

cd box64
mkdir build
cd build
cmake .. -DARM64=1 -DBAD_SIGNAL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
make
make -j
cd ../..
mv box64/build/box64 ../cross
mv box64/x64lib ../cross

cd ..
rm -rf tmp
Expand Down
66 changes: 24 additions & 42 deletions extra/cross/install-wine
Original file line number Diff line number Diff line change
Expand Up @@ -4,94 +4,76 @@ sudo apt update
sudo apt upgrade -y
sudo apt install -y nano cabextract libfreetype6 libfreetype6:armhf libfontconfig libfontconfig:armhf libxext6 libxext6:armhf libxinerama-dev libxinerama-dev:armhf libxxf86vm1 libxxf86vm1:armhf libxrender1 libxrender1:armhf libxcomposite1 libxcomposite1:armhf libxrandr2 libxrandr2:armhf libxi6 libxi6:armhf libxcursor1 libxcursor1:armhf libvulkan-dev libvulkan-dev:armhf zenity

rm -rf $HOME/.local/share/tiny/tmp
mkdir $HOME/.local/share/tiny/tmp
cd $HOME/.local/share/tiny/tmp

wget https://github.com/Kron4ek/Wine-Builds/releases/download/8.20/wine-8.20-x86.tar.xz
if [ $? -ne 0 ]; then
wget https://mirror.ghproxy.com/https://github.com/Kron4ek/Wine-Builds/releases/download/8.20/wine-8.20-x86.tar.xz
if [ $? -ne 0 ]; then
rm -rf $HOME/.local/share/tiny/tmp
echo '下载失败...退出安装...'
exit
fi
MIRROR_SITE=https://mirror.ghproxy.com
LATEST_WINE_NAME=$(curl -L https://github.com/Kron4ek/Wine-Builds/releases | grep "amd64\.tar\.xz" | grep "proton" | head -n 1 | awk '{print $NF}')
LATEST_WINE_TAG=$(echo $LATEST_WINE_NAME | cut -d "-" -f 2)

if [ $LATEST_WINE_TAG == proton ]; then
LATEST_WINE_TAG=proton-$(echo $LATEST_WINE_NAME | cut -d "-" -f 3)-$(echo $LATEST_WINE_NAME | cut -d "-" -f 4)
fi

wget https://github.com/Kron4ek/Wine-Builds/releases/download/8.20/wine-8.20-amd64.tar.xz
LATEST_WINE_LINK=https://github.com/Kron4ek/Wine-Builds/releases/download/$LATEST_WINE_TAG/$LATEST_WINE_NAME

wget $MIRROR_SITE/$LATEST_WINE_LINK
if [ $? -ne 0 ]; then
wget https://mirror.ghproxy.com/https://github.com/Kron4ek/Wine-Builds/releases/download/8.20/wine-8.20-amd64.tar.xz
wget $LATEST_WINE_LINK
if [ $? -ne 0 ]; then
rm -rf $HOME/.local/share/tiny/tmp
echo '下载失败...退出安装...'
exit
fi
fi

wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
wget $MIRROR_SITE/https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
if [ $? -ne 0 ]; then
wget https://mirror.ghproxy.com/https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
if [ $? -ne 0 ]; then
rm -rf $HOME/.local/share/tiny/tmp
echo '下载失败...退出安装...'
exit
fi
fi

tar xvf wine-8.20-x86.tar.xz
tar xvf wine-8.20-amd64.tar.xz
mv wine-8.20-x86 ../cross/wine32
mv wine-8.20-amd64 ../cross/wine64
tar xvf $LATEST_WINE_NAME
mv wine-$LATEST_WINE_TAG-amd64 ../cross/wine
mv winetricks ../cross/winetricks-executable
chmod +x $HOME/.local/share/tiny/cross/winetricks-executable
cd ..
rm -rf tmp

echo '#!/bin/bash
export WINEPREFIX=~/.wine32
box86 '"$HOME/.local/share/tiny/cross/wine32 "'"$@"' > $HOME/.local/share/tiny/cross/wine32-executable
chmod +x $HOME/.local/share/tiny/cross/wine32-executable
export WINEPREFIX=~/.wine
box86 '"$HOME/.local/share/tiny/cross/wine/bin/wine "'"$@"' > $HOME/.local/share/tiny/cross/wine-executable
chmod +x $HOME/.local/share/tiny/cross/wine-executable

echo '#!/bin/bash
export WINEPREFIX=~/.wine64
box64 '"$HOME/.local/share/tiny/cross/wine64 "'"$@"' > $HOME/.local/share/tiny/cross/wine64-executable
export WINEPREFIX=~/.wine
box64 '"$HOME/.local/share/tiny/cross/wine/bin/wine64 "'"$@"' > $HOME/.local/share/tiny/cross/wine64-executable
chmod +x $HOME/.local/share/tiny/cross/wine64-executable

echo '#!/bin/bash
export BOX86_NOBANNER=1 WINE=wine32 WINEPREFIX=~/.wine32 WINESERVER=~/.local/share/tiny/cross/wine32/bin/wineserver
wine32 '"$HOME/.local/share/tiny/cross/winetricks-executable "'"$@"' > $HOME/.local/share/tiny/cross/winetricks32-executable
chmod +x $HOME/.local/share/tiny/cross/winetricks32-executable

echo '#!/bin/bash
export BOX64_NOBANNER=1 WINE=wine64 WINEPREFIX=~/.wine64 WINESERVER=~/.local/share/tiny/cross/wine64/bin/wineserver
export BOX64_NOBANNER=1 WINE=wine64 WINEPREFIX=~/.wine WINESERVER=~/.local/share/tiny/cross/wine/bin/wineserver
wine64 '"$HOME/.local/share/tiny/cross/winetricks-executable "'"$@"' > $HOME/.local/share/tiny/cross/winetricks64-executable
chmod +x $HOME/.local/share/tiny/cross/winetricks64-executable

echo '[Desktop Entry]
Name=Wine32 启动器
Exec=wine32 start /unix %F
Icon=wine
Type=Application' > $HOME/.local/share/tiny/cross/wine32.desktop
chmod +x $HOME/.local/share/tiny/cross/wine32.desktop

echo '[Desktop Entry]
Name=Wine64 启动器
Exec=wine64 start /unix %F
Icon=wine
Type=Application' > $HOME/.local/share/tiny/cross/wine64.desktop
chmod +x $HOME/.local/share/tiny/cross/wine64.desktop

echo '[Desktop Entry]
Name=Wine32 winetricks 实用工具
Exec=winetricks32
Icon=wine
Type=Application' > $HOME/.local/share/tiny/cross/winetricks32.desktop
chmod +x $HOME/.local/share/tiny/cross/winetricks32.desktop

echo '[Desktop Entry]
Name=Wine64 winetricks 实用工具
Exec=winetricks64
Icon=wine
Type=Application' > $HOME/.local/share/tiny/cross/winetricks64.desktop
chmod +x $HOME/.local/share/tiny/cross/winetricks64.desktop

echo '安装完成'
echo '安装完成,在启用wine后可以点击exe文件选择用wine启动。'
echo '程序的运行可能依赖一些配置或组件。比如,一些使用directx的游戏可能需要安装dxvk。'
echo '如果缺失可以尝试使用winetricks安装。请务必保持耐心。'
136 changes: 120 additions & 16 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
//import 'dart:convert';

Expand Down Expand Up @@ -103,7 +104,7 @@ class SettingPage extends StatefulWidget {

class _SettingPageState extends State<SettingPage> {

final List<bool> _expandState = [false, false, false, false, false, false];
final List<bool> _expandState = [false, false, false, false, false, false, false];

@override
Widget build(BuildContext context) {
Expand All @@ -120,6 +121,22 @@ class _SettingPageState extends State<SettingPage> {
headerBuilder: ((context, isExpanded) {
return const ListTile(title: Text("高级设置"), subtitle: Text("修改后重启生效"));
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
OutlinedButton(style: D.commandButtonStyle, child: const Text("重置启动命令"), onPressed: () {
showDialog(context: context, builder: (context) {
return AlertDialog(title: const Text("注意"), content: const Text("是否重置启动命令?"), actions: [
TextButton(onPressed:() {
Navigator.of(context).pop();
}, child: const Text("取消")),
TextButton(onPressed:() async {
await Util.setCurrentProp("boot", D.boot);
G.bootTextChange.value = !G.bootTextChange.value;
if (!context.mounted) return;
Navigator.of(context).pop();
}, child: const Text("是")),
]);
});
}),
SizedBox.fromSize(size: const Size.square(8)),
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("name"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "容器名称"), onChanged: (value) async {
await Util.setCurrentProp("name", value);
//setState(() {});
Expand All @@ -135,25 +152,14 @@ class _SettingPageState extends State<SettingPage> {
await Util.setCurrentProp("vnc", value);
}),
SizedBox.fromSize(size: const Size.square(8)),
const Divider(height: 2, indent: 8, endIndent: 8),
SizedBox.fromSize(size: const Size.square(16)),
const Text("你可以在当前所有同一网络下的设备(如:连接同一路由器的手机,电脑等)里使用小小电脑。\n\n将下面的链接复制到其他设备,在其他设备上把链接localhost字样改为当前设备的IP地址(可以通过快捷指令查看),然后使用浏览器打开链接即可。"),
SizedBox.fromSize(size: const Size.square(16)),
TextFormField(maxLines: null, initialValue: Util.getCurrentProp("vncUrl"), decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "网页跳转地址"), onChanged: (value) async {
await Util.setCurrentProp("vncUrl", value);
}),
SizedBox.fromSize(size: const Size.square(8)),
OutlinedButton(style: D.commandButtonStyle, child: const Text("重置启动命令"), onPressed: () {
showDialog(context: context, builder: (context) {
return AlertDialog(title: const Text("注意"), content: const Text("是否重置启动命令?"), actions: [
TextButton(onPressed:() {
Navigator.of(context).pop();
}, child: const Text("取消")),
TextButton(onPressed:() async {
await Util.setCurrentProp("boot", D.boot);
G.bootTextChange.value = !G.bootTextChange.value;
if (!context.mounted) return;
Navigator.of(context).pop();
}, child: const Text("是")),
]);
});
}),
],))),
ExpansionPanel(
isExpanded: _expandState[1],
Expand Down Expand Up @@ -429,6 +435,104 @@ class _SettingPageState extends State<SettingPage> {
],))),
ExpansionPanel(
isExpanded: _expandState[5],
headerBuilder: ((context, isExpanded) {
return const ListTile(title: Text("跨架构/跨系统支持"), subtitle: Text("实验性功能"),);
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
const Text("""你的梦想是在你的小小电脑上,运行着那些你熟悉的x86/x64或windows的程序。你不惧怕任何困难,你勇敢地使用box86/box64或wine,让你的梦想成为现实。但是,你也要知道,这是一条漫长而艰辛的道路,你需要付出很多的代价。你的程序要经过两层的模拟,就像穿越两个世界,它们的速度会变得缓慢而沉重。你需要有足够的耐心,即使你的眼前一片空白,你的终端还在默默地工作。你要时刻关注它的输出,看看它是否还在前进,还是遇到了难以逾越的障碍。或者,你也可以选择另一条路,去寻找那些为linux arm64而生的程序,它们或许能让你的梦想更加顺畅。
你的选择就在下面,你只需勾选你想要的选项,然后重新启动你的小小电脑,你的梦想就会有所不同。
......人话:
使用box86/box64运行x86/x64架构的程序,或使用wine运行windows程序。
运行windows程序需要经过架构和系统两层模拟,不要对运行速度抱有期待。程序崩溃也是常有的。
你需要耐心。即使图形界面什么也没显示。看看终端,还在继续输出吗?还是停止在某个报错?
或者寻找该windows软件官方是否提供linux arm64版本。
以下选项启用后下次启动时生效。
"""),
SizedBox.fromSize(size: const Size.square(16)),
Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: [
OutlinedButton(style: D.commandButtonStyle, child: const Text("安装box86和box64"), onPressed: () {
Util.termWrite("bash ~/.local/share/tiny/extra/install-box");
G.pageIndex.value = 0;
}),
OutlinedButton(style: D.commandButtonStyle, child: const Text("安装wine与winetricks"), onPressed: () async {
if (!await File("${G.dataPath}/tiny/cross/box64").exists()) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("请先安装box86/box64"))
);
return;
}
Util.termWrite("bash ~/.local/share/tiny/extra/install-wine");
G.pageIndex.value = 0;
}),
OutlinedButton(style: D.commandButtonStyle, child: const Text("移除所有安装"), onPressed: () async {
if (G.wasBoxEnabled) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("请关闭跨架构支持后重试"))
);
return;
}
Util.termWrite("rm -rf ~/.local/share/tiny/cross");
G.pageIndex.value = 0;
}),
OutlinedButton(style: D.commandButtonStyle, child: const Text("清空wine数据"), onPressed: () async {
Util.termWrite("rm -rf ~/.wine");
G.pageIndex.value = 0;
}),
OutlinedButton(style: D.commandButtonStyle, child: const Text("配置wine"), onPressed: () async {
Util.termWrite("wine64 winecfg");
G.pageIndex.value = 0;
Workflow.launchBrowser();
}),
OutlinedButton(style: D.commandButtonStyle, child: const Text("启动winetricks"), onPressed: () async {
Util.termWrite("winetricks64");
G.pageIndex.value = 0;
Workflow.launchBrowser();
}),
]),
SizedBox.fromSize(size: const Size.square(8)),
SwitchListTile(title: const Text("启用box86/box64"), subtitle: const Text("运行跨架构软件"), value: Util.getGlobal("isBoxEnabled") as bool, onChanged:(value) async {
//检测box64是否存在,存在才开启
if (value && !await File("${G.dataPath}/tiny/cross/box64").exists()) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("请先安装box86/box64"))
);
return;
}
G.prefs.setBool("isBoxEnabled", value);
if (!value && Util.getGlobal("isWineEnabled")) {
G.prefs.setBool("isWineEnabled", false);
}
setState(() {});
},),
SwitchListTile(title: const Text("启用wine"), subtitle: const Text("运行windows exe软件"), value: Util.getGlobal("isWineEnabled") as bool, onChanged:(value) async {
//检测wine是否存在且box64是否开启
if (value && !(Util.getGlobal("isBoxEnabled") && await File("${G.dataPath}/tiny/cross/wine64-executable").exists())) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("请先安装wine并启用box86/box64"))
);
return;
}
G.prefs.setBool("isWineEnabled", value);
setState(() {});
},),
SizedBox.fromSize(size: const Size.square(16)),
],))),
ExpansionPanel(
isExpanded: _expandState[6],
headerBuilder: ((context, isExpanded) {
return const ListTile(title: Text("广告记录"), subtitle: Text("在这里看广告"));
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
Expand Down
Loading

0 comments on commit b342855

Please sign in to comment.