compatdb_core/runtime.rs
1//! What `compatdb.so` needs to apply a [`Resolution`] inside a process.
2//!
3//! That is the process's arch, its image path, command line and environment
4//! block as Wine hands them over in UTF-16, the reader of an image's version
5//! resource, and the values the library hands to Wine.
6//!
7//! A launcher does not need this module. It builds rules, writes the table
8//! into [`ENV_VAR`](crate::ENV_VAR) and, to show what a program would get,
9//! uses [`Table::preview`](crate::Table::preview) with a [`VersionInfo`] it
10//! fills in itself.
11//!
12//! [`Resolution`]: crate::Resolution
13//! [`VersionInfo`]: crate::VersionInfo
14
15mod process;
16mod version;
17
18pub use self::{
19 process::{
20 Arch, IMAGE_FILE_MACHINE_ARM64, append_cmdline, append_cmdline_each, basename_of,
21 env_value, merge_env,
22 },
23 version::version_info,
24};
25use crate::{D3d9, Dxgi, OpenGl, Wined3d};
26
27/// The DXGI-family implementation a process loads when no rule names one.
28///
29/// That is wined3d, as in upstream Wine, for every arch. Its tree has no
30/// D3D12. Either tree serves every arch: the 64-bit modules of both are
31/// ARM64X, so a native ARM64 program loads their ARM64 half and an x64
32/// program, which runs as ARM64EC, their ARM64EC half; an i386 program gets
33/// their i386 builds under emulation.
34#[must_use]
35pub const fn default_dxgi(_arch: Arch) -> Dxgi {
36 Dxgi::Wined3d
37}
38
39/// The DXGI-family implementation a process loads: the requested one, or
40/// [`default_dxgi`] for the arch when nothing was requested.
41#[must_use]
42pub const fn effective_dxgi(requested: Option<Dxgi>, arch: Arch) -> Dxgi {
43 match requested {
44 Some(want) => want,
45 None => default_dxgi(arch),
46 }
47}
48
49/// The D3D9 implementation a process loads when no rule names one.
50///
51/// That is wined3d, as in upstream Wine, for every arch. Either tree serves
52/// every arch: the 64-bit modules of both, mtld3d's release build and Wine's
53/// own `d3d9.dll`, are ARM64X, so a native ARM64 program loads their ARM64
54/// half and an x64 program, which runs as ARM64EC, their ARM64EC half; an
55/// i386 program gets their i386 builds under emulation.
56#[must_use]
57pub const fn default_d3d9(_arch: Arch) -> D3d9 {
58 D3d9::Wined3d
59}
60
61/// The D3D9 implementation a process loads: the requested one, or
62/// [`default_d3d9`] for the arch when nothing was requested.
63#[must_use]
64pub const fn effective_d3d9(requested: Option<D3d9>, arch: Arch) -> D3d9 {
65 match requested {
66 Some(want) => want,
67 None => default_d3d9(arch),
68 }
69}
70
71/// The value ntdll's `set_compat_opengl` takes for `opengl`: 1 for Mesa's
72/// EGL, 0 for Apple's OpenGL.
73#[must_use]
74pub const fn opengl_hook_value(opengl: OpenGl) -> i32 {
75 match opengl {
76 OpenGl::Egl => 1,
77 OpenGl::Cgl => 0,
78 }
79}
80
81/// The `WINE_D3D_CONFIG` value for the renderer `wined3d` on top of
82/// `config`.
83///
84/// `config` is the value the rules' own `env` entries leave the variable at
85/// (`None` when they do not set it, or remove it). The renderer comes first
86/// and the other options of `config` are kept, while a `renderer` option
87/// there is dropped: the setting decides the renderer. OpenGL is set as
88/// explicitly as Vulkan, so a process that asks for it does not inherit
89/// Vulkan from the process that started it.
90#[must_use]
91pub fn wined3d_config(wined3d: Wined3d, config: Option<&str>) -> String {
92 let mut options = vec![format!("renderer={}", wined3d.as_str())];
93 options.extend(
94 config
95 .unwrap_or("")
96 .split([',', ';'])
97 .filter(|o| !o.is_empty())
98 .filter(|o| o.split('=').next() != Some("renderer"))
99 .map(String::from),
100 );
101 options.join(",")
102}
103
104/// The `renderer` option of a `WINE_D3D_CONFIG` value, the first one as
105/// wined3d reads it, or `None` when the value has none.
106#[must_use]
107pub fn wined3d_renderer_in(config: &str) -> Option<&str> {
108 config
109 .split([',', ';'])
110 .find_map(|o| o.strip_prefix("renderer="))
111}
112
113#[cfg(test)]
114mod tests;