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 * (based upon 1.1 by calpefrosch) updated by www.HuwSy.ukhackers.net
10 *
11 * Copyright (C) 2002
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "plugin.h"
23
24#include <timefuncs.h>
25#include "lib/playback_control.h"
26#include "lib/configfile.h"
27
28#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
29 (CONFIG_KEYPAD == IRIVER_H300_PAD)
30#define CALENDAR_QUIT BUTTON_OFF
31#define CALENDAR_SELECT BUTTON_SELECT
32#define CALENDAR_NEXT_WEEK BUTTON_DOWN
33#define CALENDAR_PREV_WEEK BUTTON_UP
34#define CALENDAR_NEXT_DAY BUTTON_RIGHT
35#define CALENDAR_PREV_DAY BUTTON_LEFT
36#define CALENDAR_NEXT_MONTH BUTTON_MODE
37#define CALENDAR_PREV_MONTH BUTTON_REC
38
39#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
40 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
41 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
42#define CALENDAR_QUIT (BUTTON_MENU|BUTTON_REL)
43#define CALENDAR_SELECT (BUTTON_SELECT|BUTTON_REL)
44#define CALENDAR_NEXT_WEEK BUTTON_SCROLL_FWD
45#define CALENDAR_PREV_WEEK BUTTON_SCROLL_BACK
46#define CALENDAR_NEXT_DAY BUTTON_RIGHT
47#define CALENDAR_PREV_DAY BUTTON_LEFT
48
49#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
50#define CALENDAR_QUIT BUTTON_POWER
51#define CALENDAR_SELECT BUTTON_SELECT
52#define CALENDAR_NEXT_WEEK BUTTON_DOWN
53#define CALENDAR_PREV_WEEK BUTTON_UP
54#define CALENDAR_NEXT_DAY BUTTON_RIGHT
55#define CALENDAR_PREV_DAY BUTTON_LEFT
56#define CALENDAR_NEXT_MONTH BUTTON_PLAY
57#define CALENDAR_PREV_MONTH BUTTON_REC
58
59#elif CONFIG_KEYPAD == GIGABEAT_PAD
60#define CALENDAR_QUIT BUTTON_POWER
61#define CALENDAR_SELECT BUTTON_SELECT
62#define CALENDAR_NEXT_WEEK BUTTON_DOWN
63#define CALENDAR_PREV_WEEK BUTTON_UP
64#define CALENDAR_NEXT_DAY BUTTON_RIGHT
65#define CALENDAR_PREV_DAY BUTTON_LEFT
66#define CALENDAR_NEXT_MONTH BUTTON_VOL_DOWN
67#define CALENDAR_PREV_MONTH BUTTON_VOL_UP
68
69#elif CONFIG_KEYPAD == SANSA_E200_PAD
70#define CALENDAR_QUIT BUTTON_POWER
71#define CALENDAR_SELECT BUTTON_SELECT
72#define CALENDAR_NEXT_WEEK BUTTON_SCROLL_FWD
73#define CALENDAR_PREV_WEEK BUTTON_SCROLL_BACK
74#define CALENDAR_NEXT_DAY BUTTON_RIGHT
75#define CALENDAR_PREV_DAY BUTTON_LEFT
76#define CALENDAR_NEXT_MONTH BUTTON_DOWN
77#define CALENDAR_PREV_MONTH BUTTON_UP
78
79#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
80#define CALENDAR_QUIT (BUTTON_HOME|BUTTON_REPEAT)
81#define CALENDAR_SELECT BUTTON_SELECT
82#define CALENDAR_NEXT_WEEK BUTTON_SCROLL_FWD
83#define CALENDAR_PREV_WEEK BUTTON_SCROLL_BACK
84#define CALENDAR_NEXT_DAY BUTTON_RIGHT
85#define CALENDAR_PREV_DAY BUTTON_LEFT
86#define CALENDAR_NEXT_MONTH BUTTON_DOWN
87#define CALENDAR_PREV_MONTH BUTTON_UP
88
89#elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \
90 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
91 (CONFIG_KEYPAD == SANSA_M200_PAD)
92#define CALENDAR_QUIT BUTTON_POWER
93#define CALENDAR_SELECT BUTTON_SELECT
94#define CALENDAR_NEXT_WEEK BUTTON_DOWN
95#define CALENDAR_PREV_WEEK BUTTON_UP
96#define CALENDAR_NEXT_DAY BUTTON_RIGHT
97#define CALENDAR_PREV_DAY BUTTON_LEFT
98#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
99#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
100
101#elif CONFIG_KEYPAD == IRIVER_H10_PAD
102#define CALENDAR_QUIT BUTTON_POWER
103#define CALENDAR_SELECT BUTTON_PLAY
104#define CALENDAR_NEXT_WEEK BUTTON_SCROLL_DOWN
105#define CALENDAR_PREV_WEEK BUTTON_SCROLL_UP
106#define CALENDAR_NEXT_DAY BUTTON_RIGHT
107#define CALENDAR_PREV_DAY BUTTON_LEFT
108#define CALENDAR_NEXT_MONTH BUTTON_FF
109#define CALENDAR_PREV_MONTH BUTTON_REW
110
111#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
112#define CALENDAR_QUIT BUTTON_BACK
113#define CALENDAR_SELECT BUTTON_SELECT
114#define CALENDAR_NEXT_WEEK BUTTON_DOWN
115#define CALENDAR_PREV_WEEK BUTTON_UP
116#define CALENDAR_NEXT_DAY BUTTON_RIGHT
117#define CALENDAR_PREV_DAY BUTTON_LEFT
118#define CALENDAR_NEXT_MONTH BUTTON_NEXT
119#define CALENDAR_PREV_MONTH BUTTON_PREV
120
121#elif CONFIG_KEYPAD == MROBE100_PAD
122#define CALENDAR_QUIT BUTTON_POWER
123#define CALENDAR_SELECT BUTTON_SELECT
124#define CALENDAR_NEXT_WEEK BUTTON_DOWN
125#define CALENDAR_PREV_WEEK BUTTON_UP
126#define CALENDAR_NEXT_DAY BUTTON_RIGHT
127#define CALENDAR_PREV_DAY BUTTON_LEFT
128#define CALENDAR_NEXT_MONTH (BUTTON_MENU|BUTTON_DOWN)
129#define CALENDAR_PREV_MONTH (BUTTON_MENU|BUTTON_UP)
130
131#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
132#define CALENDAR_QUIT BUTTON_RC_REC
133#define CALENDAR_SELECT BUTTON_RC_PLAY
134#define CALENDAR_NEXT_WEEK BUTTON_RC_VOL_DOWN
135#define CALENDAR_PREV_WEEK BUTTON_RC_VOL_UP
136#define CALENDAR_NEXT_DAY BUTTON_RC_FF
137#define CALENDAR_PREV_DAY BUTTON_RC_REW
138#define CALENDAR_NEXT_MONTH BUTTON_RC_MODE
139#define CALENDAR_PREV_MONTH BUTTON_RC_MENU
140
141#elif (CONFIG_KEYPAD == COWON_D2_PAD)
142#define CALENDAR_QUIT BUTTON_POWER
143#define CALENDAR_SELECT BUTTON_CENTER
144#define CALENDAR_NEXT_WEEK BUTTON_DOWN
145#define CALENDAR_PREV_WEEK BUTTON_UP
146#define CALENDAR_NEXT_DAY BUTTON_RIGHT
147#define CALENDAR_PREV_DAY BUTTON_LEFT
148#define CALENDAR_NEXT_MONTH BUTTON_BOTTOMRIGHT
149#define CALENDAR_PREV_MONTH BUTTON_BOTTOMLEFT
150#define CALENDAR_EVENT_MENU_NAME "menu"
151
152#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
153#define CALENDAR_QUIT BUTTON_BACK
154#define CALENDAR_SELECT BUTTON_SELECT
155#define CALENDAR_NEXT_WEEK BUTTON_DOWN
156#define CALENDAR_PREV_WEEK BUTTON_UP
157#define CALENDAR_NEXT_DAY BUTTON_RIGHT
158#define CALENDAR_PREV_DAY BUTTON_LEFT
159#define CALENDAR_NEXT_MONTH BUTTON_CUSTOM
160#define CALENDAR_PREV_MONTH BUTTON_PLAY
161
162#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD
163#define CALENDAR_QUIT BUTTON_POWER
164#define CALENDAR_SELECT BUTTON_PLAY
165#define CALENDAR_NEXT_WEEK BUTTON_DOWN
166#define CALENDAR_PREV_WEEK BUTTON_UP
167#define CALENDAR_NEXT_DAY BUTTON_MENU
168#define CALENDAR_PREV_DAY BUTTON_BACK
169#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
170#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
171#define CALENDAR_EVENT_MENU_NAME "play"
172
173#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
174#define CALENDAR_QUIT BUTTON_POWER
175#define CALENDAR_SELECT BUTTON_SELECT
176#define CALENDAR_NEXT_WEEK BUTTON_DOWN
177#define CALENDAR_PREV_WEEK BUTTON_UP
178#define CALENDAR_NEXT_DAY BUTTON_RIGHT
179#define CALENDAR_PREV_DAY BUTTON_LEFT
180#define CALENDAR_NEXT_MONTH BUTTON_VOL_DOWN
181#define CALENDAR_PREV_MONTH BUTTON_VOL_UP
182
183#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
184#define CALENDAR_QUIT BUTTON_POWER
185#define CALENDAR_SELECT BUTTON_PLAY
186#define CALENDAR_NEXT_WEEK BUTTON_DOWN
187#define CALENDAR_PREV_WEEK BUTTON_UP
188#define CALENDAR_NEXT_DAY BUTTON_NEXT
189#define CALENDAR_PREV_DAY BUTTON_PREV
190#define CALENDAR_NEXT_MONTH BUTTON_VOL_DOWN
191#define CALENDAR_PREV_MONTH BUTTON_VOL_UP
192
193#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
194#define CALENDAR_QUIT BUTTON_POWER
195#define CALENDAR_SELECT BUTTON_PLAY
196#define CALENDAR_NEXT_WEEK BUTTON_DOWN
197#define CALENDAR_PREV_WEEK BUTTON_UP
198#define CALENDAR_NEXT_DAY BUTTON_NEXT
199#define CALENDAR_PREV_DAY BUTTON_PREV
200#define CALENDAR_NEXT_MONTH BUTTON_VOL_DOWN
201#define CALENDAR_PREV_MONTH BUTTON_VOL_UP
202
203#elif (CONFIG_KEYPAD == ONDAVX747_PAD)
204#define CALENDAR_QUIT BUTTON_POWER
205#define CALENDAR_SELECT BUTTON_MENU
206#define CALENDAR_NEXT_WEEK BUTTON_VOL_DOWN
207#define CALENDAR_PREV_WEEK BUTTON_VOL_UP
208#define CALENDAR_NEXT_DAY BUTTON_RIGHT
209#define CALENDAR_PREV_DAY BUTTON_LEFT
210#define CALENDAR_NEXT_MONTH BUTTON_BOTTOMRIGHT
211#define CALENDAR_PREV_MONTH BUTTON_BOTTOMLEFT
212#define CALENDAR_EVENT_MENU_NAME "menu"
213
214#elif (CONFIG_KEYPAD == ONDAVX777_PAD)
215#define CALENDAR_QUIT BUTTON_POWER
216
217#elif CONFIG_KEYPAD == MROBE500_PAD
218#define CALENDAR_QUIT BUTTON_POWER
219
220#elif CONFIG_KEYPAD == SAMSUNG_YH92X_PAD
221#define CALENDAR_QUIT BUTTON_REW
222#define CALENDAR_SELECT BUTTON_PLAY
223#define CALENDAR_NEXT_WEEK BUTTON_DOWN
224#define CALENDAR_PREV_WEEK BUTTON_UP
225#define CALENDAR_NEXT_DAY BUTTON_RIGHT
226#define CALENDAR_PREV_DAY BUTTON_LEFT
227#define CALENDAR_NEXT_MONTH (BUTTON_FFWD|BUTTON_DOWN)
228#define CALENDAR_PREV_MONTH (BUTTON_FFWD|BUTTON_UP)
229
230#elif CONFIG_KEYPAD == SAMSUNG_YH820_PAD
231#define CALENDAR_QUIT BUTTON_REW
232#define CALENDAR_SELECT BUTTON_PLAY
233#define CALENDAR_NEXT_WEEK BUTTON_DOWN
234#define CALENDAR_PREV_WEEK BUTTON_UP
235#define CALENDAR_NEXT_DAY BUTTON_RIGHT
236#define CALENDAR_PREV_DAY BUTTON_LEFT
237#define CALENDAR_NEXT_MONTH (BUTTON_REC|BUTTON_DOWN)
238#define CALENDAR_PREV_MONTH (BUTTON_REC|BUTTON_UP)
239
240#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
241#define CALENDAR_QUIT BUTTON_REC
242#define CALENDAR_SELECT BUTTON_OK
243#define CALENDAR_NEXT_WEEK BUTTON_DOWN
244#define CALENDAR_PREV_WEEK BUTTON_UP
245#define CALENDAR_NEXT_DAY BUTTON_NEXT
246#define CALENDAR_PREV_DAY BUTTON_PREV
247#define CALENDAR_NEXT_MONTH BUTTON_PLAY
248#define CALENDAR_PREV_MONTH BUTTON_MENU
249#define CALENDAR_EVENT_MENU_NAME "FFWD"
250
251#elif CONFIG_KEYPAD == MPIO_HD200_PAD
252#define CALENDAR_QUIT (BUTTON_REC|BUTTON_PLAY)
253#define CALENDAR_SELECT BUTTON_FUNC
254#define CALENDAR_NEXT_WEEK BUTTON_FF
255#define CALENDAR_PREV_WEEK BUTTON_REW
256#define CALENDAR_NEXT_DAY BUTTON_VOL_UP
257#define CALENDAR_PREV_DAY BUTTON_VOL_DOWN
258#define CALENDAR_NEXT_MONTH BUTTON_PLAY
259#define CALENDAR_PREV_MONTH BUTTON_REC
260#define CALENDAR_EVENT_MENU_NAME "func"
261
262#elif CONFIG_KEYPAD == MPIO_HD300_PAD
263#define CALENDAR_QUIT (BUTTON_MENU|BUTTON_REPEAT)
264#define CALENDAR_SELECT BUTTON_ENTER
265#define CALENDAR_NEXT_WEEK BUTTON_FF
266#define CALENDAR_PREV_WEEK BUTTON_REW
267#define CALENDAR_NEXT_DAY BUTTON_UP
268#define CALENDAR_PREV_DAY BUTTON_DOWN
269#define CALENDAR_NEXT_MONTH BUTTON_PLAY
270#define CALENDAR_PREV_MONTH BUTTON_REC
271#define CALENDAR_EVENT_MENU_NAME "enter"
272
273#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
274#define CALENDAR_QUIT BUTTON_POWER
275#define CALENDAR_SELECT BUTTON_SELECT
276#define CALENDAR_NEXT_WEEK BUTTON_DOWN
277#define CALENDAR_PREV_WEEK BUTTON_UP
278#define CALENDAR_NEXT_DAY BUTTON_RIGHT
279#define CALENDAR_PREV_DAY BUTTON_LEFT
280#define CALENDAR_NEXT_MONTH BUTTON_PLAYPAUSE
281#define CALENDAR_PREV_MONTH BUTTON_BACK
282#define CALENDAR_EVENT_MENU_NAME "select"
283
284#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
285#define CALENDAR_QUIT BUTTON_POWER
286#define CALENDAR_SELECT BUTTON_SELECT
287#define CALENDAR_NEXT_WEEK BUTTON_RIGHT
288#define CALENDAR_PREV_WEEK BUTTON_LEFT
289#define CALENDAR_NEXT_DAY BUTTON_UP
290#define CALENDAR_PREV_DAY BUTTON_DOWN
291#define CALENDAR_NEXT_MONTH BUTTON_NEXT
292#define CALENDAR_PREV_MONTH BUTTON_PREV
293
294#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
295#define CALENDAR_QUIT BUTTON_BACK
296#define CALENDAR_SELECT BUTTON_SELECT
297#define CALENDAR_NEXT_WEEK BUTTON_DOWN
298#define CALENDAR_PREV_WEEK BUTTON_UP
299#define CALENDAR_NEXT_DAY BUTTON_RIGHT
300#define CALENDAR_PREV_DAY BUTTON_LEFT
301#define CALENDAR_NEXT_MONTH BUTTON_POWER
302#define CALENDAR_PREV_MONTH BUTTON_USER
303
304#elif CONFIG_KEYPAD == HM60X_PAD
305#define CALENDAR_QUIT BUTTON_POWER
306#define CALENDAR_SELECT BUTTON_SELECT
307#define CALENDAR_NEXT_WEEK BUTTON_DOWN
308#define CALENDAR_PREV_WEEK BUTTON_UP
309#define CALENDAR_NEXT_DAY BUTTON_RIGHT
310#define CALENDAR_PREV_DAY BUTTON_LEFT
311#define CALENDAR_NEXT_MONTH (BUTTON_RIGHT|BUTTON_POWER)
312#define CALENDAR_PREV_MONTH (BUTTON_LEFT|BUTTON_POWER)
313#define CALENDAR_EVENT_MENU_NAME "select"
314
315#elif CONFIG_KEYPAD == HM801_PAD
316#define CALENDAR_QUIT BUTTON_POWER
317#define CALENDAR_SELECT BUTTON_SELECT
318#define CALENDAR_NEXT_WEEK BUTTON_DOWN
319#define CALENDAR_PREV_WEEK BUTTON_UP
320#define CALENDAR_NEXT_DAY BUTTON_RIGHT
321#define CALENDAR_PREV_DAY BUTTON_LEFT
322#define CALENDAR_NEXT_MONTH BUTTON_NEXT
323#define CALENDAR_PREV_MONTH BUTTON_PREV
324#define CALENDAR_EVENT_MENU_NAME "select"
325
326#elif CONFIG_KEYPAD == SONY_NWZ_PAD
327#define CALENDAR_QUIT BUTTON_BACK
328#define CALENDAR_SELECT BUTTON_PLAY
329#define CALENDAR_NEXT_DAY BUTTON_RIGHT
330#define CALENDAR_PREV_DAY BUTTON_LEFT
331#define CALENDAR_NEXT_WEEK BUTTON_DOWN
332#define CALENDAR_PREV_WEEK BUTTON_UP
333#define CALENDAR_NEXT_MONTH (BUTTON_POWER|BUTTON_DOWN)
334#define CALENDAR_PREV_MONTH (BUTTON_POWER|BUTTON_UP)
335
336#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD
337#define CALENDAR_QUIT BUTTON_BACK
338#define CALENDAR_SELECT BUTTON_SELECT
339#define CALENDAR_NEXT_DAY BUTTON_RIGHT
340#define CALENDAR_PREV_DAY BUTTON_LEFT
341#define CALENDAR_NEXT_WEEK BUTTON_DOWN
342#define CALENDAR_PREV_WEEK BUTTON_UP
343#define CALENDAR_NEXT_MONTH BUTTON_SHORTCUT
344#define CALENDAR_PREV_MONTH BUTTON_MENU
345
346#elif CONFIG_KEYPAD == DX50_PAD
347#define CALENDAR_QUIT (BUTTON_POWER|BUTTON_REL)
348#define CALENDAR_SELECT BUTTON_PLAY
349#define CALENDAR_NEXT_WEEK BUTTON_VOL_DOWN
350#define CALENDAR_PREV_WEEK BUTTON_VOL_UP
351#define CALENDAR_NEXT_DAY BUTTON_RIGHT
352#define CALENDAR_PREV_DAY BUTTON_LEFT
353#define CALENDAR_NEXT_MONTH BUTTON_BOTTOMRIGHT
354#define CALENDAR_PREV_MONTH BUTTON_BOTTOMLEFT
355#define CALENDAR_EVENT_MENU_NAME "play"
356
357#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
358#define CALENDAR_QUIT BUTTON_POWER
359#define CALENDAR_SELECT BUTTON_MENU
360#define CALENDAR_EVENT_MENU_NAME "menu"
361
362#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
363#define CALENDAR_QUIT BUTTON_POWER
364#define CALENDAR_SELECT BUTTON_SELECT
365#define CALENDAR_NEXT_DAY BUTTON_RIGHT
366#define CALENDAR_PREV_DAY BUTTON_LEFT
367#define CALENDAR_NEXT_WEEK BUTTON_DOWN
368#define CALENDAR_PREV_WEEK BUTTON_UP
369#define CALENDAR_NEXT_MONTH (BUTTON_VOLDOWN)
370#define CALENDAR_PREV_MONTH (BUTTON_VOLUP)
371
372#elif CONFIG_KEYPAD == XDUOO_X3_PAD || CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD
373#define CALENDAR_QUIT BUTTON_POWER
374#define CALENDAR_SELECT BUTTON_PLAY
375#define CALENDAR_NEXT_WEEK BUTTON_OPTION
376#define CALENDAR_PREV_WEEK BUTTON_HOME
377#define CALENDAR_NEXT_DAY BUTTON_NEXT
378#define CALENDAR_PREV_DAY BUTTON_PREV
379#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
380#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
381
382#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD
383#define CALENDAR_QUIT BUTTON_POWER
384#define CALENDAR_SELECT BUTTON_PLAY
385#define CALENDAR_NEXT_WEEK BUTTON_OPTION
386#define CALENDAR_PREV_WEEK BUTTON_HOME
387#define CALENDAR_NEXT_DAY BUTTON_NEXT
388#define CALENDAR_PREV_DAY BUTTON_PREV
389#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
390#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
391
392#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD
393#define CALENDAR_QUIT BUTTON_POWER
394#define CALENDAR_SELECT BUTTON_PLAY
395#define CALENDAR_NEXT_WEEK (BUTTON_POWER | BUTTON_VOL_DOWN)
396#define CALENDAR_PREV_WEEK (BUTTON_POWER | BUTTON_VOL_UP)
397#define CALENDAR_NEXT_DAY BUTTON_NEXT
398#define CALENDAR_PREV_DAY BUTTON_PREV
399#define CALENDAR_NEXT_MONTH BUTTON_VOL_DOWN
400#define CALENDAR_PREV_MONTH BUTTON_VOL_UP
401
402#elif CONFIG_KEYPAD == EROSQ_PAD
403#define CALENDAR_QUIT BUTTON_POWER
404#define CALENDAR_SELECT BUTTON_PLAY
405#define CALENDAR_NEXT_WEEK BUTTON_NEXT
406#define CALENDAR_PREV_WEEK BUTTON_PREV
407#define CALENDAR_NEXT_DAY BUTTON_SCROLL_FWD
408#define CALENDAR_PREV_DAY BUTTON_SCROLL_BACK
409#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
410#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
411
412#elif CONFIG_KEYPAD == FIIO_M3K_PAD
413#define CALENDAR_QUIT BUTTON_POWER
414#define CALENDAR_SELECT BUTTON_SELECT
415#define CALENDAR_NEXT_WEEK BUTTON_DOWN
416#define CALENDAR_PREV_WEEK BUTTON_UP
417#define CALENDAR_NEXT_DAY BUTTON_RIGHT
418#define CALENDAR_PREV_DAY BUTTON_LEFT
419#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
420#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
421
422#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
423/* use touchscreen */
424
425#elif CONFIG_KEYPAD == SDL_PAD
426/* use touchscreen */
427#elif CONFIG_KEYPAD == MA_PAD
428#define CALENDAR_QUIT (BUTTON_BACK|BUTTON_MENU)
429#define CALENDAR_SELECT BUTTON_PLAY
430#define CALENDAR_NEXT_WEEK BUTTON_DOWN
431#define CALENDAR_PREV_WEEK BUTTON_UP
432#define CALENDAR_NEXT_DAY BUTTON_RIGHT
433#define CALENDAR_PREV_DAY BUTTON_LEFT
434#define CALENDAR_NEXT_MONTH BUTTON_MENU
435#define CALENDAR_PREV_MONTH BUTTON_BACK
436
437#elif CONFIG_KEYPAD == RG_NANO_PAD
438#define CALENDAR_QUIT BUTTON_START
439#define CALENDAR_SELECT BUTTON_A
440#define CALENDAR_NEXT_WEEK BUTTON_DOWN
441#define CALENDAR_PREV_WEEK BUTTON_UP
442#define CALENDAR_NEXT_DAY BUTTON_RIGHT
443#define CALENDAR_PREV_DAY BUTTON_LEFT
444#define CALENDAR_NEXT_MONTH BUTTON_R
445#define CALENDAR_PREV_MONTH BUTTON_L
446#define CALENDAR_EVENT_MENU_NAME "A"
447
448#else
449#error "No keypad setting."
450#endif
451
452#ifdef HAVE_TOUCHSCREEN
453#ifndef CALENDAR_QUIT
454#define CALENDAR_QUIT BUTTON_MIDLEFT
455#endif
456#ifndef CALENDAR_SELECT
457#define CALENDAR_SELECT BUTTON_CENTER
458#endif
459#ifndef CALENDAR_NEXT_DAY
460#define CALENDAR_NEXT_DAY BUTTON_TOPLEFT
461#endif
462#ifndef CALENDAR_PREV_DAY
463#define CALENDAR_PREV_DAY BUTTON_BOTTOMLEFT
464#endif
465#ifndef CALENDAR_NEXT_WEEK
466#define CALENDAR_NEXT_WEEK BUTTON_TOPMIDDLE
467#endif
468#ifndef CALENDAR_PREV_WEEK
469#define CALENDAR_PREV_WEEK BUTTON_BOTTOMMIDDLE
470#endif
471#ifndef CALENDAR_NEXT_MONTH
472#define CALENDAR_NEXT_MONTH BUTTON_TOPRIGHT
473#endif
474#ifndef CALENDAR_PREV_MONTH
475#define CALENDAR_PREV_MONTH BUTTON_BOTTOMRIGHT
476#endif
477#ifndef CALENDAR_EVENT_MENU_NAME
478#define CALENDAR_EVENT_MENU_NAME "select"
479#endif
480#endif
481
482#ifndef CALENDAR_EVENT_MENU_NAME
483#define CALENDAR_EVENT_MENU_NAME "right"
484#endif
485
486#define MEMO_FILE PLUGIN_APPS_DATA_DIR "/.memo"
487#define TEMP_FILE PLUGIN_APPS_DATA_DIR "/~temp"
488
489#define X_OFFSET ((LCD_WIDTH%7)/2)
490#if LCD_HEIGHT <= 80
491#define Y_OFFSET 1
492#else
493#define Y_OFFSET 4
494#endif
495#define CELL_WIDTH (LCD_WIDTH / 7)
496#define CELL_HEIGHT (LCD_HEIGHT / 7)
497
498#define CFG_FILE "calendar.cfg"
499struct info {
500 int first_wday;
501#if (CONFIG_RTC == 0)
502 int last_mon;
503 int last_year;
504#endif
505};
506static struct info info = { .first_wday = 0 }, old_info;
507static struct configdata config[] = {
508 { TYPE_INT, 0, 6, { .int_p = &(info.first_wday) }, "first wday", NULL },
509#if (CONFIG_RTC == 0)
510 { TYPE_INT, 1, 12, { .int_p = &(info.last_mon) }, "last mon", NULL },
511 { TYPE_INT, 1, 3000, { .int_p = &(info.last_year) }, "last year", NULL },
512#endif
513};
514
515static bool leap_year;
516/* days_in_month[][0] is for December */
517static const int days_in_month[2][13] = {
518 {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
519 {31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
520};
521
522static const char *dayname_long[7] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};
523static const char *dayname_short[7] = {"M","T","W","T","F","S","S"};
524
525struct shown {
526 int mday; /* day of the month */
527 int mon; /* month */
528 int year; /* year since 1900 */
529 int wday; /* day of the week */
530 int firstday; /* first (w)day of month */
531 int lastday; /* last (w)day of month */
532};
533
534static bool use_system_font = false;
535
536static bool been_in_usb_mode = false;
537
538/* leap year -- account for gregorian reformation in 1752 */
539static int is_leap_year(int yr)
540{
541 return ((yr) <= 1752 ? !((yr) % 4) : \
542 (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400)) ? 1:0 ;
543}
544
545/* searches the weekday of the first day in month,
546 * relative to the given values */
547static int calc_weekday( struct shown *shown )
548{
549 return ( shown->wday + 36 - shown->mday ) % 7 ;
550}
551
552#if (CONFIG_RTC == 0)
553/* from timefunc.c */
554static void my_set_day_of_week(struct shown *shown)
555{
556 int y = shown->year;
557 int d = shown->mday;
558 int m = shown->mon-1;
559 static const char mo[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
560
561 if(m == 0 || m == 1) y--;
562 shown->wday = (d + mo[m] + y + y/4 - y/100 + y/400) % 7 - 1;
563}
564#endif
565
566static void calendar_init(struct shown *shown)
567{
568 int w, h;
569#if CONFIG_RTC
570 struct tm *tm;
571#endif
572 rb->lcd_getstringsize("A", &w, &h);
573 if ( ((w * 14) > LCD_WIDTH) || ((h * 7) > LCD_HEIGHT) )
574 {
575 use_system_font = true;
576 }
577#if CONFIG_RTC
578 tm = rb->get_time();
579 shown->mday = tm->tm_mday;
580 shown->mon = tm->tm_mon + 1;
581 shown->year = 2000 + (tm->tm_year%100);
582 shown->wday = tm->tm_wday - 1;
583#else
584#define S100(x) 1 ## x
585#define C2DIG2DEC(x) (S100(x)-100)
586 if(info.last_mon == 0 || info.last_year == 0)
587 {
588 shown->mon = C2DIG2DEC(MONTH);
589 shown->year = YEAR;
590 }
591 else
592 {
593 shown->mon = info.last_mon;
594 shown->year = info.last_year;
595 }
596 shown->mday = 1;
597 my_set_day_of_week(shown);
598#endif
599 shown->firstday = calc_weekday(shown);
600 leap_year = is_leap_year(shown->year);
601}
602
603static void draw_headers(void)
604{
605 int i, w, h;
606 int x = X_OFFSET;
607 int wday;
608 const char **dayname = dayname_long;
609
610 for (i = 0; i < 7; i++)
611 {
612 rb->lcd_getstringsize(dayname[i], &w, &h);
613 if (w > CELL_WIDTH)
614 {
615 dayname = dayname_short;
616 break;
617 }
618 }
619
620 wday = info.first_wday;
621 rb->lcd_getstringsize("A", &w, &h);
622 for (i = 0; i < 7; i++)
623 {
624 if (wday >= 7) wday = 0;
625 rb->lcd_putsxy(x, 0, dayname[wday++]);
626 x += CELL_WIDTH;
627 }
628 rb->lcd_hline(0, LCD_WIDTH-1, h);
629}
630
631static bool day_has_memo[32];
632static bool wday_has_memo[7];
633static void draw_calendar(struct shown *shown)
634{
635 int w, h;
636 int x, y, pos, days_per_month, j;
637 int wday;
638 const char *monthname[] = {
639 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
640 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
641 };
642 if(use_system_font)
643 {
644 rb->lcd_setfont(FONT_SYSFIXED);
645 }
646 rb->lcd_getstringsize("A", &w, &h);
647 rb->lcd_clear_display();
648 draw_headers();
649 wday = shown->firstday;
650 pos = wday + 7 - info.first_wday;
651 if (pos >= 7) pos -= 7;
652
653 days_per_month = days_in_month[leap_year][shown->mon];
654 x = X_OFFSET + (pos * CELL_WIDTH);
655 y = Y_OFFSET + h;
656 for (j = 1; j <= days_per_month; j++)
657 {
658 if (shown->mday == j)
659 {
660 rb->lcd_set_drawmode(DRMODE_SOLID);
661 rb->lcd_fillrect(x, y - 1, CELL_WIDTH - 1, CELL_HEIGHT);
662 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
663 shown->wday = wday;
664 }
665 else
666 {
667 rb->lcd_set_drawmode(DRMODE_SOLID);
668 }
669 if ( (day_has_memo[j]) || (wday_has_memo[wday]) )
670 rb->lcd_putsxyf(x, y, "%02d.", j);
671 else
672 rb->lcd_putsxyf(x, y, "%02d", j);
673 x += CELL_WIDTH;
674 wday++;
675 if (wday >= 7)
676 wday = 0;
677 pos++;
678 if (pos >= 7)
679 {
680 pos = 0;
681 x = X_OFFSET;
682 y += CELL_HEIGHT;
683 }
684 }
685 shown->lastday = wday;
686 rb->lcd_set_drawmode(DRMODE_SOLID);
687 rb->lcd_vline(LCD_WIDTH-w*8-10, LCD_HEIGHT-h-3, LCD_HEIGHT-1);
688 rb->lcd_hline(LCD_WIDTH-w*8-10, LCD_WIDTH-1, LCD_HEIGHT-h-3);
689 rb->lcd_putsxyf(LCD_WIDTH-w*8-8, LCD_HEIGHT-h-1, "%s %04d",
690 monthname[shown->mon-1], shown->year);
691 rb->lcd_update();
692}
693
694#define MAX_CHAR_MEMO_LEN 64
695#define MAX_MEMOS_IN_A_MONTH 128
696struct memo {
697 char message[MAX_CHAR_MEMO_LEN];
698 int day;
699 int month;
700 int file_pointer_start;
701 int file_pointer_end;
702 int year;
703 int wday;
704 int type;
705} memos[MAX_MEMOS_IN_A_MONTH];
706static int pointer_array[MAX_MEMOS_IN_A_MONTH];
707static int memos_in_memory = 0;
708static int memos_in_shown_memory = 0;
709
710static void load_memo(struct shown *shown)
711{
712 int k, fp;
713 bool exit = false;
714 char temp_memo1[2];
715 char temp_memo2[3];
716 char temp_memo4[5];
717 temp_memo1[1] = 0;
718 temp_memo2[2] = 0;
719 temp_memo4[4] = 0;
720 for (k = 1; k < 32; k++)
721 day_has_memo[k] = false;
722 for (k = 0; k < 7; k++)
723 wday_has_memo[k] = false;
724 memos_in_memory = 0;
725 fp = rb->open(MEMO_FILE, O_RDONLY);
726 if (fp > -1)
727 {
728 rb->lseek(fp, 0, SEEK_SET);
729 while (!exit)
730 {
731 bool load_to_memory;
732 struct memo *memo = &memos[memos_in_memory];
733 rb->memset(memo, 0, sizeof(*memo));
734 memo->file_pointer_start = rb->lseek(fp, 0, SEEK_CUR);
735 if (rb->read(fp, temp_memo2, 2) == 2)
736 memo->day = rb->atoi(temp_memo2);
737 if (rb->read(fp, temp_memo2, 2) == 2)
738 memo->month = rb->atoi(temp_memo2);
739 if (rb->read(fp, temp_memo4, 4) == 4)
740 memo->year = rb->atoi(temp_memo4);
741 if (rb->read(fp, temp_memo1, 1) == 1)
742 memo->wday = rb->atoi(temp_memo1);
743 if (rb->read(fp, temp_memo1, 1) == 1)
744 memo->type = rb->atoi(temp_memo1);
745 load_to_memory = ((memo->type < 2) ||
746 ((memo->type == 2) &&
747 (memo->month == shown->mon)) ||
748 ((memo->type > 2) &&
749 (memo->month == shown->mon) &&
750 (memo->year == shown->year)));
751 k = 0;
752 while (1)
753 {
754 if (rb->read(fp, temp_memo1, 1) != 1)
755 {
756 memo->day = 0;
757 memo->month = 0;
758 memo->file_pointer_start = 0;
759 memo->file_pointer_end = 0;
760 memo->year = 0;
761 memo->type = 0;
762 memo->wday = 0;
763 memo->message[0] = 0;
764 exit = true;
765 break;
766 }
767 if (load_to_memory)
768 {
769 if (temp_memo1[0] == '\n')
770 {
771 if (memo->type > 0)
772 day_has_memo[memo->day] = true;
773 else
774 wday_has_memo[memo->wday] = true;
775 memo->file_pointer_end = rb->lseek(fp, 0, SEEK_CUR);
776 memos_in_memory++;
777 }
778 else if ( (temp_memo1[0] != '\r') &&
779 (temp_memo1[0] != '\t') &&
780 k < MAX_CHAR_MEMO_LEN-1 )
781 memo->message[k++] = temp_memo1[0];
782 }
783 if (temp_memo1[0] == '\n')
784 break;
785 }
786 }
787 rb->close(fp);
788 }
789}
790
791static bool save_memo(int changed, bool new_mod, struct shown *shown)
792{
793 int fp, fq;
794 /* use O_RDWR|O_CREAT so that file is created if it doesn't exist. */
795 fp = rb->open(MEMO_FILE, O_RDWR|O_CREAT, 0666);
796 fq = rb->creat(TEMP_FILE, 0666);
797 if ( (fq > -1) && (fp > -1) )
798 {
799 int i;
800 char temp[MAX_CHAR_MEMO_LEN];
801 struct memo *memo = &memos[changed];
802 rb->lseek(fp, 0, SEEK_SET);
803 for (i = 0; i < memo->file_pointer_start; i++)
804 {
805 rb->read(fp, temp, 1);
806 rb->write(fq, temp, 1);
807 }
808 if (new_mod)
809 {
810 rb->fdprintf(fq, "%02d%02d%04d%01d%01d%s\n",
811 memo->day, memo->month, memo->year, memo->wday,
812 memo->type, memo->message);
813 }
814 rb->lseek(fp, memo->file_pointer_end, SEEK_SET);
815 while(rb->read(fp, temp, 1) == 1)
816 {
817 rb->write(fq, temp, 1);
818 }
819 rb->close(fp);
820 rb->close(fq);
821 rb->remove(MEMO_FILE);
822 rb->rename(TEMP_FILE, MEMO_FILE);
823 load_memo(shown);
824 return true;
825 }
826 else if (fp > -1)
827 rb->close(fp);
828 else if (fq > -1)
829 rb->close(fq);
830 return false;
831}
832
833static void add_memo(struct shown *shown, int type)
834{
835 bool saved = false;
836 struct memo *memo = &memos[memos_in_memory];
837 if (rb->kbd_input(memo->message, MAX_CHAR_MEMO_LEN, NULL) == 0)
838 {
839 if (memo->message[0])
840 {
841 memo->file_pointer_start = 0;
842 memo->file_pointer_end = 0;
843 memo->day = shown->mday;
844 memo->month = shown->mon;
845 memo->wday = shown->wday;
846 memo->year = shown->year;
847 memo->type = type;
848 if (save_memo(memos_in_memory, true, shown))
849 {
850 saved = true;
851 }
852 else
853 {
854 memo->file_pointer_start = 0;
855 memo->file_pointer_end = 0;
856 memo->day = 0;
857 memo->month = 0;
858 memo->year = 0;
859 memo->type = 0;
860 memo->wday = 0;
861 }
862 }
863 }
864 rb->lcd_clear_display();
865 if (saved)
866 rb->splash(HZ/2, "Event added");
867 else
868 rb->splash(HZ/2, "Event not added");
869}
870
871static int edit_menu_cb(int action,
872 const struct menu_item_ex *this_item,
873 struct gui_synclist *this_list)
874{
875 (void)this_list;
876 int i = (intptr_t)this_item;
877 if (action == ACTION_REQUEST_MENUITEM
878 && memos_in_shown_memory <= 0 && (i==0 || i==1))
879 return ACTION_EXIT_MENUITEM;
880 return action;
881}
882
883static bool edit_memo(int change, struct shown *shown)
884{
885 bool exit = false;
886 int selected = 0;
887
888 static const struct opt_items modes[7] = {
889 { "Mon", -1 },
890 { "Tue", -1 },
891 { "Wed", -1 },
892 { "Thu", -1 },
893 { "Fri", -1 },
894 { "Sat", -1 },
895 { "Sun", -1 },
896 };
897
898 MENUITEM_STRINGLIST(edit_menu, "Edit menu", edit_menu_cb,
899 "Remove", "Edit",
900 "New Weekly", "New Monthly",
901 "New Yearly", "New One off",
902 "First Day of Week",
903 "Playback Control");
904
905 while (!exit)
906 {
907 switch (rb->do_menu(&edit_menu, &selected, NULL, false))
908 {
909 case 0: /* remove */
910 save_memo(change, false, shown);
911 return false;
912
913 case 1: /* edit */
914 if(rb->kbd_input(memos[change].message,
915 MAX_CHAR_MEMO_LEN, NULL) == 0)
916 save_memo(change, true, shown);
917 return false;
918
919 case 2: /* weekly */
920 add_memo(shown, 0);
921 return false;
922
923 case 3: /* monthly */
924 add_memo(shown, 1);
925 return false;
926
927 case 4: /* yearly */
928 add_memo(shown, 2);
929 return false;
930
931 case 5: /* one off */
932 add_memo(shown, 3);
933 return false;
934
935 case 6: /* weekday */
936 rb->set_option("First Day of Week", &info.first_wday,
937 RB_INT, modes, 7, NULL);
938 break;
939
940 case 7: /* playback control */
941 playback_control(NULL);
942 break;
943
944 case GO_TO_PREVIOUS:
945 return false;
946
947 case MENU_ATTACHED_USB:
948 been_in_usb_mode = true;
949 break;
950 }
951 }
952 return false;
953}
954
955static const char* get_event_text(int selected, void *data,
956 char *buffer, size_t buffer_len)
957{
958 struct shown *shown = (struct shown *) data;
959 struct memo *memo;
960 if (selected < 0 || memos_in_shown_memory <= selected)
961 {
962 return NULL;
963 }
964 memo = &memos[pointer_array[selected]];
965 if (memo->type == 2)
966 rb->snprintf(buffer, buffer_len, "%s (%d yrs)",
967 memo->message, shown->year - memo->year);
968 else
969 rb->snprintf(buffer, buffer_len, "%s", memo->message);
970 return buffer;
971}
972
973static bool view_events(int selected, struct shown *shown)
974{
975 struct gui_synclist gui_memos;
976 bool exit=false;
977 int button;
978
979 rb->gui_synclist_init(&gui_memos, &get_event_text, shown, false, 1, NULL);
980 rb->gui_synclist_set_title(&gui_memos, "Events (" CALENDAR_EVENT_MENU_NAME " : menu)", NOICON);
981 rb->gui_synclist_set_nb_items(&gui_memos, memos_in_shown_memory);
982 rb->gui_synclist_select_item(&gui_memos, selected);
983 rb->gui_synclist_draw(&gui_memos);
984
985 while (!exit)
986 {
987 button = rb->get_action(CONTEXT_LIST, TIMEOUT_BLOCK);
988 rb->gui_synclist_do_button(&gui_memos, &button);
989
990 switch (button)
991 {
992 case ACTION_STD_OK:
993 selected = rb->gui_synclist_get_sel_pos(&gui_memos);
994 return edit_memo(pointer_array[selected], shown);
995 break;
996
997 case ACTION_STD_CANCEL:
998 return false;
999 break;
1000
1001 default:
1002 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1003 been_in_usb_mode = true;
1004 break;
1005 }
1006 }
1007
1008 return false;
1009}
1010
1011static void update_memos_shown(struct shown *shown)
1012{
1013 int i;
1014 struct memo *memo;
1015 memos_in_shown_memory = 0;
1016 for (i = 0; i < memos_in_memory; i++)
1017 {
1018 memo = &memos[i];
1019 if (((memo->type >= 1) && (memo->day == shown->mday)) ||
1020 ((memo->type < 1) && (memo->wday == shown->wday)))
1021 pointer_array[memos_in_shown_memory++] = i;
1022 }
1023}
1024
1025static bool any_events(struct shown *shown, bool force)
1026{
1027 update_memos_shown(shown);
1028
1029 if (memos_in_shown_memory > 0)
1030 return view_events(0, shown);
1031 else if (force)
1032 return edit_memo(0, shown);
1033 else
1034 return false;
1035
1036 return false;
1037}
1038
1039static void next_month(struct shown *shown, int step)
1040{
1041 shown->mon++;
1042 if (shown->mon > 12)
1043 {
1044 shown->mon = 1;
1045 shown->year++;
1046 leap_year = is_leap_year(shown->year);
1047 }
1048 if (step > 0)
1049 shown->mday = shown->mday - days_in_month[leap_year][shown->mon-1];
1050 else if (shown->mday > days_in_month[leap_year][shown->mon])
1051 shown->mday = days_in_month[leap_year][shown->mon];
1052 shown->firstday = shown->lastday;
1053 load_memo(shown);
1054 draw_calendar(shown);
1055}
1056
1057static void prev_month(struct shown *shown, int step)
1058{
1059 shown->mon--;
1060 if (shown->mon < 1)
1061 {
1062 shown->mon = 12;
1063 shown->year--;
1064 leap_year = is_leap_year(shown->year);
1065 }
1066 if (step > 0)
1067 shown->mday = shown->mday + days_in_month[leap_year][shown->mon];
1068 else if (shown->mday > days_in_month[leap_year][shown->mon])
1069 shown->mday = days_in_month[leap_year][shown->mon];
1070 shown->firstday += 7 - (days_in_month[leap_year][shown->mon] % 7);
1071 if (shown->firstday >= 7)
1072 shown->firstday -= 7;
1073 load_memo(shown);
1074 draw_calendar(shown);
1075}
1076
1077static void next_day(struct shown *shown, int step)
1078{
1079 shown->mday += step;
1080 if (shown->mday > days_in_month[leap_year][shown->mon])
1081 next_month(shown, step);
1082 else
1083 draw_calendar(shown);
1084}
1085
1086static void prev_day(struct shown *shown, int step)
1087{
1088 shown->mday -= step;
1089 if (shown->mday < 1)
1090 prev_month(shown, step);
1091 else
1092 draw_calendar(shown);
1093}
1094
1095enum plugin_status plugin_start(const void* parameter)
1096{
1097 struct shown shown;
1098 bool exit = false;
1099 int button;
1100
1101 (void)(parameter);
1102
1103 configfile_load(CFG_FILE, config, ARRAYLEN(config), 0);
1104 rb->memcpy(&old_info, &info, sizeof(struct info));
1105
1106 calendar_init(&shown);
1107 load_memo(&shown);
1108 any_events(&shown, false);
1109 draw_calendar(&shown);
1110
1111 while (!exit)
1112 {
1113 button = rb->button_get(true);
1114 switch (button)
1115 {
1116 case CALENDAR_QUIT:
1117 exit = true;
1118 break;
1119#ifdef CALENDAR_NEXT_MONTH
1120 case CALENDAR_NEXT_MONTH:
1121 case CALENDAR_NEXT_MONTH | BUTTON_REPEAT:
1122 next_month(&shown, 0);
1123 break;
1124#endif
1125#ifdef CALENDAR_PREV_MONTH
1126 case CALENDAR_PREV_MONTH:
1127 case CALENDAR_PREV_MONTH | BUTTON_REPEAT:
1128 prev_month(&shown, 0);
1129 break;
1130#endif
1131 case CALENDAR_NEXT_WEEK:
1132 case CALENDAR_NEXT_WEEK | BUTTON_REPEAT:
1133 next_day(&shown, 7);
1134 break;
1135
1136 case CALENDAR_PREV_WEEK:
1137 case CALENDAR_PREV_WEEK | BUTTON_REPEAT:
1138 prev_day(&shown, 7);
1139 break;
1140
1141 case CALENDAR_PREV_DAY:
1142 case CALENDAR_PREV_DAY | BUTTON_REPEAT:
1143 prev_day(&shown, 1);
1144 break;
1145
1146 case CALENDAR_NEXT_DAY:
1147 case CALENDAR_NEXT_DAY | BUTTON_REPEAT:
1148 next_day(&shown, 1);
1149 break;
1150
1151 case CALENDAR_SELECT:
1152 any_events(&shown, true);
1153 draw_calendar(&shown);
1154 break;
1155
1156 default:
1157 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1158 been_in_usb_mode = true;
1159 draw_calendar(&shown);
1160 break;
1161 }
1162 }
1163
1164
1165#if (CONFIG_RTC == 0)
1166 info.last_mon = shown.mon;
1167 info.last_year = shown.year;
1168#endif
1169 if (rb->memcmp(&old_info, &info, sizeof(struct info)))
1170 configfile_save(CFG_FILE, config, ARRAYLEN(config), 0);
1171 return been_in_usb_mode?PLUGIN_USB_CONNECTED:PLUGIN_OK;
1172}