xref: /aosp_15_r20/system/extras/slideshow/slideshow.cpp (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
18*288bf522SAndroid Build Coastguard Worker #include <stdlib.h>
19*288bf522SAndroid Build Coastguard Worker #include <limits.h>
20*288bf522SAndroid Build Coastguard Worker #include <time.h>
21*288bf522SAndroid Build Coastguard Worker #include <linux/input.h>
22*288bf522SAndroid Build Coastguard Worker 
23*288bf522SAndroid Build Coastguard Worker #include <functional>
24*288bf522SAndroid Build Coastguard Worker 
25*288bf522SAndroid Build Coastguard Worker #include <cutils/klog.h>
26*288bf522SAndroid Build Coastguard Worker #include <minui/minui.h>
27*288bf522SAndroid Build Coastguard Worker #include <utils/SystemClock.h>
28*288bf522SAndroid Build Coastguard Worker 
29*288bf522SAndroid Build Coastguard Worker #define NEXT_TIMEOUT_MS 5000
30*288bf522SAndroid Build Coastguard Worker #define LAST_TIMEOUT_MS 30000
31*288bf522SAndroid Build Coastguard Worker 
32*288bf522SAndroid Build Coastguard Worker #define LOGE(x...) do { KLOG_ERROR("slideshow", x); } while (0)
33*288bf522SAndroid Build Coastguard Worker 
input_cb(int fd,unsigned int epevents,int * key_code)34*288bf522SAndroid Build Coastguard Worker static int input_cb(int fd, unsigned int epevents, int *key_code)
35*288bf522SAndroid Build Coastguard Worker {
36*288bf522SAndroid Build Coastguard Worker     struct input_event ev;
37*288bf522SAndroid Build Coastguard Worker 
38*288bf522SAndroid Build Coastguard Worker     *key_code = -1;
39*288bf522SAndroid Build Coastguard Worker 
40*288bf522SAndroid Build Coastguard Worker     if (ev_get_input(fd, epevents, &ev)) {
41*288bf522SAndroid Build Coastguard Worker         return -1;
42*288bf522SAndroid Build Coastguard Worker     }
43*288bf522SAndroid Build Coastguard Worker 
44*288bf522SAndroid Build Coastguard Worker     if (ev.type == EV_KEY && ev.value == 1) {
45*288bf522SAndroid Build Coastguard Worker         *key_code = ev.code;
46*288bf522SAndroid Build Coastguard Worker     }
47*288bf522SAndroid Build Coastguard Worker 
48*288bf522SAndroid Build Coastguard Worker     return 0;
49*288bf522SAndroid Build Coastguard Worker }
50*288bf522SAndroid Build Coastguard Worker 
clear()51*288bf522SAndroid Build Coastguard Worker static void clear()
52*288bf522SAndroid Build Coastguard Worker {
53*288bf522SAndroid Build Coastguard Worker     gr_color(0, 0, 0, 0);
54*288bf522SAndroid Build Coastguard Worker     gr_clear();
55*288bf522SAndroid Build Coastguard Worker     gr_flip();
56*288bf522SAndroid Build Coastguard Worker }
57*288bf522SAndroid Build Coastguard Worker 
draw(const char * resname)58*288bf522SAndroid Build Coastguard Worker static void draw(const char *resname)
59*288bf522SAndroid Build Coastguard Worker {
60*288bf522SAndroid Build Coastguard Worker     GRSurface* surface;
61*288bf522SAndroid Build Coastguard Worker     int w, h, x, y;
62*288bf522SAndroid Build Coastguard Worker 
63*288bf522SAndroid Build Coastguard Worker     if (res_create_display_surface(resname, &surface) < 0) {
64*288bf522SAndroid Build Coastguard Worker         LOGE("failed to create surface for %s\n", resname);
65*288bf522SAndroid Build Coastguard Worker         return;
66*288bf522SAndroid Build Coastguard Worker     }
67*288bf522SAndroid Build Coastguard Worker 
68*288bf522SAndroid Build Coastguard Worker     w = gr_get_width(surface);
69*288bf522SAndroid Build Coastguard Worker     h = gr_get_height(surface);
70*288bf522SAndroid Build Coastguard Worker     x = (gr_fb_width() - w) / 2;
71*288bf522SAndroid Build Coastguard Worker     y = (gr_fb_height() - h) / 2;
72*288bf522SAndroid Build Coastguard Worker 
73*288bf522SAndroid Build Coastguard Worker     gr_blit(surface, 0, 0, w, h, x, y);
74*288bf522SAndroid Build Coastguard Worker     gr_flip();
75*288bf522SAndroid Build Coastguard Worker 
76*288bf522SAndroid Build Coastguard Worker     res_free_surface(surface);
77*288bf522SAndroid Build Coastguard Worker }
78*288bf522SAndroid Build Coastguard Worker 
usage()79*288bf522SAndroid Build Coastguard Worker int usage()
80*288bf522SAndroid Build Coastguard Worker {
81*288bf522SAndroid Build Coastguard Worker     LOGE("usage: slideshow [-t timeout] image.png [image2.png ...] last.png\n");
82*288bf522SAndroid Build Coastguard Worker     return EXIT_FAILURE;
83*288bf522SAndroid Build Coastguard Worker }
84*288bf522SAndroid Build Coastguard Worker 
main(int argc,char ** argv)85*288bf522SAndroid Build Coastguard Worker int main(int argc, char **argv)
86*288bf522SAndroid Build Coastguard Worker {
87*288bf522SAndroid Build Coastguard Worker     int key_code = -1;
88*288bf522SAndroid Build Coastguard Worker     int input = false;
89*288bf522SAndroid Build Coastguard Worker     int opt;
90*288bf522SAndroid Build Coastguard Worker     long int timeout = NEXT_TIMEOUT_MS;
91*288bf522SAndroid Build Coastguard Worker     int64_t start;
92*288bf522SAndroid Build Coastguard Worker 
93*288bf522SAndroid Build Coastguard Worker     while ((opt = getopt(argc, argv, "t:")) != -1) {
94*288bf522SAndroid Build Coastguard Worker         switch (opt) {
95*288bf522SAndroid Build Coastguard Worker         case 't':
96*288bf522SAndroid Build Coastguard Worker             timeout = strtol(optarg, NULL, 0);
97*288bf522SAndroid Build Coastguard Worker 
98*288bf522SAndroid Build Coastguard Worker             if (timeout < 0 || timeout >= LONG_MAX) {
99*288bf522SAndroid Build Coastguard Worker                 timeout = NEXT_TIMEOUT_MS;
100*288bf522SAndroid Build Coastguard Worker                 LOGE("invalid timeout %s, defaulting to %ld\n", optarg,
101*288bf522SAndroid Build Coastguard Worker                     timeout);
102*288bf522SAndroid Build Coastguard Worker             }
103*288bf522SAndroid Build Coastguard Worker             break;
104*288bf522SAndroid Build Coastguard Worker         default:
105*288bf522SAndroid Build Coastguard Worker             return usage();
106*288bf522SAndroid Build Coastguard Worker         }
107*288bf522SAndroid Build Coastguard Worker     }
108*288bf522SAndroid Build Coastguard Worker 
109*288bf522SAndroid Build Coastguard Worker     if (optind >= argc) {
110*288bf522SAndroid Build Coastguard Worker         return usage();
111*288bf522SAndroid Build Coastguard Worker     }
112*288bf522SAndroid Build Coastguard Worker 
113*288bf522SAndroid Build Coastguard Worker     if (gr_init() == -1 || ev_init(std::bind(&input_cb, std::placeholders::_1,
114*288bf522SAndroid Build Coastguard Worker                                              std::placeholders::_2, &key_code)) == -1) {
115*288bf522SAndroid Build Coastguard Worker         LOGE("failed to initialize minui\n");
116*288bf522SAndroid Build Coastguard Worker         return EXIT_FAILURE;
117*288bf522SAndroid Build Coastguard Worker     }
118*288bf522SAndroid Build Coastguard Worker 
119*288bf522SAndroid Build Coastguard Worker     /* display all images except the last one, switch to next image after
120*288bf522SAndroid Build Coastguard Worker      * timeout or user input */
121*288bf522SAndroid Build Coastguard Worker 
122*288bf522SAndroid Build Coastguard Worker     while (optind < argc - 1) {
123*288bf522SAndroid Build Coastguard Worker         draw(argv[optind++]);
124*288bf522SAndroid Build Coastguard Worker 
125*288bf522SAndroid Build Coastguard Worker         start = android::uptimeMillis();
126*288bf522SAndroid Build Coastguard Worker         long int timeout_remaining = timeout;
127*288bf522SAndroid Build Coastguard Worker         do {
128*288bf522SAndroid Build Coastguard Worker             if (ev_wait(timeout_remaining) == 0) {
129*288bf522SAndroid Build Coastguard Worker                 ev_dispatch();
130*288bf522SAndroid Build Coastguard Worker 
131*288bf522SAndroid Build Coastguard Worker                 if (key_code != -1) {
132*288bf522SAndroid Build Coastguard Worker                     input = true;
133*288bf522SAndroid Build Coastguard Worker                     break;
134*288bf522SAndroid Build Coastguard Worker                 }
135*288bf522SAndroid Build Coastguard Worker             }
136*288bf522SAndroid Build Coastguard Worker             timeout_remaining -= android::uptimeMillis() - start;
137*288bf522SAndroid Build Coastguard Worker         } while (timeout_remaining > 0);
138*288bf522SAndroid Build Coastguard Worker     };
139*288bf522SAndroid Build Coastguard Worker 
140*288bf522SAndroid Build Coastguard Worker     /* if there was user input while showing the images, display the last
141*288bf522SAndroid Build Coastguard Worker      * image and wait until the power button is pressed or LAST_TIMEOUT_MS
142*288bf522SAndroid Build Coastguard Worker      * has elapsed */
143*288bf522SAndroid Build Coastguard Worker 
144*288bf522SAndroid Build Coastguard Worker     if (input) {
145*288bf522SAndroid Build Coastguard Worker         start = android::uptimeMillis();
146*288bf522SAndroid Build Coastguard Worker 
147*288bf522SAndroid Build Coastguard Worker         draw(argv[optind]);
148*288bf522SAndroid Build Coastguard Worker 
149*288bf522SAndroid Build Coastguard Worker         do {
150*288bf522SAndroid Build Coastguard Worker             if (ev_wait(timeout) == 0) {
151*288bf522SAndroid Build Coastguard Worker                 ev_dispatch();
152*288bf522SAndroid Build Coastguard Worker             }
153*288bf522SAndroid Build Coastguard Worker 
154*288bf522SAndroid Build Coastguard Worker             if (android::uptimeMillis() - start >= LAST_TIMEOUT_MS) {
155*288bf522SAndroid Build Coastguard Worker                 break;
156*288bf522SAndroid Build Coastguard Worker             }
157*288bf522SAndroid Build Coastguard Worker         } while (key_code != KEY_POWER);
158*288bf522SAndroid Build Coastguard Worker     }
159*288bf522SAndroid Build Coastguard Worker 
160*288bf522SAndroid Build Coastguard Worker     clear();
161*288bf522SAndroid Build Coastguard Worker     gr_exit();
162*288bf522SAndroid Build Coastguard Worker     ev_exit();
163*288bf522SAndroid Build Coastguard Worker 
164*288bf522SAndroid Build Coastguard Worker     return EXIT_SUCCESS;
165*288bf522SAndroid Build Coastguard Worker }
166