]> git.karo-electronics.de Git - oswald.git/blob - ui/oswald_screens.c
Starting to get rid of borrowed code (LcdDisplay, Fonts), integrate
[oswald.git] / ui / oswald_screens.c
1 #include <stdio.h>
2
3 #include "oswald.h"
4 #include "oswald_main.h"
5 #include "oswald_watch_faces.h"
6 #include "oswald_graphics.h"
7 #include "oswald_hal.h"
8
9 #include "oswald_screens.h"
10
11 #include "LcdDisplay.h"
12 #include "Fonts.h"
13
14 #if defined(__GNUC__) && (__MSP430X__ > 0)
15 __attribute__((__far__))
16 #endif
17 #include "bitmaps/timesetup_icon.xbm"
18 #if defined(__GNUC__) && (__MSP430X__ > 0)
19 __attribute__((__far__))
20 #endif
21 #include "bitmaps/stopwatch_icon.xbm"
22 #if defined(__GNUC__) && (__MSP430X__ > 0)
23 __attribute__((__far__))
24 #endif
25 #include "bitmaps/alarm_icon.xbm"
26 #if defined(__GNUC__) && (__MSP430X__ > 0)
27 __attribute__((__far__))
28 #endif
29 #include "bitmaps/startstopbutton_icon.xbm"
30 #if defined(__GNUC__) && (__MSP430X__ > 0)
31 __attribute__((__far__))
32 #endif
33 #include "bitmaps/lapsebutton_icon.xbm"
34 #if defined(__GNUC__) && (__MSP430X__ > 0)
35 __attribute__((__far__))
36 #endif
37 #include "bitmaps/upbutton_icon.xbm"
38 #if defined(__GNUC__) && (__MSP430X__ > 0)
39 __attribute__((__far__))
40 #endif
41 #include "bitmaps/downbutton_icon.xbm"
42 #if defined(__GNUC__) && (__MSP430X__ > 0)
43 __attribute__((__far__))
44 #endif
45 #include "bitmaps/Bluetooth_icon.xbm"
46
47
48 typedef struct {
49         void (*screendraw_func)(boolean show_seconds);
50         boolean show_seconds;
51         boolean analogue;
52 } idle_data_t;
53 static idle_data_t idle_screen = {
54         DrawLcdDigitalClock,
55         TRUE,
56         FALSE,
57 };
58  
59 void idle_handle_user_buttons(watch_button button)
60 {
61         switch (button) {
62                 case BUTTON_A:
63                         if (idle_screen.show_seconds)
64                                 idle_screen.show_seconds = FALSE;
65                         else
66                                 idle_screen.show_seconds = TRUE;
67                         break;
68                 case BUTTON_B:
69                         if (idle_screen.analogue == TRUE) {
70                                 idle_screen.analogue = FALSE;
71                                 idle_screen.screendraw_func = DrawLcdDigitalClock;
72                         } else {
73                                 idle_screen.analogue = TRUE;
74                                 idle_screen.screendraw_func = DrawLcdAnaClock;
75                         };
76                         break;
77                 case BUTTON_F:
78                         OswaldState.screen_id = DATETIME_SETTING_SCREEN;
79                         OswaldState.screen = &OswaldScreens[OswaldState.screen_id];
80                         OswaldState.screen->event_func(EVENT_SCREEN_VISIBLE, NULL);
81                         return;
82                         break;
83                 default:
84                         break;
85         };
86         idle_screen.screendraw_func(idle_screen.show_seconds);
87 }
88
89 void idle_handle_events(u16t event, void *data)
90 {
91         switch (event) {
92                 case EVENT_ONE_SEC_TIMER:
93                 case EVENT_SCREEN_VISIBLE:
94                         idle_screen.screendraw_func(idle_screen.show_seconds);
95                         break;
96                 case EVENT_USER_BUTTONS:
97                         dbg_out("button event %d\n", *(int *)data);
98                         idle_handle_user_buttons(*(watch_button *)data);
99                         break;
100                 default:
101                         break;
102         };
103 }
104
105
106 typedef struct {
107         accel_data_t accdata;
108 } accelscreen_data_t;
109 static accelscreen_data_t accel_screen = {
110         { 0, 0, 0},
111 };
112
113 void draw_accel_screen(accel_data_t *accel_data)
114 {
115         hal_lcd_clear_display();
116
117         oswald_write_string(0, 2, FONT_7x12b, "X:");
118         oswald_write_number(20, 2, FONT_7x12b, accel_data->x);
119         oswald_write_string(0, 18, FONT_7x12b, "Y:");
120         oswald_write_number(20, 18, FONT_7x12b, accel_data->y);
121 #if 0
122         oswald_write_string(0, 34, FONT_8x12, "Z:");
123         oswald_write_number(20, 34, FONT_8x12, accel_data->z);
124
125         oswald_write_string(0, 54, FONT_12x16, "Light:");
126         oswald_write_number(50, 54, FONT_12x16, accel_data->z);
127
128         oswald_write_string(0, 70, FONT_12x20, "23:59");
129 #endif
130         hal_lcd_update_display();
131 }
132
133 void accel_handle_events(u16t event, void *data)
134 {
135         switch (event) {
136                 case EVENT_SCREEN_VISIBLE:
137                         draw_accel_screen(&accel_screen.accdata);
138                         break;
139                 case EVENT_ACCEL_UPDATE: {
140                         accel_data_t *accel_data = (accel_data_t *)data;
141                         accel_screen.accdata.x = accel_data->x;
142                         accel_screen.accdata.y = accel_data->y;
143                         accel_screen.accdata.z = accel_data->z;
144                         draw_accel_screen(&accel_screen.accdata);
145                         };
146                         break;
147                 case EVENT_USER_BUTTONS:
148                         dbg_out("button event %d\n", *(int *)data);
149                         break;
150                 default:
151                         break;
152         };
153 }
154
155
156 typedef struct {
157         u8t pos;
158         boolean on;
159 } datetime_setup_data_t;
160 static datetime_setup_data_t dt_setup_screen = {
161         0,
162         TRUE
163 };
164
165 void draw_datetime_setup_screen(datetime_setup_data_t *sdata)
166 {
167         hal_lcd_clear_display();
168
169         oswald_draw_bitmap(36, 0, timesetup_icon_width, timesetup_icon_height, timesetup_icon_bits);
170
171         oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
172         oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
173
174         SetFont(MetaWatchTime);
175         if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
176                 WriteLcdCharacter(2, 30, (OswaldClk.hour / 10));
177                 WriteLcdCharacter(14, 30, (OswaldClk.hour % 10));
178         }
179         WriteLcdCharacter(26, 30, TIME_CHARACTER_COLON_INDEX);
180
181         if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
182                 WriteLcdCharacter(31, 30, (OswaldClk.minute / 10));
183                 WriteLcdCharacter(43, 30, (OswaldClk.minute % 10));
184         }
185
186         SetFont(MetaWatch16);
187         if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2) {
188                 WriteLcdCharacter(59, 36, 0x30 + (OswaldClk.second / 10));
189                 WriteLcdCharacter(66, 36, 0x30 + (OswaldClk.second % 10));
190         }
191
192
193         if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3) {
194                 WriteLcdNumber(2, 55, OswaldClk.day);
195         }
196         WriteLcdString(18, 55, ".");
197         if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4) {
198                 WriteLcdNumber(22, 55, OswaldClk.month);
199         }
200         WriteLcdString(38, 55, ".");
201         if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5) {
202                 WriteLcdNumber(42, 55, OswaldClk.year);
203         }
204
205         SetFont(MetaWatch7);
206         if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6) {
207                 if (OswaldClk.clk24hr)
208                         WriteLcdString(2, 76, "x");
209                 else
210                         WriteLcdString(2, 76, "_");
211         }
212         WriteLcdString(15, 76, "24hr");
213
214         if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7) {
215                 if (OswaldClk.day_first)
216                         WriteLcdString(2, 89, "x");
217                 else
218                         WriteLcdString(2, 89, "_");
219         }
220         WriteLcdString(15, 89, "dd.mm.  mm/dd");
221
222         hal_lcd_update_display();
223 }
224
225 void datetime_handle_updown(u8t pos, s8t incr)
226 {
227         switch (pos) {
228                 case 0: // hour
229                         if (OswaldClk.hour == 0 && incr == -1) {
230                                 OswaldClk.hour = 23;
231                                 break;
232                         };
233                         OswaldClk.hour += incr;
234                         if (OswaldClk.hour > 23)
235                                 OswaldClk.hour = 0;
236                         break;
237                 case 1: // minute
238                         if (OswaldClk.minute == 0 && incr == -1) {
239                                 OswaldClk.minute = 59;
240                                 break;
241                         };
242                         OswaldClk.minute += incr;
243                         if (OswaldClk.minute > 59)
244                                 OswaldClk.minute = 0;
245                         break;
246                 case 2: // second
247                         OswaldClk.second = 0;
248                         break;
249                 case 3: // day
250                         if (OswaldClk.day == 1 && incr == -1) {
251                                 OswaldClk.day = 31;
252                                 break;
253                         };
254                         OswaldClk.day += incr;
255                         if (OswaldClk.day > 31)
256                                 OswaldClk.day = 1;
257                         break;
258                 case 4: // month
259                         if (OswaldClk.month == 1 && incr == -1) {
260                                 OswaldClk.month = 12;
261                                 break;
262                         };
263                         OswaldClk.month += incr;
264                         if (OswaldClk.month > 12)
265                                 OswaldClk.month = 1;
266                         break;
267                 case 5: // year
268                         OswaldClk.year += incr;
269                         break;
270                 case 6: // 24hr / 12hr
271                         if (OswaldClk.clk24hr)
272                                 OswaldClk.clk24hr = FALSE;
273                         else
274                                 OswaldClk.clk24hr = TRUE;
275                         break;
276                 case 7: // dd.mm. / mm/dd
277                         if (OswaldClk.day_first)
278                                 OswaldClk.day_first = FALSE;
279                         else
280                                 OswaldClk.day_first = TRUE;
281                         break;
282                 default:
283                         break;
284         };
285         if (pos == 2)
286                 hal_set_rtc(&OswaldClk, TRUE);
287         else
288                 hal_set_rtc(&OswaldClk, FALSE);
289 }
290
291 void handle_setup_datetime_buttons(watch_button button, datetime_setup_data_t *sdata)
292 {
293         switch (button) {
294                 case BUTTON_A:
295                         datetime_handle_updown(sdata->pos, 1);
296                         break;
297                 case BUTTON_B:
298                         datetime_handle_updown(sdata->pos, -1);
299                         break;
300                 case BUTTON_F:
301                         sdata->pos++;
302                         sdata->pos %= 8;
303                         break;
304                 default:
305                         break;
306         }
307         draw_datetime_setup_screen(sdata);
308 }
309
310 void datetime_setup_events(u16t event, void *data)
311 {
312         switch (event) {
313                 case EVENT_SCREEN_VISIBLE:
314                         dt_setup_screen.pos = 0;
315                         draw_datetime_setup_screen(&dt_setup_screen);
316                         hal_enable_halfsecond_timer();
317                         break;
318                 case EVENT_SCREEN_DESTROY:
319                         hal_disable_halfsecond_timer();
320                         break;
321                 case EVENT_USER_BUTTONS:
322                         dbg_out("button event %d\n", *(int *)data);
323                         handle_setup_datetime_buttons(*(watch_button *)data, &dt_setup_screen);
324                         break;
325                 case EVENT_HALF_SEC_TIMER:
326                         if (dt_setup_screen.on)
327                                 dt_setup_screen.on = FALSE;
328                         else
329                                 dt_setup_screen.on = TRUE;
330                         draw_datetime_setup_screen(&dt_setup_screen);
331                         break;
332                 default:
333                         break;
334         };
335 }
336
337
338 /*
339  * Alarm setup
340  */
341
342 typedef struct {
343         u8t pos;
344         boolean on;
345 } alarm_setup_data_t;
346 static alarm_setup_data_t alarm_setup_screen = {
347         0,
348         TRUE
349 };
350
351 void draw_alarm_setup_screen(alarm_setup_data_t *sdata)
352 {
353         hal_lcd_clear_display();
354
355         oswald_draw_bitmap(36, 0, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
356
357         oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
358         oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
359
360         SetFont(MetaWatchTime);
361         if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
362                 WriteLcdCharacter(22, 30, (OswaldAlarm.hour / 10));
363                 WriteLcdCharacter(34, 30, (OswaldAlarm.hour % 10));
364         }
365         WriteLcdCharacter(46, 30, TIME_CHARACTER_COLON_INDEX);
366
367         if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
368                 WriteLcdCharacter(51, 30, (OswaldAlarm.minute / 10));
369                 WriteLcdCharacter(63, 30, (OswaldAlarm.minute % 10));
370         }
371
372         SetFont(MetaWatchMonospaced10);
373         WriteLcdCharacter(3, 55, 'S');
374         WriteLcdCharacter(15, 55, 'M');
375         WriteLcdCharacter(27, 55, 'T');
376         WriteLcdCharacter(39, 55, 'W');
377         WriteLcdCharacter(51, 55, 'T');
378         WriteLcdCharacter(63, 55, 'F');
379         WriteLcdCharacter(75, 55, 'S');
380
381         if ((sdata->pos == 2 && sdata->on) || sdata->pos != 2)
382                 WriteLcdCharacter(3, 65, (OswaldAlarm.wday & WDAY_SUNDAY) ? 'x' : '_');
383         if ((sdata->pos == 3 && sdata->on) || sdata->pos != 3)
384                 WriteLcdCharacter(15, 65, (OswaldAlarm.wday & WDAY_MONDAY) ? 'x' : '_');
385         if ((sdata->pos == 4 && sdata->on) || sdata->pos != 4)
386                 WriteLcdCharacter(27, 65, (OswaldAlarm.wday & WDAY_TUESDAY) ? 'x' : '_');
387         if ((sdata->pos == 5 && sdata->on) || sdata->pos != 5)
388                 WriteLcdCharacter(39, 65, (OswaldAlarm.wday & WDAY_WEDNESDAY) ? 'x' : '_');
389         if ((sdata->pos == 6 && sdata->on) || sdata->pos != 6)
390                 WriteLcdCharacter(51, 65, (OswaldAlarm.wday & WDAY_THURSDAY) ? 'x' : '_');
391         if ((sdata->pos == 7 && sdata->on) || sdata->pos != 7)
392                 WriteLcdCharacter(63, 65, (OswaldAlarm.wday & WDAY_FRIDAY) ? 'x' : '_');
393         if ((sdata->pos == 8 && sdata->on) || sdata->pos != 8)
394                 WriteLcdCharacter(75, 65, (OswaldAlarm.wday & WDAY_SATURDAY) ? 'x' : '_');
395
396         hal_lcd_update_display();
397 }
398
399 void alarm_handle_updown(u8t pos, s8t incr)
400 {
401         switch (pos) {
402                 case 0: // hour
403                         if (OswaldAlarm.hour == 0 && incr == -1) {
404                                 OswaldAlarm.hour = 23;
405                                 break;
406                         };
407                         OswaldAlarm.hour += incr;
408                         if (OswaldAlarm.hour > 23)
409                                 OswaldAlarm.hour = 0;
410                         break;
411                 case 1: // minute
412                         if (OswaldAlarm.minute == 0 && incr == -1) {
413                                 OswaldAlarm.minute = 59;
414                                 break;
415                         };
416                         OswaldAlarm.minute += incr;
417                         if (OswaldAlarm.minute > 59)
418                                 OswaldAlarm.minute = 0;
419                         break;
420                 case 2: // sunday
421                         OswaldAlarm.wday ^= WDAY_SUNDAY;
422                         break;
423                 case 3: // monday
424                         OswaldAlarm.wday ^= WDAY_MONDAY;
425                         break;
426                 case 4: // tuesday
427                         OswaldAlarm.wday ^= WDAY_TUESDAY;
428                         break;
429                 case 5: // wednesday
430                         OswaldAlarm.wday ^= WDAY_WEDNESDAY;
431                         break;
432                 case 6: // thursday
433                         OswaldAlarm.wday ^= WDAY_THURSDAY;
434                         break;
435                 case 7: // friday
436                         OswaldAlarm.wday ^= WDAY_FRIDAY;
437                         break;
438                 case 8: // saturday
439                         OswaldAlarm.wday ^= WDAY_SATURDAY;
440                         break;
441                 default:
442                         break;
443         };
444 }
445
446 void handle_setup_alarm_buttons(watch_button button, alarm_setup_data_t *sdata)
447 {
448         switch (button) {
449                 case BUTTON_A:
450                         alarm_handle_updown(sdata->pos, 1);
451                         break;
452                 case BUTTON_B:
453                         alarm_handle_updown(sdata->pos, -1);
454                         break;
455                 case BUTTON_F:
456                         sdata->pos++;
457                         sdata->pos %= 9;
458                         break;
459                 default:
460                         break;
461         }
462         draw_alarm_setup_screen(sdata);
463 }
464
465 void alarm_setup_events(u16t event, void *data)
466 {
467         switch (event) {
468                 case EVENT_SCREEN_VISIBLE:
469                         alarm_setup_screen.pos = 0;
470                         draw_alarm_setup_screen(&alarm_setup_screen);
471                         hal_enable_halfsecond_timer();
472                         break;
473                 case EVENT_SCREEN_DESTROY:
474                         hal_disable_halfsecond_timer();
475                         break;
476                 case EVENT_USER_BUTTONS:
477                         dbg_out("button event %d\n", *(int *)data);
478                         handle_setup_alarm_buttons(*(watch_button *)data, &alarm_setup_screen);
479                         break;
480                 case EVENT_HALF_SEC_TIMER:
481                         if (alarm_setup_screen.on)
482                                 alarm_setup_screen.on = FALSE;
483                         else
484                                 alarm_setup_screen.on = TRUE;
485                         draw_alarm_setup_screen(&alarm_setup_screen);
486                         break;
487                 default:
488                         break;
489         };
490 }
491
492
493 /*
494  * Test menu
495  */
496
497 typedef struct {
498         u8t menu_pos;
499 } test_menu_t;
500 static test_menu_t test_menu = { 0 };
501
502 void draw_menu_test_screen(void)
503 {
504         hal_lcd_clear_display();
505         SetFont(MetaWatch16);
506         WriteLcdString(2, 2, "Menu");
507         SetFont(MetaWatch7);
508         WriteLcdString(2, 20, "Item 1");
509         WriteLcdString(2, 29, "Item 2");
510         WriteLcdString(2, 38, "Item 3");
511         WriteLcdString(2, 47, "Item 4");
512         WriteLcdString(2, 56, "Item 5");
513
514         WriteLcdString(50, 20+(9*test_menu.menu_pos), "*");
515         hal_lcd_update_display();
516 }
517
518 static void handle_menu_user_buttons(watch_button button)
519 {
520         switch (button) {
521                 case BUTTON_A:
522                         test_menu.menu_pos--;
523                         test_menu.menu_pos%=5;
524                         break;
525                 case BUTTON_B:
526                         test_menu.menu_pos++;
527                         test_menu.menu_pos%=5;
528                         break;
529                 default:
530                         break;
531         }
532         draw_menu_test_screen();
533 }
534
535 void test_menu_handle_events(u16t event, void *data)
536 {
537         switch (event) {
538                 case EVENT_USER_BUTTONS:
539                         dbg_out("button event %d\n", *(int *)data);
540                         handle_menu_user_buttons(*(watch_button *)data);
541                         break;
542                 case EVENT_SCREEN_VISIBLE:
543                         test_menu.menu_pos = 0;
544                         draw_menu_test_screen();
545                         break;
546                 default:
547                         break;
548         };
549 }
550
551
552 /*
553  * Stop Watch
554  */
555
556 typedef struct {
557         u8t hr;
558         u8t min;
559         u8t sec;
560         u8t csec;
561         u8t lapse_hr;
562         u8t lapse_min;
563         u8t lapse_sec;
564         u8t lapse_csec;
565         boolean running;
566 } stopwatch_data_t;
567 static stopwatch_data_t stopwatch_screen = { 0, 0, 0, 0, 0, 0, 0, 0, FALSE };
568
569
570 static void update_stop_watch_screen(stopwatch_data_t *sdata)
571 {
572         char tstr[16];
573         SetFont(MetaWatchMonospaced10);
574
575         snprintf(tstr, 16, "%02d:%02d:%02d.%1d", sdata->hr, sdata->min, sdata->sec, sdata->csec / 10);
576         WriteLcdString(5, 40, tstr);
577         snprintf(tstr, 16, "%02d:%02d:%02d.%02d", sdata->lapse_hr, sdata->lapse_min, sdata->lapse_sec, sdata->lapse_csec);
578         WriteLcdString(5, 60, tstr);
579
580         hal_lcd_update_display();
581 }
582
583 static void draw_stop_watch_screen(stopwatch_data_t *sdata)
584 {
585         oswald_draw_bitmap(36, 0, stopwatch_icon_width, stopwatch_icon_height, stopwatch_icon_bits);
586         oswald_draw_bitmap(81, 6, startstopbutton_icon_width, startstopbutton_icon_height, startstopbutton_icon_bits);
587         oswald_draw_bitmap(81, 38, lapsebutton_icon_width, lapsebutton_icon_height, lapsebutton_icon_bits);
588
589         update_stop_watch_screen(sdata);
590 }
591
592 static void handle_stop_watch_buttons(watch_button button)
593 {
594         switch (button) {
595                 case BUTTON_A: // start/stop
596                         if (stopwatch_screen.running) {
597                                 hal_disable_centisecond_timer();
598                                 stopwatch_screen.running = FALSE;
599                         } else {
600                                 hal_enable_centisecond_timer();
601                                 stopwatch_screen.running = TRUE;
602                         }
603                         break;
604                 case BUTTON_B: // lapse
605                         stopwatch_screen.lapse_hr = stopwatch_screen.hr;
606                         stopwatch_screen.lapse_min = stopwatch_screen.min;
607                         stopwatch_screen.lapse_sec = stopwatch_screen.sec;
608                         stopwatch_screen.lapse_csec = stopwatch_screen.csec;
609                         break;
610                 case BUTTON_F: // reset
611                         stopwatch_screen.hr = 0;
612                         stopwatch_screen.min = 0;
613                         stopwatch_screen.sec = 0;
614                         stopwatch_screen.csec = 0;
615                         stopwatch_screen.lapse_hr = 0;
616                         stopwatch_screen.lapse_min = 0;
617                         stopwatch_screen.lapse_sec = 0;
618                         stopwatch_screen.lapse_csec = 0;
619                         break;
620                 default:
621                         break;
622         }
623 }
624
625 void stop_watch_handle_events(u16t event, void *data)
626 {
627         switch (event) {
628                 case EVENT_USER_BUTTONS:
629                         dbg_out("button event %d\n", *(int *)data);
630                         handle_stop_watch_buttons(*(watch_button *)data);
631                         update_stop_watch_screen(&stopwatch_screen);
632                         break;
633                 case EVENT_SCREEN_VISIBLE:
634                         hal_lcd_clear_display();
635                         draw_stop_watch_screen(&stopwatch_screen);
636                         break;
637                 case EVENT_SCREEN_DESTROY:
638                         hal_disable_centisecond_timer();
639                         stopwatch_screen.running = FALSE;
640                         break;
641                 case EVENT_CS_TIMER:
642                         stopwatch_screen.csec++;
643                         if (stopwatch_screen.csec > 99) {
644                                 stopwatch_screen.csec = 0;
645                                 stopwatch_screen.sec++;
646                         };
647                         if (stopwatch_screen.sec > 59) {
648                                 stopwatch_screen.sec = 0;
649                                 stopwatch_screen.min++;
650                         };
651                         if (stopwatch_screen.min > 59) {
652                                 stopwatch_screen.min = 0;
653                                 stopwatch_screen.hr++;
654                         };
655                         if (stopwatch_screen.hr > 59) {
656                                 stopwatch_screen.hr = 0;
657                         };
658                         if (stopwatch_screen.csec % 10 == 0)
659                                 update_stop_watch_screen(&stopwatch_screen);
660                         break;
661                 default:
662                         break;
663         };
664 }
665
666
667 /*
668  * when alarm is fired
669  */
670 void draw_alarm_screen(void)
671 {
672         hal_lcd_clear_display();
673
674 //      SetFont(MetaWatch16);
675 //      WriteLcdString(2, 2, "ALARM !");
676         oswald_draw_bitmap(36, 20, alarm_icon_width, alarm_icon_height, alarm_icon_bits);
677
678
679         hal_lcd_update_display();
680 }
681
682 void alarm_handle_events(u16t event, void *data)
683 {
684         switch (event) {
685                 case EVENT_SCREEN_VISIBLE:
686                         draw_alarm_screen();
687                         hal_enable_halfsecond_timer();
688                         hal_vibration_set_state(TRUE);
689                         break;
690                 case EVENT_SCREEN_DESTROY:
691                         hal_disable_halfsecond_timer();
692                         hal_lcd_set_backlight(FALSE);
693                         hal_vibration_set_state(FALSE);
694                         break;
695                 case EVENT_USER_BUTTONS:
696                         dbg_out("button event %d\n", *(int *)data);
697                         // hal_lcd_set_backlight(FALSE);
698                         break;
699                 case EVENT_HALF_SEC_TIMER:
700                         hal_lcd_set_backlight(!hal_lcd_get_backlight());
701                         hal_vibration_set_state(!hal_vibration_get_state());
702                         dbg_out("timer\n");
703                         break;
704                 default:
705                         break;
706         };
707 }
708
709
710 /*
711  * Bluetooth screen
712  */
713 typedef struct {
714         u8t pos;
715         boolean bt_en;
716         boolean on;
717 } bluetooth_data_t;
718 static bluetooth_data_t bluetooth_screen = {
719         0,
720         FALSE,
721         TRUE
722 };
723
724 void draw_bluetooth_screen(bluetooth_data_t *sdata)
725 {
726         char bstr[20];
727         uint8_t *bd_addr;
728
729         hal_lcd_clear_display();
730
731         oswald_draw_bitmap(36, 0, Bluetooth_icon_width, Bluetooth_icon_height, Bluetooth_icon_bits);
732
733         oswald_draw_bitmap(81, 6, upbutton_icon_width, upbutton_icon_height, upbutton_icon_bits);
734         oswald_draw_bitmap(81, 38, downbutton_icon_width, downbutton_icon_height, downbutton_icon_bits);
735
736         SetFont(MetaWatch5);
737         WriteLcdString(2, 30, "Enable:");
738         if ((sdata->pos == 0 && sdata->on) || sdata->pos != 0) {
739                 WriteLcdCharacter(45, 30, bluetooth_screen.bt_en ? 'x' : '_');
740         }
741         WriteLcdString(2, 39, "State:");
742         switch (hal_bluetooth_get_state()) {
743                 case BLUETOOTH_OFF:
744                         WriteLcdString(45, 39, "off");
745                         break;
746                 case BLUETOOTH_ON:
747                         WriteLcdString(45, 39, "on");
748                         break;
749                 case BLUETOOTH_CONNECTED:
750                         WriteLcdString(45, 39, "conn.");
751                         break;
752                 default:
753                         break;
754         };
755         if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
756                 bd_addr = hal_bluetooth_get_local_bdaddr();
757                 snprintf(bstr, 20, "%02x:%02x:%02x:%02x:%02x:%02x", bd_addr[5], bd_addr[4], bd_addr[3], bd_addr[2], bd_addr[1], bd_addr[0]);
758                 WriteLcdString(2, 48, bstr);
759         } else {
760         }
761         WriteLcdString(2, 57, "Visible:");
762         if ((sdata->pos == 1 && sdata->on) || sdata->pos != 1) {
763                 WriteLcdCharacter(45, 57, hal_bluetooth_get_visible() ? 'x' : '_');
764         }
765
766         hal_lcd_update_display();
767 }
768
769 void bluetooth_handle_updown(u8t pos, s8t incr)
770 {
771         switch (pos) {
772                 case 0:
773                         if (hal_bluetooth_get_state() >= BLUETOOTH_ON) {
774                                 hal_bluetooth_set_state(BLUETOOTH_OFF);
775                                 bluetooth_screen.bt_en = FALSE;
776                         } else {
777                                 hal_bluetooth_set_state(BLUETOOTH_ON);
778                                 bluetooth_screen.bt_en = TRUE;
779                         }
780                         break;
781                 case 1:
782                         if (hal_bluetooth_get_state() >= BLUETOOTH_ON && !hal_bluetooth_get_visible()) {
783                                 hal_bluetooth_set_visible(TRUE);
784                         } else {
785                                 hal_bluetooth_set_visible(FALSE);
786                         }
787                         break;
788                 case 2:
789                         break;
790                 case 3:
791                         break;
792                 case 4:
793                         break;
794                 case 5:
795                         break;
796                 case 6:
797                         break;
798                 case 7:
799                         break;
800                 case 8:
801                         break;
802                 default:
803                         break;
804         };
805 }
806
807 void handle_bluetooth_buttons(watch_button button, bluetooth_data_t *sdata)
808 {
809         switch (button) {
810                 case BUTTON_A:
811                         bluetooth_handle_updown(sdata->pos, 1);
812                         break;
813                 case BUTTON_B:
814                         bluetooth_handle_updown(sdata->pos, -1);
815                         break;
816                 case BUTTON_F:
817                         sdata->pos++;
818                         sdata->pos %= 2;
819                         break;
820                 default:
821                         break;
822         }
823         draw_bluetooth_screen(sdata);
824 }
825
826 void bluetooth_screen_events(u16t event, void *data)
827 {
828         switch (event) {
829                 case EVENT_SCREEN_VISIBLE:
830                         bluetooth_screen.pos = 0;
831                         bluetooth_screen.bt_en = (hal_bluetooth_get_state() > 0);
832                         draw_bluetooth_screen(&bluetooth_screen);
833                         hal_enable_halfsecond_timer();
834                         break;
835                 case EVENT_SCREEN_DESTROY:
836                         hal_disable_halfsecond_timer();
837                         break;
838                 case EVENT_USER_BUTTONS:
839                         dbg_out("button event %d\n", *(int *)data);
840                         handle_bluetooth_buttons(*(watch_button *)data, &bluetooth_screen);
841                         break;
842                 case EVENT_HALF_SEC_TIMER:
843                         if (bluetooth_screen.on)
844                                 bluetooth_screen.on = FALSE;
845                         else
846                                 bluetooth_screen.on = TRUE;
847                         draw_bluetooth_screen(&bluetooth_screen);
848                         break;
849                 default:
850                         break;
851         };
852 }
853