blob: d3e9f83195f570ebdd2198e8899f729be5c2773c [file] [log] [blame]
Sami Tolvanena0f13e02015-02-19 10:44:12 +00001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <unistd.h>
18#include <stdlib.h>
19#include <limits.h>
20#include <time.h>
21#include <linux/input.h>
Tao Baoebc30882017-01-20 08:55:20 -080022
23#include <functional>
24
Sami Tolvanena0f13e02015-02-19 10:44:12 +000025#include <cutils/klog.h>
Tao Baoebc30882017-01-20 08:55:20 -080026#include <minui/minui.h>
Johan Redestigc38026b2015-10-12 10:24:30 +020027#include <utils/SystemClock.h>
Sami Tolvanena0f13e02015-02-19 10:44:12 +000028
29#define NEXT_TIMEOUT_MS 5000
Johan Redestigc38026b2015-10-12 10:24:30 +020030#define LAST_TIMEOUT_MS 30000
Sami Tolvanena0f13e02015-02-19 10:44:12 +000031
32#define LOGE(x...) do { KLOG_ERROR("slideshow", x); } while (0)
33
Tao Baoebc30882017-01-20 08:55:20 -080034static int input_cb(int fd, unsigned int epevents, int *key_code)
Sami Tolvanena0f13e02015-02-19 10:44:12 +000035{
36 struct input_event ev;
Sami Tolvanena0f13e02015-02-19 10:44:12 +000037
38 *key_code = -1;
39
40 if (ev_get_input(fd, epevents, &ev)) {
41 return -1;
42 }
43
Johan Redestig44fec942015-10-09 09:54:57 +020044 if (ev.type == EV_KEY && ev.value == 1) {
Sami Tolvanena0f13e02015-02-19 10:44:12 +000045 *key_code = ev.code;
46 }
47
48 return 0;
49}
50
51static void clear()
52{
53 gr_color(0, 0, 0, 0);
54 gr_clear();
55 gr_flip();
56}
57
58static void draw(const char *resname)
59{
Elliott Hughes99e2aca2015-04-15 10:23:15 -070060 GRSurface* surface;
Sami Tolvanena0f13e02015-02-19 10:44:12 +000061 int w, h, x, y;
62
63 if (res_create_display_surface(resname, &surface) < 0) {
64 LOGE("failed to create surface for %s\n", resname);
65 return;
66 }
67
68 w = gr_get_width(surface);
69 h = gr_get_height(surface);
70 x = (gr_fb_width() - w) / 2;
71 y = (gr_fb_height() - h) / 2;
72
73 gr_blit(surface, 0, 0, w, h, x, y);
74 gr_flip();
75
76 res_free_surface(surface);
77}
78
79int usage()
80{
81 LOGE("usage: slideshow [-t timeout] image.png [image2.png ...] last.png\n");
82 return EXIT_FAILURE;
83}
84
85int main(int argc, char **argv)
86{
87 int key_code = -1;
88 int input = false;
89 int opt;
90 long int timeout = NEXT_TIMEOUT_MS;
Johan Redestigc38026b2015-10-12 10:24:30 +020091 int64_t start;
Sami Tolvanena0f13e02015-02-19 10:44:12 +000092
Johan Redestig4ef1adc2015-10-09 10:37:37 +020093 while ((opt = getopt(argc, argv, "t:")) != -1) {
Sami Tolvanena0f13e02015-02-19 10:44:12 +000094 switch (opt) {
95 case 't':
96 timeout = strtol(optarg, NULL, 0);
97
98 if (timeout < 0 || timeout >= LONG_MAX) {
99 timeout = NEXT_TIMEOUT_MS;
Sami Tolvanen5b97aa62015-04-01 17:53:41 +0100100 LOGE("invalid timeout %s, defaulting to %ld\n", optarg,
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000101 timeout);
102 }
103 break;
104 default:
105 return usage();
106 }
107 }
108
109 if (optind >= argc) {
110 return usage();
111 }
112
Tao Baoebc30882017-01-20 08:55:20 -0800113 if (gr_init() == -1 || ev_init(std::bind(&input_cb, std::placeholders::_1,
114 std::placeholders::_2, &key_code)) == -1) {
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000115 LOGE("failed to initialize minui\n");
116 return EXIT_FAILURE;
117 }
118
119 /* display all images except the last one, switch to next image after
120 * timeout or user input */
121
122 while (optind < argc - 1) {
123 draw(argv[optind++]);
124
Johan Redestigc38026b2015-10-12 10:24:30 +0200125 start = android::uptimeMillis();
Johan Redestig810ae482015-10-09 13:25:39 +0200126 long int timeout_remaining = timeout;
127 do {
128 if (ev_wait(timeout_remaining) == 0) {
129 ev_dispatch();
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000130
Johan Redestig810ae482015-10-09 13:25:39 +0200131 if (key_code != -1) {
132 input = true;
133 break;
134 }
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000135 }
Johan Redestigc38026b2015-10-12 10:24:30 +0200136 timeout_remaining -= android::uptimeMillis() - start;
Johan Redestig810ae482015-10-09 13:25:39 +0200137 } while (timeout_remaining > 0);
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000138 };
139
140 /* if there was user input while showing the images, display the last
Johan Redestigc38026b2015-10-12 10:24:30 +0200141 * image and wait until the power button is pressed or LAST_TIMEOUT_MS
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000142 * has elapsed */
143
144 if (input) {
Johan Redestigc38026b2015-10-12 10:24:30 +0200145 start = android::uptimeMillis();
146
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000147 draw(argv[optind]);
148
149 do {
150 if (ev_wait(timeout) == 0) {
151 ev_dispatch();
152 }
153
Johan Redestigc38026b2015-10-12 10:24:30 +0200154 if (android::uptimeMillis() - start >= LAST_TIMEOUT_MS) {
Sami Tolvanena0f13e02015-02-19 10:44:12 +0000155 break;
156 }
157 } while (key_code != KEY_POWER);
158 }
159
160 clear();
161 gr_exit();
162 ev_exit();
163
164 return EXIT_SUCCESS;
165}