blob: 511ab90e46929a0709122eba8d1f3d9744d5adb5 [file] [log] [blame]
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -07001/*
2 * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7#include <libtsm.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <unistd.h>
David Sodmanbbcb0522014-09-19 10:34:07 -070011#include <memory.h>
12#include <getopt.h>
13#include <stdbool.h>
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070014
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070015#include "input.h"
16#include "term.h"
17#include "video.h"
David Sodmanbbcb0522014-09-19 10:34:07 -070018#include "dbus.h"
19#include "util.h"
20#include "splash.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'
27#define FLAG_PRINT_RESOLUTION 'p'
28
29static struct option command_options[] = {
30 { "clear", required_argument, NULL, FLAG_CLEAR },
31 { "daemon", no_argument, NULL, FLAG_DAEMON },
32 { "dev-mode", no_argument, NULL, FLAG_DEV_MODE },
33 { "frame-interval", required_argument, NULL, FLAG_FRAME_INTERVAL },
34 { "gamma", required_argument, NULL, FLAG_GAMMA },
35 { "print-resolution", no_argument, NULL, FLAG_PRINT_RESOLUTION },
36 { NULL, 0, NULL, 0 }
37};
38
39typedef struct {
40 bool print_resolution;
41 bool frame_interval;
42} commandflags_t;
43
44int main(int argc, char* argv[])
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070045{
Stéphane Marchesinaf4423b2014-08-13 16:39:24 -070046 int32_t width, height, pitch, scaling;
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070047 int ret;
David Sodmanbbcb0522014-09-19 10:34:07 -070048 int c;
49 int i;
50 commandflags_t flags;
51 splash_t *splash;
52 video_t *video;
53 terminal_t *terminal;
54 dbus_t *dbus;
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070055
David Sodmanbbcb0522014-09-19 10:34:07 -070056 memset(&flags, 0, sizeof(flags));
57
58 video = video_init(&width, &height, &pitch, &scaling);
59 if (video == NULL) {
60 LOG(ERROR, "Video init failed");
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070061 return EXIT_FAILURE;
62 }
63
David Sodmanbbcb0522014-09-19 10:34:07 -070064
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070065 ret = input_init();
66 if (ret) {
David Sodmanbbcb0522014-09-19 10:34:07 -070067 LOG(ERROR, "Input init failed");
68 video_close(video);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070069 return EXIT_FAILURE;
70 }
71
David Sodmanbbcb0522014-09-19 10:34:07 -070072 terminal = term_init(video);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070073 if (ret) {
David Sodmanbbcb0522014-09-19 10:34:07 -070074 LOG(ERROR, "Term init failed");
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070075 input_close();
David Sodmanbbcb0522014-09-19 10:34:07 -070076 video_close(video);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -070077 return EXIT_FAILURE;
78 }
79
David Sodmanbbcb0522014-09-19 10:34:07 -070080 splash = splash_init(video);
81 if (splash == NULL) {
82 LOG(ERROR, "splash init failed");
83 return EXIT_FAILURE;
84 }
85
86 for (;;) {
87 c = getopt_long(argc, argv, "", command_options, NULL);
88
89 if (c == -1)
90 break;
91
92 switch (c) {
93 case FLAG_CLEAR:
94 splash_set_clear(splash, strtoul(optarg, NULL, 0));
95 break;
96
97 case FLAG_DAEMON:
98 daemonize();
99 break;
100
101 case FLAG_DEV_MODE:
102 splash_set_devmode(splash);
103 break;
104
105 case FLAG_PRINT_RESOLUTION:
106 flags.print_resolution = true;
107 break;
108
109 case FLAG_GAMMA:
110 video_set_gamma(video, optarg);
111 break;
112
113 case FLAG_FRAME_INTERVAL:
114 splash_set_frame_rate(splash, strtoul(optarg, NULL, 0));
115 for (i = optind; i < argc; i++) {
116 splash_add_image(splash, argv[i]);
117 }
118 flags.frame_interval = true;
119 break;
120 }
121 }
122
123 /*
124 * The DBUS service launches later than the boot-splash service, and
125 * as a result, when splash_run starts dbus is not yet up, but, by
126 * the time splash_run completes, it is running. At the same time,
127 * splash_run needs dbus to determine when chrome is visible. So,
128 * it creates the dbus object and then passes it back to the caller
129 * who can then pass it to the other objects that need it
130 */
131 dbus = NULL;
132 if (flags.print_resolution) {
133 printf("%d %d", video_getwidth(video), video_getheight(video));
134 return EXIT_SUCCESS;
135 }
136 else if (flags.frame_interval) {
137 ret = splash_run(splash, &dbus);
138 if (ret) {
139 LOG(ERROR, "splash_run failed: %d", ret);
140 return EXIT_FAILURE;
141 }
142 }
143
144 /*
145 * If splash_run didn't create the dbus object (for example, if
146 * we didn't supply the frame-interval parameter, then go ahead
147 * and create it now
148 */
149 if (dbus == NULL) {
150 dbus = dbus_init();
151 }
152
153 input_set_dbus(dbus);
154 term_set_dbus(terminal, dbus);
155
156 ret = term_run(terminal);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700157
158 input_close();
David Sodmanbbcb0522014-09-19 10:34:07 -0700159 term_close(terminal);
160 video_close(video);
Stéphane Marchesinae37e6c2014-08-08 18:19:40 -0700161
162 return ret;
163}