blob: 4c859d9766a1d84ea3be0b1a6fbba2b06c69fd0f [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
Dominik Behr580462b2014-11-20 13:50:05 -08007#include <getopt.h>
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -07008#include <libtsm.h>
Dominik Behr580462b2014-11-20 13:50:05 -08009#include <memory.h>
10#include <stdbool.h>
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070011#include <stdio.h>
12#include <stdlib.h>
13#include <unistd.h>
14
Dominik Behr580462b2014-11-20 13:50:05 -080015#include "dbus.h"
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070016#include "input.h"
Dominik Behr580462b2014-11-20 13:50:05 -080017#include "splash.h"
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070018#include "term.h"
David Sodmanbbcb0522014-09-19 10:34:07 -070019#include "util.h"
Stéphane Marchesin62561a12015-12-11 17:32:37 -080020#include "video.h"
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070021
David Sodmanbbcb0522014-09-19 10:34:07 -070022#define FLAG_CLEAR 'c'
23#define FLAG_DAEMON 'd'
24#define FLAG_DEV_MODE 'e'
25#define FLAG_FRAME_INTERVAL 'f'
26#define FLAG_GAMMA 'g'
Dominik Behr32a7c892015-10-09 15:47:53 -070027#define FLAG_IMAGE 'i'
28#define FLAG_IMAGE_HIRES 'I'
David Sodman8ef20062015-01-06 09:23:40 -080029#define FLAG_LOOP_START 'l'
30#define FLAG_LOOP_INTERVAL 'L'
31#define FLAG_LOOP_OFFSET 'o'
32#define FLAG_OFFSET 'O'
David Sodmanbbcb0522014-09-19 10:34:07 -070033#define FLAG_PRINT_RESOLUTION 'p'
34
35static struct option command_options[] = {
36 { "clear", required_argument, NULL, FLAG_CLEAR },
37 { "daemon", no_argument, NULL, FLAG_DAEMON },
38 { "dev-mode", no_argument, NULL, FLAG_DEV_MODE },
39 { "frame-interval", required_argument, NULL, FLAG_FRAME_INTERVAL },
40 { "gamma", required_argument, NULL, FLAG_GAMMA },
Dominik Behr32a7c892015-10-09 15:47:53 -070041 { "image", required_argument, NULL, FLAG_IMAGE },
42 { "image-hires", required_argument, NULL, FLAG_IMAGE_HIRES },
David Sodman8ef20062015-01-06 09:23:40 -080043 { "loop-start", required_argument, NULL, FLAG_LOOP_START },
44 { "loop-interval", required_argument, NULL, FLAG_LOOP_INTERVAL },
45 { "loop-offset", required_argument, NULL, FLAG_LOOP_OFFSET },
46 { "offset", required_argument, NULL, FLAG_OFFSET },
David Sodmanbbcb0522014-09-19 10:34:07 -070047 { "print-resolution", no_argument, NULL, FLAG_PRINT_RESOLUTION },
48 { NULL, 0, NULL, 0 }
49};
50
David Sodman8ef20062015-01-06 09:23:40 -080051typedef struct {
David Sodman8ef20062015-01-06 09:23:40 -080052 bool standalone;
David Sodman8ef20062015-01-06 09:23:40 -080053} commandflags_t;
Dominik Behr580462b2014-11-20 13:50:05 -080054
Stéphane Marchesin8fc13522015-12-14 17:02:28 -080055static void parse_offset(char* param, int32_t* x, int32_t* y)
David Sodman8ef20062015-01-06 09:23:40 -080056{
57 char* token;
58 char* saveptr;
59
60 token = strtok_r(param, ",", &saveptr);
61 if (token)
62 *x = strtol(token, NULL, 0);
63
64 token = strtok_r(NULL, ",", &saveptr);
65 if (token)
66 *y = strtol(token, NULL, 0);
67}
David Sodmanbbcb0522014-09-19 10:34:07 -070068
69int main(int argc, char* argv[])
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070070{
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070071 int ret;
David Sodmanbbcb0522014-09-19 10:34:07 -070072 int c;
David Sodman8ef20062015-01-06 09:23:40 -080073 int32_t x, y;
Stéphane Marchesin00ff1872015-12-14 13:40:09 -080074 splash_t* splash;
David Sodman8ef20062015-01-06 09:23:40 -080075 commandflags_t command_flags;
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070076
Douglas Anderson4da95cd2015-10-05 15:04:30 -070077 /* Handle resolution special before splash init */
78 for (;;) {
79 c = getopt_long(argc, argv, "", command_options, NULL);
80 if (c == -1) {
81 break;
82 } else if (c == FLAG_PRINT_RESOLUTION) {
83 video_t *video = video_init();
84 if (!video)
85 return EXIT_FAILURE;
86
87 printf("%d %d", video_getwidth(video),
88 video_getheight(video));
89 video_close(video);
90 return EXIT_SUCCESS;
91 }
92 }
93
94 /* Reset option parsing */
95 optind = 1;
96
Dominik Behr580462b2014-11-20 13:50:05 -080097 memset(&command_flags, 0, sizeof(command_flags));
98 command_flags.standalone = true;
David Sodmanbbcb0522014-09-19 10:34:07 -070099
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700100 ret = input_init();
101 if (ret) {
David Sodmanbbcb0522014-09-19 10:34:07 -0700102 LOG(ERROR, "Input init failed");
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700103 return EXIT_FAILURE;
104 }
105
David Sodmanbf3f2842014-11-12 08:26:58 -0800106 splash = splash_init();
David Sodmanbbcb0522014-09-19 10:34:07 -0700107 if (splash == NULL) {
108 LOG(ERROR, "splash init failed");
109 return EXIT_FAILURE;
110 }
111
112 for (;;) {
113 c = getopt_long(argc, argv, "", command_options, NULL);
114
115 if (c == -1)
116 break;
117
118 switch (c) {
119 case FLAG_CLEAR:
120 splash_set_clear(splash, strtoul(optarg, NULL, 0));
121 break;
122
123 case FLAG_DAEMON:
Dominik Behr580462b2014-11-20 13:50:05 -0800124 command_flags.standalone = false;
David Sodmanbbcb0522014-09-19 10:34:07 -0700125 break;
126
David Sodman8ef20062015-01-06 09:23:40 -0800127 case FLAG_FRAME_INTERVAL:
128 splash_set_default_duration(splash, strtoul(optarg, NULL, 0));
129 break;
130
David Sodmanbbcb0522014-09-19 10:34:07 -0700131 case FLAG_DEV_MODE:
132 splash_set_devmode(splash);
133 break;
134
Dominik Behr32a7c892015-10-09 15:47:53 -0700135 case FLAG_IMAGE:
136 if (!splash_is_hires(splash))
137 splash_add_image(splash, optarg);
138 break;
139
140 case FLAG_IMAGE_HIRES:
141 if (splash_is_hires(splash))
142 splash_add_image(splash, optarg);
143 break;
144
David Sodman8ef20062015-01-06 09:23:40 -0800145 case FLAG_LOOP_START:
146 splash_set_loop_start(splash, strtoul(optarg, NULL, 0));
147 break;
148
149 case FLAG_LOOP_INTERVAL:
150 splash_set_loop_duration(splash, strtoul(optarg, NULL, 0));
151 break;
152
153 case FLAG_LOOP_OFFSET:
154 parse_offset(optarg, &x, &y);
155 splash_set_loop_offset(splash, x, y);
156 break;
157
158 case FLAG_OFFSET:
159 parse_offset(optarg, &x, &y);
160 splash_set_offset(splash, x, y);
161 break;
David Sodmanbbcb0522014-09-19 10:34:07 -0700162 }
163 }
164
Stéphane Marchesinac14d292015-12-14 15:27:18 -0800165 for (int i = optind; i < argc; i++)
David Sodman8ef20062015-01-06 09:23:40 -0800166 splash_add_image(splash, argv[i]);
167
David Sodmanbbcb0522014-09-19 10:34:07 -0700168 /*
169 * The DBUS service launches later than the boot-splash service, and
170 * as a result, when splash_run starts dbus is not yet up, but, by
171 * the time splash_run completes, it is running. At the same time,
172 * splash_run needs dbus to determine when chrome is visible. So,
173 * it creates the dbus object and then passes it back to the caller
174 * who can then pass it to the other objects that need it
175 */
Douglas Anderson4da95cd2015-10-05 15:04:30 -0700176 if (command_flags.standalone == false) {
David Sodmanf0a925a2015-05-04 11:19:19 -0700177 splash_present_term_file(splash);
178 daemonize();
179 }
180 if (splash_num_images(splash) > 0) {
Dominik Behr797a3832016-01-11 15:53:11 -0800181 ret = splash_run(splash);
David Sodmanbbcb0522014-09-19 10:34:07 -0700182 if (ret) {
Yuly Novikov945871e2015-05-23 00:00:41 -0400183 LOG(ERROR, "splash_run failed: %d", ret);
184 return EXIT_FAILURE;
David Sodmanbbcb0522014-09-19 10:34:07 -0700185 }
186 }
David Sodmanf0a925a2015-05-04 11:19:19 -0700187 splash_destroy(splash);
David Sodmanbbcb0522014-09-19 10:34:07 -0700188
189 /*
190 * If splash_run didn't create the dbus object (for example, if
David Sodman8ef20062015-01-06 09:23:40 -0800191 * there are no splash screen images), then go ahead and create
192 * it now
David Sodmanbbcb0522014-09-19 10:34:07 -0700193 */
Dominik Behr797a3832016-01-11 15:53:11 -0800194 if (!dbus_is_initialized()) {
195 dbus_init();
David Sodmanbbcb0522014-09-19 10:34:07 -0700196 }
David Sodman8ef20062015-01-06 09:23:40 -0800197
Dominik Behr580462b2014-11-20 13:50:05 -0800198 ret = input_run(command_flags.standalone);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700199
200 input_close();
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700201
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700202 return ret;
203}