blob: ff0e196f6a168bf56eacc08a726ed82598f3efd4 [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"
19#include "video.h"
David Sodmanbbcb0522014-09-19 10:34:07 -070020#include "util.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'
David Sodman8ef20062015-01-06 09:23:40 -080027#define FLAG_LOOP_START 'l'
28#define FLAG_LOOP_INTERVAL 'L'
29#define FLAG_LOOP_OFFSET 'o'
30#define FLAG_OFFSET 'O'
David Sodmanbbcb0522014-09-19 10:34:07 -070031#define FLAG_PRINT_RESOLUTION 'p'
32
33static struct option command_options[] = {
34 { "clear", required_argument, NULL, FLAG_CLEAR },
35 { "daemon", no_argument, NULL, FLAG_DAEMON },
36 { "dev-mode", no_argument, NULL, FLAG_DEV_MODE },
37 { "frame-interval", required_argument, NULL, FLAG_FRAME_INTERVAL },
38 { "gamma", required_argument, NULL, FLAG_GAMMA },
David Sodman8ef20062015-01-06 09:23:40 -080039 { "loop-start", required_argument, NULL, FLAG_LOOP_START },
40 { "loop-interval", required_argument, NULL, FLAG_LOOP_INTERVAL },
41 { "loop-offset", required_argument, NULL, FLAG_LOOP_OFFSET },
42 { "offset", required_argument, NULL, FLAG_OFFSET },
David Sodmanbbcb0522014-09-19 10:34:07 -070043 { "print-resolution", no_argument, NULL, FLAG_PRINT_RESOLUTION },
44 { NULL, 0, NULL, 0 }
45};
46
David Sodman8ef20062015-01-06 09:23:40 -080047typedef struct {
48 bool print_resolution;
49 bool standalone;
David Sodman8ef20062015-01-06 09:23:40 -080050} commandflags_t;
Dominik Behr580462b2014-11-20 13:50:05 -080051
David Sodman8ef20062015-01-06 09:23:40 -080052static
53void parse_offset(char* param, int32_t* x, int32_t* y)
54{
55 char* token;
56 char* saveptr;
57
58 token = strtok_r(param, ",", &saveptr);
59 if (token)
60 *x = strtol(token, NULL, 0);
61
62 token = strtok_r(NULL, ",", &saveptr);
63 if (token)
64 *y = strtol(token, NULL, 0);
65}
David Sodmanbbcb0522014-09-19 10:34:07 -070066
67int main(int argc, char* argv[])
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070068{
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070069 int ret;
David Sodmanbbcb0522014-09-19 10:34:07 -070070 int c;
71 int i;
David Sodman8ef20062015-01-06 09:23:40 -080072 int32_t x, y;
David Sodmanbbcb0522014-09-19 10:34:07 -070073 splash_t *splash;
74 video_t *video;
David Sodmanbbcb0522014-09-19 10:34:07 -070075 dbus_t *dbus;
David Sodman8ef20062015-01-06 09:23:40 -080076 commandflags_t command_flags;
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070077
Dominik Behr580462b2014-11-20 13:50:05 -080078 memset(&command_flags, 0, sizeof(command_flags));
79 command_flags.standalone = true;
David Sodmanbbcb0522014-09-19 10:34:07 -070080
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070081 ret = input_init();
82 if (ret) {
David Sodmanbbcb0522014-09-19 10:34:07 -070083 LOG(ERROR, "Input init failed");
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070084 return EXIT_FAILURE;
85 }
86
David Sodmanbf3f2842014-11-12 08:26:58 -080087 splash = splash_init();
David Sodmanbbcb0522014-09-19 10:34:07 -070088 if (splash == NULL) {
89 LOG(ERROR, "splash init failed");
90 return EXIT_FAILURE;
91 }
92
93 for (;;) {
94 c = getopt_long(argc, argv, "", command_options, NULL);
95
96 if (c == -1)
97 break;
98
99 switch (c) {
100 case FLAG_CLEAR:
101 splash_set_clear(splash, strtoul(optarg, NULL, 0));
102 break;
103
104 case FLAG_DAEMON:
Dominik Behr580462b2014-11-20 13:50:05 -0800105 command_flags.standalone = false;
David Sodmanbbcb0522014-09-19 10:34:07 -0700106 break;
107
David Sodman8ef20062015-01-06 09:23:40 -0800108 case FLAG_FRAME_INTERVAL:
109 splash_set_default_duration(splash, strtoul(optarg, NULL, 0));
110 break;
111
David Sodmanbbcb0522014-09-19 10:34:07 -0700112 case FLAG_DEV_MODE:
113 splash_set_devmode(splash);
114 break;
115
David Sodman8ef20062015-01-06 09:23:40 -0800116 case FLAG_LOOP_START:
117 splash_set_loop_start(splash, strtoul(optarg, NULL, 0));
118 break;
119
120 case FLAG_LOOP_INTERVAL:
121 splash_set_loop_duration(splash, strtoul(optarg, NULL, 0));
122 break;
123
124 case FLAG_LOOP_OFFSET:
125 parse_offset(optarg, &x, &y);
126 splash_set_loop_offset(splash, x, y);
127 break;
128
129 case FLAG_OFFSET:
130 parse_offset(optarg, &x, &y);
131 splash_set_offset(splash, x, y);
132 break;
133
David Sodmanbbcb0522014-09-19 10:34:07 -0700134 case FLAG_PRINT_RESOLUTION:
Dominik Behr580462b2014-11-20 13:50:05 -0800135 command_flags.print_resolution = true;
David Sodmanbbcb0522014-09-19 10:34:07 -0700136 break;
David Sodmanbbcb0522014-09-19 10:34:07 -0700137 }
138 }
139
David Sodman8ef20062015-01-06 09:23:40 -0800140 for (i = optind; i < argc; i++)
141 splash_add_image(splash, argv[i]);
142
David Sodmanbbcb0522014-09-19 10:34:07 -0700143 /*
144 * The DBUS service launches later than the boot-splash service, and
145 * as a result, when splash_run starts dbus is not yet up, but, by
146 * the time splash_run completes, it is running. At the same time,
147 * splash_run needs dbus to determine when chrome is visible. So,
148 * it creates the dbus object and then passes it back to the caller
149 * who can then pass it to the other objects that need it
150 */
151 dbus = NULL;
Dominik Behr580462b2014-11-20 13:50:05 -0800152 if (command_flags.print_resolution) {
David Sodmanbf3f2842014-11-12 08:26:58 -0800153 video = video_init();
Yuly Novikov945871e2015-05-23 00:00:41 -0400154 if (!video)
155 return EXIT_FAILURE;
156
David Sodmanbbcb0522014-09-19 10:34:07 -0700157 printf("%d %d", video_getwidth(video), video_getheight(video));
158 return EXIT_SUCCESS;
159 }
David Sodmanf0a925a2015-05-04 11:19:19 -0700160 else if (command_flags.standalone == false) {
161 splash_present_term_file(splash);
162 daemonize();
163 }
164 if (splash_num_images(splash) > 0) {
David Sodmanbbcb0522014-09-19 10:34:07 -0700165 ret = splash_run(splash, &dbus);
166 if (ret) {
Yuly Novikov945871e2015-05-23 00:00:41 -0400167 LOG(ERROR, "splash_run failed: %d", ret);
168 return EXIT_FAILURE;
David Sodmanbbcb0522014-09-19 10:34:07 -0700169 }
170 }
David Sodmanf0a925a2015-05-04 11:19:19 -0700171 splash_destroy(splash);
David Sodmanbbcb0522014-09-19 10:34:07 -0700172
173 /*
174 * If splash_run didn't create the dbus object (for example, if
David Sodman8ef20062015-01-06 09:23:40 -0800175 * there are no splash screen images), then go ahead and create
176 * it now
David Sodmanbbcb0522014-09-19 10:34:07 -0700177 */
178 if (dbus == NULL) {
179 dbus = dbus_init();
180 }
David Sodmanbbcb0522014-09-19 10:34:07 -0700181 input_set_dbus(dbus);
David Sodman8ef20062015-01-06 09:23:40 -0800182
Dominik Behr580462b2014-11-20 13:50:05 -0800183 ret = input_run(command_flags.standalone);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700184
185 input_close();
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700186
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700187 return ret;
188}