Wine适配OpenHarmony
# Wine on OpenHarmony 适配方案
## 1. OpenHarmony 原生适配 Wine 的思路
OpenHarmony 虽然默认使用标准Linux 内核的操作系统,其图形栈、音频栈与常见Linux 桌面环境不同,因此无法直接运行传统 Linux 版 Wine。Wine从7.0开始采用了"PE/Unix"分离的构建架构。需要从以下层面进行适配:
- **图形与窗口系统适配**:Wine 通过 `winex11.drv`、`winemac.drv`、`wineandroid.drv` 等驱动与宿主窗口系统交互。
OpenHarmony系统上需要实现类似的 `wineohos.drv` 驱动,工作内容:
* PE侧(Windows 视角):编写wineohos.drv的Win32部分。它负责接收 Windows 应用的 CreateWindow、BitBlt 消息,然后通过 Wine的__wine_unix_call宏,跨越边界把请求吐给 Unix 侧。
* Unix侧(OpenHarmony 视角):编写对接OpenHarmony NDK的.so代理层库。它接收到PE侧传来的请求后,调用 Rosen WM创建窗口,或者处理键鼠事件。
## 2. Wine 11 编译支持
Wine 11 版本可能需要打Musl补丁才能正常编译或者工作。这意味着:
- 需要把当前Wine对Glibc的特定接口依赖,改为Musl的接口才能正常功能。
1. 目前前我在Wine11上没有做该部分工作,MVP阶段仅做了Windows Console应用支持,如sqlite3操作数据库,运行成功。
2. adb connect ip:host不能正常,是因为在windows上adb.exe依赖wineconsole.exe创建终端窗口(从Wine日志上看到有CreateWindowEx接口调用失败输出),而我没实现窗口集成,后续验证。
- 需要分两步编译,第一步先编译Windows应用依赖的基础动态库(PE阶段),如ntdll.dll、kernel32.dll等,第二步编译宿主机依赖库(Unix 阶段),生成真正负责与OpenHarmony系统底层进行互通的桥接驱动与核心服务进程(如 wineohos.drv.so、ntdll.so)。
## 3. libfreetype 编译依赖
如果 Wine 11 需要运行 Windows GUI 应用,**必须编译并链接 libfreetype 库**,否则窗口尺寸测量会出现以下问题(我在这个问题被坑了好久😓):
- 字体度量(metrics)获取失败,导致窗口尺寸计算错误。
- 文本渲染异常,部分控件显示空白或尺寸异常。
- 对话框布局引擎(`comctl32`、`user32`)依赖字体信息进行窗口布局。
**解决方案**:在交叉编译工具链中预先编译 `libfreetype`,并在 Wine 的 `configure` 阶段确保 `--with-freetype` 开启。
## 4. 本地窗口适配方案
### 方案一:直接调用 OHOS 窗口管理器(类似 X11/Wayland 方式)
直接调用 `OHOS::Rosen::WindowManager::Create()` 创建原生窗口,优点在于实现简单、性能开销低。但存在以下问题:
- 这部分接口属于内部接口,所以需要做一个代理层(见下面代理层部分),提供接口给wineohos.drv使用。
- **默认没有标题栏**,绘制标题栏有以下两种方式:
1. 自己实现标题栏,这样有不小额外的工作量。
2. 使用wine默认的标题栏,风格老旧。
- 窗口管理需要自行处理窗口激活、最小化、关闭等事件。
- 任务栏没有任务窗口显示,需要自己适配。
- 适用于需要深度定制的PC多窗口场景。
### 方案二:Wine Android 方式(OHOS 应用 + XComponent)
参考 `wineandroid.drv` 的适配模式:
1. 编写一个 OpenHarmony 原生应用作为宿主,内嵌 **XComponent** 用于承载 Windows 应用的图形输出。
2. XComponent 提供NativeWindow渲染接口,可以直接绑定 `wineohos.drv` 的图形缓冲区。
3. Windows 应用窗口作为子窗口嵌入到 Component中,窗口事件通过 OHOS 的输入事件通道转发。
4. 优点:可以获得完整的 OHOS 窗口生命周期管理,标题栏、导航栏、手势操作等原生支持
5. 缺点:多窗口场景下每个窗口都需要一个XComponent实例,与PC习惯不一致。
## 5. Wine 驱动层:`wineohos.drv`
在 `wine/dlls/` 目录下实现 `wineohos.drv`,作为 OpenHarmony 的 Wine 图形/窗口驱动:
```
wine/dlls/wineohos.drv/
├── ohos_window.c # 窗口创建、销毁、布局管理
├── ohos_display.c # 显示模式、屏幕信息枚举
├── ohos_keyboard.c # 键盘事件转换(OHOS KeyEvent → Win32 虚拟键码)
├── ohos_mouse.c # 鼠标事件转换
├── ohos_clipboard.c # 剪贴板桥接
├── ohos_cursor.c # 光标管理
├── ohos_gdi.c # GDI 绘图桥接
├── ohos_opengl.c # OpenGL 适配(通过 Zink 走 Vulkan)
├── ohos_vulkan.c # Vulkan 直接对接
├── ohos_icon.c # 图标管理
├── ohos_init.c # 驱动初始化与注册
├── ohos_res.c # 资源管理
└── Makefile.in # 构建配置
```
驱动内部与宿主机系统绑定,通过代理层接口调用原生OpenHarmony系统能力。
## 6. OpenHarmony 代理层
在 OpenHarmony 系统侧提供一个代理层(Native Service 或 System Ability),为 `wineohos.drv` 提供以下能力:
| 能力 | 接口 | 说明 |
|------|------|------|
| 窗口创建 | `OHOS::Rosen::WindowManager::CreateWindow()` | 创建 OHOS 原生窗口,设置窗口属性 |
| 图层拷贝 | `OHOS::Rosen::Surface::CopyLayer()` | 将 Wine 渲染的图形缓冲区拷贝到窗口图层 |
| 键鼠事件 | `OHOS::MMI::InputManager` | 监听输入事件,转发给 Wine 的输入处理 |
| 光标管理 | `OHOS::Rosen::CursorManager` | 设置/隐藏光标,更改光标样式 |
| 剪贴板 | `OHOS::MiscServices::PasteboardManager` | 同步系统剪贴板与 Windows 剪贴板 |
| 显示信息 | `OHOS::Rosen::DisplayManager` | 获取屏幕分辨率、刷新率、DPI 等信息 |
使用方式:和OpenHarmony编码一起编译出so(如libohw_proxy.z.so),导出相关的接口供`wineohos.drv`使用。
## 7. GPU 加速方案
### Vulkan 作为统一 GPU 接口
```
Windows 应用
├── Direct3D 9/10/11/12 ──→ Wine D3D 转译层 ──→ Vulkan
├── OpenGL ──→ Mesa3D Zink ──→ Vulkan
└── Vulkan ──→ 直接透传 ──→ Vulkan
│
▼
OpenHarmony Vulkan 驱动
(OHOS Vulkan ICD / Loader)
```
- **D3D → Vulkan**:Wine 内置的 `wined3d` 或 `dxvk` 项目已实现 Direct3D 到 Vulkan 的转译,性能损耗小,兼容性好。
- **OpenGL → Vulkan**:对于依赖 OpenGL 的老旧 Windows 应用,使用 **Mesa3D 的 Zink** 驱动,将 OpenGL API 调用转译为 Vulkan,无需 GL 原生驱动。
- **Vulkan 适配 OHOS**:只需在 OHOS 上实现 Vulkan 的 ICD(Installable Client Driver)和 Loader,即可运行上述所有图形栈。OpenHarmony 的 GPU 厂商(如 Mali、Adreno 等)通常已提供 Vulkan 支持。如果要自己基于Mesa3d实现Vulkan支持OHOS,可以参照其他文章。
### 优势
- 统一底层 GPU 接口,无需为 D3D 和 OpenGL 分别适配。
- Vulkan 的显存管理、管线状态、命令缓冲等机制与 Wine 的 D3D 转译层高度匹配。
- 可以利用 Vulkan 的跨平台特性,快速适配不同 GPU 硬件。
## 8. 音视频编解码
音视频编解码通过 **OHOS NDK** 提供的接口进行对接:
| 功能 | OHOS NDK 接口 | 说明 |
|------|---------------|------|
| 音频输出 | `OH_AudioRenderer` | 播放 Windows 应用的音频输出 |
| 音频输入 | `OH_AudioCapturer` | 采集麦克风输入,提供给 Windows 应用 |
| 视频解码 | `OH_AVCodec` | 硬件加速解码(H.264/H.265/MPEG4 等) |
| 视频编码 | `OH_AVCodec` | 硬件加速编码 |
| 媒体容器 | `OH_AVDemuxer` / `OH_AVMuxer` | 音视频封装/解封装 |
**适配方式**:
- 在 `wineohos.drv` 或独立的 `wineohos.media` 模块中,封装 OHOS NDK 的媒体接口。
- 通过 Wine 的 `winmm.dll`、`quartz.dll` 或 `mf.dll` 的 Hook 机制,将 Windows 多媒体 API 调用桥接到 OHOS 媒体栈。
- 利用 OHOS 的硬件编解码能力,确保音视频播放性能接近原生。
更多推荐



所有评论(0)