A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 855 lines 27 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2002 Kjell Ericson 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#include "plugin.h" 22#include "lib/playback_control.h" 23 24/* variable button definitions */ 25#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ 26 (CONFIG_KEYPAD == IRIVER_H300_PAD) 27#define CHC_QUIT BUTTON_SELECT 28#define CHC_STARTSTOP BUTTON_ON 29#define CHC_RESET BUTTON_OFF 30#define CHC_MENU BUTTON_REC 31#define CHC_SETTINGS_INC BUTTON_RIGHT 32#define CHC_SETTINGS_DEC BUTTON_LEFT 33#define CHC_SETTINGS_OK BUTTON_ON 34#define CHC_SETTINGS_CANCEL BUTTON_OFF 35#define CHC_SETTINGS_CANCEL2 BUTTON_REC 36 37#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ 38 (CONFIG_KEYPAD == IPOD_3G_PAD) || \ 39 (CONFIG_KEYPAD == IPOD_1G2G_PAD) 40#define CHC_QUIT BUTTON_PLAY 41#define CHC_STARTSTOP BUTTON_SELECT 42#define CHC_RESET BUTTON_LEFT 43#define CHC_MENU BUTTON_MENU 44#define CHC_SETTINGS_INC BUTTON_SCROLL_FWD 45#define CHC_SETTINGS_DEC BUTTON_SCROLL_BACK 46#define CHC_SETTINGS_OK BUTTON_SELECT 47#define CHC_SETTINGS_CANCEL BUTTON_MENU 48 49#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD 50#define CHC_QUIT BUTTON_REC 51#define CHC_STARTSTOP BUTTON_PLAY 52#define CHC_RESET BUTTON_POWER 53#define CHC_MENU BUTTON_SELECT 54#define CHC_SETTINGS_INC BUTTON_RIGHT 55#define CHC_SETTINGS_DEC BUTTON_LEFT 56#define CHC_SETTINGS_OK BUTTON_SELECT 57#define CHC_SETTINGS_CANCEL BUTTON_REC 58 59#elif CONFIG_KEYPAD == GIGABEAT_PAD 60#define CHC_QUIT BUTTON_POWER 61#define CHC_STARTSTOP BUTTON_SELECT 62#define CHC_RESET BUTTON_A 63#define CHC_MENU BUTTON_MENU 64#define CHC_SETTINGS_INC BUTTON_UP 65#define CHC_SETTINGS_DEC BUTTON_DOWN 66#define CHC_SETTINGS_OK BUTTON_SELECT 67#define CHC_SETTINGS_CANCEL BUTTON_POWER 68 69#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ 70 (CONFIG_KEYPAD == SANSA_C200_PAD) || \ 71 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \ 72 (CONFIG_KEYPAD == SANSA_M200_PAD) 73#define CHC_QUIT BUTTON_POWER 74#define CHC_STARTSTOP BUTTON_SELECT 75#define CHC_RESET BUTTON_DOWN 76#define CHC_MENU BUTTON_UP 77#define CHC_SETTINGS_INC BUTTON_RIGHT 78#define CHC_SETTINGS_DEC BUTTON_LEFT 79#define CHC_SETTINGS_OK BUTTON_SELECT 80#define CHC_SETTINGS_CANCEL BUTTON_POWER 81 82#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) 83#define CHC_QUIT BUTTON_POWER 84#define CHC_STARTSTOP BUTTON_SELECT 85#define CHC_RESET BUTTON_DOWN 86#define CHC_MENU BUTTON_UP 87#define CHC_SETTINGS_INC BUTTON_RIGHT 88#define CHC_SETTINGS_DEC BUTTON_LEFT 89#define CHC_SETTINGS_OK BUTTON_SELECT 90#define CHC_SETTINGS_CANCEL (BUTTON_HOME|BUTTON_REPEAT) 91 92#elif CONFIG_KEYPAD == IRIVER_H10_PAD 93#define CHC_QUIT BUTTON_POWER 94#define CHC_STARTSTOP BUTTON_PLAY 95#define CHC_RESET BUTTON_FF 96#define CHC_MENU BUTTON_REW 97#define CHC_SETTINGS_INC BUTTON_RIGHT 98#define CHC_SETTINGS_DEC BUTTON_LEFT 99#define CHC_SETTINGS_OK BUTTON_PLAY 100#define CHC_SETTINGS_CANCEL BUTTON_POWER 101 102#elif CONFIG_KEYPAD == MROBE500_PAD 103#define CHC_QUIT BUTTON_POWER 104#define CHC_STARTSTOP BUTTON_RC_PLAY 105#define CHC_RESET BUTTON_RC_HEART 106#define CHC_MENU BUTTON_RC_MODE 107#define CHC_SETTINGS_INC BUTTON_RC_VOL_UP 108#define CHC_SETTINGS_DEC BUTTON_RC_VOL_DOWN 109#define CHC_SETTINGS_OK BUTTON_RC_PLAY 110#define CHC_SETTINGS_CANCEL BUTTON_POWER 111 112#elif CONFIG_KEYPAD == GIGABEAT_S_PAD 113#define CHC_QUIT BUTTON_BACK 114#define CHC_STARTSTOP BUTTON_PLAY 115#define CHC_RESET BUTTON_PREV 116#define CHC_MENU BUTTON_MENU 117#define CHC_SETTINGS_INC BUTTON_UP 118#define CHC_SETTINGS_DEC BUTTON_DOWN 119#define CHC_SETTINGS_OK BUTTON_SELECT 120#define CHC_SETTINGS_CANCEL BUTTON_BACK 121 122#elif CONFIG_KEYPAD == MROBE100_PAD 123#define CHC_QUIT BUTTON_POWER 124#define CHC_STARTSTOP BUTTON_SELECT 125#define CHC_RESET BUTTON_DISPLAY 126#define CHC_MENU BUTTON_MENU 127#define CHC_SETTINGS_INC BUTTON_UP 128#define CHC_SETTINGS_DEC BUTTON_DOWN 129#define CHC_SETTINGS_OK BUTTON_SELECT 130#define CHC_SETTINGS_CANCEL BUTTON_POWER 131 132#elif CONFIG_KEYPAD == IAUDIO_M3_PAD 133#define CHC_QUIT BUTTON_RC_REC 134#define CHC_STARTSTOP BUTTON_RC_PLAY 135#define CHC_RESET BUTTON_RC_REW 136#define CHC_MENU BUTTON_RC_MENU 137#define CHC_SETTINGS_INC BUTTON_RC_VOL_UP 138#define CHC_SETTINGS_DEC BUTTON_RC_VOL_DOWN 139#define CHC_SETTINGS_OK BUTTON_RC_PLAY 140#define CHC_SETTINGS_CANCEL BUTTON_RC_REC 141 142#elif CONFIG_KEYPAD == COWON_D2_PAD 143#define CHC_QUIT BUTTON_POWER 144#define CHC_RESET (BUTTON_CENTER|BUTTON_MENU) 145#define CHC_MENU BUTTON_MENU 146#define CHC_SETTINGS_INC BUTTON_PLUS 147#define CHC_SETTINGS_DEC BUTTON_MINUS 148#define CHC_SETTINGS_CANCEL BUTTON_POWER 149 150#elif CONFIG_KEYPAD == CREATIVEZVM_PAD 151#define CHC_QUIT BUTTON_BACK 152#define CHC_STARTSTOP BUTTON_PLAY 153#define CHC_RESET BUTTON_CUSTOM 154#define CHC_MENU BUTTON_MENU 155#define CHC_SETTINGS_INC BUTTON_UP 156#define CHC_SETTINGS_DEC BUTTON_DOWN 157#define CHC_SETTINGS_OK BUTTON_SELECT 158#define CHC_SETTINGS_CANCEL BUTTON_BACK 159 160#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD 161#define CHC_QUIT BUTTON_POWER 162#define CHC_STARTSTOP BUTTON_PLAY 163#define CHC_RESET (BUTTON_BACK|BUTTON_REPEAT) 164#define CHC_MENU BUTTON_MENU 165#define CHC_SETTINGS_INC BUTTON_UP 166#define CHC_SETTINGS_DEC BUTTON_DOWN 167#define CHC_SETTINGS_OK BUTTON_PLAY 168#define CHC_SETTINGS_CANCEL BUTTON_POWER 169 170#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD 171#define CHC_QUIT BUTTON_POWER 172#define CHC_STARTSTOP BUTTON_SELECT 173#define CHC_RESET BUTTON_VIEW 174#define CHC_MENU BUTTON_MENU 175#define CHC_SETTINGS_INC BUTTON_RIGHT 176#define CHC_SETTINGS_DEC BUTTON_LEFT 177#define CHC_SETTINGS_OK BUTTON_SELECT 178#define CHC_SETTINGS_CANCEL BUTTON_POWER 179 180#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD 181#define CHC_QUIT BUTTON_POWER 182#define CHC_STARTSTOP BUTTON_PLAY 183#define CHC_RESET BUTTON_RIGHT 184#define CHC_MENU BUTTON_MENU 185#define CHC_SETTINGS_INC BUTTON_NEXT 186#define CHC_SETTINGS_DEC BUTTON_PREV 187#define CHC_SETTINGS_OK BUTTON_PLAY 188#define CHC_SETTINGS_CANCEL BUTTON_POWER 189 190#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD 191#define CHC_QUIT BUTTON_POWER 192#define CHC_STARTSTOP BUTTON_PLAY 193#define CHC_RESET BUTTON_RIGHT 194#define CHC_MENU BUTTON_MENU 195#define CHC_SETTINGS_INC BUTTON_NEXT 196#define CHC_SETTINGS_DEC BUTTON_PREV 197#define CHC_SETTINGS_OK BUTTON_PLAY 198#define CHC_SETTINGS_CANCEL BUTTON_POWER 199 200#elif CONFIG_KEYPAD == ONDAVX747_PAD 201#define CHC_QUIT BUTTON_POWER 202#define CHC_RESET (BUTTON_VOL_UP|BUTTON_VOL_DOWN) 203#define CHC_MENU BUTTON_MENU 204#define CHC_SETTINGS_INC BUTTON_VOL_UP 205#define CHC_SETTINGS_DEC BUTTON_VOL_DOWN 206#define CHC_SETTINGS_CANCEL BUTTON_POWER 207 208#elif CONFIG_KEYPAD == ONDAVX777_PAD 209#define CHC_QUIT BUTTON_POWER 210#define CHC_SETTINGS_CANCEL BUTTON_POWER 211 212#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \ 213 (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD) 214#define CHC_QUIT BUTTON_REW 215#define CHC_STARTSTOP BUTTON_PLAY 216#define CHC_RESET BUTTON_FFWD 217#define CHC_MENU BUTTON_LEFT 218#define CHC_SETTINGS_INC BUTTON_UP 219#define CHC_SETTINGS_DEC BUTTON_DOWN 220#define CHC_SETTINGS_OK BUTTON_PLAY 221#define CHC_SETTINGS_OK2 BUTTON_RIGHT 222#define CHC_SETTINGS_CANCEL BUTTON_REW 223#define CHC_SETTINGS_CANCEL2 BUTTON_LEFT 224 225#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD 226#define CHC_QUIT BUTTON_REC 227#define CHC_STARTSTOP BUTTON_PLAY 228#define CHC_RESET BUTTON_PREV 229#define CHC_MENU BUTTON_MENU 230#define CHC_SETTINGS_INC BUTTON_UP 231#define CHC_SETTINGS_DEC BUTTON_DOWN 232#define CHC_SETTINGS_OK BUTTON_OK 233#define CHC_SETTINGS_CANCEL BUTTON_CANCEL 234 235#elif CONFIG_KEYPAD == MPIO_HD200_PAD 236#define CHC_QUIT (BUTTON_REC|BUTTON_PLAY) 237#define CHC_STARTSTOP BUTTON_PLAY 238#define CHC_RESET BUTTON_REW 239#define CHC_MENU (BUTTON_FUNC|BUTTON_REPEAT) 240#define CHC_SETTINGS_INC BUTTON_VOL_UP 241#define CHC_SETTINGS_DEC BUTTON_VOL_DOWN 242#define CHC_SETTINGS_OK BUTTON_FUNC 243#define CHC_SETTINGS_CANCEL BUTTON_REC 244 245#elif CONFIG_KEYPAD == MPIO_HD300_PAD 246#define CHC_QUIT (BUTTON_MENU|BUTTON_REPEAT) 247#define CHC_STARTSTOP BUTTON_PLAY 248#define CHC_RESET BUTTON_REW 249#define CHC_MENU BUTTON_MENU 250#define CHC_SETTINGS_INC BUTTON_UP 251#define CHC_SETTINGS_DEC BUTTON_DOWN 252#define CHC_SETTINGS_OK BUTTON_ENTER 253#define CHC_SETTINGS_CANCEL BUTTON_REC 254 255#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD 256#define CHC_QUIT BUTTON_POWER 257#define CHC_STARTSTOP BUTTON_PLAYPAUSE 258#define CHC_RESET BUTTON_BACK 259#define CHC_MENU (BUTTON_SELECT|BUTTON_REPEAT) 260#define CHC_SETTINGS_INC BUTTON_UP 261#define CHC_SETTINGS_DEC BUTTON_DOWN 262#define CHC_SETTINGS_OK BUTTON_SELECT 263#define CHC_SETTINGS_CANCEL BUTTON_BACK 264 265#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD 266#define CHC_QUIT BUTTON_POWER 267#define CHC_STARTSTOP BUTTON_NEXT 268#define CHC_RESET BUTTON_PREV 269#define CHC_MENU BUTTON_SELECT 270#define CHC_SETTINGS_INC BUTTON_VOL_UP 271#define CHC_SETTINGS_DEC BUTTON_VOL_DOWN 272#define CHC_SETTINGS_OK BUTTON_SELECT 273#define CHC_SETTINGS_CANCEL BUTTON_LEFT 274 275#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD 276#define CHC_QUIT BUTTON_BACK 277#define CHC_STARTSTOP BUTTON_SELECT 278#define CHC_RESET BUTTON_USER 279#define CHC_MENU BUTTON_MENU 280#define CHC_SETTINGS_INC BUTTON_UP 281#define CHC_SETTINGS_DEC BUTTON_DOWN 282#define CHC_SETTINGS_OK BUTTON_SELECT 283#define CHC_SETTINGS_CANCEL BUTTON_BACK 284 285#elif CONFIG_KEYPAD == HM60X_PAD 286#define CHC_QUIT BUTTON_POWER 287#define CHC_STARTSTOP BUTTON_SELECT 288#define CHC_RESET BUTTON_LEFT 289#define CHC_MENU BUTTON_RIGHT 290#define CHC_SETTINGS_INC BUTTON_UP 291#define CHC_SETTINGS_DEC BUTTON_DOWN 292#define CHC_SETTINGS_OK BUTTON_SELECT 293#define CHC_SETTINGS_CANCEL BUTTON_POWER 294 295#elif CONFIG_KEYPAD == HM801_PAD 296#define CHC_QUIT BUTTON_POWER 297#define CHC_STARTSTOP BUTTON_PLAY 298#define CHC_RESET BUTTON_LEFT 299#define CHC_MENU BUTTON_RIGHT 300#define CHC_SETTINGS_INC BUTTON_UP 301#define CHC_SETTINGS_DEC BUTTON_DOWN 302#define CHC_SETTINGS_OK BUTTON_SELECT 303#define CHC_SETTINGS_CANCEL BUTTON_PREV 304 305#elif CONFIG_KEYPAD == SONY_NWZ_PAD 306#define CHC_QUIT BUTTON_BACK 307#define CHC_STARTSTOP BUTTON_PLAY 308#define CHC_RESET BUTTON_LEFT 309#define CHC_MENU BUTTON_POWER 310#define CHC_SETTINGS_INC BUTTON_UP 311#define CHC_SETTINGS_DEC BUTTON_DOWN 312#define CHC_SETTINGS_OK BUTTON_RIGHT 313#define CHC_SETTINGS_CANCEL BUTTON_BACK 314 315#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD 316#define CHC_QUIT BUTTON_BACK 317#define CHC_STARTSTOP BUTTON_PLAYPAUSE 318#define CHC_RESET BUTTON_SHORTCUT 319#define CHC_MENU BUTTON_MENU 320#define CHC_SETTINGS_INC BUTTON_UP 321#define CHC_SETTINGS_DEC BUTTON_DOWN 322#define CHC_SETTINGS_OK BUTTON_SELECT 323#define CHC_SETTINGS_CANCEL BUTTON_BACK 324 325#elif CONFIG_KEYPAD == DX50_PAD 326#define CHC_QUIT (BUTTON_POWER|BUTTON_REPEAT) 327#define CHC_RESET (BUTTON_PLAY|BUTTON_REPEAT) 328#define CHC_MENU BUTTON_RIGHT 329#define CHC_STARTSTOP BUTTON_PLAY 330#define CHC_SETTINGS_INC BUTTON_VOL_UP 331#define CHC_SETTINGS_DEC BUTTON_VOL_DOWN 332#define CHC_SETTINGS_CANCEL BUTTON_RIGHT 333 334#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD 335#define CHC_QUIT BUTTON_POWER 336#define CHC_STARTSTOP BUTTON_MENU 337 338#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD 339#define CHC_QUIT (BUTTON_POWER|BUTTON_REPEAT) 340#define CHC_RESET (BUTTON_LEFT) 341#define CHC_MENU BUTTON_RIGHT 342#define CHC_STARTSTOP BUTTON_SELECT 343#define CHC_SETTINGS_INC BUTTON_VOLUP 344#define CHC_SETTINGS_DEC BUTTON_VOLDOWN 345#define CHC_SETTINGS_CANCEL BUTTON_RIGHT 346#define CHC_SETTINGS_OK (BUTTON_SELECT|BUTTON_REPEAT) 347 348#elif (CONFIG_KEYPAD == XDUOO_X3_PAD) || (CONFIG_KEYPAD == XDUOO_X3II_PAD) || (CONFIG_KEYPAD == XDUOO_X20_PAD) 349#define CHC_QUIT BUTTON_POWER 350#define CHC_STARTSTOP BUTTON_PLAY 351#define CHC_RESET BUTTON_OPTION 352#define CHC_MENU BUTTON_HOME 353#define CHC_SETTINGS_INC BUTTON_NEXT 354#define CHC_SETTINGS_DEC BUTTON_PREV 355#define CHC_SETTINGS_OK BUTTON_PLAY 356#define CHC_SETTINGS_CANCEL BUTTON_POWER 357 358#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD 359#define CHC_QUIT BUTTON_POWER 360#define CHC_STARTSTOP BUTTON_PLAY 361#define CHC_RESET BUTTON_OPTION 362#define CHC_MENU BUTTON_HOME 363#define CHC_SETTINGS_INC BUTTON_NEXT 364#define CHC_SETTINGS_DEC BUTTON_PREV 365#define CHC_SETTINGS_OK BUTTON_PLAY 366#define CHC_SETTINGS_CANCEL BUTTON_POWER 367 368#elif (CONFIG_KEYPAD == IHIFI_770_PAD) || (CONFIG_KEYPAD == IHIFI_800_PAD) 369#define CHC_QUIT BUTTON_POWER 370#define CHC_STARTSTOP BUTTON_PLAY 371#define CHC_RESET (BUTTON_PLAY|BUTTON_REPEAT) 372#define CHC_MENU BUTTON_HOME 373#define CHC_SETTINGS_INC BUTTON_VOL_UP 374#define CHC_SETTINGS_DEC BUTTON_VOL_DOWN 375#define CHC_SETTINGS_OK BUTTON_PLAY 376#define CHC_SETTINGS_CANCEL BUTTON_HOME 377 378#elif CONFIG_KEYPAD == EROSQ_PAD 379#define CHC_QUIT BUTTON_POWER 380#define CHC_STARTSTOP BUTTON_PLAY 381#define CHC_RESET BUTTON_BACK 382#define CHC_MENU BUTTON_MENU 383#define CHC_SETTINGS_INC BUTTON_NEXT 384#define CHC_SETTINGS_DEC BUTTON_PREV 385#define CHC_SETTINGS_OK BUTTON_PLAY 386#define CHC_SETTINGS_CANCEL BUTTON_POWER 387 388#elif CONFIG_KEYPAD == FIIO_M3K_PAD 389#define CHC_QUIT BUTTON_POWER 390#define CHC_STARTSTOP BUTTON_PLAY 391#define CHC_RESET BUTTON_BACK 392#define CHC_MENU BUTTON_MENU 393#define CHC_SETTINGS_INC BUTTON_UP 394#define CHC_SETTINGS_DEC BUTTON_DOWN 395#define CHC_SETTINGS_OK BUTTON_SELECT 396#define CHC_SETTINGS_CANCEL BUTTON_POWER 397 398#elif CONFIG_KEYPAD == SHANLING_Q1_PAD 399#define CHC_QUIT BUTTON_POWER 400 401#elif CONFIG_KEYPAD == SDL_PAD 402/* use touchscreen */ 403#elif (CONFIG_KEYPAD == MA_PAD) 404#define CHC_QUIT (BUTTON_BACK|BUTTON_REPEAT) 405#define CHC_STARTSTOP BUTTON_PLAY 406#define CHC_RESET BUTTON_BACK 407#define CHC_MENU BUTTON_MENU 408#define CHC_SETTINGS_INC BUTTON_UP 409#define CHC_SETTINGS_DEC BUTTON_DOWN 410#define CHC_SETTINGS_OK BUTTON_PLAY 411#define CHC_SETTINGS_CANCEL BUTTON_BACK 412 413#elif CONFIG_KEYPAD == RG_NANO_PAD 414#define CHC_QUIT BUTTON_START 415#define CHC_STARTSTOP BUTTON_A 416#define CHC_RESET BUTTON_X 417#define CHC_MENU BUTTON_B 418#define CHC_SETTINGS_INC BUTTON_UP 419#define CHC_SETTINGS_DEC BUTTON_DOWN 420#define CHC_SETTINGS_OK BUTTON_A 421#define CHC_SETTINGS_CANCEL BUTTON_B 422 423#else 424#error No keymap defined! 425#endif 426 427#ifdef HAVE_TOUCHSCREEN 428#ifndef CHC_QUIT 429#define CHC_QUIT (BUTTON_TOPLEFT | BUTTON_CENTER) 430#endif 431#ifndef CHC_SETTINGS_OK 432#define CHC_SETTINGS_OK BUTTON_CENTER 433#endif 434#ifndef CHC_SETTINGS_CANCEL 435#define CHC_SETTINGS_CANCEL BUTTON_TOPLEFT 436#endif 437#ifndef CHC_STARTSTOP 438#define CHC_STARTSTOP BUTTON_CENTER 439#endif 440#ifndef CHC_SETTINGS_INC 441#define CHC_SETTINGS_INC BUTTON_TOPMIDDLE 442#endif 443#ifndef CHC_SETTINGS_DEC 444#define CHC_SETTINGS_DEC BUTTON_BOTTOMMIDDLE 445#endif 446#ifndef CHC_RESET 447#define CHC_RESET BUTTON_TOPLEFT 448#endif 449#ifndef CHC_MENU 450#define CHC_MENU BUTTON_TOPRIGHT 451#endif 452#endif 453 454 455/* leave first line blank on bitmap display, for pause icon */ 456#define FIRST_LINE 1 457 458#define MAX_PLAYERS 10 459 460enum { 461 CHCL_OK, 462 CHCL_CANCEL, 463 CHCL_USB, 464 CHCL_NEXT, 465 CHCL_PREV, 466}; 467 468static struct { 469 int nr_timers; 470 int total_time; 471 int round_time; 472} settings; 473 474static struct { 475 int total_time; 476 int used_time; 477 bool hidden; 478} timer_holder[MAX_PLAYERS]; 479 480static int run_timer(int nr); 481static int chessclock_set_int(char* string, 482 int* variable, 483 int step, 484 int min, 485 int max, 486 int flags); 487#define FLAGS_SET_INT_SECONDS 1 488 489static char * show_time(int secs); 490 491static bool chesspause; 492 493#define MAX_TIME 7200 494 495/* this is the plugin entry point */ 496enum plugin_status plugin_start(const void* parameter) 497{ 498 int i; 499 bool done; 500 int nr; 501 502 (void)parameter; 503 504 settings.nr_timers = 1; 505 settings.total_time = 10; 506 settings.round_time = 10; 507 508 /* now go ahead and have fun! */ 509 rb->splash(HZ, "Chess Clock"); 510 511 rb->lcd_clear_display(); 512 i=0; 513 while (1) { 514 int res; 515 switch (i) { 516 case 0: 517 res=chessclock_set_int("Number of players", 518 &settings.nr_timers, 1, 1, 519 MAX_PLAYERS, 0); 520 break; 521 case 1: 522 res=chessclock_set_int("Total time", 523 &settings.total_time, 10, 10, MAX_TIME, 524 FLAGS_SET_INT_SECONDS); 525 settings.round_time=settings.total_time; 526 break; 527 case 2: 528 res=chessclock_set_int("Max round time", &settings.round_time, 529 10, 10, settings.round_time, 530 FLAGS_SET_INT_SECONDS); 531 break; 532 default: 533 res=-2; /* done */ 534 break; 535 } 536 if (res==CHCL_USB) { 537 return PLUGIN_USB_CONNECTED; 538 } else if (res==CHCL_CANCEL) { 539 i--; 540 if (i<0) { 541 return PLUGIN_OK; 542 } 543 } else if (res==CHCL_OK) { 544 i++; 545 } else if (res==-2) { /* done */ 546 break; 547 } 548 } 549 for (i=0; i<settings.nr_timers; i++) { 550 timer_holder[i].total_time=settings.total_time; 551 timer_holder[i].used_time=0; 552 timer_holder[i].hidden=false; 553 } 554 555 chesspause=true; /* We start paused */ 556 557 nr=0; 558 do { 559 int ret=0; 560 done=true; 561 i = nr; 562 do { 563 if (!timer_holder[i].hidden) 564 { 565 nr = i; 566 done = false; 567 break; 568 } 569 if (++i == settings.nr_timers) 570 i = 0; 571 } while (i != nr); 572 573 if (done) { 574 return PLUGIN_OK; 575 } 576 577 ret = run_timer(nr); 578 switch (ret) { 579 case CHCL_CANCEL: /* exit */ 580 done=true; 581 break; 582 case CHCL_USB: 583 return PLUGIN_USB_CONNECTED; 584 case CHCL_NEXT: 585 nr++; 586 if (nr>=settings.nr_timers) 587 nr=0; 588 break; 589 case CHCL_PREV: 590 do { 591 nr--; 592 if (nr<0) 593 nr=settings.nr_timers-1; 594 } while (timer_holder[nr].hidden); 595 break; 596 } 597 } while (!done); 598 return PLUGIN_OK; 599} 600 601static void show_pause_mode(bool enabled) 602{ 603 static const char pause_icon[] = {0x00,0x7f,0x7f,0x00,0x7f,0x7f,0x00}; 604 605 if (enabled) 606 rb->lcd_mono_bitmap((unsigned char *)pause_icon, 52, 0, 7, 8); 607 else 608 { 609 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 610 rb->lcd_fillrect(52, 0, 7, 8); 611 rb->lcd_set_drawmode(DRMODE_SOLID); 612 } 613} 614 615static int run_timer(int nr) 616{ 617 char buf[40]; 618 char player_info[13]; 619 long last_tick; 620 bool done=false; 621 int retval=CHCL_OK; 622 long max_ticks=timer_holder[nr].total_time*HZ-timer_holder[nr].used_time; 623 long ticks=0; 624 bool round_time=false; 625 626 show_pause_mode(chesspause); 627 628 if (settings.round_time*HZ<max_ticks) { 629 max_ticks=settings.round_time*HZ; 630 round_time=true; 631 } 632 rb->snprintf(player_info, sizeof(player_info), "Player %d", nr+1); 633 rb->lcd_puts(0, FIRST_LINE, (unsigned char *)player_info); 634 last_tick=*rb->current_tick; 635 636 while (!done) { 637 int button; 638 long now; 639 if (ticks>=max_ticks) { 640 if (round_time) 641 rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)"ROUND UP!"); 642 else 643 rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)"TIME OUT!"); 644#ifdef HAVE_BACKLIGHT 645 rb->backlight_on(); 646#endif 647 ticks = max_ticks; 648 } else { 649 now=*rb->current_tick; 650 if (!chesspause) { 651 ticks+=now-last_tick; 652 if ((max_ticks-ticks)/HZ == 10) { 653#ifdef HAVE_BACKLIGHT 654 /* Backlight on if 10 seconds remain */ 655 rb->backlight_on(); 656#endif 657 } 658 } 659 last_tick=now; 660 if (round_time) { 661 rb->snprintf(buf, sizeof(buf), "%s/", 662 show_time((max_ticks-ticks+HZ-1)/HZ)); 663 /* Append total time */ 664 rb->strcpy(&buf[rb->strlen(buf)], 665 show_time((timer_holder[nr].total_time*HZ- 666 timer_holder[nr].used_time- 667 ticks+HZ-1)/HZ)); 668 rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)buf); 669 } else { 670 rb->lcd_puts(0, FIRST_LINE+1, 671 (unsigned char *)show_time((max_ticks-ticks+HZ-1)/HZ)); 672 } 673 } 674 rb->lcd_update(); 675 676 button = rb->button_get(false); 677 switch (button) { 678 /* OFF/ON key to exit */ 679 case CHC_QUIT: 680 return CHCL_CANCEL; /* Indicate exit */ 681 682 /* PLAY = Stop/Start toggle */ 683 case CHC_STARTSTOP: 684 chesspause=!chesspause; 685 show_pause_mode(chesspause); 686 break; 687 688 /* LEFT = Reset timer */ 689 case CHC_RESET: 690 ticks=0; 691 break; 692 693 /* MENU */ 694 case CHC_MENU: 695 { 696 MENUITEM_STRINGLIST(menu, "Menu", NULL, 697 "Delete player", "Restart round", 698 "Set round time", "Set total time", 699 "Playback Control"); 700 701 int val, res; 702 switch(rb->do_menu(&menu, NULL, NULL, false)) 703 { 704 case 0: 705 /* delete player */ 706 timer_holder[nr].hidden=true; 707 retval = CHCL_NEXT; 708 done=true; 709 break; 710 case 1: 711 /* restart */ 712 ticks=0; 713 last_tick=*rb->current_tick; 714 break; 715 case 2: 716 /* set round time */ 717 val=(max_ticks-ticks)/HZ; 718 res=chessclock_set_int("Round time", 719 &val, 10, 0, MAX_TIME, 720 FLAGS_SET_INT_SECONDS); 721 if (res==CHCL_USB) { 722 retval = CHCL_USB; 723 done=true; 724 } else if (res==CHCL_OK) { 725 ticks=max_ticks-val*HZ; 726 last_tick=*rb->current_tick; 727 } 728 break; 729 case 3: 730 /* set total time */ 731 val=timer_holder[nr].total_time; 732 res=chessclock_set_int("Total time", 733 &val, 734 10, 0, MAX_TIME, 735 FLAGS_SET_INT_SECONDS); 736 if (res==CHCL_USB) { 737 retval = CHCL_USB; 738 done=true; 739 } else if (res==CHCL_OK) { 740 timer_holder[nr].total_time=val; 741 } 742 break; 743 case 4: 744 playback_control(NULL); 745 break; 746 case MENU_ATTACHED_USB: 747 retval = CHCL_USB; 748 done=true; 749 break; 750 } 751 rb->lcd_clear_display(); 752 show_pause_mode(chesspause); 753 rb->lcd_puts(0, FIRST_LINE, (unsigned char *)player_info); 754 } 755 break; 756 757 /* UP (RIGHT/+) = Scroll Lap timer up */ 758 case CHC_SETTINGS_INC: 759 retval = CHCL_NEXT; 760 done = true; 761 break; 762 763 /* DOWN (LEFT/-) = Scroll Lap timer down */ 764 case CHC_SETTINGS_DEC: 765 retval = CHCL_PREV; 766 done = true; 767 break; 768 769 default: 770 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { 771 retval = CHCL_USB; 772 done = true; 773 } 774 break; 775 } 776 rb->sleep(HZ/4); /* Sleep 1/4 of a second */ 777 } 778 779 timer_holder[nr].used_time+=ticks; 780 781 return retval; 782} 783 784static int chessclock_set_int(char* string, 785 int* variable, 786 int step, 787 int min, 788 int max, 789 int flags) 790{ 791 bool done = false; 792 int button; 793 794 rb->lcd_clear_display(); 795 rb->lcd_puts_scroll(0, FIRST_LINE, (unsigned char *)string); 796 797 while (!done) { 798 char str[32]; 799 if (flags & FLAGS_SET_INT_SECONDS) 800 rb->snprintf(str, sizeof str,"%s (m:s)", show_time(*variable)); 801 else 802 rb->snprintf(str, sizeof str,"%d", *variable); 803 rb->lcd_puts(0, FIRST_LINE+1, (unsigned char *)str); 804 rb->lcd_update(); 805 806 button = rb->button_get(true); 807 switch(button) { 808 case CHC_SETTINGS_INC: 809 case CHC_SETTINGS_INC | BUTTON_REPEAT: 810 *variable += step; 811 break; 812 813 case CHC_SETTINGS_DEC: 814 case CHC_SETTINGS_DEC | BUTTON_REPEAT: 815 *variable -= step; 816 break; 817 818 case CHC_SETTINGS_OK: 819#ifdef CHC_SETTINGS_OK2 820 case CHC_SETTINGS_OK2: 821#endif 822 done = true; 823 break; 824 825 case CHC_SETTINGS_CANCEL: 826#ifdef CHC_SETTINGS_CANCEL2 827 case CHC_SETTINGS_CANCEL2: 828#endif 829 return CHCL_CANCEL; 830 break; 831 832 default: 833 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) 834 return CHCL_USB; 835 break; 836 837 } 838 if(*variable > max ) 839 *variable = max; 840 841 if(*variable < min ) 842 *variable = min; 843 844 } 845 rb->lcd_scroll_stop(); 846 847 return CHCL_OK; 848} 849 850static char * show_time(int seconds) 851{ 852 static char buf[]="00:00"; 853 rb->snprintf(buf, sizeof(buf), "%02d:%02d", seconds/60, seconds%60); 854 return buf; 855}