Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

bootloader: Consolidate xDuoo X3ii/X20 and AGPTek Rocker bootloaders

Bonus changes:

* boot mode selection stored on SD card

Change-Id: I225a06d149ae71c1882f632c30d0fe4ab5308a74

+50 -581
+1 -3
bootloader/SOURCES
··· 76 76 mpio_hd200_hd300.c 77 77 #elif defined(SONY_NWZ_LINUX) 78 78 nwz_linux.c 79 - #elif defined(AGPTEK_ROCKER) 79 + #elif defined(AGPTEK_ROCKER) || defined(XDUOO_X3II) || defined(XDUOO_X20) 80 80 rocker_linux.c 81 - #elif (defined(XDUOO_X3II) || defined(XDUOO_X20)) 82 - xduoo_linux.c 83 81 #elif defined(RK27_GENERIC) || defined(HM60X) || defined(HM801) \ 84 82 || defined(MA9) || defined(MA9C) || defined(MA8) || defined(MA8C) \ 85 83 || defined(IHIFI760) || defined(IHIFI960) || defined(IHIFI800) \
+49 -23
bootloader/rocker_linux.c
··· 9 9 * 10 10 * Copyright (C) 2016 by Amaury Pouly 11 11 * 2018 by Marcin Bukat 12 + * 2018 by Roman Stolyarov 12 13 * 13 14 * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing 14 15 * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach ··· 45 46 #include <stdarg.h> 46 47 #include "version.h" 47 48 48 - /* all images must have the following size */ 49 + /* Basic configuration */ 50 + #if defined(AGPTEK_ROCKER) 49 51 #define ICON_WIDTH 70 50 52 #define ICON_HEIGHT 70 53 + #define RBFILE "rockbox.rocker" 54 + #elif defined(XDUOO_X3II) 55 + #define ICON_WIDTH 130 56 + #define ICON_HEIGHT 130 57 + #define RBFILE "rockbox.x3ii" 58 + #elif defined(XDUOO_X20) 59 + #define ICON_WIDTH 130 60 + #define ICON_HEIGHT 130 61 + #define RBFILE "rockbox.x20" 62 + #else 63 + #error "must define ICON_WIDTH/HEIGHT" 64 + #endif 65 + 66 + #define BASE_DIR "/mnt/sd_0" 51 67 52 68 /* images */ 53 69 #include "bitmaps/rockboxicon.h" ··· 68 84 #error toolsicon has the wrong resolution 69 85 #endif 70 86 71 - #ifndef BUTTON_REW 72 - #define BUTTON_REW BUTTON_LEFT 87 + #ifndef BUTTON_LEFT 88 + #define BUTTON_LEFT BUTTON_REW 73 89 #endif 74 - #ifndef BUTTON_FF 75 - #define BUTTON_FF BUTTON_RIGHT 90 + #ifndef BUTTON_RIGHT 91 + #define BUTTON_RIGHT BUTTON_FF 76 92 #endif 77 - #ifndef BUTTON_PLAY 78 - #define BUTTON_PLAY BUTTON_SELECT 93 + #ifndef BUTTON_SELECT 94 + #define BUTTON_SELECT BUTTON_PLAY 95 + #endif 96 + #ifndef BUTTON_DOWN 97 + #define BUTTON_DOWN BUTTON_NEXT 98 + #endif 99 + #ifndef BUTTON_UP 100 + #define BUTTON_UP BUTTON_PREV 79 101 #endif 80 102 81 103 /* return icon y position (x is always centered) */ ··· 143 165 * (since the mostly suspends instead of powering down) */ 144 166 static enum boot_mode load_boot_mode(enum boot_mode mode) 145 167 { 146 - int fd = open("/data/rb_bl_mode.txt", O_RDONLY); 168 + int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDONLY); 147 169 if(fd >= 0) 148 170 { 149 171 read(fd, &mode, sizeof(mode)); ··· 154 176 155 177 static void save_boot_mode(enum boot_mode mode) 156 178 { 157 - int fd = open("/data/rb_bl_mode.txt", O_RDWR | O_CREAT | O_TRUNC); 179 + int fd = open(BASE_DIR "/.rockbox/rb_bl_mode.txt", O_RDWR | O_CREAT | O_TRUNC); 158 180 if(fd >= 0) 159 181 { 160 182 write(fd, &mode, sizeof(mode)); ··· 250 272 if(btn & BUTTON_REPEAT) 251 273 btn &= ~BUTTON_REPEAT; 252 274 /* play -> stop loop and return mode */ 253 - if(btn == BUTTON_PLAY) 275 + if(btn == BUTTON_SELECT) 254 276 break; 255 277 /* left/right/up/down: change mode */ 256 - if(btn == BUTTON_LEFT || btn == BUTTON_DOWN || btn == BUTTON_REW) 278 + if(btn == BUTTON_LEFT || btn == BUTTON_DOWN) 257 279 mode = (mode + BOOT_COUNT - 1) % BOOT_COUNT; 258 - if(btn == BUTTON_RIGHT || btn == BUTTON_UP || btn == BUTTON_FF) 280 + if(btn == BUTTON_RIGHT || btn == BUTTON_UP) 259 281 mode = (mode + 1) % BOOT_COUNT; 260 282 } 261 283 ··· 323 345 if(btn & BUTTON_REPEAT) 324 346 btn &= ~BUTTON_REPEAT; 325 347 /* play -> stop loop and return mode */ 326 - if(btn == BUTTON_PLAY || btn == BUTTON_LEFT) 348 + if(btn == BUTTON_SELECT || btn == BUTTON_LEFT) 327 349 { 328 350 free(buf); 329 - return btn == BUTTON_PLAY ? choice : -1; 351 + return btn == BUTTON_SELECT ? choice : -1; 330 352 } 331 353 /* left/right/up/down: change mode */ 332 354 if(btn == BUTTON_UP) ··· 338 360 339 361 void run_file(const char *name) 340 362 { 341 - char *dirname = "/mnt/sd_0/"; 363 + char *dirname = BASE_DIR; 342 364 char *buf = malloc(strlen(dirname) + strlen(name) + 1); 343 365 sprintf(buf, "%s%s", dirname, name); 344 366 ··· 380 402 { 381 403 const char **entries = NULL; 382 404 int nr_entries = 0; 383 - DIR *dir = opendir("/mnt/sd_0"); 405 + DIR *dir = opendir(BASE_DIR); 384 406 struct dirent *ent; 385 407 while((ent = readdir(dir))) 386 408 { ··· 443 465 { 444 466 run_script_menu(); 445 467 } 446 - // else if(choice == 2) 447 - // nwz_power_restart(); 468 + else if(choice == 3) 469 + { 470 + system_reboot(); 471 + } 448 472 else if(choice == 4) 473 + { 449 474 power_off(); 475 + } 450 476 } 451 477 452 478 #if 0 ··· 454 480 static int open_log(void) 455 481 { 456 482 /* open regular log file */ 457 - int fd = open("/mnt/sd_0/rockbox.log", O_RDWR | O_CREAT | O_APPEND); 483 + int fd = open(BASE_DIR "/rockbox.log", O_RDWR | O_CREAT | O_APPEND); 458 484 /* get its size */ 459 485 struct stat stat; 460 486 if(fstat(fd, &stat) != 0) ··· 464 490 return fd; 465 491 close(fd); 466 492 /* move file */ 467 - rename("/mnt/sd_0/rockbox.log", "/mnt_sd_0/rockbox.log.1"); 493 + rename(BASE_DIR "/rockbox.log", BASE_DIR "/rockbox.log.1"); 468 494 /* re-open the file, truncate in case the move was unsuccessful */ 469 - return open("/mnt/sd_0/rockbox.log", O_RDWR | O_CREAT | O_APPEND | O_TRUNC); 495 + return open(BASE_DIR "/rockbox.log", O_RDWR | O_CREAT | O_APPEND | O_TRUNC); 470 496 } 471 497 #endif 472 498 ··· 529 555 else if(mode == BOOT_ROCKBOX) 530 556 { 531 557 fflush(stdout); 532 - system("/bin/cp /mnt/sd_0/.rockbox/rockbox.rocker /tmp"); 533 - execl("/tmp/rockbox.rocker", "rockbox.rocker", NULL); 558 + system("/bin/cp " BASE_DIR "/.rockbox/" RBFILE " /tmp"); 559 + execl("/tmp/" RBFILE, RBFILE, NULL); 534 560 printf("execvp failed: %s\n", strerror(errno)); 535 561 /* fallback to OF in case of failure */ 536 562 error_screen("Cannot boot Rockbox");
-555
bootloader/xduoo_linux.c
··· 1 - /*************************************************************************** 2 - * __________ __ ___. 3 - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 - * \/ \/ \/ \/ \/ 8 - * 9 - * 10 - * Copyright (C) 2016 by Amaury Pouly 11 - * 2018 by Marcin Bukat 12 - * 2018 by Roman Stolyarov 13 - * 14 - * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing 15 - * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach 16 - * 17 - * This program is free software; you can redistribute it and/or 18 - * modify it under the terms of the GNU General Public License 19 - * as published by the Free Software Foundation; either version 2 20 - * of the License, or (at your option) any later version. 21 - * 22 - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 23 - * KIND, either express or implied. 24 - * 25 - ****************************************************************************/ 26 - 27 - #include "system.h" 28 - #include "lcd.h" 29 - #include "backlight.h" 30 - #include "button-target.h" 31 - #include "button.h" 32 - #include "../kernel/kernel-internal.h" 33 - #include "core_alloc.h" 34 - #include "filesystem-app.h" 35 - #include "lcd.h" 36 - #include "font.h" 37 - #include "power.h" 38 - #include <string.h> 39 - #include <stdlib.h> 40 - #include <unistd.h> 41 - #include <sys/types.h> 42 - #include <sys/stat.h> 43 - #include <fcntl.h> 44 - #include <dirent.h> 45 - #include <sys/wait.h> 46 - #include <stdarg.h> 47 - #include "version.h" 48 - 49 - /* all images must have the following size */ 50 - #define ICON_WIDTH 130 51 - #define ICON_HEIGHT 130 52 - 53 - /* images */ 54 - #include "bitmaps/rockboxicon.h" 55 - #include "bitmaps/hibyicon.h" 56 - #include "bitmaps/toolsicon.h" 57 - 58 - /* don't issue an error when parsing the file for dependencies */ 59 - #if defined(BMPWIDTH_rockboxicon) && (BMPWIDTH_rockboxicon != ICON_WIDTH || \ 60 - BMPHEIGHT_rockboxicon != ICON_HEIGHT) 61 - #error rockboxicon has the wrong resolution 62 - #endif 63 - #if defined(BMPWIDTH_hibyicon) && (BMPWIDTH_hibyicon != ICON_WIDTH || \ 64 - BMPHEIGHT_hibyicon != ICON_HEIGHT) 65 - #error hibyicon has the wrong resolution 66 - #endif 67 - #if defined(BMPWIDTH_toolsicon) && (BMPWIDTH_toolsicon != ICON_WIDTH || \ 68 - BMPHEIGHT_toolsicon != ICON_HEIGHT) 69 - #error toolsicon has the wrong resolution 70 - #endif 71 - 72 - #ifndef BUTTON_UP 73 - #define BUTTON_UP BUTTON_PREV 74 - #endif 75 - #ifndef BUTTON_DOWN 76 - #define BUTTON_DOWN BUTTON_NEXT 77 - #endif 78 - #ifndef BUTTON_ENTER 79 - #define BUTTON_ENTER BUTTON_PLAY 80 - #endif 81 - 82 - /* return icon y position (x is always centered) */ 83 - static int get_icon_y(void) 84 - { 85 - int h; 86 - lcd_getstringsize("X", NULL, &h); 87 - return ((LCD_HEIGHT - ICON_HEIGHT)/2) - h; 88 - } 89 - 90 - /* Important Note: this bootloader is carefully written so that in case of 91 - * error, the OF is run. This seems like the safest option since the OF is 92 - * always there and might do magic things. */ 93 - 94 - enum boot_mode 95 - { 96 - BOOT_ROCKBOX, 97 - BOOT_TOOLS, 98 - BOOT_OF, 99 - BOOT_COUNT, 100 - BOOT_USB, /* special */ 101 - BOOT_STOP, /* power down/suspend */ 102 - }; 103 - 104 - static void display_text_center(int y, const char *text) 105 - { 106 - int width; 107 - lcd_getstringsize(text, &width, NULL); 108 - lcd_putsxy(LCD_WIDTH / 2 - width / 2, y, text); 109 - } 110 - 111 - static void display_text_centerf(int y, const char *format, ...) 112 - { 113 - char buf[1024]; 114 - va_list ap; 115 - va_start(ap, format); 116 - 117 - vsnprintf(buf, sizeof(buf), format, ap); 118 - display_text_center(y, buf); 119 - } 120 - 121 - /* get timeout before taking action if the user doesn't touch the device */ 122 - static int get_inactivity_tmo(void) 123 - { 124 - #if defined(HAS_BUTTON_HOLD) 125 - if(button_hold()) 126 - return 5 * HZ; /* Inactivity timeout when on hold */ 127 - else 128 - #endif 129 - return 10 * HZ; /* Inactivity timeout when not on hold */ 130 - } 131 - 132 - /* return action on idle timeout */ 133 - static enum boot_mode inactivity_action(enum boot_mode cur_selection) 134 - { 135 - #if defined(HAS_BUTTON_HOLD) 136 - if(button_hold()) 137 - return BOOT_STOP; /* power down/suspend */ 138 - else 139 - #endif 140 - return cur_selection; /* return last choice */ 141 - } 142 - 143 - /* we store the boot mode in a file in /tmp so we can reload it between 'boots' 144 - * (since the mostly suspends instead of powering down) */ 145 - static enum boot_mode load_boot_mode(enum boot_mode mode) 146 - { 147 - int fd = open("/data/rb_bl_mode.txt", O_RDONLY); 148 - if(fd >= 0) 149 - { 150 - read(fd, &mode, sizeof(mode)); 151 - close(fd); 152 - } 153 - return mode; 154 - } 155 - 156 - static void save_boot_mode(enum boot_mode mode) 157 - { 158 - int fd = open("/data/rb_bl_mode.txt", O_RDWR | O_CREAT | O_TRUNC); 159 - if(fd >= 0) 160 - { 161 - write(fd, &mode, sizeof(mode)); 162 - close(fd); 163 - } 164 - } 165 - 166 - static enum boot_mode get_boot_mode(void) 167 - { 168 - /* load previous mode, or start with rockbox if none */ 169 - enum boot_mode init_mode = load_boot_mode(BOOT_ROCKBOX); 170 - /* wait for user action */ 171 - enum boot_mode mode = init_mode; 172 - int last_activity = current_tick; 173 - #if defined(HAS_BUTTON_HOLD) 174 - bool hold_status = button_hold(); 175 - #endif 176 - while(true) 177 - { 178 - /* on usb detect, return to usb 179 - * FIXME this is a hack, we need proper usb detection */ 180 - if(power_input_status() & POWER_INPUT_USB_CHARGER) 181 - { 182 - /* save last choice */ 183 - save_boot_mode(mode); 184 - return BOOT_USB; 185 - } 186 - /* inactivity detection */ 187 - int timeout = last_activity + get_inactivity_tmo(); 188 - if(TIME_AFTER(current_tick, timeout)) 189 - { 190 - /* save last choice */ 191 - save_boot_mode(mode); 192 - return inactivity_action(mode); 193 - } 194 - /* redraw */ 195 - lcd_clear_display(); 196 - /* display top text */ 197 - #if defined(HAS_BUTTON_HOLD) 198 - if(button_hold()) 199 - { 200 - lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); 201 - display_text_center(0, "ON HOLD!"); 202 - } 203 - else 204 - #endif 205 - { 206 - lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); 207 - display_text_center(0, "SELECT PLAYER"); 208 - } 209 - lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); 210 - /* display icon */ 211 - const struct bitmap *icon = (mode == BOOT_OF) ? &bm_hibyicon : 212 - (mode == BOOT_ROCKBOX) ? &bm_rockboxicon : &bm_toolsicon; 213 - lcd_bmp(icon, (LCD_WIDTH - ICON_WIDTH) / 2, get_icon_y()); 214 - /* display bottom description */ 215 - const char *desc = (mode == BOOT_OF) ? "HIBY PLAYER" : 216 - (mode == BOOT_ROCKBOX) ? "ROCKBOX" : "TOOLS"; 217 - 218 - int desc_height; 219 - lcd_getstringsize(desc, NULL, &desc_height); 220 - display_text_center(LCD_HEIGHT - 3*desc_height, desc); 221 - 222 - /* display arrows */ 223 - int arrow_width, arrow_height; 224 - lcd_getstringsize("<", &arrow_width, &arrow_height); 225 - int arrow_y = get_icon_y() + ICON_HEIGHT / 2 - arrow_height / 2; 226 - lcd_putsxy(arrow_width / 2, arrow_y, "<"); 227 - lcd_putsxy(LCD_WIDTH - 3 * arrow_width / 2, arrow_y, ">"); 228 - 229 - lcd_set_foreground(LCD_RGBPACK(0, 255, 0)); 230 - display_text_centerf(LCD_HEIGHT - arrow_height * 3 / 2, "timeout in %d sec", 231 - (timeout - current_tick + HZ - 1) / HZ); 232 - 233 - lcd_update(); 234 - 235 - /* wait for a key */ 236 - int btn = button_get_w_tmo(HZ / 10); 237 - 238 - #if defined(HAS_BUTTON_HOLD) 239 - /* record action, changing HOLD counts as action */ 240 - if(btn & BUTTON_MAIN || hold_status != button_hold()) 241 - last_activity = current_tick; 242 - 243 - hold_status = button_hold(); 244 - #else 245 - if(btn & BUTTON_MAIN) 246 - last_activity = current_tick; 247 - #endif 248 - /* ignore release, allow repeat */ 249 - if(btn & BUTTON_REL) 250 - continue; 251 - if(btn & BUTTON_REPEAT) 252 - btn &= ~BUTTON_REPEAT; 253 - /* play -> stop loop and return mode */ 254 - if(btn == BUTTON_ENTER) 255 - break; 256 - /* left/right/up/down: change mode */ 257 - if(btn == BUTTON_UP || btn == BUTTON_VOL_UP) 258 - mode = (mode + BOOT_COUNT - 1) % BOOT_COUNT; 259 - if(btn == BUTTON_DOWN || btn == BUTTON_VOL_DOWN) 260 - mode = (mode + 1) % BOOT_COUNT; 261 - } 262 - 263 - /* save mode */ 264 - save_boot_mode(mode); 265 - return mode; 266 - } 267 - 268 - void error_screen(const char *msg) 269 - { 270 - lcd_clear_display(); 271 - lcd_putsf(0, 0, msg); 272 - lcd_update(); 273 - } 274 - 275 - int choice_screen(const char *title, bool center, int nr_choices, const char *choices[]) 276 - { 277 - int choice = 0; 278 - int max_len = 0; 279 - int h; 280 - lcd_getstringsize("x", NULL, &h); 281 - for(int i = 0; i < nr_choices; i++) 282 - { 283 - int len = strlen(choices[i]); 284 - if(len > max_len) 285 - max_len = len; 286 - } 287 - char *buf = malloc(max_len + 10); 288 - int top_y = 2 * h; 289 - int nr_lines = (LCD_HEIGHT - top_y) / h; 290 - while(true) 291 - { 292 - /* make sure choice is visible */ 293 - int offset = choice - nr_lines / 2; 294 - if(offset < 0) 295 - offset = 0; 296 - lcd_clear_display(); 297 - /* display top text */ 298 - lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); 299 - display_text_center(0, title); 300 - int line = 0; 301 - for(int i = 0; i < nr_choices && line < nr_lines; i++) 302 - { 303 - if(i < offset) 304 - continue; 305 - if(i == choice) 306 - lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); 307 - else 308 - lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); 309 - sprintf(buf, "%s", choices[i]); 310 - if(center) 311 - display_text_center(top_y + h * line, buf); 312 - else 313 - lcd_putsxy(0, top_y + h * line, buf); 314 - line++; 315 - } 316 - 317 - lcd_update(); 318 - 319 - /* wait for a key */ 320 - int btn = button_get_w_tmo(HZ / 10); 321 - /* ignore release, allow repeat */ 322 - if(btn & BUTTON_REL) 323 - continue; 324 - if(btn & BUTTON_REPEAT) 325 - btn &= ~BUTTON_REPEAT; 326 - /* play -> stop loop and return mode */ 327 - if(btn == BUTTON_ENTER) 328 - { 329 - free(buf); 330 - return btn == BUTTON_ENTER ? choice : -1; 331 - } 332 - /* left/right/up/down: change mode */ 333 - if(btn == BUTTON_UP || btn == BUTTON_VOL_UP) 334 - choice = (choice + nr_choices - 1) % nr_choices; 335 - if(btn == BUTTON_DOWN || btn == BUTTON_VOL_DOWN) 336 - choice = (choice + 1) % nr_choices; 337 - } 338 - } 339 - 340 - void run_file(const char *name) 341 - { 342 - char *dirname = "/mnt/sd_0/"; 343 - char *buf = malloc(strlen(dirname) + strlen(name) + 1); 344 - sprintf(buf, "%s%s", dirname, name); 345 - 346 - lcd_clear_display(); 347 - lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); 348 - lcd_putsf(0, 0, "Running %s", name); 349 - lcd_update(); 350 - 351 - pid_t pid = fork(); 352 - if(pid == 0) 353 - { 354 - execlp("sh", "sh", buf, NULL); 355 - _exit(42); 356 - } 357 - int status; 358 - waitpid(pid, &status, 0); 359 - if(WIFEXITED(status)) 360 - { 361 - lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); 362 - lcd_putsf(0, 1, "program returned %d", WEXITSTATUS(status)); 363 - } 364 - else 365 - { 366 - lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); 367 - lcd_putsf(0, 1, "an error occured: %x", status); 368 - } 369 - lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); 370 - lcd_putsf(0, 3, "Press any key or wait"); 371 - lcd_update(); 372 - /* wait a small time */ 373 - sleep(HZ); 374 - /* ignore event */ 375 - while(button_get(false) != 0) {} 376 - /* wait for any key or timeout */ 377 - button_get_w_tmo(4 * HZ); 378 - } 379 - 380 - void run_script_menu(void) 381 - { 382 - const char **entries = NULL; 383 - int nr_entries = 0; 384 - DIR *dir = opendir("/mnt/sd_0"); 385 - struct dirent *ent; 386 - while((ent = readdir(dir))) 387 - { 388 - if(ent->d_type != DT_REG) 389 - continue; 390 - entries = realloc(entries, (nr_entries + 1) * sizeof(const char *)); 391 - entries[nr_entries++] = strdup(ent->d_name); 392 - } 393 - closedir(dir); 394 - int idx = choice_screen("RUN SCRIPT", false, nr_entries, entries); 395 - if(idx >= 0) 396 - run_file(entries[idx]); 397 - for(int i = 0; i < nr_entries; i++) 398 - free((char *)entries[i]); 399 - free(entries); 400 - } 401 - 402 - static void adb(int start) 403 - { 404 - pid_t pid = fork(); 405 - if(pid == 0) 406 - { 407 - execlp("/etc/init.d/K90adb", "K90adb", start ? "start" : "stop", NULL); 408 - _exit(42); 409 - } 410 - int status; 411 - waitpid(pid, &status, 0); 412 - #if 0 413 - if(WIFEXITED(status)) 414 - { 415 - lcd_set_foreground(LCD_RGBPACK(255, 201, 0)); 416 - lcd_putsf(0, 1, "program returned %d", WEXITSTATUS(status)); 417 - } 418 - else 419 - { 420 - lcd_set_foreground(LCD_RGBPACK(255, 0, 0)); 421 - lcd_putsf(0, 1, "an error occured: %x", status); 422 - } 423 - #endif 424 - } 425 - 426 - static void tools_screen(void) 427 - { 428 - const char *choices[] = {"ADB start", "ADB stop", "Run script", "Restart", "Shutdown"}; 429 - int choice = choice_screen("TOOLS MENU", true, 5, choices); 430 - if(choice == 0) 431 - { 432 - /* run service menu */ 433 - printf("Starting ADB service...\n"); 434 - fflush(stdout); 435 - adb(1); 436 - } 437 - else if(choice == 1) 438 - { 439 - printf("Stopping ADB service...\n"); 440 - fflush(stdout); 441 - adb(0); 442 - } 443 - else if(choice == 2) 444 - { 445 - run_script_menu(); 446 - } 447 - else if(choice == 3) 448 - system_reboot(); 449 - else if(choice == 4) 450 - power_off(); 451 - } 452 - 453 - #if 0 454 - /* open log file */ 455 - static int open_log(void) 456 - { 457 - /* open regular log file */ 458 - int fd = open("/mnt/sd_0/rockbox.log", O_RDWR | O_CREAT | O_APPEND); 459 - /* get its size */ 460 - struct stat stat; 461 - if(fstat(fd, &stat) != 0) 462 - return fd; /* on error, don't do anything */ 463 - /* if file is too large, rename it and start a new log file */ 464 - if(stat.st_size < 1000000) 465 - return fd; 466 - close(fd); 467 - /* move file */ 468 - rename("/mnt/sd_0/rockbox.log", "/mnt/sd_0/rockbox.log.1"); 469 - /* re-open the file, truncate in case the move was unsuccessful */ 470 - return open("/mnt/sd_0/rockbox.log", O_RDWR | O_CREAT | O_APPEND | O_TRUNC); 471 - } 472 - #endif 473 - 474 - int main(int argc, char **argv) 475 - { 476 - (void) argc; 477 - (void) argv; 478 - #if 0 479 - /* redirect stdout and stderr to have error messages logged somewhere on the 480 - * user partition */ 481 - int fd = open_log(); 482 - if(fd >= 0) 483 - { 484 - dup2(fd, fileno(stdout)); 485 - dup2(fd, fileno(stderr)); 486 - close(fd); 487 - } 488 - /* print version */ 489 - printf("Rockbox boot loader\n"); 490 - printf("Version: %s\n", rbversion); 491 - printf("%s\n", MODEL_NAME); 492 - #endif 493 - 494 - system_init(); 495 - core_allocator_init(); 496 - kernel_init(); 497 - paths_init(); 498 - lcd_init(); 499 - font_init(); 500 - button_init(); 501 - backlight_init(); 502 - backlight_set_brightness(DEFAULT_BRIGHTNESS_SETTING); 503 - 504 - /* try to load the extra font we install on the device */ 505 - //int font_id = font_load("/usr/rockbox/fonts/20-Terminus-Bold.fnt"); 506 - //if(font_id >= 0) 507 - // lcd_setfont(font_id); 508 - 509 - /* run all tools menu */ 510 - while(true) 511 - { 512 - enum boot_mode mode = get_boot_mode(); 513 - if(mode == BOOT_USB || mode == BOOT_OF) 514 - { 515 - #if 0 516 - fflush(stdout); 517 - fflush(stderr); 518 - close(fileno(stdout)); 519 - close(fileno(stderr)); 520 - #endif 521 - /* for now the only way we have to trigger USB mode it to run the OF */ 522 - /* boot OF */ 523 - execvp("/usr/bin/hiby_player", argv); 524 - error_screen("Cannot boot OF"); 525 - sleep(5 * HZ); 526 - } 527 - else if(mode == BOOT_TOOLS) 528 - { 529 - tools_screen(); 530 - } 531 - else if(mode == BOOT_ROCKBOX) 532 - { 533 - fflush(stdout); 534 - #if defined(XDUOO_X3II) 535 - system("/bin/cp /mnt/sd_0/.rockbox/rockbox.x3ii /tmp"); 536 - execl("/tmp/rockbox.x3ii", "rockbox.x3ii", NULL); 537 - #elif defined(XDUOO_X20) 538 - system("/bin/cp /mnt/sd_0/.rockbox/rockbox.x20 /tmp"); 539 - execl("/tmp/rockbox.x20", "rockbox.x20", NULL); 540 - #endif 541 - printf("execvp failed: %s\n", strerror(errno)); 542 - /* fallback to OF in case of failure */ 543 - error_screen("Cannot boot Rockbox"); 544 - sleep(5 * HZ); 545 - } 546 - else 547 - { 548 - printf("suspend\n"); 549 - // nwz_power_suspend(); 550 - } 551 - } 552 - /* if we reach this point, everything failed, so return an error so that 553 - * sysmgrd knows something is wrong */ 554 - return 1; 555 - }