summaryrefslogtreecommitdiff
path: root/rbutil/ibassoboot/jni/ibassodualboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/ibassoboot/jni/ibassodualboot.c')
-rw-r--r--rbutil/ibassoboot/jni/ibassodualboot.c439
1 files changed, 439 insertions, 0 deletions
diff --git a/rbutil/ibassoboot/jni/ibassodualboot.c b/rbutil/ibassoboot/jni/ibassodualboot.c
new file mode 100644
index 0000000000..3f20bbeecf
--- /dev/null
+++ b/rbutil/ibassoboot/jni/ibassodualboot.c
@@ -0,0 +1,439 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Ilia Sergachev
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <dirent.h>
23#include <errno.h>
24#include <fcntl.h>
25
26#include <linux/fb.h>
27#include <linux/input.h>
28#include <linux/reboot.h>
29
30#include <stdbool.h>
31#include <string.h>
32#include <stdint.h>
33#include <stdio.h>
34#include <stdlib.h>
35
36#include <time.h>
37
38#include <sys/limits.h>
39#include <sys/mman.h>
40#include <sys/inotify.h>
41#include <sys/ioctl.h>
42#include <sys/poll.h>
43#include <sys/stat.h>
44#include <sys/time.h>
45#include <sys/types.h>
46
47#include <unistd.h>
48
49#include "qdbmp.h"
50
51
52#define MIN_TIME 1395606821
53#define TIME_FILE "/data/time_store"
54#define TIME_CHECK_PERIOD 60 /* seconds */
55#define VOLD_LINK "/data/vold"
56#define PLAYER_FILE "/data/chosen_player"
57#define NOASK_FLAG "/data/no_ask_once"
58#define POLL_MS 10
59
60
61#define KEYCODE_HEADPHONES 114
62#define KEYCODE_HOLD 115
63#define KEYCODE_PWR 116
64#define KEYCODE_PWR_LONG 117
65#define KEYCODE_SD 143
66#define KEYCODE_VOLPLUS 158
67#define KEYCODE_VOLMINUS 159
68#define KEYCODE_PREV 160
69#define KEYCODE_NEXT 162
70#define KEYCODE_PLAY 161
71
72#define KEY_HOLD_OFF 16
73
74void checktime()
75{
76 time_t t_stored=0, t_current=time(NULL);
77
78 FILE *f = fopen(TIME_FILE, "r");
79 if(f!=NULL)
80 {
81 fscanf(f, "%ld", &t_stored);
82 fclose(f);
83 }
84
85 printf("stored time: %ld, current time: %ld\n", t_stored, t_current);
86
87 if(t_stored<MIN_TIME)
88 t_stored=MIN_TIME;
89
90 if(t_stored<t_current)
91 {
92 f = fopen(TIME_FILE, "w");
93 fprintf(f, "%ld", t_current);
94 fclose(f);
95 }
96 else
97 {
98 t_stored += TIME_CHECK_PERIOD;
99 struct tm *t = localtime(&t_stored);
100 struct timeval tv = {mktime(t), 0};
101 settimeofday(&tv, 0);
102 }
103}
104
105
106static struct pollfd *ufds;
107static char **device_names;
108static int nfds;
109
110
111
112static int open_device(const char *device, int print_flags)
113{
114 int fd;
115 struct pollfd *new_ufds;
116 char **new_device_names;
117
118 fd = open(device, O_RDWR);
119 if(fd < 0)
120 {
121 fprintf(stderr, "could not open %s, %s\n", device, strerror(errno));
122 return -1;
123 }
124
125 new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1));
126 if(new_ufds == NULL)
127 {
128 fprintf(stderr, "out of memory\n");
129 return -1;
130 }
131 ufds = new_ufds;
132 new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1));
133 if(new_device_names == NULL)
134 {
135 fprintf(stderr, "out of memory\n");
136 return -1;
137 }
138 device_names = new_device_names;
139
140 ufds[nfds].fd = fd;
141 ufds[nfds].events = POLLIN;
142 device_names[nfds] = strdup(device);
143 nfds++;
144
145 return 0;
146}
147
148
149
150static int scan_dir(const char *dirname, int print_flags)
151{
152 char devname[PATH_MAX];
153 char *filename;
154 DIR *dir;
155 struct dirent *de;
156 dir = opendir(dirname);
157 if(dir == NULL)
158 return -1;
159 strcpy(devname, dirname);
160 filename = devname + strlen(devname);
161 *filename++ = '/';
162 while((de = readdir(dir)))
163 {
164 if(de->d_name[0] == '.' &&
165 (de->d_name[1] == '\0' ||
166 (de->d_name[1] == '.' && de->d_name[2] == '\0')))
167 continue;
168 strcpy(filename, de->d_name);
169 open_device(devname, print_flags);
170 }
171 closedir(dir);
172 return 0;
173}
174
175
176
177void button_init_device(void)
178{
179 int res;
180 int print_flags = 0;
181 const char *device = NULL;
182 const char *device_path = "/dev/input";
183
184 nfds = 1;
185 ufds = calloc(1, sizeof(ufds[0]));
186 ufds[0].fd = inotify_init();
187 ufds[0].events = POLLIN;
188 if(device)
189 {
190 res = open_device(device, print_flags);
191 if(res < 0) {
192 fprintf(stderr, "open device failed\n");
193 }
194 }
195 else
196 {
197 res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
198 if(res < 0)
199 {
200 fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno));
201 }
202 res = scan_dir(device_path, print_flags);
203 if(res < 0)
204 {
205 fprintf(stderr, "scan dir failed for %s\n", device_path);
206 }
207 }
208}
209
210
211int draw()
212{
213 int fbfd = 0;
214 struct fb_var_screeninfo vinfo;
215 struct fb_fix_screeninfo finfo;
216 long int screensize = 0;
217 char *fbp = 0;
218 int x = 0, y = 0;
219 long int location = 0;
220
221 /* Open the file for reading and writing */
222 fbfd = open("/dev/graphics/fb0", O_RDWR);
223 if (fbfd == -1)
224 {
225 perror("Error: cannot open framebuffer device");
226 exit(1);
227 }
228 /* Get fixed screen information */
229 if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1)
230 {
231 perror("Error reading fixed information");
232 exit(2);
233 }
234
235 /* Get variable screen information */
236 if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1)
237 {
238 perror("Error reading variable information");
239 exit(3);
240 }
241
242 /* Figure out the size of the screen in bytes */
243 screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
244
245 vinfo.xres = vinfo.xres_virtual = vinfo.width = 320;
246 vinfo.yres = vinfo.yres_virtual = vinfo.height = 240;
247 vinfo.xoffset = vinfo.yoffset = vinfo.sync = vinfo.vmode = 0;
248 vinfo.pixclock = 104377;
249 vinfo.left_margin = 20;
250 vinfo.right_margin = 50;
251 vinfo.upper_margin = 2;
252 vinfo.lower_margin = 4;
253 vinfo.hsync_len = 10;
254 vinfo.vsync_len = 2;
255 vinfo.red.offset = 11;
256 vinfo.red.length = 5;
257 vinfo.red.msb_right = 0;
258 vinfo.green.offset = 5;
259 vinfo.green.length = 6;
260 vinfo.green.msb_right = 0;
261 vinfo.blue.offset = 0;
262 vinfo.blue.length = 5;
263 vinfo.blue.msb_right = 0;
264 vinfo.transp.offset = vinfo.transp.length = vinfo.transp.msb_right = 0;
265 vinfo.nonstd = 4;
266
267 if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo))
268 {
269 perror("fbset(ioctl)");
270 exit(4);
271 }
272
273
274 /* Map the device to memory */
275 fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
276 fbfd, 0);
277 if ((int)fbp == -1)
278 {
279 perror("Error: failed to map framebuffer device to memory");
280 exit(4);
281 }
282
283 BMP* bmp = BMP_ReadFile("/system/rockbox/chooser.bmp");
284 BMP_CHECK_ERROR( stderr, -1 );
285
286 UCHAR r, g, b;
287 unsigned short int t;
288
289 for (y = 0; y < 240; y++)
290 for (x = 0; x < 320; x++)
291 {
292 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
293 (y+vinfo.yoffset) * finfo.line_length;
294
295 BMP_GetPixelRGB(bmp, x, y, &r, &g, &b);
296 t = (r>>3)<<11 | (g>>2) << 5 | (b>>3);
297 *((unsigned short int*)(fbp + location)) = t;
298 }
299
300 BMP_Free( bmp );
301
302 munmap(fbp, screensize);
303 close(fbfd);
304 return 0;
305}
306
307
308int choose_player()
309{
310 int i;
311 int res;
312 struct input_event event;
313
314 while(true)
315 {
316 poll(ufds, nfds, POLL_MS);
317 for(i = 1; i < nfds; i++)
318 {
319 if(ufds[i].revents & POLLIN)
320 {
321 res = read(ufds[i].fd, &event, sizeof(event));
322 if(res < (int)sizeof(event))
323 {
324 fprintf(stderr, "could not get event\n");
325 }
326 if(event.type==1)
327 {
328 if(event.code==KEYCODE_NEXT)
329 {
330 puts("rockbox!");
331 return 1;
332 }
333 else if(event.code==KEYCODE_PREV)
334 {
335 puts("mango!");
336 return 0;
337 }
338 else if(event.code==KEYCODE_PWR || event.code==KEYCODE_PWR_LONG)
339 {
340 reboot(LINUX_REBOOT_CMD_POWER_OFF);
341 }
342 }
343 else if(event.type==3)
344 {
345 if(event.code==53) //x coord
346 {
347 if(event.value<160)
348 {
349 puts("mango!");
350 return 0;
351 }
352 else
353 {
354 puts("rockbox!");
355 return 1;
356 }
357 }
358 }
359 }
360 }
361 }
362 return true;
363}
364
365bool check_for_hold()
366{
367 FILE *f = fopen("/sys/class/axppower/holdkey", "r");
368 char x;
369 fscanf(f, "%c", &x);
370 fclose(f);
371
372 if(x & KEY_HOLD_OFF)
373 return false;
374 else
375 return true;
376}
377
378int main(int argc, char **argv)
379{
380 FILE *f;
381 int last_chosen_player = -1;
382
383 f = fopen(PLAYER_FILE, "r");
384 if(f!=NULL)
385 {
386 fscanf(f, "%d", &last_chosen_player);
387 fclose(f);
388 }
389 bool ask = (access(VOLD_LINK, F_OK) == -1) || ((access(NOASK_FLAG, F_OK) == -1) && check_for_hold()) || (last_chosen_player==-1);
390
391 if(ask)
392 {
393 draw();
394 button_init_device();
395 int player_chosen_now = choose_player();
396
397 if(last_chosen_player!=player_chosen_now)
398 {
399 f = fopen(PLAYER_FILE, "w");
400 fprintf(f, "%d", player_chosen_now);
401 fclose(f);
402 }
403
404 if(last_chosen_player!=player_chosen_now || (access(VOLD_LINK, F_OK) == -1))
405 {
406 system("rm "VOLD_LINK);
407
408 if(player_chosen_now)
409 system("ln -s /system/bin/vold_rockbox "VOLD_LINK);
410 else
411 system("ln -s /system/bin/vold_original "VOLD_LINK);
412
413 system("touch "NOASK_FLAG);
414 system("reboot");
415 }
416 last_chosen_player = player_chosen_now;
417 }
418
419 system("rm "NOASK_FLAG);
420
421 while(1)
422 {
423 if(last_chosen_player)
424 {
425// system("/system/bin/openadb");
426 system("/system/rockbox/lib/rockbox");
427 }
428 else
429// system("/system/bin/closeadb");
430 system("/system/bin/MangoPlayer_original");
431
432 sleep(1);
433 }
434
435 return 0;
436}
437
438
439