A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 603 lines 20 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2004 Mike Holden 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 "plugin.h" 23 24#define TIMER_Y 1 25 26#define LAP_Y TIMER_Y+1 27#define MAX_LAPS 64 28 29#define STOPWATCH_FILE PLUGIN_APPS_DATA_DIR "/stopwatch.dat" 30 31/* variable button definitions */ 32#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ 33 (CONFIG_KEYPAD == IRIVER_H300_PAD) 34#define STOPWATCH_QUIT BUTTON_OFF 35#define STOPWATCH_START_STOP BUTTON_SELECT 36#define STOPWATCH_RESET_TIMER BUTTON_DOWN 37#define STOPWATCH_LAP_TIMER BUTTON_ON 38#define STOPWATCH_SCROLL_UP BUTTON_RIGHT 39#define STOPWATCH_SCROLL_DOWN BUTTON_LEFT 40#define STOPWATCH_RC_QUIT BUTTON_RC_STOP 41 42#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ 43 (CONFIG_KEYPAD == IPOD_3G_PAD) || \ 44 (CONFIG_KEYPAD == IPOD_1G2G_PAD) 45#define STOPWATCH_QUIT BUTTON_MENU 46#define STOPWATCH_START_STOP BUTTON_SELECT 47#define STOPWATCH_RESET_TIMER BUTTON_LEFT 48#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 49#define STOPWATCH_SCROLL_UP BUTTON_SCROLL_FWD 50#define STOPWATCH_SCROLL_DOWN BUTTON_SCROLL_BACK 51 52#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD 53#define STOPWATCH_QUIT BUTTON_POWER 54#define STOPWATCH_START_STOP BUTTON_PLAY 55#define STOPWATCH_RESET_TIMER BUTTON_REC 56#define STOPWATCH_LAP_TIMER BUTTON_SELECT 57#define STOPWATCH_SCROLL_UP BUTTON_UP 58#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 59 60#elif CONFIG_KEYPAD == GIGABEAT_PAD 61#define STOPWATCH_QUIT BUTTON_POWER 62#define STOPWATCH_START_STOP BUTTON_SELECT 63#define STOPWATCH_RESET_TIMER BUTTON_A 64#define STOPWATCH_LAP_TIMER BUTTON_MENU 65#define STOPWATCH_SCROLL_UP BUTTON_UP 66#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 67 68#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ 69(CONFIG_KEYPAD == SANSA_C200_PAD) || \ 70(CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ 71(CONFIG_KEYPAD == SANSA_M200_PAD) 72#define STOPWATCH_QUIT BUTTON_POWER 73#define STOPWATCH_START_STOP BUTTON_RIGHT 74#define STOPWATCH_RESET_TIMER BUTTON_LEFT 75#define STOPWATCH_LAP_TIMER BUTTON_SELECT 76#define STOPWATCH_SCROLL_UP BUTTON_UP 77#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 78 79#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) 80#define STOPWATCH_QUIT (BUTTON_HOME|BUTTON_REPEAT) 81#define STOPWATCH_START_STOP BUTTON_RIGHT 82#define STOPWATCH_RESET_TIMER BUTTON_LEFT 83#define STOPWATCH_LAP_TIMER BUTTON_SELECT 84#define STOPWATCH_SCROLL_UP BUTTON_SCROLL_BACK 85#define STOPWATCH_SCROLL_DOWN BUTTON_SCROLL_FWD 86 87#elif CONFIG_KEYPAD == IRIVER_H10_PAD 88#define STOPWATCH_QUIT BUTTON_POWER 89#define STOPWATCH_START_STOP BUTTON_PLAY 90#define STOPWATCH_RESET_TIMER BUTTON_REW 91#define STOPWATCH_LAP_TIMER BUTTON_FF 92#define STOPWATCH_SCROLL_UP BUTTON_SCROLL_UP 93#define STOPWATCH_SCROLL_DOWN BUTTON_SCROLL_DOWN 94 95#elif CONFIG_KEYPAD == MROBE500_PAD 96#define STOPWATCH_QUIT BUTTON_POWER 97 98#elif CONFIG_KEYPAD == GIGABEAT_S_PAD 99#define STOPWATCH_QUIT BUTTON_BACK 100#define STOPWATCH_START_STOP BUTTON_PLAY 101#define STOPWATCH_RESET_TIMER BUTTON_MENU 102#define STOPWATCH_LAP_TIMER BUTTON_SELECT 103#define STOPWATCH_SCROLL_UP BUTTON_UP 104#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 105 106#elif CONFIG_KEYPAD == MROBE100_PAD 107#define STOPWATCH_QUIT BUTTON_POWER 108#define STOPWATCH_START_STOP BUTTON_SELECT 109#define STOPWATCH_RESET_TIMER BUTTON_DISPLAY 110#define STOPWATCH_LAP_TIMER BUTTON_MENU 111#define STOPWATCH_SCROLL_UP BUTTON_UP 112#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 113 114#elif CONFIG_KEYPAD == IAUDIO_M3_PAD 115#define STOPWATCH_QUIT BUTTON_RC_REC 116#define STOPWATCH_START_STOP BUTTON_RC_PLAY 117#define STOPWATCH_RESET_TIMER BUTTON_RC_REW 118#define STOPWATCH_LAP_TIMER BUTTON_RC_FF 119#define STOPWATCH_SCROLL_UP BUTTON_RC_VOL_UP 120#define STOPWATCH_SCROLL_DOWN BUTTON_RC_VOL_DOWN 121#define STOPWATCH_RC_QUIT BUTTON_REC 122 123#elif CONFIG_KEYPAD == COWON_D2_PAD 124#define STOPWATCH_QUIT BUTTON_POWER 125 126#elif CONFIG_KEYPAD == CREATIVEZVM_PAD 127#define STOPWATCH_QUIT BUTTON_BACK 128#define STOPWATCH_START_STOP BUTTON_PLAY 129#define STOPWATCH_RESET_TIMER BUTTON_SELECT 130#define STOPWATCH_LAP_TIMER BUTTON_CUSTOM 131#define STOPWATCH_SCROLL_UP BUTTON_UP 132#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 133 134#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD 135#define STOPWATCH_QUIT BUTTON_POWER 136#define STOPWATCH_START_STOP (BUTTON_PLAY|BUTTON_REL) 137#define STOPWATCH_RESET_TIMER (BUTTON_PLAY|BUTTON_REPEAT) 138#define STOPWATCH_LAP_TIMER BUTTON_MENU 139#define STOPWATCH_SCROLL_UP BUTTON_UP 140#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 141 142#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD 143#define STOPWATCH_QUIT BUTTON_POWER 144#define STOPWATCH_START_STOP BUTTON_SELECT 145#define STOPWATCH_RESET_TIMER BUTTON_MENU 146#define STOPWATCH_LAP_TIMER BUTTON_VIEW 147#define STOPWATCH_SCROLL_UP BUTTON_UP 148#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 149 150#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD 151#define STOPWATCH_QUIT BUTTON_POWER 152#define STOPWATCH_START_STOP BUTTON_PLAY 153#define STOPWATCH_RESET_TIMER BUTTON_MENU 154#define STOPWATCH_LAP_TIMER BUTTON_NEXT 155#define STOPWATCH_SCROLL_UP BUTTON_UP 156#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 157 158#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD 159#define STOPWATCH_QUIT BUTTON_POWER 160#define STOPWATCH_START_STOP BUTTON_PLAY 161#define STOPWATCH_RESET_TIMER BUTTON_MENU 162#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 163#define STOPWATCH_SCROLL_UP BUTTON_UP 164#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 165 166#elif CONFIG_KEYPAD == ONDAVX747_PAD 167#define STOPWATCH_QUIT BUTTON_POWER 168#elif CONFIG_KEYPAD == ONDAVX777_PAD 169#define STOPWATCH_QUIT BUTTON_POWER 170 171#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \ 172 (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD) 173#define STOPWATCH_QUIT BUTTON_REW 174#define STOPWATCH_START_STOP BUTTON_PLAY 175#define STOPWATCH_RESET_TIMER BUTTON_LEFT 176#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 177#define STOPWATCH_SCROLL_UP BUTTON_UP 178#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 179 180#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD 181#define STOPWATCH_QUIT BUTTON_REC 182#define STOPWATCH_START_STOP BUTTON_PLAY 183#define STOPWATCH_RESET_TIMER BUTTON_OK 184#define STOPWATCH_LAP_TIMER BUTTON_MENU 185#define STOPWATCH_SCROLL_UP BUTTON_UP 186#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 187 188#elif CONFIG_KEYPAD == MPIO_HD200_PAD 189#define STOPWATCH_QUIT (BUTTON_REC|BUTTON_PLAY) 190#define STOPWATCH_START_STOP BUTTON_PLAY 191#define STOPWATCH_RESET_TIMER BUTTON_REW 192#define STOPWATCH_LAP_TIMER BUTTON_FF 193#define STOPWATCH_SCROLL_UP BUTTON_VOL_UP 194#define STOPWATCH_SCROLL_DOWN BUTTON_VOL_DOWN 195 196#elif CONFIG_KEYPAD == MPIO_HD300_PAD 197#define STOPWATCH_QUIT (BUTTON_MENU|BUTTON_REPEAT) 198#define STOPWATCH_START_STOP BUTTON_PLAY 199#define STOPWATCH_RESET_TIMER BUTTON_REW 200#define STOPWATCH_LAP_TIMER BUTTON_FF 201#define STOPWATCH_SCROLL_UP BUTTON_UP 202#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 203 204#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD 205#define STOPWATCH_QUIT BUTTON_POWER 206#define STOPWATCH_START_STOP BUTTON_PLAYPAUSE 207#define STOPWATCH_RESET_TIMER BUTTON_BACK 208#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 209#define STOPWATCH_SCROLL_UP BUTTON_UP 210#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 211 212#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD 213#define STOPWATCH_QUIT BUTTON_POWER 214#define STOPWATCH_START_STOP BUTTON_SELECT 215#define STOPWATCH_RESET_TIMER BUTTON_LEFT 216#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 217#define STOPWATCH_SCROLL_UP BUTTON_UP 218#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 219 220#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD 221#define STOPWATCH_QUIT BUTTON_BACK 222#define STOPWATCH_START_STOP BUTTON_SELECT 223#define STOPWATCH_RESET_TIMER BUTTON_MENU 224#define STOPWATCH_LAP_TIMER BUTTON_USER 225#define STOPWATCH_SCROLL_UP BUTTON_UP 226#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 227 228#elif (CONFIG_KEYPAD == HM60X_PAD) || \ 229 (CONFIG_KEYPAD == HM801_PAD) 230#define STOPWATCH_QUIT BUTTON_POWER 231#define STOPWATCH_START_STOP BUTTON_SELECT 232#define STOPWATCH_RESET_TIMER BUTTON_LEFT 233#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 234#define STOPWATCH_SCROLL_UP BUTTON_UP 235#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 236 237#elif (CONFIG_KEYPAD == SONY_NWZ_PAD) 238#define STOPWATCH_QUIT BUTTON_POWER 239#define STOPWATCH_START_STOP BUTTON_PLAY 240#define STOPWATCH_RESET_TIMER BUTTON_BACK 241#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 242#define STOPWATCH_SCROLL_UP BUTTON_UP 243#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 244 245#elif (CONFIG_KEYPAD == CREATIVE_ZEN_PAD) 246#define STOPWATCH_QUIT BUTTON_BACK 247#define STOPWATCH_START_STOP BUTTON_PLAYPAUSE 248#define STOPWATCH_RESET_TIMER BUTTON_SHORTCUT 249#define STOPWATCH_LAP_TIMER BUTTON_SELECT 250#define STOPWATCH_SCROLL_UP BUTTON_UP 251#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 252 253#elif (CONFIG_KEYPAD == AGPTEK_ROCKER_PAD) 254#define STOPWATCH_QUIT BUTTON_POWER 255#define STOPWATCH_START_STOP BUTTON_SELECT 256#define STOPWATCH_RESET_TIMER BUTTON_LEFT 257#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 258#define STOPWATCH_SCROLL_UP BUTTON_UP 259#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 260 261#elif CONFIG_KEYPAD == XDUOO_X3_PAD || CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD 262#define STOPWATCH_QUIT BUTTON_POWER 263#define STOPWATCH_START_STOP BUTTON_NEXT 264#define STOPWATCH_RESET_TIMER BUTTON_PREV 265#define STOPWATCH_LAP_TIMER BUTTON_PLAY 266#define STOPWATCH_SCROLL_UP BUTTON_HOME 267#define STOPWATCH_SCROLL_DOWN BUTTON_OPTION 268 269#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD 270#define STOPWATCH_QUIT BUTTON_POWER 271#define STOPWATCH_START_STOP BUTTON_NEXT 272#define STOPWATCH_RESET_TIMER BUTTON_PREV 273#define STOPWATCH_LAP_TIMER BUTTON_PLAY 274#define STOPWATCH_SCROLL_UP BUTTON_HOME 275#define STOPWATCH_SCROLL_DOWN BUTTON_OPTION 276 277#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD 278#define STOPWATCH_QUIT BUTTON_POWER 279#define STOPWATCH_START_STOP BUTTON_NEXT 280#define STOPWATCH_RESET_TIMER BUTTON_PREV 281#define STOPWATCH_LAP_TIMER BUTTON_PLAY 282#define STOPWATCH_SCROLL_UP BUTTON_VOL_UP 283#define STOPWATCH_SCROLL_DOWN BUTTON_VOL_DOWN 284 285#elif CONFIG_KEYPAD == EROSQ_PAD 286#define STOPWATCH_QUIT BUTTON_POWER 287#define STOPWATCH_START_STOP BUTTON_PLAY 288#define STOPWATCH_RESET_TIMER BUTTON_BACK 289#define STOPWATCH_LAP_TIMER BUTTON_MENU 290#define STOPWATCH_SCROLL_UP BUTTON_SCROLL_FWD 291#define STOPWATCH_SCROLL_DOWN BUTTON_SCROLL_BACK 292 293#elif CONFIG_KEYPAD == FIIO_M3K_PAD 294#define STOPWATCH_QUIT BUTTON_POWER 295#define STOPWATCH_START_STOP BUTTON_PLAY 296#define STOPWATCH_RESET_TIMER BUTTON_BACK 297#define STOPWATCH_LAP_TIMER BUTTON_SELECT 298#define STOPWATCH_SCROLL_UP BUTTON_SCROLL_BACK 299#define STOPWATCH_SCROLL_DOWN BUTTON_SCROLL_FWD 300 301#elif CONFIG_KEYPAD == SDL_PAD 302#define STOPWATCH_QUIT BUTTON_MENU 303#define STOPWATCH_START_STOP BUTTON_SELECT 304#define STOPWATCH_RESET_TIMER BUTTON_LEFT 305#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 306#define STOPWATCH_SCROLL_UP BUTTON_UP 307#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 308#elif CONFIG_KEYPAD == MA_PAD 309#define STOPWATCH_QUIT BUTTON_BACK 310#define STOPWATCH_START_STOP BUTTON_PLAY 311#define STOPWATCH_RESET_TIMER BUTTON_LEFT 312#define STOPWATCH_LAP_TIMER BUTTON_RIGHT 313#define STOPWATCH_SCROLL_UP BUTTON_UP 314#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 315 316#elif CONFIG_KEYPAD == RG_NANO_PAD 317#define STOPWATCH_QUIT BUTTON_START 318#define STOPWATCH_START_STOP BUTTON_A 319#define STOPWATCH_RESET_TIMER BUTTON_X 320#define STOPWATCH_LAP_TIMER BUTTON_Y 321#define STOPWATCH_SCROLL_UP BUTTON_UP 322#define STOPWATCH_SCROLL_DOWN BUTTON_DOWN 323 324#else 325#error No keymap defined! 326#endif 327 328#ifdef HAVE_TOUCHSCREEN 329#ifndef STOPWATCH_QUIT 330#define STOPWATCH_QUIT BUTTON_TOPLEFT 331#endif 332#ifndef STOPWATCH_START_STOP 333#define STOPWATCH_START_STOP BUTTON_CENTER 334#endif 335#ifndef STOPWATCH_RESET_TIMER 336#define STOPWATCH_RESET_TIMER BUTTON_MIDRIGHT 337#endif 338#ifndef STOPWATCH_LAP_TIMER 339#define STOPWATCH_LAP_TIMER BUTTON_MIDLEFT 340#endif 341#ifndef STOPWATCH_SCROLL_UP 342#define STOPWATCH_SCROLL_UP BUTTON_TOPMIDDLE 343#endif 344#ifndef STOPWATCH_SCROLL_DOWN 345#define STOPWATCH_SCROLL_DOWN BUTTON_BOTTOMMIDDLE 346#endif 347#endif 348 349static int stopwatch = 0; 350static long start_at = 0; 351static int prev_total = 0; 352static bool counting = false; 353static int curr_lap = 0; 354static int lap_scroll = 0; 355static int lap_start; 356static int lap_times[MAX_LAPS]; 357 358static void ticks_to_string(int ticks,int lap,int buflen, char * buf) 359{ 360 int hours, minutes, seconds, cs; 361 362 hours = ticks / (HZ * 3600); 363 ticks -= (HZ * hours * 3600); 364 minutes = ticks / (HZ * 60); 365 ticks -= (HZ * minutes * 60); 366 seconds = ticks / HZ; 367 ticks -= (HZ * seconds); 368 cs = ticks; 369 if (!lap) 370 rb->snprintf(buf, buflen, 371 "%2d:%02d:%02d.%02d ", /* add some blank space, in case */ 372 hours, minutes, seconds, cs); /* char width differs, since we */ 373 /* don't clear the viewport */ 374 else if (lap > 1) 375 { 376 int last_ticks, last_hours, last_minutes, last_seconds, last_cs; 377 last_ticks = lap_times[(lap-1)%MAX_LAPS] - lap_times[(lap-2)%MAX_LAPS]; 378 last_hours = last_ticks / (HZ * 3600); 379 last_ticks -= (HZ * last_hours * 3600); 380 last_minutes = last_ticks / (HZ * 60); 381 last_ticks -= (HZ * last_minutes * 60); 382 last_seconds = last_ticks / HZ; 383 last_ticks -= (HZ * last_seconds); 384 last_cs = last_ticks; 385 386 rb->snprintf(buf, buflen, 387 "%2d %2d:%02d:%02d.%02d [%2d:%02d:%02d.%02d]", 388 lap, hours, minutes, seconds, cs, last_hours, 389 last_minutes, last_seconds, last_cs); 390 } 391 else 392 rb->snprintf(buf, buflen, 393 "%2d %2d:%02d:%02d.%02d", 394 lap, hours, minutes, seconds, cs); 395} 396 397/* 398 * Load saved stopwatch state, if exists. 399 */ 400static void load_stopwatch(void) 401{ 402 int fd = rb->open(STOPWATCH_FILE, O_RDONLY); 403 if (fd < 0) 404 return; 405 406 /* variable stopwatch isn't saved/loaded, because it is only used 407 * temporarily in main loop 408 */ 409 410 rb->read(fd, &start_at, sizeof(start_at)); 411 rb->read(fd, &prev_total, sizeof(prev_total)); 412 rb->read(fd, &counting, sizeof(counting)); 413 rb->read(fd, &curr_lap, sizeof(curr_lap)); 414 rb->read(fd, &lap_scroll, sizeof(lap_scroll)); 415 rb->read(fd, &lap_start, sizeof(lap_start)); 416 rb->read(fd, lap_times, sizeof(lap_times)); 417 418 if (counting && start_at > *rb->current_tick) 419 { 420 /* Stopwatch started in the future? Unlikely; probably started on a 421 * previous session and powered off in-between. We'll keep 422 * everything intact (user can clear manually) but stop the 423 * stopwatch to avoid negative timing. 424 */ 425 start_at = 0; 426 counting = false; 427 } 428 429 rb->close(fd); 430} 431 432/* 433 * Save stopwatch state. 434 */ 435static void save_stopwatch(void) 436{ 437 int fd = rb->open(STOPWATCH_FILE, O_CREAT|O_WRONLY|O_TRUNC, 0666); 438 if (fd < 0) 439 return; 440 441 /* variable stopwatch isn't saved/loaded, because it is only used 442 * temporarily in main loop 443 */ 444 445 rb->write(fd, &start_at, sizeof(start_at)); 446 rb->write(fd, &prev_total, sizeof(prev_total)); 447 rb->write(fd, &counting, sizeof(counting)); 448 rb->write(fd, &curr_lap, sizeof(curr_lap)); 449 rb->write(fd, &lap_scroll, sizeof(lap_scroll)); 450 rb->write(fd, &lap_start, sizeof(lap_start)); 451 rb->write(fd, lap_times, sizeof(lap_times)); 452 453 rb->close(fd); 454} 455 456enum plugin_status plugin_start(const void* parameter) 457{ 458 struct viewport vp, *last_vp; 459 struct screen *display; 460 char buf[32]; 461 int button; 462 int lap; 463 int done = false; 464 bool update_lap = true; 465 int lines; 466 int ret = PLUGIN_OK; 467 (void)parameter; 468 int h; 469 470 FOR_NB_SCREENS(i) 471 rb->viewportmanager_theme_enable(i, true, NULL); 472 473 rb->viewport_set_defaults(&vp, SCREEN_MAIN); 474 display = rb->screens[SCREEN_MAIN]; 475 476 display->setfont(FONT_UI); 477 display->getstringsize("M", NULL, &h); 478 lines = (vp.height / h) - (LAP_Y); 479 480 load_stopwatch(); 481 482 while (!done) 483 { 484 rb->send_event(GUI_EVENT_ACTIONUPDATE, NULL); /* update status bar */ 485 if (counting) 486 stopwatch = prev_total + *rb->current_tick - start_at; 487 else 488 stopwatch = prev_total; 489 490 ticks_to_string(stopwatch,0,32,buf); 491 last_vp = display->set_viewport(&vp); 492 493 if(update_lap) 494 { 495 display->clear_viewport(); 496 display->puts(0, TIMER_Y, buf); 497 lap_start = curr_lap - lap_scroll; 498 for (lap = lap_start; lap > lap_start - lines; lap--) 499 { 500 if (lap > 0) 501 { 502 ticks_to_string(lap_times[(lap-1)%MAX_LAPS],lap,32,buf); 503 display->puts_scroll(0, LAP_Y + lap_start - lap, buf); 504 } 505 else 506 display->puts(0, LAP_Y + lap_start - lap, 507 " "); 508 } 509 update_lap = false; 510 } 511 else 512 display->puts(0, TIMER_Y, buf); 513 display->update_viewport(); 514 display->set_viewport(last_vp); 515 if (!counting) 516 button = rb->button_get_w_tmo(HZ/2); 517 else 518 { 519 button = rb->button_get_w_tmo(HZ/10); 520 rb->reset_poweroff_timer(); 521 } 522 switch (button) 523 { 524#ifdef STOPWATCH_RC_QUIT 525 case STOPWATCH_RC_QUIT: 526#endif 527 case STOPWATCH_QUIT: 528 save_stopwatch(); 529 done = true; 530 break; 531 532 /* Stop/Start toggle */ 533 case STOPWATCH_START_STOP: 534 counting = ! counting; 535 if (counting) 536 { 537 start_at = *rb->current_tick; 538 stopwatch = prev_total + *rb->current_tick - start_at; 539 } 540 else 541 { 542 prev_total += *rb->current_tick - start_at; 543 stopwatch = prev_total; 544 } 545 break; 546 547 /* Reset timer */ 548 case STOPWATCH_RESET_TIMER: 549 if (!counting) 550 { 551 prev_total = 0; 552 curr_lap = 0; 553 lap_scroll = 0; 554 update_lap = true; 555 } 556 break; 557 558 /* Lap timer */ 559 case STOPWATCH_LAP_TIMER: 560 /*check if we're timing, and start if not*/ 561 if (counting) 562 { 563 lap_times[curr_lap%MAX_LAPS] = stopwatch; 564 curr_lap++; 565 update_lap = true; 566 } 567 else 568 { 569 counting = ! counting; 570 start_at = *rb->current_tick; 571 stopwatch = prev_total + *rb->current_tick - start_at; 572 } 573 break; 574 575 /* Scroll Lap timer up */ 576 case STOPWATCH_SCROLL_UP: 577 if (lap_scroll > 0) 578 { 579 lap_scroll--; 580 update_lap = true; 581 } 582 break; 583 584 /* Scroll Lap timer down */ 585 case STOPWATCH_SCROLL_DOWN: 586 if ((lap_scroll < curr_lap - lines) && 587 (lap_scroll < (MAX_LAPS - lines)) ) 588 { 589 lap_scroll++; 590 update_lap = true; 591 } 592 break; 593 594 default: 595 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) 596 ret = PLUGIN_USB_CONNECTED; 597 break; 598 } 599 } 600 FOR_NB_SCREENS(i) 601 rb->viewportmanager_theme_undo(i, false); 602 return ret; 603}