blob: 89a75d9213426071f00303e1e20ec01423b8594d [file] [log] [blame]
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -07001/*
David Sodman8ef20062015-01-06 09:23:40 -08002 * Copyright 2014 The Chromium OS Authors. All rights reserved.
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -07003 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
Mike Frysingerfbc52f32016-08-31 16:11:25 -04007#include <assert.h>
Dominik Behrda6df412016-08-02 12:56:42 -07008#include <errno.h>
Dominik Behr46c567f2016-03-08 15:11:48 -08009#include <fcntl.h>
Dominik Behr580462b2014-11-20 13:50:05 -080010#include <getopt.h>
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070011#include <libtsm.h>
Dominik Behr580462b2014-11-20 13:50:05 -080012#include <memory.h>
13#include <stdbool.h>
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070014#include <stdio.h>
15#include <stdlib.h>
16#include <unistd.h>
Dominik Behr46c567f2016-03-08 15:11:48 -080017#include <sys/stat.h>
18#include <sys/types.h>
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070019
Dominik Behr580462b2014-11-20 13:50:05 -080020#include "dbus.h"
Dominik Behr44e07e62016-01-13 19:43:57 -080021#include "dbus_interface.h"
Dominik Behr5239cca2016-01-21 18:22:04 -080022#include "dev.h"
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070023#include "input.h"
Dominik Behr44e07e62016-01-13 19:43:57 -080024#include "main.h"
Dominik Behr580462b2014-11-20 13:50:05 -080025#include "splash.h"
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070026#include "term.h"
David Sodmanbbcb0522014-09-19 10:34:07 -070027#include "util.h"
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070028
David Sodmanbbcb0522014-09-19 10:34:07 -070029#define FLAG_CLEAR 'c'
30#define FLAG_DAEMON 'd'
Dominik Behrd2530902016-05-05 14:01:06 -070031#define FLAG_ENABLE_GFX 'G'
Dominik Behr0bb51772016-07-26 18:04:53 -070032#define FLAG_ENABLE_VT1 '1'
Dominik Behr46c567f2016-03-08 15:11:48 -080033#define FLAG_ENABLE_VTS 'e'
David Sodmanbbcb0522014-09-19 10:34:07 -070034#define FLAG_FRAME_INTERVAL 'f'
Mike Frysingerfbc52f32016-08-31 16:11:25 -040035#define FLAG_HELP 'h'
Dominik Behr32a7c892015-10-09 15:47:53 -070036#define FLAG_IMAGE 'i'
37#define FLAG_IMAGE_HIRES 'I'
Dominik Behrfd9fdda2016-03-28 17:16:45 -070038#define FLAG_LOOP_COUNT 'C'
David Sodman8ef20062015-01-06 09:23:40 -080039#define FLAG_LOOP_START 'l'
40#define FLAG_LOOP_INTERVAL 'L'
41#define FLAG_LOOP_OFFSET 'o'
Dominik Behrda6df412016-08-02 12:56:42 -070042#define FLAG_NUM_VTS 'N'
Dominik Behr222936d2016-05-05 13:50:50 -070043#define FLAG_NO_LOGIN 'n'
David Sodman8ef20062015-01-06 09:23:40 -080044#define FLAG_OFFSET 'O'
Dominik Behrda6df412016-08-02 12:56:42 -070045#define FLAG_PRE_CREATE_VTS 'P'
David Sodmanbbcb0522014-09-19 10:34:07 -070046#define FLAG_PRINT_RESOLUTION 'p'
Dominik Behr92d9e312016-05-04 20:10:48 -070047#define FLAG_SCALE 'S'
Dominik Behrfd9fdda2016-03-28 17:16:45 -070048#define FLAG_SPLASH_ONLY 's'
Dominik Behr09f2b722016-10-05 12:02:04 -070049#define FLAG_WAIT_CHILD 'w'
David Sodmanbbcb0522014-09-19 10:34:07 -070050
Mike Frysingerfbc52f32016-08-31 16:11:25 -040051static const struct option command_options[] = {
David Sodmanbbcb0522014-09-19 10:34:07 -070052 { "clear", required_argument, NULL, FLAG_CLEAR },
53 { "daemon", no_argument, NULL, FLAG_DAEMON },
Dominik Behr46c567f2016-03-08 15:11:48 -080054 { "dev-mode", no_argument, NULL, FLAG_ENABLE_VTS },
Dominik Behrd2530902016-05-05 14:01:06 -070055 { "enable-gfx", no_argument, NULL, FLAG_ENABLE_GFX },
Dominik Behr0bb51772016-07-26 18:04:53 -070056 { "enable-vt1", no_argument, NULL, FLAG_ENABLE_VT1 },
Dominik Behr46c567f2016-03-08 15:11:48 -080057 { "enable-vts", no_argument, NULL, FLAG_ENABLE_VTS },
David Sodmanbbcb0522014-09-19 10:34:07 -070058 { "frame-interval", required_argument, NULL, FLAG_FRAME_INTERVAL },
Mike Frysingerfbc52f32016-08-31 16:11:25 -040059 { "help", no_argument, NULL, FLAG_HELP },
Dominik Behr32a7c892015-10-09 15:47:53 -070060 { "image", required_argument, NULL, FLAG_IMAGE },
61 { "image-hires", required_argument, NULL, FLAG_IMAGE_HIRES },
Dominik Behrfd9fdda2016-03-28 17:16:45 -070062 { "loop-count", required_argument, NULL, FLAG_LOOP_COUNT },
David Sodman8ef20062015-01-06 09:23:40 -080063 { "loop-start", required_argument, NULL, FLAG_LOOP_START },
64 { "loop-interval", required_argument, NULL, FLAG_LOOP_INTERVAL },
65 { "loop-offset", required_argument, NULL, FLAG_LOOP_OFFSET },
Dominik Behrda6df412016-08-02 12:56:42 -070066 { "num-vts", required_argument, NULL, FLAG_NUM_VTS },
Dominik Behr222936d2016-05-05 13:50:50 -070067 { "no-login", no_argument, NULL, FLAG_NO_LOGIN },
David Sodman8ef20062015-01-06 09:23:40 -080068 { "offset", required_argument, NULL, FLAG_OFFSET },
David Sodmanbbcb0522014-09-19 10:34:07 -070069 { "print-resolution", no_argument, NULL, FLAG_PRINT_RESOLUTION },
Dominik Behrda6df412016-08-02 12:56:42 -070070 { "pre-create-vts", no_argument, NULL, FLAG_PRE_CREATE_VTS },
Dominik Behr92d9e312016-05-04 20:10:48 -070071 { "scale", required_argument, NULL, FLAG_SCALE },
Dominik Behrfd9fdda2016-03-28 17:16:45 -070072 { "splash-only", no_argument, NULL, FLAG_SPLASH_ONLY },
David Sodmanbbcb0522014-09-19 10:34:07 -070073 { NULL, 0, NULL, 0 }
74};
Mike Frysingerfbc52f32016-08-31 16:11:25 -040075static const char * const command_help[] = {
76 "Splash screen clear color.",
77 "Daemonize frecon.",
78 "Force dev mode behavior (same as --enable-vts).",
79 "Enable image and box drawing OSC escape codes.",
80 "Enable switching to VT1 and keep a terminal on it.",
81 "Enable additional terminals beyond VT1.",
82 "Default time (in msecs) between splash animation frames.",
Mike Frysingerfbc52f32016-08-31 16:11:25 -040083 "This help screen!",
84 "Image (low res) to use for splash animation.",
85 "Image (hi res) to use for splash animation.",
86 "Number of times to loop splash animations (0 = forever).",
87 "First frame to start the splash animation loop (and enable looping).",
88 "Pause time (in msecs) between splash animation frames.",
89 "Offset (as x,y) for centering looped image.",
90 "Number of enabled VTs. The default is 4, the maximum is 12.",
91 "Do not display login prompt on additional VTs.",
92 "Absolute location of the splash image on screen (as x,y).",
93 "(Deprecated) Print detected screen resolution and exit.",
94 "Create all VTs immediately instead of on-demand.",
95 "Default scale for splash screen images.",
96 "Exit immediately after finishing splash animation.",
97};
98
99static void usage(int status)
100{
101 FILE *out = status ? stderr : stdout;
102
103 static_assert(ARRAY_SIZE(command_help) == ARRAY_SIZE(command_options) - 1,
104 "The help & option arrays need resyncing");
105
106 fprintf(out,
107 "Frecon: The Freon based console daemon.\n"
108 "\n"
109 "Usage: frecon [options] [splash images]\n"
110 "\n"
111 "Options:\n"
112 );
113
114 /* Output all the options & help text, and auto-align them. */
115 int len;
116 for (int i = 0; command_options[i].name; ++i) {
117 len = fprintf(out, " -%c, --%s ",
118 command_options[i].val, command_options[i].name);
119 if (command_options[i].has_arg == required_argument)
120 len += fprintf(out, "<arg> ");
121 fprintf(out, "%*s %s\n", (30 - len), "", command_help[i]);
122 }
123
124 fprintf(out, "\nFor more detailed documentation, visit:\n"
125 "https://chromium.googlesource.com/chromiumos/platform/frecon/+/master\n");
126
127 exit(status);
128}
David Sodmanbbcb0522014-09-19 10:34:07 -0700129
Dominik Behr46c567f2016-03-08 15:11:48 -0800130commandflags_t command_flags = { 0 };
Dominik Behr580462b2014-11-20 13:50:05 -0800131
Stéphane Marchesin8fc13522015-12-14 17:02:28 -0800132static void parse_offset(char* param, int32_t* x, int32_t* y)
David Sodman8ef20062015-01-06 09:23:40 -0800133{
134 char* token;
135 char* saveptr;
136
137 token = strtok_r(param, ",", &saveptr);
138 if (token)
139 *x = strtol(token, NULL, 0);
140
141 token = strtok_r(NULL, ",", &saveptr);
142 if (token)
143 *y = strtol(token, NULL, 0);
144}
David Sodmanbbcb0522014-09-19 10:34:07 -0700145
Dominik Behr44e07e62016-01-13 19:43:57 -0800146int main_process_events(uint32_t usec)
147{
148 terminal_t* terminal;
149 terminal_t* new_terminal;
150 fd_set read_set, exception_set;
Dominik Behrd7112672016-01-20 16:59:34 -0800151 int maxfd = -1;
Dominik Behr44e07e62016-01-13 19:43:57 -0800152 int sstat;
153 struct timeval tm;
154 struct timeval* ptm;
155
156 terminal = term_get_current_terminal();
157
158 FD_ZERO(&read_set);
159 FD_ZERO(&exception_set);
160
Dominik Behrd7112672016-01-20 16:59:34 -0800161 dbus_add_fds(&read_set, &exception_set, &maxfd);
Dominik Behrd7112672016-01-20 16:59:34 -0800162 input_add_fds(&read_set, &exception_set, &maxfd);
Dominik Behr5239cca2016-01-21 18:22:04 -0800163 dev_add_fds(&read_set, &exception_set, &maxfd);
Dominik Behr44e07e62016-01-13 19:43:57 -0800164
Dominik Behrda6df412016-08-02 12:56:42 -0700165 for (unsigned i = 0; i < term_num_terminals; i++) {
166 terminal_t* current_term = term_get_terminal(i);
167 if (term_is_valid(current_term))
Dominik Behrd7112672016-01-20 16:59:34 -0800168 term_add_fds(current_term, &read_set, &exception_set, &maxfd);
Dominik Behr44e07e62016-01-13 19:43:57 -0800169 }
170
171 if (usec) {
172 ptm = &tm;
173 tm.tv_sec = 0;
174 tm.tv_usec = usec;
175 } else
176 ptm = NULL;
177
Dominik Behrd7112672016-01-20 16:59:34 -0800178 sstat = select(maxfd + 1, &read_set, NULL, &exception_set, ptm);
Dominik Behr44e07e62016-01-13 19:43:57 -0800179 if (sstat == 0)
180 return 0;
181
182 dbus_dispatch_io();
183
184 if (term_exception(terminal, &exception_set))
185 return -1;
186
Dominik Behr5239cca2016-01-21 18:22:04 -0800187 dev_dispatch_io(&read_set, &exception_set);
Dominik Behr44e07e62016-01-13 19:43:57 -0800188 input_dispatch_io(&read_set, &exception_set);
189
Dominik Behrda6df412016-08-02 12:56:42 -0700190 for (unsigned i = 0; i < term_num_terminals; i++) {
191 terminal_t* current_term = term_get_terminal(i);
192 if (term_is_valid(current_term))
Dominik Behr44e07e62016-01-13 19:43:57 -0800193 term_dispatch_io(current_term, &read_set);
Dominik Behr44e07e62016-01-13 19:43:57 -0800194 }
195
Dominik Behrda6df412016-08-02 12:56:42 -0700196 /* Could have changed in input dispatch. */
197 terminal = term_get_current_terminal();
198
199 /* Restart terminal on which child has exited. We don't want possible garbage settings from previous session to remain. */
Dominik Behr44e07e62016-01-13 19:43:57 -0800200 if (term_is_valid(terminal)) {
201 if (term_is_child_done(terminal)) {
Dominik Behrda6df412016-08-02 12:56:42 -0700202 if (terminal == term_get_terminal(TERM_SPLASH_TERMINAL) && !command_flags.enable_vt1) {
203 /* Let the old term be, splash_destroy will clean it up. */
204 return 0;
Dominik Behr44e07e62016-01-13 19:43:57 -0800205 }
Dominik Behrda6df412016-08-02 12:56:42 -0700206 term_set_current_terminal(term_init(term_get_current(), -1));
Dominik Behr44e07e62016-01-13 19:43:57 -0800207 new_terminal = term_get_current_terminal();
208 if (!term_is_valid(new_terminal)) {
209 return -1;
210 }
211 term_activate(new_terminal);
212 term_close(terminal);
213 }
214 }
215
216 return 0;
217}
218
Dominik Behr46c567f2016-03-08 15:11:48 -0800219int main_loop(void)
Dominik Behr44e07e62016-01-13 19:43:57 -0800220{
Dominik Behr44e07e62016-01-13 19:43:57 -0800221 int status;
222
Dominik Behr44e07e62016-01-13 19:43:57 -0800223 while (1) {
224 status = main_process_events(0);
225 if (status != 0) {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700226 LOG(ERROR, "Input process returned %d.", status);
Dominik Behr44e07e62016-01-13 19:43:57 -0800227 break;
228 }
229 }
230
231 return 0;
232}
233
Dominik Behr46c567f2016-03-08 15:11:48 -0800234bool set_drm_master_relax(void)
235{
236 int fd;
237 int num_written;
238
239 /*
240 * Setting drm_master_relax flag in kernel allows us to transfer DRM master
Dominik Behrb1abcba2016-04-14 14:57:21 -0700241 * between Chrome and frecon.
Dominik Behr46c567f2016-03-08 15:11:48 -0800242 */
243 fd = open("/sys/kernel/debug/dri/drm_master_relax", O_WRONLY);
244 if (fd != -1) {
245 num_written = write(fd, "Y", 1);
246 close(fd);
247 if (num_written != 1) {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700248 LOG(ERROR, "Unable to set drm_master_relax.");
Dominik Behr46c567f2016-03-08 15:11:48 -0800249 return false;
250 }
251 } else {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700252 LOG(ERROR, "Unable to open drm_master_relax.");
Dominik Behr46c567f2016-03-08 15:11:48 -0800253 return false;
254 }
255 return true;
256}
257
258static void main_on_login_prompt_visible(void* ptr)
259{
260 if (command_flags.daemon && !command_flags.enable_vts) {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700261 LOG(INFO, "Chrome started, our work is done, exiting.");
Dominik Behr46c567f2016-03-08 15:11:48 -0800262 exit(EXIT_SUCCESS);
263 } else
264 if (ptr) {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700265 LOG(INFO, "Chrome started, splash screen is not needed anymore.");
Dominik Behr0bb51772016-07-26 18:04:53 -0700266 if (command_flags.enable_vt1)
267 LOG(WARNING, "VT1 enabled and Chrome is active!");
Dominik Behrda6df412016-08-02 12:56:42 -0700268 splash_destroy((splash_t*)ptr);
269 }
270}
271
272static void legacy_print_resolution(int argc, char* argv[])
273{
274 int c;
275
276 optind = 1;
Mike Frysingerfbc52f32016-08-31 16:11:25 -0400277 opterr = 0;
Dominik Behrda6df412016-08-02 12:56:42 -0700278 for (;;) {
279 c = getopt_long(argc, argv, "", command_options, NULL);
280 if (c == -1) {
281 break;
282 } else if (c == FLAG_PRINT_RESOLUTION) {
283 drm_t *drm = drm_scan();
284 if (!drm)
285 exit(EXIT_FAILURE);
286
287 printf("%d %d", drm_gethres(drm),
288 drm_getvres(drm));
289 drm_delref(drm);
290 exit(EXIT_SUCCESS);
291 }
Dominik Behr46c567f2016-03-08 15:11:48 -0800292 }
293}
Dominik Behr44e07e62016-01-13 19:43:57 -0800294
David Sodmanbbcb0522014-09-19 10:34:07 -0700295int main(int argc, char* argv[])
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700296{
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700297 int ret;
David Sodmanbbcb0522014-09-19 10:34:07 -0700298 int c;
Dominik Behrda6df412016-08-02 12:56:42 -0700299 int pts_fd;
Dominik Behr09f2b722016-10-05 12:02:04 -0700300 unsigned vt;
David Sodman8ef20062015-01-06 09:23:40 -0800301 int32_t x, y;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -0800302 splash_t* splash;
Dominik Behrb1abcba2016-04-14 14:57:21 -0700303 drm_t* drm;
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700304
Dominik Behrda6df412016-08-02 12:56:42 -0700305 legacy_print_resolution(argc, argv);
306
Dominik Behr2b9f1232016-08-02 01:11:12 -0700307 fix_stdio();
Dominik Behrda6df412016-08-02 12:56:42 -0700308 pts_fd = posix_openpt(O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
Dominik Behr2b9f1232016-08-02 01:11:12 -0700309
Dominik Behrb1abcba2016-04-14 14:57:21 -0700310 optind = 1;
Mike Frysingerfbc52f32016-08-31 16:11:25 -0400311 opterr = 1;
Dominik Behrb1abcba2016-04-14 14:57:21 -0700312 for (;;) {
313 c = getopt_long(argc, argv, "", command_options, NULL);
Dominik Behr0bb51772016-07-26 18:04:53 -0700314
315 if (c == -1)
Dominik Behrb1abcba2016-04-14 14:57:21 -0700316 break;
Dominik Behr0bb51772016-07-26 18:04:53 -0700317
318 switch (c) {
319 case FLAG_DAEMON:
320 command_flags.daemon = true;
321 break;
322
323 case FLAG_ENABLE_GFX:
324 command_flags.enable_gfx = true;
325 break;
326
327 case FLAG_ENABLE_VT1:
328 command_flags.enable_vt1 = true;
329 break;
330
331 case FLAG_ENABLE_VTS:
332 command_flags.enable_vts = true;;
333 break;
334
335 case FLAG_NO_LOGIN:
336 command_flags.no_login = true;
337 break;
338
Dominik Behrda6df412016-08-02 12:56:42 -0700339 case FLAG_NUM_VTS:
340 term_set_num_terminals(strtoul(optarg, NULL, 0));
341 break;
342
343 case FLAG_PRE_CREATE_VTS:
344 command_flags.pre_create_vts = true;
345 break;
346
Dominik Behr0bb51772016-07-26 18:04:53 -0700347 case FLAG_SPLASH_ONLY:
348 command_flags.splash_only = true;
349 break;
Mike Frysingerfbc52f32016-08-31 16:11:25 -0400350
351 case FLAG_HELP:
352 usage(0);
353 break;
354
355 case '?':
356 usage(1);
357 break;
Dominik Behrb1abcba2016-04-14 14:57:21 -0700358 }
359 }
360
Dominik Behr09f2b722016-10-05 12:02:04 -0700361 /* Remove all stale VT links. */
362 for (vt = 0; vt < TERM_MAX_TERMINALS; vt++) {
363 char path[32];
364 snprintf(path, sizeof(path), FRECON_VT_PATH, vt);
365 unlink(path);
366 }
367 /* And PID file. */
368 unlink(FRECON_PID_FILE);
369
Dominik Behrb1abcba2016-04-14 14:57:21 -0700370 if (command_flags.daemon) {
Dominik Behrda6df412016-08-02 12:56:42 -0700371 int status;
Dominik Behr09f2b722016-10-05 12:02:04 -0700372
Dominik Behrda6df412016-08-02 12:56:42 -0700373 fprintf(stdout, "%s\n", ptsname(pts_fd));
Dominik Behr09f2b722016-10-05 12:02:04 -0700374 daemonize(command_flags.pre_create_vts);
Dominik Behrda6df412016-08-02 12:56:42 -0700375 status = mkdir(FRECON_RUN_DIR, S_IRWXU);
376 if (status == 0 || (status < 0 && errno == EEXIST)) {
377 char pids[32];
378
379 sprintf(pids, "%u", getpid());
380 write_string_to_file(FRECON_PID_FILE, pids);
381 }
Dominik Behrb1abcba2016-04-14 14:57:21 -0700382 }
Douglas Anderson4da95cd2015-10-05 15:04:30 -0700383
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700384 ret = input_init();
385 if (ret) {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700386 LOG(ERROR, "Input init failed.");
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700387 return EXIT_FAILURE;
388 }
389
Dominik Behr5239cca2016-01-21 18:22:04 -0800390 ret = dev_init();
391 if (ret) {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700392 LOG(ERROR, "Device management init failed.");
Dominik Behr5239cca2016-01-21 18:22:04 -0800393 return EXIT_FAILURE;
394 }
395
Dominik Behrb1abcba2016-04-14 14:57:21 -0700396 drm_set(drm = drm_scan());
Dominik Behrda6df412016-08-02 12:56:42 -0700397
398 splash = splash_init(pts_fd);
399 if (splash == NULL) {
400 LOG(ERROR, "Splash init failed.");
401 return EXIT_FAILURE;
402 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700403
Dominik Behr06c5b932016-10-24 16:12:48 -0700404 if (command_flags.pre_create_vts) {
405 for (unsigned vt = command_flags.enable_vt1 ? TERM_SPLASH_TERMINAL : 1;
406 vt < (command_flags.enable_vts ? term_num_terminals : 1); vt++) {
Dominik Behr09f2b722016-10-05 12:02:04 -0700407 terminal_t *terminal = term_get_terminal(vt);
408 if (!terminal) {
409 terminal = term_init(vt, -1);
410 term_set_terminal(vt, terminal);
411 }
412 }
413 }
414
415 if (command_flags.daemon && command_flags.pre_create_vts)
416 daemon_exit_code(EXIT_SUCCESS);
417
Dominik Behr0bb51772016-07-26 18:04:53 -0700418 /* These flags can be only processed after splash object has been created. */
Dominik Behrb1abcba2016-04-14 14:57:21 -0700419 optind = 1;
David Sodmanbbcb0522014-09-19 10:34:07 -0700420 for (;;) {
421 c = getopt_long(argc, argv, "", command_options, NULL);
422
423 if (c == -1)
424 break;
425
426 switch (c) {
427 case FLAG_CLEAR:
428 splash_set_clear(splash, strtoul(optarg, NULL, 0));
429 break;
430
David Sodman8ef20062015-01-06 09:23:40 -0800431 case FLAG_FRAME_INTERVAL:
432 splash_set_default_duration(splash, strtoul(optarg, NULL, 0));
433 break;
434
Dominik Behr32a7c892015-10-09 15:47:53 -0700435 case FLAG_IMAGE:
436 if (!splash_is_hires(splash))
437 splash_add_image(splash, optarg);
438 break;
439
440 case FLAG_IMAGE_HIRES:
441 if (splash_is_hires(splash))
442 splash_add_image(splash, optarg);
443 break;
444
Dominik Behrfd9fdda2016-03-28 17:16:45 -0700445 case FLAG_LOOP_COUNT:
446 splash_set_loop_count(splash, strtoul(optarg, NULL, 0));
447 break;
448
David Sodman8ef20062015-01-06 09:23:40 -0800449 case FLAG_LOOP_START:
450 splash_set_loop_start(splash, strtoul(optarg, NULL, 0));
451 break;
452
453 case FLAG_LOOP_INTERVAL:
454 splash_set_loop_duration(splash, strtoul(optarg, NULL, 0));
455 break;
456
457 case FLAG_LOOP_OFFSET:
458 parse_offset(optarg, &x, &y);
459 splash_set_loop_offset(splash, x, y);
460 break;
461
462 case FLAG_OFFSET:
463 parse_offset(optarg, &x, &y);
464 splash_set_offset(splash, x, y);
465 break;
Dominik Behrfd9fdda2016-03-28 17:16:45 -0700466
Dominik Behr92d9e312016-05-04 20:10:48 -0700467 case FLAG_SCALE:
468 splash_set_scale(splash, strtoul(optarg, NULL, 0));
469 break;
David Sodmanbbcb0522014-09-19 10:34:07 -0700470 }
471 }
472
Stéphane Marchesinac14d292015-12-14 15:27:18 -0800473 for (int i = optind; i < argc; i++)
David Sodman8ef20062015-01-06 09:23:40 -0800474 splash_add_image(splash, argv[i]);
475
David Sodmanf0a925a2015-05-04 11:19:19 -0700476 if (splash_num_images(splash) > 0) {
Dominik Behr797a3832016-01-11 15:53:11 -0800477 ret = splash_run(splash);
David Sodmanbbcb0522014-09-19 10:34:07 -0700478 if (ret) {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700479 LOG(ERROR, "Splash_run failed: %d.", ret);
Yuly Novikov945871e2015-05-23 00:00:41 -0400480 return EXIT_FAILURE;
David Sodmanbbcb0522014-09-19 10:34:07 -0700481 }
482 }
483
Dominik Behr0bb51772016-07-26 18:04:53 -0700484 if (command_flags.splash_only) {
Dominik Behrda6df412016-08-02 12:56:42 -0700485 splash_destroy(splash);
Dominik Behrfd9fdda2016-03-28 17:16:45 -0700486 goto main_done;
Dominik Behr0bb51772016-07-26 18:04:53 -0700487 }
Dominik Behrfd9fdda2016-03-28 17:16:45 -0700488
David Sodmanbbcb0522014-09-19 10:34:07 -0700489 /*
Dominik Behr46c567f2016-03-08 15:11:48 -0800490 * The DBUS service launches later than the boot-splash service, and
491 * as a result, when splash_run starts DBUS is not yet up, but, by
492 * the time splash_run completes, it is running.
Dominik Behrb1abcba2016-04-14 14:57:21 -0700493 * We really need DBUS now, so we can interact with Chrome.
David Sodmanbbcb0522014-09-19 10:34:07 -0700494 */
Dominik Behr5f6742f2016-03-10 18:03:54 -0800495 dbus_init_wait();
David Sodman8ef20062015-01-06 09:23:40 -0800496
Dominik Behr46c567f2016-03-08 15:11:48 -0800497 /*
498 * Ask DBUS to call us back so we can destroy splash (or quit) when login
Dominik Behrb1abcba2016-04-14 14:57:21 -0700499 * prompt is visible.
Dominik Behr46c567f2016-03-08 15:11:48 -0800500 */
501 dbus_set_login_prompt_visible_callback(main_on_login_prompt_visible,
502 (void*)splash);
Dominik Behr0bb51772016-07-26 18:04:53 -0700503#if !DBUS
Dominik Behrda6df412016-08-02 12:56:42 -0700504 splash_destroy(splash);
Dominik Behr0bb51772016-07-26 18:04:53 -0700505#endif
Dominik Behr1883c042016-04-27 12:31:02 -0700506 /*
507 * Ask DBUS to notify us when suspend has finished so monitors can be reprobed
508 * in case they changed during suspend.
509 */
510 dbus_set_suspend_done_callback(term_suspend_done, NULL);
511
Dominik Behr46c567f2016-03-08 15:11:48 -0800512 if (command_flags.daemon) {
513 if (command_flags.enable_vts)
Dominik Behr83864df2016-04-21 12:35:08 -0700514 set_drm_master_relax(); /* TODO(dbehr) Remove when Chrome is fixed to actually release master. */
Dominik Behrda6df412016-08-02 12:56:42 -0700515 if (command_flags.enable_vt1)
516 term_switch_to(TERM_SPLASH_TERMINAL);
517 else
Dominik Behr0bb51772016-07-26 18:04:53 -0700518 term_background();
Dominik Behr46c567f2016-03-08 15:11:48 -0800519 } else {
Dominik Behrb1abcba2016-04-14 14:57:21 -0700520 /* Create and switch to first term in interactve mode. */
Dominik Behr83864df2016-04-21 12:35:08 -0700521 set_drm_master_relax(); /* TODO(dbehr) Remove when Chrome is fixed to actually release master. */
Dominik Behrda6df412016-08-02 12:56:42 -0700522 term_switch_to(command_flags.enable_vt1 ? TERM_SPLASH_TERMINAL : 1);
Dominik Behr46c567f2016-03-08 15:11:48 -0800523 }
524
525 ret = main_loop();
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700526
Dominik Behrfd9fdda2016-03-28 17:16:45 -0700527main_done:
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700528 input_close();
Dominik Behr5239cca2016-01-21 18:22:04 -0800529 dev_close();
Dominik Behr44e07e62016-01-13 19:43:57 -0800530 dbus_destroy();
Dominik Behr83010f82016-03-18 18:43:08 -0700531 drm_close();
Dominik Behrda6df412016-08-02 12:56:42 -0700532 if (command_flags.daemon)
533 unlink(FRECON_PID_FILE);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700534
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700535 return ret;
536}