# 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 的硬件编解码能力,确保音视频播放性能接近原生。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐