diff --git a/src/plugins/openmoko.c b/src/plugins/openmoko.c
index 5aa6e30..d892c3e 100644
--- a/src/plugins/openmoko.c
+++ b/src/plugins/openmoko.c
@@ -14,7 +14,6 @@
* along with this program. If not, see . */
/* TODO:
* - add an icon
- * - implement a configuration menu for deep sleep
* - register a handler for deep sleep (just to avoid unknown errors)
* - implement notification lights */
@@ -26,7 +25,7 @@
#include
#include
#include
-#include
+#include
#include
#include "Phone.h"
#include "../../config.h"
@@ -44,8 +43,20 @@
/* Openmoko */
/* private */
+/* types */
+typedef struct _Openmoko
+{
+ GtkWidget * window;
+ GtkWidget * deepsleep;
+} Openmoko;
+
+
/* prototypes */
+static int _openmoko_init(PhonePlugin * plugin);
+static int _openmoko_destroy(PhonePlugin * plugin);
static int _openmoko_event(PhonePlugin * plugin, PhoneEvent event, ...);
+static void _openmoko_deepsleep(PhonePlugin * plugin);
+static void _openmoko_settings(PhonePlugin * plugin);
/* public */
@@ -55,16 +66,41 @@ PhonePlugin plugin =
NULL,
"Openmoko",
NULL,
- NULL,
- NULL,
+ _openmoko_init,
+ _openmoko_destroy,
_openmoko_event,
- NULL,
+ _openmoko_settings,
NULL
};
/* private */
/* functions */
+/* openmoko_init */
+static int _openmoko_init(PhonePlugin * plugin)
+{
+ Openmoko * openmoko;
+
+ if((openmoko = object_new(sizeof(*openmoko))) == NULL)
+ return 1;
+ plugin->priv = openmoko;
+ openmoko->window = NULL;
+ return 0;
+}
+
+
+/* openmoko_destroy */
+static int _openmoko_destroy(PhonePlugin * plugin)
+{
+ Openmoko * openmoko = plugin->priv;
+
+ if(openmoko->window != NULL)
+ gtk_widget_destroy(openmoko->window);
+ free(openmoko);
+ return 0;
+}
+
+
/* openmoko_event */
static int _event_mixer_set(PhonePlugin * plugin, char const * filename);
static int _event_power_on(PhonePlugin * plugin, gboolean power);
@@ -94,9 +130,7 @@ static int _openmoko_event(PhonePlugin * plugin, PhoneEvent event, ...)
_event_mixer_set(plugin, "stereoout.state");
break;
case PHONE_EVENT_FUNCTIONAL:
- /* FIXME prevent deep sleep only optionally */
- plugin->helper->queue(plugin->helper->phone,
- "AT%SLEEP=2");
+ _openmoko_deepsleep(plugin);
break;
case PHONE_EVENT_NOTIFICATION_OFF:
/* FIXME implement */
@@ -203,3 +237,111 @@ static int _event_vibrator(PhonePlugin * plugin, gboolean vibrate)
close(fd);
return ret;
}
+
+
+/* openmoko_deepsleep */
+static void _openmoko_deepsleep(PhonePlugin * plugin)
+{
+ char const * cmd = "AT%SLEEP=4"; /* allow deep sleep */
+ char const * p;
+
+ if((p = plugin->helper->config_get(plugin->helper->phone, "openmoko",
+ "deepsleep")) != NULL
+ && strtoul(p, NULL, 10) != 0)
+ cmd = "AT%SLEEP=2"; /* prevent deep sleep */
+ /* XXX may reset the hardware modem */
+ plugin->helper->queue(plugin->helper->phone, cmd);
+ plugin->helper->queue(plugin->helper->phone, "AT+CPIN?");
+}
+
+
+/* openmoko_settings */
+static void _on_settings_cancel(gpointer data);
+static gboolean _on_settings_closex(gpointer data);
+static void _on_settings_ok(gpointer data);
+
+static void _openmoko_settings(PhonePlugin * plugin)
+{
+ Openmoko * openmoko = plugin->priv;
+ GtkWidget * vbox;
+ GtkWidget * bbox;
+ GtkWidget * widget;
+
+ if(openmoko->window != NULL)
+ {
+ gtk_window_present(GTK_WINDOW(openmoko->window));
+ return;
+ }
+ openmoko->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_border_width(GTK_CONTAINER(openmoko->window), 4);
+ gtk_window_set_default_size(GTK_WINDOW(openmoko->window), 200, 300);
+#if GTK_CHECK_VERSION(2, 6, 0)
+ gtk_window_set_icon_name(GTK_WINDOW(openmoko->window),
+ "gnome-settings");
+#endif
+ gtk_window_set_title(GTK_WINDOW(openmoko->window),
+ "Openmoko preferences");
+ g_signal_connect_swapped(G_OBJECT(openmoko->window), "delete-event",
+ G_CALLBACK(_on_settings_closex), plugin);
+ vbox = gtk_vbox_new(FALSE, 0);
+ /* check button */
+ openmoko->deepsleep = gtk_check_button_new_with_label(
+ "Prevent deep sleep");
+ gtk_box_pack_start(GTK_BOX(vbox), openmoko->deepsleep, FALSE, TRUE, 0);
+ /* button box */
+ bbox = gtk_hbutton_box_new();
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+ gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 4);
+ widget = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ g_signal_connect_swapped(G_OBJECT(widget), "clicked", G_CALLBACK(
+ _on_settings_cancel), plugin);
+ gtk_container_add(GTK_CONTAINER(bbox), widget);
+ widget = gtk_button_new_from_stock(GTK_STOCK_OK);
+ g_signal_connect_swapped(G_OBJECT(widget), "clicked", G_CALLBACK(
+ _on_settings_ok), plugin);
+ gtk_container_add(GTK_CONTAINER(bbox), widget);
+ gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(openmoko->window), vbox);
+ _on_settings_cancel(plugin);
+ gtk_widget_show_all(openmoko->window);
+}
+
+static void _on_settings_cancel(gpointer data)
+{
+ PhonePlugin * plugin = data;
+ Openmoko * openmoko = plugin->priv;
+ char const * p;
+
+ if((p = plugin->helper->config_get(plugin->helper->phone, "openmoko",
+ "deepsleep")) == NULL
+ || strtoul(p, NULL, 10) == 0)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ openmoko->deepsleep), FALSE);
+ else
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
+ openmoko->deepsleep), TRUE);
+ gtk_widget_hide(openmoko->window);
+}
+
+static gboolean _on_settings_closex(gpointer data)
+{
+ PhonePlugin * plugin = data;
+ Openmoko * openmoko = plugin->priv;
+
+ gtk_widget_hide(openmoko->window);
+ return TRUE;
+}
+
+static void _on_settings_ok(gpointer data)
+{
+ PhonePlugin * plugin = data;
+ Openmoko * openmoko = plugin->priv;
+ gboolean value;
+
+ value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ openmoko->deepsleep));
+ plugin->helper->config_set(plugin->helper->phone, "openmoko",
+ "deepsleep", value ? "1" : "0");
+ _openmoko_deepsleep(plugin);
+ gtk_widget_hide(openmoko->window);
+}