From: Nils Faerber Date: Sat, 27 Aug 2011 18:38:16 +0000 (+0200) Subject: More callbacks, further GUI work X-Git-Url: https://git.kernelconcepts.de/?p=metawatch.git;a=commitdiff_plain;h=44f70f5275339fba3609ec94fe797c907290549b;ds=sidebyside More callbacks, further GUI work --- diff --git a/Makefile b/Makefile index 3107098..e71d837 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # prefix for installation and search path (like icons) PREFIX = /usr/local/ -CFLAGS = -Wall -O2 $(CCFLAGS) `pkg-config --cflags glib-2.0` `pkg-config --cflags dbus-glib-1` `pkg-config --cflags dbus-1` +CFLAGS = -Wall -g -DDEBUG -O2 $(CCFLAGS) `pkg-config --cflags glib-2.0` `pkg-config --cflags dbus-glib-1` `pkg-config --cflags dbus-1` #CFLAGS = -Wall -O2 $(CCFLAGS) LDFLAGS = `pkg-config --libs glib-2.0` `pkg-config --libs dbus-glib-1` `pkg-config --libs dbus-1` @@ -30,9 +30,9 @@ $(PRGNAME): $(OBJS) $(CC) -o $@ $^ $(LDFLAGS) libmetawatch.a: metawatch.o crc16ccitt.o mw_utility.o bt_helper.o - ar -cvq libmetawatch.a metawatch.o crc16ccitt.o mw_utility.o bt_helper.o + rm -f libmetawatch.a; ar -cvq libmetawatch.a metawatch.o crc16ccitt.o mw_utility.o bt_helper.o clean: - rm -f *.o *.d $(PRGNAME) + rm -f *.o *.d $(PRGNAME) libmetawatch.a -include $(DEPS) diff --git a/gtk-gui/Makefile b/gtk-gui/Makefile index 5de16ab..cb81f85 100644 --- a/gtk-gui/Makefile +++ b/gtk-gui/Makefile @@ -4,7 +4,7 @@ # prefix for installation and search path (like icons) PREFIX = /usr/local/ -CFLAGS = -DDEBUG -Wall -O2 -Wl,--export-dynamic $(CCFLAGS) -I.. `pkg-config --cflags glib-2.0` `pkg-config --cflags dbus-glib-1` `pkg-config --cflags dbus-1` `pkg-config --cflags gtk+-2.0` +CFLAGS = -DDEBUG -g -Wall -O2 -Wl,--export-dynamic $(CCFLAGS) -I.. `pkg-config --cflags glib-2.0` `pkg-config --cflags dbus-glib-1` `pkg-config --cflags dbus-1` `pkg-config --cflags gtk+-2.0` #CFLAGS = -Wall -O2 $(CCFLAGS) LDFLAGS = `pkg-config --libs glib-2.0` `pkg-config --libs dbus-glib-1` `pkg-config --libs dbus-1` `pkg-config --libs gtk+-2.0` `pkg-config --libs gmodule-export-2.0` -L.. -lmetawatch diff --git a/gtk-gui/mw-client.c b/gtk-gui/mw-client.c index b4dbab9..37fdcc5 100644 --- a/gtk-gui/mw-client.c +++ b/gtk-gui/mw-client.c @@ -62,6 +62,38 @@ void mw_get_battery_voltage_response_cb(mwdevice_t *mwdevice, unsigned short *vo gtk_progress_bar_set_text(batbar, batstr); } +void on_notify_ok_clicked (GtkButton *button, gpointer user_data) +{ + mwdata_t *mdata = (mwdata_t *)user_data; + GtkWidget *notify_win; + GtkTextView *tview; + GtkTextBuffer *tbuf; + GtkTextIter siter, eiter; + gchar *text; + + tview = GTK_TEXT_VIEW (gtk_builder_get_object (mdata->builder, "notify_textview")); + tbuf = gtk_text_view_get_buffer(tview); + gtk_text_buffer_get_start_iter(tbuf, &siter); + gtk_text_buffer_get_end_iter(tbuf, &eiter); + + text = gtk_text_buffer_get_text(tbuf, &siter, &eiter, FALSE); + + mw_do_notification(&mdata->mwdevice, "Notification", text, 2); + + notify_win = GTK_WIDGET (gtk_builder_get_object (mdata->builder, "notify_win")); + gtk_widget_hide (notify_win); +} + +void on_notify_cancel_clicked (GtkButton *button, gpointer user_data) +{ + mwdata_t *mdata = (mwdata_t *)user_data; + GtkWidget *notify_win; + + notify_win = GTK_WIDGET (gtk_builder_get_object (mdata->builder, "notify_win")); + gtk_widget_hide (notify_win); +} + + void on_rtc_button_clicked (GtkButton *button, gpointer user_data) { mwdata_t *mdata = (mwdata_t *)user_data; @@ -72,7 +104,10 @@ void on_rtc_button_clicked (GtkButton *button, gpointer user_data) void on_notify_button_clicked (GtkButton *button, gpointer user_data) { mwdata_t *mdata = (mwdata_t *)user_data; + GtkWidget *notify_win; + notify_win = GTK_WIDGET (gtk_builder_get_object (mdata->builder, "notify_win")); + gtk_widget_show (notify_win); } void bitmap_read(mwdevice_t *mwdevice, char *filename) @@ -143,6 +178,28 @@ void bitmap_read(mwdevice_t *mwdevice, char *filename) free(bmapbuf); } +void on_vibrate_button_clicked (GtkButton *button, gpointer user_data) +{ + mwdata_t *mdata = (mwdata_t *)user_data; +} + +void on_set_hands_clicked (GtkButton *button, gpointer user_data) +{ + mwdata_t *mdata = (mwdata_t *)user_data; + time_t mtime; + struct tm mtm; + unsigned short hour; + + mtime = time(NULL); + localtime_r(&mtime, &mtm); + + hour = (unsigned char) mtm.tm_hour; + if (hour > 12) + hour -= 12; + + mw_advance_watch_hands(&mdata->mwdevice, hour, (unsigned char) mtm.tm_min, (unsigned char) mtm.tm_sec); +} + void on_bitmap_button_clicked (GtkButton *button, gpointer user_data) { mwdata_t *mdata = (mwdata_t *)user_data; @@ -163,6 +220,31 @@ void on_bitmap_button_clicked (GtkButton *button, gpointer user_data) gtk_widget_destroy(dialog); } +void setup_watchtype_gui(mwdata_t *mdata) +{ + GtkWidget *w; + + if (mdata->mwdevice.devtype == MW_DEVICE_TYPE_DIGITAL || mdata->mwdevice.devtype == MW_DEVICE_TYPE_DEVB_DIGI) { + w = GTK_WIDGET (gtk_builder_get_object (mdata->builder, "set_hands")); + gtk_widget_hide(w); + } + if (mdata->mwdevice.devtype == MW_DEVICE_TYPE_ANA_DIGI || mdata->mwdevice.devtype == MW_DEVICE_TYPE_DEVB_ANA_DIGI) { + w = GTK_WIDGET (gtk_builder_get_object (mdata->builder, "F_button_label")); + gtk_widget_hide(w); + w = GTK_WIDGET (gtk_builder_get_object (mdata->builder, "E_button_label")); + gtk_widget_hide(w); + w = GTK_WIDGET (gtk_builder_get_object (mdata->builder, "D_button_label")); + gtk_widget_hide(w); + } +} + +void mw_get_device_type_response_cb(mwdevice_t *mwdevice, unsigned char devtype, void *user_data) +{ + mwdata_t *mdata = (mwdata_t *)user_data; + + setup_watchtype_gui(mdata); +} + void mw_get_real_time_clock_response_cb(mwdevice_t *mwdevice, struct tm *mw_tm, void *user_data) { mwdata_t *mdata = (mwdata_t *)user_data; @@ -182,7 +264,7 @@ gboolean handle_mw_io(GIOChannel *mw_io, GIOCondition condition, gpointer udata) int rcvd; int processed; - rcvd = read(mdata->mwdevice.mw_fd, mdata->rcvbuf+mdata->rcvbuf_pos, 64); + rcvd = read(mdata->mwdevice.mw_fd, mdata->rcvbuf/*+mdata->rcvbuf_pos*/, 64); #ifdef DEBUG fprintf(stderr, "read %d bytes:\n", rcvd); #endif @@ -211,9 +293,7 @@ on_window_destroy (GtkObject *object, gpointer user_data) } - -int -main (int argc, char *argv[]) +int main (int argc, char *argv[]) { GtkBuilder *builder; GtkWidget *window; @@ -269,6 +349,7 @@ main (int argc, char *argv[]) mw_init(&mdata.mwdevice, mw_fd); + mw_set_get_device_type_response_cb(&mdata.mwdevice, mw_get_device_type_response_cb, &mdata); mw_set_get_real_time_clock_response_cb(&mdata.mwdevice, mw_get_real_time_clock_response_cb, &mdata); mw_set_get_battery_voltage_response_cb(&mdata.mwdevice, mw_get_battery_voltage_response_cb, &mdata); @@ -276,7 +357,9 @@ main (int argc, char *argv[]) mdata.bat_timeout_id = g_timeout_add_seconds(10, battery_level_get_timeout, &mdata); + // setup_watchtype_gui(&mdata); gtk_main (); return 0; } + diff --git a/gtk-gui/mw-client.glade b/gtk-gui/mw-client.glade index 34a6559..e1db3b8 100644 --- a/gtk-gui/mw-client.glade +++ b/gtk-gui/mw-client.glade @@ -194,7 +194,7 @@ True False - 3 + 2 3 @@ -296,6 +296,97 @@ 2 + + + RTC + True + True + True + False + + + + 1 + 2 + + + + + + + True + False + + + True + False + True + 0.28571428571428592 + Battery + bat_adjust + + + True + True + 0 + + + + + True + False + unknown + + + True + True + 1 + + + + + 2 + 3 + + + + + True + False + + + 1 + 2 + 1 + 2 + + + + + gtk-about + True + True + True + False + True + + + + + + + + + + True + True + 1 + + + + + True + False Notification @@ -306,8 +397,9 @@ - 2 - 3 + False + False + 0 @@ -320,10 +412,9 @@ - 1 - 2 - 2 - 3 + False + False + 1 @@ -335,42 +426,227 @@ False + + False + False + 2 + + + + + Set Hands + True + True + True + False + + + + False + False + 3 + + + + + True + True + 2 + + + + + True + False + 2 + + + False + True + 3 + + + + + + + False + True + center-on-parent + + + True + False + + + True + False + 1 + <b>Notification text</b> + True + + + True + True + 0 + + + + + True + True + automatic + automatic + + + True + True + + + + + True + True + 1 + + + + + True + False + + + gtk-cancel + True + True + True + False + True + + + + False + False + 0 + + + + + gtk-apply + True + True + True + False + True + + + + False + False + 1 + + + + + True + True + 2 + + + + + + + False + + + True + False + + + True + False + <b>RTC</b> + True + + + True + True + 5 + 0 + + + + + True + False + 2 + 4 + + + True + False + Date + + + + + True + False + Time + 2 3 - 2 - 3 - - RTC + + 12h True True - True + False False - + True + True + h24_radio - 1 - 2 + 2 + 3 + 1 + 2 - + + 24h + True + True + False + False + True + True + + + 3 + 4 + 1 + 2 + - + True False - + True - False - True - 0.28571428571428592 - Battery - bat_adjust + True + 2011 + 7 + 21 + True True @@ -379,10 +655,54 @@ - + True False - unknown + + + True + False + Format + + + True + True + 0 + + + + + MM/DD + True + True + False + False + True + True + ddmm_radio + + + True + True + 1 + + + + + DD.MM + True + True + False + False + True + True + + + True + True + 2 + + True @@ -391,23 +711,20 @@ - - 2 - 3 - - - - - True - False - 1 2 - 1 - 2 + + + + + + + + + True @@ -416,13 +733,82 @@ - + True False - 2 + + + True + False + + + Get RTC from +watch + True + True + True + False + + + False + False + 0 + + + + + Get RTC from +System + True + True + True + False + + + True + True + 1 + + + + + False + False + 0 + + + + + Set RTC + True + True + True + False + + + False + False + 1 + + + + + gtk-apply + True + True + True + False + True + + + False + False + 2 + + - False + True True 2 diff --git a/metawatch.c b/metawatch.c index 08d5aca..5c5b73b 100644 --- a/metawatch.c +++ b/metawatch.c @@ -222,6 +222,7 @@ int mw_write_oled_buffer(mwdevice_t *mwdevice, if (mwdevice->devtype != MW_DEVICE_TYPE_ANA_DIGI && mwdevice->devtype != MW_DEVICE_TYPE_DEVB_ANA_DIGI) return -1; + fprintf(stderr, "write oled buf len = %d\n", buflen); /* lower row first since display wil be updated after completion of upper row */ if (buflen > 80) { for (i=80; i 12) + return -1; + if (minutes > 60) + return -1; + if (seconds > 60) + return -1; + + mdata[0] = hours; + mdata[1] = minutes; + mdata[2] = seconds; + + return mw_send_frame(mwdevice, MW_ADVANCE_WATCH_HANDS, 0, mdata, 3); +} + /* ---------------------------------------------------------------------- * Watch responses, events or notifications * ---------------------------------------------------------------------- */ +int mw_get_device_type_response(mwdevice_t *mwdevice, unsigned char devtype) +{ +#ifdef DEBUG + fprintf(stderr, "Got device type "); + switch(devtype) { + case 0: + fprintf(stderr, "Reserved\n"); + break; + case 1: + fprintf(stderr, "Ana-Digi\n"); + break; + case 2: + fprintf(stderr, "Digital\n"); + break; + case 3: + fprintf(stderr, "Development Board Digital\n"); + break; + case 4: + fprintf(stderr, "Development Board Ana-Digi\n"); + break; + default: + fprintf(stderr, "unknown %d\n", devtype); + break; + }; +#endif + mwdevice->devtype = devtype; + if (mwdevice->mw_get_device_type_response_cb != NULL) + mwdevice->mw_get_device_type_response_cb(mwdevice, devtype, mwdevice->mw_gdtypersp_data); + return 0; +} + +void mw_set_get_device_type_response_cb(mwdevice_t *mwdevice, void (*mw_get_device_type_response_cb) (mwdevice_t *mwdevice, unsigned char devtype, void *user_data), void *user_data) +{ + if (mw_get_device_type_response_cb != NULL) + mwdevice->mw_get_device_type_response_cb = mw_get_device_type_response_cb; + if (user_data != NULL) + mwdevice->mw_gdtypersp_data = user_data; +} + + int mw_get_real_time_clock_response(mwdevice_t *mwdevice, unsigned char *rtcrsp, int len) { struct tm mtm; @@ -435,18 +495,10 @@ int decode_frame(mwdevice_t *mwdevice, unsigned char *buf, int len) fprintf(stderr, "decode frame CRC error\n"); return -1; } -#ifdef DEBUG - else - fprintf(stderr, "decode frame CRC OK\n"); -#endif if (buf[0] != MW_SOF) { fprintf(stderr, "decode frame SOF not found\n"); return -1; } -#ifdef DEBUG - else - fprintf(stderr, "decode frame found SOF\n"); -#endif msglen = buf[1]; msgtype = buf[2]; @@ -456,28 +508,7 @@ int decode_frame(mwdevice_t *mwdevice, unsigned char *buf, int len) switch (msgtype) { case MW_GET_DEVICE_TYPE_RSP: - fprintf(stderr, "Got device type "); - switch(msgdata[0]) { - case 0: - fprintf(stderr, "Reserved\n"); - break; - case 1: - fprintf(stderr, "Ana-Digi\n"); - break; - case 2: - fprintf(stderr, "Digital\n"); - break; - case 3: - fprintf(stderr, "Development Board Digital\n"); - break; - case 4: - fprintf(stderr, "Development Board Ana-Digi\n"); - break; - default: - fprintf(stderr, "unknown %d\n", msgdata[0]); - break; - }; - mwdevice->devtype = msgdata[0]; + mw_get_device_type_response(mwdevice, msgdata[0]); break; case MW_GET_INFORMATION_STRING_RSP: msgdata[len-2] = 0; diff --git a/metawatch.h b/metawatch.h index eb93784..5df07a0 100644 --- a/metawatch.h +++ b/metawatch.h @@ -13,6 +13,9 @@ typedef struct _mwdevice_t { int mw_fd; /* file decriptor for MW connection */ unsigned char devtype; /* the device type of the connected device */ + /* watch message callbacks */ + void (*mw_get_device_type_response_cb) (struct _mwdevice_t *mwdevice, unsigned char devtype, void *user_data); + void *mw_gdtypersp_data; void (*mw_get_real_time_clock_response_cb) (struct _mwdevice_t *mwdevice, struct tm *mw_tm, void *user_data); void *mw_grtcrsp_data; void (*mw_get_battery_voltage_response_cb) (struct _mwdevice_t *mwdevice, unsigned short *voltage, unsigned char *pgood, unsigned char *charging, void *user_data); @@ -53,6 +56,9 @@ int mw_write_oled_buffer(mwdevice_t *mwdevice, unsigned char col_index, /* starting index */ unsigned char *buffer, int buflen); +int mw_get_device_type_response(mwdevice_t *mwdevice, unsigned char devtype); +void mw_set_get_device_type_response_cb(mwdevice_t *mwdevice, void (*mw_get_device_type_response_cb) (mwdevice_t *mwdevice, unsigned char devtype, void *user_data), void *user_data); + int mw_get_real_time_clock_response(mwdevice_t *mwdevice, unsigned char *rtcrsp, int len); void mw_set_get_real_time_clock_response_cb(mwdevice_t *mwdevice, void (*mw_get_real_time_clock_response_cb) (mwdevice_t *mwdevice, struct tm *mw_tm, void *user_data), void *user_data); @@ -71,6 +77,8 @@ int mw_enable_button(mwdevice_t *mwdevice, unsigned char mode, unsigned char but int mw_disable_button(mwdevice_t *mwdevice, unsigned char mode, unsigned char button_index, unsigned char press_type); +int mw_advance_watch_hands(mwdevice_t *mwdevice, unsigned char hours, unsigned char minutes, unsigned char seconds); + int decode_frame(mwdevice_t *mwdevice, unsigned char *buf, int len); int mw_init(mwdevice_t *mwdevice, int mw_fd); diff --git a/mw_main.c b/mw_main.c index c08b2d3..dd4e4a4 100644 --- a/mw_main.c +++ b/mw_main.c @@ -343,7 +343,7 @@ void process_cmd(char *cmdline, int clinep, mwdata_t *mwdata) } if (strncmp(cmdline, "srtc", 4) == 0) { fprintf(stderr, "Setting RTC from system time..."); - mw_set_rtc(&mwdata->mwdevice, MW_RTC_CLOCK_24HR, MW_RTC_DATE_DDMM); + mw_set_rtc(&mwdata->mwdevice, MW_RTC_CLOCK_12HR, MW_RTC_DATE_MMDD); fprintf(stderr, "OK\n"); } if (strncmp(cmdline, "grtc", 4) == 0) { @@ -399,7 +399,8 @@ void process_cmd(char *cmdline, int clinep, mwdata_t *mwdata) bitmap_read(&mwdata->mwdevice); } if (strncmp(cmdline, "tnote", 5) == 0) { - test_notification(&mwdata->mwdevice); + // test_notification(&mwdata->mwdevice); + mw_do_notification(&mwdata->mwdevice, "TestNotification", "This is a pretty long text that needs to be broken and torn", 1); } if (strncmp(cmdline, "tapp", 4) == 0) { test_application(&mwdata->mwdevice); @@ -598,6 +599,8 @@ int main(int argc, char **argv) memset(mdata.cmdline, 0, 128); mdata.cmdline_pos = 0; + mw_init(&mdata.mwdevice, mw_fd); + g_main_loop_run (mdata.mloop); fsync(mw_fd); diff --git a/mw_utility.c b/mw_utility.c index 2ddc12d..53c5f7a 100644 --- a/mw_utility.c +++ b/mw_utility.c @@ -21,11 +21,15 @@ #include #include -#include "mw_utility.h" #include "metawatch.h" +#include "mw_utility.h" #include "fonts.h" +/* ---------------------------------------------------------------------- + * Generic drawing functions + * ---------------------------------------------------------------------- */ + /* * The pixmap buffer has at least one byte per pixel, even for monochrome (bpp=1) * bitmaps @@ -252,3 +256,93 @@ void mw_buf_draw_line_bresenham(mw_buffer *mwbuf, unsigned int xstart, unsigned } } + +/* ---------------------------------------------------------------------- + * Complex combined functions, for user convenience + * ---------------------------------------------------------------------- */ + +/* + * send a text notification, automatically take care of device type (ana/digi) + * char *title is displayed inverse in top line + * char *text is the notification text + * vibrate is the number of 300ms vibrations, 0 for none + */ +void mw_do_notification(mwdevice_t *mwdevice, char *title, char *text, unsigned char vibrate) +{ + mw_buffer *mwbuf; + unsigned char *bbuf; + int len,i,c,r; + char sstr[32]; + + // fprintf(stderr, "do_notify devtype=%d, title='%s', text='%s', vibrate=%d\n", mwdevice->devtype, title, text, vibrate); + if (mwdevice->devtype == MW_DEVICE_TYPE_DIGITAL || mwdevice->devtype == MW_DEVICE_TYPE_DEVB_DIGI) { + mwbuf = mw_alloc_pbuffer(96, 96, 1); + mw_buf_clear(mwbuf, MW_BLACK); + + mw_buf_print(mwbuf, 0, 0, title, 0, MW_BLACK, MW_WHITE); + + i=0; + c=0; r=1; + memset(sstr,0,32); + while (i=16 || i>=strlen(text)) { + mw_buf_print(mwbuf, 0, r*9, sstr, 0, MW_WHITE, MW_BLACK); + memset(sstr,0,32); + c=0; r++; + if (r>10) + break; + }; + }; + + bbuf = mw_make_mw_buffer(mwbuf, &len); + mw_send_bitmap(mwdevice, MW_SCREEN_MODE_NOTIFICATION, 96, 96, 0, bbuf, len); + mw_update_display(mwdevice, MW_SCREEN_MODE_NOTIFICATION, 1); + mw_free_pbuffer(mwbuf); + } else if (mwdevice->devtype == MW_DEVICE_TYPE_ANA_DIGI || mwdevice->devtype == MW_DEVICE_TYPE_DEVB_ANA_DIGI) { + fprintf(stderr, "do notify OLED\n"); + mwbuf = mw_alloc_pbuffer(80, 16, 1); + mw_buf_clear(mwbuf, MW_BLACK); + + mw_buf_print(mwbuf, 0, 0, title, 0, MW_BLACK, MW_WHITE); + + i=0; + c=0; r=1; + memset(sstr,0,32); + while (i=13 || i>=strlen(text)) { + mw_buf_print(mwbuf, 0, r*9, sstr, 0, MW_WHITE, MW_BLACK); + memset(sstr,0,32); + c=0; r++; + }; + }; + + bbuf = mw_make_mw_oled_buffer(mwbuf, &len); + mw_write_oled_buffer(mwdevice, 0, MW_OLED_UPPER, 80, 0, bbuf, len); + + mw_buf_clear(mwbuf, MW_BLACK); + c=0; r=0; + memset(sstr,0,32); + while (i=13 || i>=strlen(text)) { + mw_buf_print(mwbuf, 0, r*9, sstr, 0, MW_WHITE, MW_BLACK); + memset(sstr,0,32); + c=0; r++; + if (r>2) + break; + }; + }; + + bbuf = mw_make_mw_oled_buffer(mwbuf, &len); + mw_write_oled_buffer(mwdevice, 0, MW_OLED_LOWER, 80, 0, bbuf, len); + + mw_free_pbuffer(mwbuf); + } else + fprintf(stderr, "Watch type not set - forgot to call mw_init()?\n"); + + if (vibrate) + mw_set_vibrate_mode(mwdevice, 1, 300, 300, vibrate); +} + diff --git a/mw_utility.h b/mw_utility.h index 8067729..7092818 100644 --- a/mw_utility.h +++ b/mw_utility.h @@ -54,5 +54,8 @@ void mw_buf_print(mw_buffer *mwbuf, unsigned int x, unsigned int y, char *text, void mw_buf_draw_line_bresenham(mw_buffer *mwbuf, unsigned int xstart, unsigned int ystart, unsigned int xend, unsigned int yend, mw_color clr); + +void mw_do_notification(mwdevice_t *mwdevice, char *title, char *text, unsigned char vibrate); + #endif