2 * (c) 2011 Siegen, Germany by Nils Faerber <nils.faerber@kernelconcepts.de>
21 #include <bluetooth/bluetooth.h>
22 #include <bluetooth/rfcomm.h>
25 #include <dbus/dbus.h>
26 #include <dbus/dbus-glib.h>
27 #include <dbus/dbus-glib-lowlevel.h>
29 #include <libsoup/soup.h>
31 #include <libxml/tree.h>
32 #include <libxml/parser.h>
35 #include <bluetooth/sdp.h>
36 #include <bluetooth/sdp_lib.h>
39 #include "metawatch.h"
40 #include "crc16ccitt.h"
41 #include "mw_utility.h"
43 #include "bt_helper.h"
48 unsigned char rcvbuf[128];
50 int con_fd; /* console input fd */
57 void bitmap_test(mwdevice_t *mwdevice)
59 /* a nice checker-board pattern */
60 unsigned char checkbuf[24] = {
61 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
62 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
63 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
64 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
66 mw_write_buffer(mwdevice, MW_SCREEN_MODE_IDLE, 0, 31, checkbuf, 24);
67 mw_write_buffer(mwdevice, MW_SCREEN_MODE_IDLE, 0, 33, checkbuf, 24);
68 mw_write_buffer(mwdevice, MW_SCREEN_MODE_IDLE, 0, 35, checkbuf, 24);
69 mw_write_buffer(mwdevice, MW_SCREEN_MODE_IDLE, 0, 37, checkbuf, 24);
71 mw_update_display(mwdevice, MW_SCREEN_MODE_IDLE, 1);
74 void bitmap_test2(mwdevice_t *mwdevice)
76 mw_buffer *mwbuf1, *mwbuf2;
80 mwbuf1 = mw_alloc_pbuffer(96, 66, 1);
81 mwbuf2 = mw_alloc_pbuffer(96, 66, 1);
83 mw_buf_clear(mwbuf1, MW_BLACK);
84 mw_buf_clear(mwbuf2, MW_WHITE);
86 for (x=0; x<66; x++) {
87 //mw_buf_clear(mwbuf1, MW_BLACK);
88 mw_buf_draw_pixel(mwbuf1, x, x, MW_WHITE);
89 mw_dump_mw_buffer(mwbuf1);
90 bbuf = mw_make_mw_buffer(mwbuf1, &len);
91 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len);
92 mw_update_display(mwdevice, MW_SCREEN_MODE_IDLE, 1);
96 mw_free_pbuffer(mwbuf1);
97 mw_free_pbuffer(mwbuf2);
100 void text_test(mwdevice_t *mwdevice)
106 mwbuf = mw_alloc_pbuffer(96, 66, 1);
107 mw_buf_clear(mwbuf, MW_BLACK);
109 mw_buf_print(mwbuf, 1, 10, "Font 0", 0, MW_WHITE, MW_BLACK);
110 mw_buf_print(mwbuf, 1, 20, "Font 1", 1, MW_WHITE, MW_BLACK);
111 mw_buf_print(mwbuf, 1, 30, "Font 2", 2, MW_WHITE, MW_BLACK);
112 mw_buf_print(mwbuf, 1, 45, "Big Fat Clipping", 2, MW_BLACK, MW_WHITE);
114 bbuf = mw_make_mw_buffer(mwbuf, &len);
115 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len);
116 mw_update_display(mwdevice, MW_SCREEN_MODE_IDLE, 1);
117 mw_free_pbuffer(mwbuf);
120 void line_test(mwdevice_t *mwdevice)
126 mwbuf = mw_alloc_pbuffer(96, 66, 1);
127 mw_buf_clear(mwbuf, MW_BLACK);
129 for (p=0; p<=96; p+=8)
130 mw_buf_draw_line_bresenham(mwbuf, p, 0, 95-p, 65, MW_WHITE);
132 bbuf = mw_make_mw_buffer(mwbuf, &len);
133 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len);
134 mw_update_display(mwdevice, MW_SCREEN_MODE_IDLE, 1);
135 mw_free_pbuffer(mwbuf);
138 void bitmap_read(mwdevice_t *mwdevice)
142 unsigned int width, height, i;
146 unsigned int rowlength;
147 unsigned char *bmapbuf;
148 // unsigned char mw_buf[24];
150 ffd = open("test.pbm", O_RDONLY);
155 ret = read(ffd, rbuf, 3);
156 if (rbuf[0] != 'P' || rbuf[1] != '4') {
157 fprintf(stderr, "not a PBM file\n");
160 memset(rbuf, 0, 256);
163 ret = read(ffd, (rbuf+i), 1);
164 } while (!isspace(rbuf[i++]));
167 memset(rbuf, 0, 256);
170 ret = read(ffd, (rbuf+i), 1);
171 } while (!isspace(rbuf[i++]));
174 rowlength = ((width / 8) + 1);
176 bmapbuf = malloc(rowlength * height);
178 ret = read(ffd, bmapbuf, rowlength * height);
182 fprintf(stderr, "row length = %d bytes\n", rowlength);
183 fprintf(stderr, "bitmap resolution is %d x %d\n", width, height);
184 fprintf(stderr, "read %d of %d bytes\n", ret, rowlength * height);
185 fprintf(stderr, "\n");
186 for (y=0; y<height; y++) {
187 for (x=0; x<rowlength; x++) {
189 fprintf(stderr, "%c", (bmapbuf[(y*rowlength)+x] & (1<<(7-i))) ? '.' : ' ');
191 fprintf(stderr, "\n");
193 fprintf(stderr, "\n");
196 /* reverse bits and invert the bmap */
197 bmap_buffer_flipinvert(1, 1, bmapbuf, rowlength * height);
198 /* send the buffer to the watch */
199 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_IDLE, width, height, 31, bmapbuf, rowlength * height);
200 /* update the display */
201 mw_update_display(mwdevice, MW_SCREEN_MODE_IDLE, 1);
206 void test_notification(mwdevice_t *mwdevice)
212 mwbuf = mw_alloc_pbuffer(96, 96, 1);
213 mw_buf_clear(mwbuf, MW_BLACK);
215 mw_buf_draw_line_bresenham(mwbuf, 2, 0, 93, 0, MW_WHITE);
216 mw_buf_draw_line_bresenham(mwbuf, 0, 1, 95, 1, MW_WHITE);
217 mw_buf_draw_line_bresenham(mwbuf, 0, 94, 95, 94, MW_WHITE);
218 mw_buf_draw_line_bresenham(mwbuf, 2, 95, 93, 95, MW_WHITE);
220 mw_buf_draw_line_bresenham(mwbuf, 0, 2, 0, 93, MW_WHITE);
221 mw_buf_draw_line_bresenham(mwbuf, 1, 0, 1, 95, MW_WHITE);
222 mw_buf_draw_line_bresenham(mwbuf, 95, 2, 95, 93, MW_WHITE);
223 mw_buf_draw_line_bresenham(mwbuf, 94, 0, 94, 95, MW_WHITE);
225 mw_buf_print(mwbuf, 4, 4, "012345678901234", 0, MW_WHITE, MW_BLACK);
226 mw_buf_print(mwbuf, 4, 13, "012345678901234", 0, MW_WHITE, MW_BLACK);
227 mw_buf_print(mwbuf, 4, 22, "0123456789g1234", 0, MW_WHITE, MW_BLACK);
228 mw_buf_print(mwbuf, 4, 31, "012345678901234", 0, MW_WHITE, MW_BLACK);
229 mw_buf_print(mwbuf, 4, 40, "012345678901234", 0, MW_WHITE, MW_BLACK);
230 mw_buf_print(mwbuf, 4, 49, "012345678901234", 0, MW_WHITE, MW_BLACK);
231 mw_buf_print(mwbuf, 4, 58, "0123456789g1234", 0, MW_WHITE, MW_BLACK);
232 mw_buf_print(mwbuf, 4, 67, "012345678901234", 0, MW_WHITE, MW_BLACK);
233 mw_buf_print(mwbuf, 4, 76, "012345678901234", 0, MW_WHITE, MW_BLACK);
234 mw_buf_print(mwbuf, 4, 85, "012345678901234", 0, MW_WHITE, MW_BLACK);
236 bbuf = mw_make_mw_buffer(mwbuf, &len);
237 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_NOTIFICATION, 96, 96, 0, bbuf, len);
238 mw_update_display(mwdevice, MW_SCREEN_MODE_NOTIFICATION, 1);
239 mw_free_pbuffer(mwbuf);
241 mw_set_vibrate_mode(mwdevice, 1, 300, 300, 3);
244 int days(int m1, int y1)
247 if(m1==1 || m1==3 || m1==5 || m1==7 || m1==8 || m1==10 || m1==12)
249 else if(m1==4 || m1==6 || m1==9 || m1==11)
251 else if((y1%100!=0 && y1%4==0) || y1%400==0)
258 void draw_idle_calendar(mwdevice_t *mwdevice)
261 unsigned int y,y1,m,m1,d,i,j,k;
262 /* const char a[12][20]={"January","February","March","April","May","June","July","August","September","October","November","December"}; */
263 const char dnames[7][3] = { "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So" };
273 localtime_r(&mtime, &mtm);
276 y = mtm.tm_year + 1900;
279 mwbuf = mw_alloc_pbuffer(96, 66, 1);
280 mw_buf_clear(mwbuf, MW_BLACK);
284 if (m <= 0 || m >= 13)
289 if (((y1 % 100) != 0 && (y1 % 4) == 0) || (y1 % 400) == 0)
302 printf("Year: '%u'\n",y);
303 printf("Month: '%s'\n",a[m-1]);
305 printf("%6s%6s%6s%6s%6s%6s%6s\n","Sun","Mon","Tue","Wed","Thu","Fri","Sat");
309 /* 0 = 1st day is Monday, 1 = 1st day is Sunday */
313 for (i=0; i<7; i++) {
314 snprintf(pnum, 3, "%s", dnames[i]);
315 mw_buf_print(mwbuf, px, py, pnum, 0, MW_WHITE, MW_BLACK);
320 for (i = 1; i <= days(m,y); i++, k++) {
323 for (j = 1; j < 7; j++, k++) {
324 printf("+--"); //printf("%3s","");
328 for (j = 1; j < d; j++, k++) {
330 printf("--+"); //printf("%3s","");
334 snprintf(pnum, 8, "%2d", i);
336 mw_buf_print(mwbuf, px, py, pnum, 0, MW_BLACK, MW_WHITE);
338 mw_buf_print(mwbuf, px, py, pnum, 0, MW_WHITE, MW_BLACK);
352 //mw_buf_print(mwbuf, 1, 10, "Font 0", 0, MW_WHITE, MW_BLACK);
354 bbuf = mw_make_mw_buffer(mwbuf, &len);
355 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_IDLE, 96, 65, 31, bbuf, len);
356 mw_update_display(mwdevice, MW_SCREEN_MODE_IDLE, 1);
357 mw_free_pbuffer(mwbuf);
360 void mw_send_notify(mwdevice_t *mwdevice, char *header, char *body)
367 mwbuf = mw_alloc_pbuffer(96, 96, 1);
368 mw_buf_clear(mwbuf, MW_BLACK);
370 mw_buf_print(mwbuf, 0, 0, header, 0, MW_BLACK, MW_WHITE);
375 while (i<strlen(body)) {
376 sstr[c++] = body[i++];
377 if (c>=16 || i>=strlen(body)) {
378 mw_buf_print(mwbuf, 0, r*9, sstr, 0, MW_WHITE, MW_BLACK);
386 bbuf = mw_make_mw_buffer(mwbuf, &len);
387 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_APPLICATION, 96, 96, 0, bbuf, len);
388 mw_update_display(mwdevice, MW_SCREEN_MODE_APPLICATION, 1);
389 mw_free_pbuffer(mwbuf);
391 mw_set_vibrate_mode(mwdevice, 1, 300, 300, 2);
394 void test_application(mwdevice_t *mwdevice)
400 mw_enable_button(mwdevice, MW_SCREEN_MODE_IDLE, MW_BUTTON_A, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_A);
402 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_A, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_A);
403 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_B, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_B);
404 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_C, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_C);
405 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_E, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_E);
406 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_F, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_F);
407 mw_configure_watch_mode(mwdevice, MW_SCREEN_MODE_APPLICATION, 0, 30, 0);
409 mwbuf = mw_alloc_pbuffer(96, 96, 1);
410 mw_buf_clear(mwbuf, MW_BLACK);
412 mw_buf_print(mwbuf, 0, 0, " Application ", 0, MW_BLACK, MW_WHITE);
413 mw_buf_print(mwbuf, 0, 9, "0123456789012345", 0, MW_WHITE, MW_BLACK);
414 mw_buf_print(mwbuf, 0, 18, "0123456789g12345", 0, MW_WHITE, MW_BLACK);
415 mw_buf_print(mwbuf, 0, 27, "0123456789012345", 0, MW_WHITE, MW_BLACK);
416 mw_buf_print(mwbuf, 0, 36, "0123456789012345", 0, MW_WHITE, MW_BLACK);
417 mw_buf_print(mwbuf, 0, 45, "0123456789012345", 0, MW_WHITE, MW_BLACK);
418 mw_buf_print(mwbuf, 0, 54, "0123456789g12345", 0, MW_WHITE, MW_BLACK);
419 mw_buf_print(mwbuf, 0, 63, "0123456789012345", 0, MW_WHITE, MW_BLACK);
420 mw_buf_print(mwbuf, 0, 72, "0123456789012345", 0, MW_WHITE, MW_BLACK);
421 mw_buf_print(mwbuf, 0, 81, "0123456789012345", 0, MW_WHITE, MW_BLACK);
423 bbuf = mw_make_mw_buffer(mwbuf, &len);
424 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_APPLICATION, 96, 96, 0, bbuf, len);
425 mw_update_display(mwdevice, MW_SCREEN_MODE_APPLICATION, 1);
426 mw_free_pbuffer(mwbuf);
429 void draw_app_ana_clock(mwdevice_t *mwdevice, int hour, int minute, unsigned char day)
435 unsigned int i, x, y, x2, y2;
438 mw_enable_button(mwdevice, MW_SCREEN_MODE_IDLE, MW_BUTTON_A, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_A);
440 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_A, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_A);
441 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_B, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_B);
442 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_C, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_C);
443 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_E, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_E);
444 mw_enable_button(mwdevice, MW_SCREEN_MODE_APPLICATION, MW_BUTTON_F, MW_BUTTON_IMMEDIATE, MW_BUTTON_EVENT_MESSAGE, MW_BUTTON_F);
445 mw_configure_watch_mode(mwdevice, MW_SCREEN_MODE_APPLICATION, 0, 30, 0);
447 mwbuf = mw_alloc_pbuffer(96, 96, 1);
448 mw_buf_clear(mwbuf, MW_BLACK);
451 mf = (1. / 59.) * (double)minute;
454 // plot(R*cos(360° * i/N), R*sin(360° * i/N))
455 for (i=0; i<12; i++) {
456 tmp = 48. + (43. * cos(((2. * M_PI) / 12.) * (double)i));
458 tmp = 48 + (43. * sin(((2. * M_PI) / 12.) * (double)i));
460 tmp = 48. + (48. * cos(((2. * M_PI) / 12.) * (double)i));
462 tmp = 48 + (48. * sin(((2. * M_PI) / 12.) * (double)i));
464 mw_buf_draw_line_bresenham_w(mwbuf, x, y, x2, y2, 2, MW_WHITE);
467 g_print("hour = %d -> %f (%f)\n", hour, (double)hour + mf, mf);
468 tmp = 48. + (30. * cos(((2. * M_PI) / 12.) * ((double)hour + mf)));
470 tmp = 48 + (30. * sin(((2. * M_PI) / 12.) * ((double)hour + mf)));
472 mw_buf_draw_line_bresenham_w(mwbuf, 48, 48, x, y, 2, MW_WHITE);
474 tmp = 48. + (40. * cos(((2. * M_PI) / 60.) * (double)minute));
476 tmp = 48 + (40. * sin(((2. * M_PI) / 60.) * (double)minute));
478 mw_buf_draw_line_bresenham_w(mwbuf, 48, 48, x, y, 2, MW_WHITE);
480 snprintf(daystr, 5, "%d", day);
481 mw_buf_print(mwbuf, 74, 45, daystr, 0, MW_WHITE, MW_BLACK);
483 bbuf = mw_make_mw_buffer(mwbuf, &len);
484 mw_send_bitmap(mwdevice, MW_SCREEN_MODE_APPLICATION, 96, 96, 0, bbuf, len);
485 mw_update_display(mwdevice, MW_SCREEN_MODE_APPLICATION, 1);
486 mw_free_pbuffer(mwbuf);
489 void test_oled(mwdevice_t *mwdevice, unsigned char oled)
495 mwbuf = mw_alloc_pbuffer(80, 16, 1);
496 mw_buf_clear(mwbuf, MW_BLACK);
498 mw_buf_print(mwbuf, 0, 0, "Application", 0, MW_WHITE, MW_BLACK);
499 mw_buf_print(mwbuf, 0, 8, "012345678901234", 0, MW_WHITE, MW_BLACK);
501 bbuf = mw_make_mw_oled_buffer(mwbuf, &len);
502 mw_write_oled_buffer(mwdevice, 0, oled, 80, 0, bbuf, len);
504 mw_free_pbuffer(mwbuf);
508 weather_soup_callback (SoupSession *session, SoupMessage *msg, gpointer user_data)
512 /* Handle the response here */
513 if (msg->response_body->data != NULL && msg->response_body->length != 0) {
514 fprintf(stderr, "%s\n", msg->response_body->data);
515 xdoc = xmlReadMemory(msg->response_body->data, msg->response_body->length, "noname.xml", NULL, 0);
517 fprintf(stderr, "Failed to parse document\n");
525 void do_weather(mwdata_t *mwdata)
527 mwdata->msoup = soup_session_async_new();
528 mwdata->smsg = soup_message_new ("GET", "http://www.google.com/ig/api?weather=siegen&hl=de");
529 soup_session_send_message (mwdata->msoup, mwdata->smsg);
530 soup_session_queue_message (mwdata->msoup, mwdata->smsg, weather_soup_callback, mwdata);
533 void print_help(void)
535 g_print("Not yet implemented..\n");
539 #define PARAMS_LEN 16
541 static int separate_params(char *params[], char *pbuf)
547 memset(tbuf, 0, 128);
548 strncpy(tbuf, pbuf, strlen(pbuf));
549 // strdump(tbuf, strlen(tbuf));
550 /* we know we do have at least one parameter */
551 ret = strtok(tbuf, " ");
552 while (ret != NULL) {
553 // dbg_printf("tok '%s'\n", ret);
554 strncpy(params[cnt++], ret, PARAMS_LEN-1);
555 if (cnt > PARAMS_MAX)
557 ret = strtok(NULL, " ");
563 static void params_free(char **params)
567 for (i=0; i < PARAMS_MAX; i++)
568 if (params[i] != NULL)
572 void process_cmd(char *cmdline, int clinep, mwdata_t *mwdata)
574 unsigned char mdata[32];
575 unsigned int intopt=0;
576 char cmd[128], pbuf[128], *params[PARAMS_MAX];
578 char *inbuf = cmdline;
580 g_print("command: '%s'\n", cmdline);
582 for (i=0; i<PARAMS_MAX; i++) {
583 params[i] = malloc(PARAMS_LEN);
584 memset(params[i], 0, PARAMS_LEN);
587 memset(pbuf, 0, 128);
593 } while (*inbuf != 0 && *inbuf != 0x20);
595 if (inbuf != NULL && *inbuf == 0x20) {
598 pbuf[i++] = *(inbuf++);
599 } while (*inbuf != 0);
601 if (strlen(pbuf) > 0)
602 pcnt = separate_params(params, pbuf);
606 if (strncmp(cmd, "quit", 4) == 0) {
607 /* just in case we quit and show another screen */
608 mw_update_display(&mwdata->mwdevice, MW_SCREEN_MODE_IDLE, 0);
609 // params_free(params);
610 g_main_loop_quit (mwdata->mloop);
612 if (strncmp(cmd, "help", 4) == 0) {
615 if (strncmp(cmd, "ahand", 5) == 0) {
617 intopt = atoi(params[0]); /*atoi(cmdline+5);*/
618 g_print("Advance analog hands by %d minutes\n", intopt);
619 mdata[0] = intopt / 60;
620 mdata[1] = intopt % 60;
622 mw_send_frame(&mwdata->mwdevice, MW_ADVANCE_WATCH_HANDS, 0, mdata, 3);
624 g_print("missing argument\n ahand # - # = no. of minutes\n");
626 if (strncmp(cmd, "srtc", 4) == 0) {
631 localtime_r(&mtime, &mtm);
633 g_print("Setting RTC from system time...");
634 mw_set_rtc(&mwdata->mwdevice, &mtm);
637 if (strncmp(cmd, "grtc", 4) == 0) {
638 mw_send_frame(&mwdata->mwdevice, MW_GET_REAL_TIME_CLOCK, 0, NULL, 0);
640 if (strncmp(cmd, "gistr", 5) == 0) {
642 intopt = atoi(params[0]);
643 if (intopt >= 0 && intopt <= 3)
647 mw_send_frame(&mwdata->mwdevice, MW_GET_INFORMATION_STRING, 0, mdata, 1);
649 if (strncmp(cmd, "gdtype", 6) == 0) {
650 mw_send_frame(&mwdata->mwdevice, MW_GET_DEVICE_TYPE, 0, NULL, 0);
652 if (strncmp(cmd, "rvbat", 5) == 0) {
653 mw_send_frame(&mwdata->mwdevice, MW_READ_BATTERY_VOLTAGE_MSG, 0, NULL, 0);
655 if (strncmp(cmd, "rlight", 6) == 0) {
656 mw_send_frame(&mwdata->mwdevice, MW_READ_LIGHT_SENSOR_MSG, 0, NULL, 0);
658 if (strncmp(cmd, "modecfg", 6) == 0) {
659 mw_configure_watch_mode(&mwdata->mwdevice, MW_SCREEN_MODE_IDLE, 0, 4, 1);
660 mw_update_display(&mwdata->mwdevice, MW_SCREEN_MODE_IDLE, 0);
663 if (strncmp(cmdline, "rbtcfg", 6) == 0) {
664 intopt = cmdline[7]-0x30;
665 mdata[0] = 0; /* idle screen */
666 mdata[1] = intopt; /* button index */
667 /* for reading the config those are unnecessary */
668 mdata[2] = 0; /* button press type */
669 mdata[3] = 0; /* callback message type */
670 mdata[4] = 0; /* callback message option */
671 mw_send_frame(&mwdata->mwdevice, MW_READ_BUTTON_CONFIG, 0, mdata, 5);
674 if (strncmp(cmd, "svib", 4) == 0) {
675 mw_set_vibrate_mode(&mwdata->mwdevice, 1, 300, 300, 5);
677 if (strncmp(cmd, "tbmp", 4) == 0) {
678 bitmap_test(&mwdata->mwdevice);
680 if (strncmp(cmd, "t2bmp", 5) == 0) {
681 bitmap_test2(&mwdata->mwdevice);
683 if (strncmp(cmd, "text", 4) == 0) {
684 text_test(&mwdata->mwdevice);
686 if (strncmp(cmd, "tline", 5) == 0) {
687 line_test(&mwdata->mwdevice);
689 if (strncmp(cmd, "rbmp", 4) == 0) {
690 bitmap_read(&mwdata->mwdevice);
692 if (strncmp(cmd, "tnote", 5) == 0) {
693 // test_notification(&mwdata->mwdevice);
694 mw_do_notification(&mwdata->mwdevice, "TestNotification", "This is a pretty long text that needs to be broken and torn", 1);
696 if (strncmp(cmd, "tapp", 4) == 0) {
697 test_application(&mwdata->mwdevice);
699 if (strncmp(cmd, "eoled", 5) == 0) {
701 intopt = atoi(params[0]);
702 if (intopt == MW_OLED_UPPER || intopt == MW_OLED_LOWER)
703 mw_send_frame(&mwdata->mwdevice, MW_ENABLE_OLED_DISPLAY_MSG, intopt, NULL, 0);
706 if (strncmp(cmd, "toled", 5) == 0) {
707 intopt = atoi(params[0]);
708 test_oled(&mwdata->mwdevice, intopt);
709 //mw_write_oled_buffer(mwdevice, 0, 80, 0, mdata, 10);
710 //mw_send_frame(mwdevice, MW_UPDATE_OLED_DISPLAY_MSG, 0, NULL, 0);
712 if (strncmp(cmd, "cal", 3) == 0) {
713 draw_idle_calendar(&mwdata->mwdevice);
715 if (strncmp(cmd, "wet", 3) == 0) {
718 if (strncmp(cmd, "lang_de", 7) == 0) {
719 mdata[0] = MW_LANG_DE;
720 mw_nval_operation(&mwdata->mwdevice, MW_NVAL_OPERATION_WRITE, MW_NVAL_LANGUAGE , 1, mdata);
722 if (strncmp(cmd, "c24", 3) == 0) {
723 mdata[0] = MW_RTC_CLOCK_24HR;
724 mw_nval_operation(&mwdata->mwdevice, MW_NVAL_OPERATION_WRITE, MW_NVAL_TIME_FORMAT, 1, mdata);
726 if (strncmp(cmd, "g24", 3) == 0) {
728 mw_nval_operation(&mwdata->mwdevice, MW_NVAL_OPERATION_READ, MW_NVAL_TIME_FORMAT, 1, mdata);
730 if (strncmp(cmd, "sdm", 3) == 0) {
731 mdata[0] = MW_RTC_DATE_DDMM;
732 mw_nval_operation(&mwdata->mwdevice, MW_NVAL_OPERATION_WRITE, MW_NVAL_DATE_FORMAT, 1, mdata);
734 if (strncmp(cmd, "gdm", 3) == 0) {
736 mw_nval_operation(&mwdata->mwdevice, MW_NVAL_OPERATION_READ, MW_NVAL_DATE_FORMAT, 1, mdata);
738 if (strncmp(cmd, "dana", 4) == 0) {
740 g_print("two few params, hour minute, day of month\ndana h m d\n");
742 draw_app_ana_clock(&mwdata->mwdevice, atoi(params[0]), atoi(params[1]), atoi(params[2]));
749 int feed_menu(mwdata_t *mdata)
753 rcvd = read(0, (mdata->cmdline+mdata->cmdline_pos), 1);
755 if (mdata->cmdline[mdata->cmdline_pos] == '\r') {
757 mdata->cmdline[mdata->cmdline_pos--] = '\0';
758 process_cmd(mdata->cmdline, mdata->cmdline_pos, mdata);
759 mdata->cmdline_pos = 0;
760 memset(mdata->cmdline, 0, 128);
762 mdata->cmdline_pos++;
763 if (mdata->cmdline_pos > 75)
764 mdata->cmdline_pos = 75;
765 printf("\r> %s", mdata->cmdline);
773 gboolean handle_mw_io(GIOChannel *mw_io, GIOCondition condition, gpointer udata)
775 mwdata_t *mdata = (mwdata_t *)udata;
778 rcvd = read(mdata->mwdevice.mw_fd, mdata->rcvbuf, 64);
780 fprintf(stderr, "read %d bytes:\n", rcvd);
784 dump_frame(mdata->rcvbuf, rcvd);
786 mw_feed_msg_buffer(&mdata->mwdevice, mdata->rcvbuf, rcvd);
792 gboolean handle_min_io(GIOChannel *mw_io, GIOCondition condition, gpointer udata)
794 mwdata_t *mdata = (mwdata_t *)udata;
801 static DBusHandlerResult
802 signal_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
804 //GMainLoop *loop = user_data;
805 mwdata_t *mdata = (mwdata_t *)user_data;
807 char *app_name, *app_icon, *summary, *body; // **actions;
808 int replace_id; // dict, expire;
810 /* A signal from the bus saying we are about to be disconnected */
811 if (dbus_message_is_signal(message, "org.freedesktop.Local", "Disconnected")) {
812 /* Tell the main loop to quit */
813 g_main_loop_quit (mdata->mloop);
814 /* We have handled this message, don't pass it on */
815 return DBUS_HANDLER_RESULT_HANDLED;
818 if (dbus_message_is_method_call (message,"org.freedesktop.Notifications", "Notify")) {
819 g_print("method call\n");
820 dbus_error_init (&error);
821 if (dbus_message_get_args(message, &error,
822 DBUS_TYPE_STRING, &app_name,
823 DBUS_TYPE_UINT32, &replace_id,
824 DBUS_TYPE_STRING, &app_icon,
825 DBUS_TYPE_STRING, &summary,
826 DBUS_TYPE_STRING, &body,
827 /* G_TYPE_STRV, &actions,
828 DBUS_TYPE_DICT_ENTRY_AS_STRING, &dict,
829 DBUS_TYPE_INT32, &expire, */
830 DBUS_TYPE_INVALID)) {
831 g_print("Notify received: from app %s, icon %s:\nSummary: %s\nBody: %s\n", app_name, app_icon, summary, body);
832 mw_send_notify(&mdata->mwdevice, summary, body);
833 /* we just listen, we do not handle it here */
834 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
836 g_print("Notify received, but error getting message: %s\n", error.message);
837 dbus_error_free (&error);
840 g_print("Not signal received\n");
841 return DBUS_HANDLER_RESULT_HANDLED;
844 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
847 void mw_button_event_message_cb(mwdevice_t *mwdevice, unsigned char buttons, unsigned char options, void *user_data)
849 g_print("button event cb:0x%02x 0x%02x\n", buttons, options);
850 g_print("screen is %d\n", mwdevice->screen_mode);
851 if (mwdevice->screen_mode == MW_SCREEN_MODE_IDLE) {
852 if (buttons == MW_BUTTON_A)
853 test_application(mwdevice);
855 if (mwdevice->screen_mode == MW_SCREEN_MODE_APPLICATION) {
856 if (buttons == MW_BUTTON_C)
857 mw_update_display(mwdevice, MW_SCREEN_MODE_IDLE, 0);
861 int main(int argc, char **argv)
865 struct termios tconfd, otconfd, tmwfd;
867 GIOChannel *mw_io, *m_in;
872 fprintf(stderr, "Usage:\n\t%s <devicename>\n", argv[0]);
877 mdata.mloop = g_main_loop_new (NULL, FALSE);
882 mw_fd = open(argv[1], O_RDWR);
888 if (str2ba(argv[1], &btaddr))
890 mw_fd = open_socket(&btaddr, 1);
894 fprintf(stderr, "connected to %s\n", argv[1]);
897 /* we have a connection, RFCOMM socket is on mw_fd */
898 /* make the tty raw */
899 tcgetattr(mw_fd, &tmwfd);
901 tmwfd.c_oflag |= ONLCR | OPOST;
902 tmwfd.c_lflag |= ISIG;
903 tcsetattr(mw_fd, TCSANOW, &tmwfd);
905 mdata.mwdevice.mw_fd = mw_fd;
906 mdata.rcvbuf_pos = 0;
907 memset(mdata.rcvbuf, 0, 128);
909 dbus_error_init (&error);
910 bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
913 g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
914 dbus_error_free (&error);
918 dbus_connection_setup_with_g_main (bus, NULL);
919 dbus_bus_add_match (bus, "interface='org.freedesktop.Notifications'", &error);
921 dbus_connection_add_filter (bus, signal_filter, &mdata, NULL);
924 mw_io = g_io_channel_unix_new(mw_fd);
925 g_io_add_watch(mw_io, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, handle_mw_io, &mdata);
927 tcgetattr(0, &tconfd);
928 tcgetattr(0, &otconfd);
930 tconfd.c_oflag |= ONLCR | OPOST;
931 tconfd.c_lflag |= ISIG;
932 tcsetattr(0, TCSANOW, &tconfd);
936 m_in = g_io_channel_unix_new(0); /* stdin for kbd */
937 g_io_add_watch(m_in, G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, handle_min_io, &mdata);
939 memset(mdata.cmdline, 0, 128);
940 mdata.cmdline_pos = 0;
942 mw_init(&mdata.mwdevice, mw_fd);
943 mw_set_button_event_message_cb(&mdata.mwdevice, mw_button_event_message_cb, NULL);
945 g_main_loop_run (mdata.mloop);
950 /* reset the controlling tty again */
951 tcsetattr(0, TCSANOW, &otconfd);