1use std::path::PathBuf;
2
3use crate::common::{OnOff, YesNo};
4use crate::to_command::{ToArg, ToCommand};
5
6pub enum OnCoreEsOff {
7 On,
8 Core,
9 Es,
10 Off,
11}
12
13impl ToArg for OnCoreEsOff {
14 fn to_arg(&self) -> &str {
15 match self {
16 OnCoreEsOff::On => "on",
17 OnCoreEsOff::Core => "core",
18 OnCoreEsOff::Es => "es",
19 OnCoreEsOff::Off => "off",
20 }
21 }
22}
23
24pub enum QemuDisplay {
25 Spice {
26 gl: Option<OnOff>,
27 },
28 Sdl {
29 gl: Option<OnCoreEsOff>,
30 grab_mod: Option<String>,
31 show_cursor: Option<OnOff>,
32 window_close: Option<OnOff>,
33 },
34 Gtk {
35 fullscreen: Option<OnOff>,
36 gl: Option<OnOff>,
37 grab_on_hover: Option<OnOff>,
38 show_tabs: Option<OnOff>,
39 show_cursor: Option<OnOff>,
40 window_close: Option<OnOff>,
41 show_menubar: Option<OnOff>,
42 zoom_to_fit: Option<OnOff>,
43 },
44 Vnc {
45 vnc: String,
46 optargs: Option<String>,
47 },
48 Curses {
49 charset: Option<String>,
50 },
51 Cocoa {
52 full_grab: Option<OnOff>,
53 swap_opt_cmd: Option<OnOff>,
54 show_cursor: Option<OnOff>,
55 left_command_key: Option<OnOff>,
56 full_screen: Option<OnOff>,
57 zoom_to_fit: Option<OnOff>,
58 },
59 EglHeadless {
60 rendernode: Option<PathBuf>,
61 },
62 Dbus {
63 addr: Option<String>,
64 p2p: Option<YesNo>,
65 gl: Option<OnCoreEsOff>,
66 rendernode: Option<PathBuf>,
67 },
68 None,
69}
70
71impl ToCommand for QemuDisplay {
72 fn to_command(&self) -> Vec<String> {
73 let mut cmd = vec![];
74
75 cmd.push("-display".to_string());
76
77 let mut args = vec![];
78 match self {
79 QemuDisplay::Spice { gl } => {
80 args.push("spice-app".to_string());
81 if let Some(gl) = gl {
82 args.push(format!("gl={}", gl.to_arg()));
83 }
84 }
85 QemuDisplay::Sdl {
86 gl,
87 grab_mod,
88 show_cursor,
89 window_close,
90 } => {
91 args.push("sdl".to_string());
92 if let Some(gl) = gl {
93 args.push(format!("gl={}", gl.to_arg()));
94 }
95 if let Some(grab_mod) = grab_mod {
96 args.push(format!("grab-mod={}", grab_mod));
97 }
98 if let Some(show_cursor) = show_cursor {
99 args.push(format!("show-cursor={}", show_cursor.to_arg()));
100 }
101 if let Some(window_close) = window_close {
102 args.push(format!("window-close={}", window_close.to_arg()));
103 }
104 }
105 QemuDisplay::Gtk {
106 fullscreen,
107 gl,
108 grab_on_hover,
109 show_tabs,
110 show_cursor,
111 window_close,
112 show_menubar,
113 zoom_to_fit,
114 } => {
115 args.push("gtk".to_string());
116 if let Some(fullscreen) = fullscreen {
117 args.push(format!("full-screen={}", fullscreen.to_arg()));
118 }
119 if let Some(gl) = gl {
120 args.push(format!("gl={}", gl.to_arg()));
121 }
122 if let Some(grab_on_hover) = grab_on_hover {
123 args.push(format!("grab-on-hover={}", grab_on_hover.to_arg()));
124 }
125 if let Some(show_tabs) = show_tabs {
126 args.push(format!("show-tabs={}", show_tabs.to_arg()));
127 }
128 if let Some(show_cursor) = show_cursor {
129 args.push(format!("show-cursor={}", show_cursor.to_arg()));
130 }
131 if let Some(window_close) = window_close {
132 args.push(format!("window-close={}", window_close.to_arg()));
133 }
134 if let Some(show_menubar) = show_menubar {
135 args.push(format!("show-menubar={}", show_menubar.to_arg()));
136 }
137 if let Some(zoom_to_fit) = zoom_to_fit {
138 args.push(format!("zoom-to-fit={}", zoom_to_fit.to_arg()));
139 }
140 }
141 QemuDisplay::Vnc { vnc, optargs } => {
142 args.push(format!("vnc={}", vnc.clone()));
143 if let Some(optargs) = optargs {
144 args.push(optargs.clone());
145 }
146 }
147 QemuDisplay::Curses { charset } => {
148 args.push("curses".to_string());
149 if let Some(charset) = charset {
150 args.push(format!("charset={}", charset));
151 }
152 }
153 QemuDisplay::Cocoa {
154 full_grab,
155 swap_opt_cmd,
156 show_cursor,
157 left_command_key,
158 full_screen,
159 zoom_to_fit,
160 } => {
161 args.push("cocoa".to_string());
162 if let Some(full_grab) = full_grab {
163 args.push(format!("full-grab={}", full_grab.to_arg()));
164 }
165 if let Some(swap_opt_cmd) = swap_opt_cmd {
166 args.push(format!("swap-opt-cmd={}", swap_opt_cmd.to_arg()));
167 }
168 if let Some(show_cursor) = show_cursor {
169 args.push(format!("show-cursor={}", show_cursor.to_arg()));
170 }
171 if let Some(left_command_key) = left_command_key {
172 args.push(format!("left-command-key={}", left_command_key.to_arg()));
173 }
174 if let Some(full_screen) = full_screen {
175 args.push(format!("full-screen={}", full_screen.to_arg()));
176 }
177 if let Some(zoom_to_fit) = zoom_to_fit {
178 args.push(format!("zoom-to-fit={}", zoom_to_fit.to_arg()));
179 }
180 }
181 QemuDisplay::EglHeadless { rendernode } => {
182 args.push("egl-headless".to_string());
183 if let Some(rendernode) = rendernode {
184 args.push(format!("rendernode={}", rendernode.display()));
185 }
186 }
187 QemuDisplay::Dbus {
188 addr,
189 p2p,
190 gl,
191 rendernode,
192 } => {
193 args.push("dbus".to_string());
194 if let Some(addr) = addr {
195 args.push(format!("addr={}", addr));
196 }
197 if let Some(p2p) = p2p {
198 args.push(format!("p2p={}", p2p.to_arg()));
199 }
200 if let Some(gl) = gl {
201 args.push(format!("gl={}", gl.to_arg()));
202 }
203 if let Some(rendernode) = rendernode {
204 args.push(format!("rendernode={}", rendernode.display()));
205 }
206 }
207 QemuDisplay::None => {
208 args.push("none".to_string());
209 }
210 }
211 cmd.push(args.join(","));
212 cmd
213 }
214}