A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
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}