diff options
Diffstat (limited to 'apps/plugins/alarmclock.c')
-rw-r--r-- | apps/plugins/alarmclock.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/apps/plugins/alarmclock.c b/apps/plugins/alarmclock.c new file mode 100644 index 0000000000..c8653dcd64 --- /dev/null +++ b/apps/plugins/alarmclock.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2010 Clément Pit-Claudel | ||
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 | #include "lib/pluginlib_actions.h" | ||
24 | |||
25 | PLUGIN_HEADER | ||
26 | |||
27 | const struct button_mapping *plugin_contexts[] = {generic_directions, | ||
28 | generic_actions}; | ||
29 | |||
30 | static int current = 0; | ||
31 | static int alarm[2] = {0, 0}, maxval[2] = {24, 60}; | ||
32 | static bool quit = false, usb = false, waiting = false, done = false; | ||
33 | |||
34 | static inline int get_button(void) { | ||
35 | return pluginlib_getaction(HZ/2, plugin_contexts, 2); | ||
36 | } | ||
37 | |||
38 | int rem_seconds(void) { | ||
39 | return (((alarm[0] - rb->get_time()->tm_hour) * 3600) | ||
40 | +((alarm[1] - rb->get_time()->tm_min) * 60) | ||
41 | -(rb->get_time()->tm_sec)); | ||
42 | } | ||
43 | |||
44 | void draw(void) { | ||
45 | char info[128]; | ||
46 | rb->lcd_clear_display(); | ||
47 | |||
48 | int secs = rem_seconds(); | ||
49 | |||
50 | if (waiting) | ||
51 | rb->snprintf(info, sizeof(info), "Next alarm in %02dh," | ||
52 | " %02dmn, and %02ds.", | ||
53 | secs / 3600, (secs / 60) % 60, secs % 60); | ||
54 | else { | ||
55 | if (current == 0) | ||
56 | rb->snprintf(info, sizeof(info), "Set alarm at [%02d]:%02d.", | ||
57 | alarm[0], | ||
58 | alarm[1]); | ||
59 | else | ||
60 | rb->snprintf(info, sizeof(info), "Set alarm at %02d:[%02d].", | ||
61 | alarm[0], | ||
62 | alarm[1]); | ||
63 | } | ||
64 | |||
65 | int w, h; | ||
66 | rb->lcd_getstringsize(info, &w, &h); | ||
67 | |||
68 | if (w > LCD_WIDTH || h > LCD_HEIGHT) | ||
69 | rb->splash(0, info); | ||
70 | else { | ||
71 | rb->lcd_putsxy((LCD_WIDTH - w) / 2, (LCD_HEIGHT - h) / 2, info); | ||
72 | rb->lcd_update(); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | bool can_play(void) { | ||
77 | int audio_status = rb->audio_status(); | ||
78 | if ((!audio_status && rb->global_status->resume_index != -1) | ||
79 | && (rb->playlist_resume() != -1)) { | ||
80 | return true; | ||
81 | } | ||
82 | else if (audio_status & AUDIO_STATUS_PAUSE) | ||
83 | return true; | ||
84 | |||
85 | return false; | ||
86 | } | ||
87 | |||
88 | void play(void) { | ||
89 | int audio_status = rb->audio_status(); | ||
90 | if (!audio_status && rb->global_status->resume_index != -1) { | ||
91 | if (rb->playlist_resume() != -1) { | ||
92 | rb->playlist_start(rb->global_status->resume_index, | ||
93 | rb->global_status->resume_offset); | ||
94 | } | ||
95 | } | ||
96 | else if (audio_status & AUDIO_STATUS_PAUSE) | ||
97 | rb->audio_resume(); | ||
98 | } | ||
99 | |||
100 | enum plugin_status plugin_start(const void* parameter) | ||
101 | { | ||
102 | int button; | ||
103 | (void)parameter; | ||
104 | |||
105 | if (!can_play()) { | ||
106 | rb->splash(4*HZ, "No track to resume! This plugin will resume a track " | ||
107 | "at a specific time. Therefore, you need to first play" | ||
108 | " one, and then pause it and start the plugin again."); | ||
109 | quit = true; | ||
110 | } | ||
111 | |||
112 | while(!quit) { | ||
113 | button = get_button(); | ||
114 | |||
115 | if (button == PLA_QUIT) | ||
116 | quit = true; | ||
117 | |||
118 | draw(); | ||
119 | if (waiting) { | ||
120 | if (rem_seconds() <= 0) { | ||
121 | quit = done = true; | ||
122 | play(); | ||
123 | } | ||
124 | } | ||
125 | else { | ||
126 | switch (button) { | ||
127 | case PLA_UP: | ||
128 | case PLA_UP_REPEAT: | ||
129 | alarm[current] = (alarm[current] + 1) % maxval[current]; | ||
130 | break; | ||
131 | |||
132 | case PLA_DOWN: | ||
133 | case PLA_DOWN_REPEAT: | ||
134 | alarm[current] = (alarm[current] + maxval[current] - 1) | ||
135 | % maxval[current]; | ||
136 | break; | ||
137 | |||
138 | case PLA_LEFT: | ||
139 | case PLA_LEFT_REPEAT: | ||
140 | case PLA_RIGHT: | ||
141 | case PLA_RIGHT_REPEAT: | ||
142 | current = (current + 1) % 2; | ||
143 | break; | ||
144 | |||
145 | case PLA_FIRE: { | ||
146 | if (rem_seconds() < 0) | ||
147 | alarm[0] += 24; | ||
148 | |||
149 | waiting = true; | ||
150 | break; | ||
151 | } | ||
152 | |||
153 | default: | ||
154 | if (rb->default_event_handler(button) == SYS_USB_CONNECTED) | ||
155 | quit = usb = true; | ||
156 | break; | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | return (usb) ? PLUGIN_USB_CONNECTED | ||
162 | : (done ? PLUGIN_GOTO_WPS : PLUGIN_OK); | ||
163 | } | ||
164 | |||