@@ -37,7 +37,9 @@ static void print_help(char *const name)
37
37
" --net=NET_MODE Set network mode\n"
38
38
" --passt-socket=PATH Instead of starting passt, connect to passt socket at PATH"
39
39
"NET_MODE can be either TSI (default) or PASST\n"
40
+ " --display=DISPLAY Add a display to the vm (can be specified multiple times)\n"
40
41
"\n"
42
+ "DISPLAY: string in the form 'display_id:width:height' (e.g. '0:1920:1080')\n"
41
43
"NEWROOT: the root directory of the vm\n"
42
44
"COMMAND: the command you want to execute in the vm\n"
43
45
"COMMAND_ARGS: arguments of COMMAND\n" ,
@@ -49,17 +51,47 @@ static const struct option long_options[] = {
49
51
{ "help" , no_argument , NULL , 'h' },
50
52
{ "net_mode" , required_argument , NULL , 'N' },
51
53
{ "passt-socket" , required_argument , NULL , 'P' },
54
+ { "display" , required_argument , NULL , 'D' },
52
55
{ NULL , 0 , NULL , 0 }
53
56
};
54
57
58
+ struct display {
59
+ bool enabled ;
60
+ uint32_t width ;
61
+ uint32_t height ;
62
+ };
63
+
55
64
struct cmdline {
56
65
bool show_help ;
57
66
enum net_mode net_mode ;
58
67
char const * passt_socket_path ;
59
68
char const * new_root ;
60
69
char * const * guest_argv ;
70
+ bool enable_display_backend ;
71
+ struct display displays [KRUN_MAX_DISPLAYS ];
61
72
};
62
73
74
+ bool add_display (struct cmdline * cmdline , const char * arg ) {
75
+ uint32_t index , width , height ;
76
+
77
+ if (sscanf (arg , "%u:%u:%u" , & index , & width , & height ) != 3 ) {
78
+ fprintf (stderr , "Invalid value for --display\n" , index );
79
+ return false;
80
+ }
81
+
82
+ if (index >= KRUN_MAX_DISPLAYS ) {
83
+ fprintf (stderr , "Invalid display id: %u\n" , index );
84
+ return false;
85
+ }
86
+
87
+ cmdline -> enable_display_backend = true;
88
+ cmdline -> displays [index ].enabled = true;
89
+ cmdline -> displays [index ].width = width ;
90
+ cmdline -> displays [index ].height = height ;
91
+
92
+ return true;
93
+ }
94
+
63
95
bool parse_cmdline (int argc , char * const argv [], struct cmdline * cmdline )
64
96
{
65
97
assert (cmdline != NULL );
@@ -71,6 +103,8 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
71
103
.passt_socket_path = NULL ,
72
104
.new_root = NULL ,
73
105
.guest_argv = NULL ,
106
+ .enable_display_backend = false,
107
+ .displays = { 0 },
74
108
};
75
109
76
110
int option_index = 0 ;
@@ -94,6 +128,11 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
94
128
case 'P' :
95
129
cmdline -> passt_socket_path = optarg ;
96
130
break ;
131
+ case 'D' :
132
+ if (!add_display (cmdline , optarg )) {
133
+ return false;
134
+ }
135
+ break ;
97
136
case '?' :
98
137
return false;
99
138
default :
@@ -259,6 +298,22 @@ int main(int argc, char *const argv[])
259
298
return -1 ;
260
299
}
261
300
301
+ if (cmdline .enable_display_backend && (err = krun_set_display_backend_gtk (ctx_id ))) {
302
+ errno = - err ;
303
+ perror ("Error enabling gtk display" );
304
+ return -1 ;
305
+ }
306
+
307
+ for (int i = 0 ; i < KRUN_MAX_DISPLAYS ; ++ i ) {
308
+ if (cmdline .displays [i ].enabled ) {
309
+ if (err = krun_set_display (ctx_id , i , cmdline .displays [i ].width , cmdline .displays [i ].height )) {
310
+ errno = - err ;
311
+ perror ("Error adding a display" );
312
+ return -1 ;
313
+ }
314
+ }
315
+ }
316
+
262
317
// Map port 18000 in the host to 8000 in the guest (if networking uses TSI)
263
318
if (cmdline .net_mode == NET_MODE_TSI ) {
264
319
if (err = krun_set_port_map (ctx_id , & port_map [0 ])) {
0 commit comments