From 0563b798aa3e40c4e6c70b34ce612967e584c794 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Sat, 7 Aug 2010 00:28:54 +0000 Subject: [PATCH] Allows tracking the battery level as well --- src/plugins/panel.c | 164 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 30 deletions(-) diff --git a/src/plugins/panel.c b/src/plugins/panel.c index e66d23b..ed11851 100644 --- a/src/plugins/panel.c +++ b/src/plugins/panel.c @@ -15,7 +15,11 @@ +#define DEBUG #include +#ifdef DEBUG +# include +#endif #include #include #include "Phone.h" @@ -25,6 +29,18 @@ /* Panel */ /* private */ /* types */ +typedef enum _PanelBattery +{ + PANEL_BATTERY_UNKNOWN = 0, + PANEL_BATTERY_ERROR, + PANEL_BATTERY_CAUTION, + PANEL_BATTERY_LOW, + PANEL_BATTERY_NORMAL, + PANEL_BATTERY_CHARGING +} PanelBattery; +#define PANEL_BATTERY_LAST PANEL_BATTERY_CHARGING +#define PANEL_BATTERY_COUNT (PANEL_BATTERY_LAST + 1) + typedef enum _PanelSignal { PANEL_SIGNAL_UNKNOWN, @@ -39,11 +55,17 @@ typedef enum _PanelSignal typedef struct _Panel { - guint source; - PanelSignal signal; + guint timeout; + GtkWidget * plug; GtkWidget * hbox; - GtkWidget * icon; - GtkWidget * image; + /* battery */ + PanelBattery battery_level; + GtkWidget * battery_image; + guint battery_timeout; + /* signal */ + PanelSignal signal_level; + GtkWidget * signal_image; + /* operator */ GtkWidget * operator; } Panel; @@ -76,11 +98,13 @@ PhonePlugin plugin = /* panel_init */ static gboolean _on_plug_delete_event(gpointer data); static void _on_plug_embedded(gpointer data); +static gboolean _on_battery_timeout(gpointer data); static int _panel_init(PhonePlugin * plugin) { Panel * panel; PangoFontDescription * bold; + char const * p; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); @@ -88,64 +112,87 @@ static int _panel_init(PhonePlugin * plugin) if((panel = object_new(sizeof(*panel))) == NULL) return 1; plugin->priv = panel; - panel->source = 0; + panel->timeout = 0; bold = pango_font_description_new(); pango_font_description_set_weight(bold, PANGO_WEIGHT_BOLD); - panel->signal = -1; - panel->icon = gtk_plug_new(0); - g_signal_connect_swapped(G_OBJECT(panel->icon), "delete-event", - G_CALLBACK(_on_plug_delete_event), panel); - g_signal_connect_swapped(G_OBJECT(panel->icon), "embedded", G_CALLBACK( - _on_plug_embedded), panel); + panel->plug = gtk_plug_new(0); + g_signal_connect_swapped(G_OBJECT(panel->plug), "delete-event", + G_CALLBACK(_on_plug_delete_event), plugin); + g_signal_connect_swapped(G_OBJECT(panel->plug), "embedded", G_CALLBACK( + _on_plug_embedded), plugin); panel->hbox = gtk_hbox_new(FALSE, 2); - panel->image = gtk_image_new(); - gtk_box_pack_start(GTK_BOX(panel->hbox), panel->image, FALSE, TRUE, 0); + /* battery */ + panel->battery_timeout = 0; + panel->battery_level = -1; + if((p = plugin->helper->config_get(plugin->helper->phone, "panel", + "battery")) != NULL + && strcmp(p, "1") == 0) + { + panel->battery_image = gtk_image_new(); + gtk_box_pack_start(GTK_BOX(panel->hbox), panel->battery_image, + FALSE, TRUE, 0); + } + /* signal */ + panel->signal_level = -1; + panel->signal_image = gtk_image_new(); + gtk_box_pack_start(GTK_BOX(panel->hbox), panel->signal_image, FALSE, + TRUE, 0); panel->operator = gtk_label_new(NULL); gtk_widget_modify_font(panel->operator, bold); gtk_box_pack_start(GTK_BOX(panel->hbox), panel->operator, TRUE, TRUE, 0); _panel_set_signal_level(panel, 0.0 / 0.0); - gtk_container_add(GTK_CONTAINER(panel->icon), panel->hbox); - gtk_widget_show_all(panel->icon); - gtk_widget_map(panel->icon); + gtk_container_add(GTK_CONTAINER(panel->plug), panel->hbox); + gtk_widget_show_all(panel->hbox); pango_font_description_free(bold); - _on_plug_delete_event(panel); + _on_plug_delete_event(plugin); return 0; } static gboolean _on_plug_delete_event(gpointer data) { - Panel * panel = data; + PhonePlugin * plugin = data; + Panel * panel = plugin->priv; GdkEvent event; GdkEventClient * client = &event.client; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif - if(panel->source == 0) - panel->source = g_timeout_add(5000, _on_plug_delete_event, - panel); + if(panel->timeout == 0) + panel->timeout = g_timeout_add(5000, _on_plug_delete_event, + plugin); memset(&event, 0, sizeof(event)); client->type = GDK_CLIENT_EVENT; client->window = NULL; client->send_event = TRUE; client->message_type = gdk_atom_intern(PHONE_EMBED_MESSAGE, FALSE); client->data_format = 32; - client->data.l[0] = gtk_plug_get_id(GTK_PLUG(panel->icon)); + client->data.l[0] = gtk_plug_get_id(GTK_PLUG(panel->plug)); gdk_event_send_clientmessage_toall(&event); return TRUE; } static void _on_plug_embedded(gpointer data) { - Panel * panel = data; + PhonePlugin * plugin = data; + Panel * panel = plugin->priv; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif - if(panel->source != 0) - g_source_remove(panel->source); - panel->source = 0; + if(panel->timeout != 0) + g_source_remove(panel->timeout); + panel->timeout = 0; + gtk_widget_show(panel->plug); +} + +static gboolean _on_battery_timeout(gpointer data) +{ + PhonePlugin * plugin = data; + + plugin->helper->queue(plugin->helper->phone, "AT+CBC"); + return TRUE; } @@ -161,6 +208,8 @@ static int _panel_destroy(PhonePlugin * plugin) /* panel_event */ +static int _event_set_battery_level(Panel * panel, gdouble level); +static void _set_battery_image(Panel * panel, PanelBattery battery); static int _event_set_operator(Panel * panel, char const * operator); static int _panel_event(PhonePlugin * plugin, PhoneEvent event, ...) @@ -170,9 +219,24 @@ static int _panel_event(PhonePlugin * plugin, PhoneEvent event, ...) char const * operator; gdouble level; +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(plugin, %u, ...)\n", __func__, event); +#endif va_start(ap, event); switch(event) { + case PHONE_EVENT_BATTERY_LEVEL: + level = va_arg(ap, gdouble); + _event_set_battery_level(panel, level); + break; + case PHONE_EVENT_FUNCTIONAL: + /* FIXME should be disabled upon errors fetching CBC */ + if(panel->battery_timeout != 0) + break; + panel->battery_timeout = g_timeout_add(5000, + _on_battery_timeout, plugin); + _on_battery_timeout(plugin); + break; case PHONE_EVENT_SET_OPERATOR: operator = va_arg(ap, char const *); _event_set_operator(panel, operator); @@ -194,6 +258,46 @@ static int _event_set_operator(Panel * panel, char const * operator) return 0; } +static int _event_set_battery_level(Panel * panel, gdouble level) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(plugin, %lf)\n", __func__, level); +#endif + if(level >= 0.0 && level <= 100.0) + gtk_widget_show(panel->battery_image); + if(level < 0.0) + _set_battery_image(panel, PANEL_BATTERY_UNKNOWN); + else if(level <= 10.0) + _set_battery_image(panel, PANEL_BATTERY_CAUTION); + else if(level <= 20.0) + _set_battery_image(panel, PANEL_BATTERY_LOW); + else if(level <= 100.0) + _set_battery_image(panel, PANEL_BATTERY_NORMAL); + else + _set_battery_image(panel, PANEL_BATTERY_ERROR); + return 0; +} + +static void _set_battery_image(Panel * panel, PanelBattery battery) +{ + char const * icons[PANEL_BATTERY_COUNT] = + { + "stock_dialog-question", + "stock_dialog-error", + "battery-caution", + "battery-low", + "battery", + "battery" /* XXX find a better icon */ + }; + + if(panel->battery_level == battery) + return; + panel->battery_level = battery; + /* XXX may not be the correct size */ + gtk_image_set_from_icon_name(GTK_IMAGE(panel->battery_image), + icons[battery], GTK_ICON_SIZE_SMALL_TOOLBAR); +} + /* panel_set_signal_level */ static void _signal_level_set_image(Panel * panel, PanelSignal signal); @@ -226,10 +330,10 @@ static void _signal_level_set_image(Panel * panel, PanelSignal signal) "phone-signal-100" }; - if(panel->signal == signal) + if(panel->signal_level == signal) return; - panel->signal = signal; + panel->signal_level = signal; /* XXX may not be the correct size */ - gtk_image_set_from_icon_name(GTK_IMAGE(panel->image), icons[signal], - GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_image_set_from_icon_name(GTK_IMAGE(panel->signal_image), + icons[signal], GTK_ICON_SIZE_SMALL_TOOLBAR); }