X-Git-Url: https://git.llucax.com/software/sadba.git/blobdiff_plain/b095c6c5d46d838e36cc89e987c9f6350bd4baf0..34be6718234530569786db18f27b71792ea1e9df:/src/lib-display-blanking-status-menu-widget.c diff --git a/src/lib-display-blanking-status-menu-widget.c b/src/lib-display-blanking-status-menu-widget.c index 1d7227e..5c4cdbb 100644 --- a/src/lib-display-blanking-status-menu-widget.c +++ b/src/lib-display-blanking-status-menu-widget.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -70,16 +71,18 @@ GType display_blanking_status_plugin_get_type (void); TYPE_DISPLAY_BLANKING_STATUS_PLUGIN, \ DisplayBlankingStatusPluginPrivate)) -#define GCONF_KEY_DISPLAY_BLANKING "/system/osso/dsm/display/inhibit_blank_mode" +#define MODE_GCONF_ROOT "/system/osso/dsm/display" +#define MODE_GCONF_KEY MODE_GCONF_ROOT "/inhibit_blank_mode" -// Shoud contain one, and only one "%d" -#define DISPLAY_BLANKING_ICON_TEMPLATE "display-blanking-icon.%d" +#define INHIBIT_MSG_INTERVAL 30 // in seconds #define GETTEXT_DOM "status-area-displayblanking-applet" #define gettext_noop(str) (str) -#define DISPLAY_BLANKING_MODES 5 -static const char *_DisplayBlankingDescription[DISPLAY_BLANKING_MODES] = +// Undocumented blanking modes as reported by David Weinehall from Nokia: +// http://www.gossamer-threads.com/lists/maemo/developers/61201#61201 +#define BLANKING_MODES 5 +static const char *_DisplayBlankingDescription[BLANKING_MODES] = { gettext_noop ("Both enabled"), gettext_noop ("Both only on battery"), @@ -87,16 +90,25 @@ static const char *_DisplayBlankingDescription[DISPLAY_BLANKING_MODES] = gettext_noop ("Both disabled"), gettext_noop ("Only dimming") }; +static const char *mode_icon_name[BLANKING_MODES] = +{ + "display-blanking-icon.0", + "display-blanking-icon.1", + "display-blanking-icon.2", + "display-blanking-icon.3", + "display-blanking-icon.4", +}; struct _DisplayBlankingStatusPluginPrivate { - GtkWidget *button; GConfClient *gconf_client; + GtkWidget *mode_button; + GtkWidget *mode_dialog; gpointer data; }; HD_DEFINE_PLUGIN_MODULE (DisplayBlankingStatusPlugin, - display_blanking_status_plugin, HD_TYPE_STATUS_MENU_ITEM); + display_blanking_status_plugin, HD_TYPE_STATUS_MENU_ITEM) static void display_blanking_status_plugin_class_finalize ( @@ -111,75 +123,164 @@ display_blanking_status_plugin_class_init (DisplayBlankingStatusPluginClass *c) } static void -display_blanking_status_plugin_mode_set (DisplayBlankingStatusPluginPrivate *priv, - gboolean update) +update_mode_gui (gint mode, DisplayBlankingStatusPluginPrivate *priv) { - // Should be enough if DISPLAY_BLANKING_MODES stays in 1 digit, "%d" - // provides space for that digit and '\0' - static char icon_name[sizeof (DISPLAY_BLANKING_ICON_TEMPLATE)]; - - // Get the mode to set - gint mode = gconf_client_get_int (priv->gconf_client, - GCONF_KEY_DISPLAY_BLANKING, NULL); - if (update) - mode = (mode + 1) % DISPLAY_BLANKING_MODES; - - // Toggle display blanking - gconf_client_set_int (priv->gconf_client, GCONF_KEY_DISPLAY_BLANKING, - mode, NULL); - - // Update button text and status bar icon - hildon_button_set_value (HILDON_BUTTON (priv->button), + hildon_button_set_value (HILDON_BUTTON (priv->mode_button), dgettext (GETTEXT_DOM, _DisplayBlankingDescription[mode])); - int r = snprintf (icon_name, sizeof (icon_name), - DISPLAY_BLANKING_ICON_TEMPLATE, mode); - g_assert(r < sizeof (icon_name)); // otherwise it was truncated - GtkWidget *icon = gtk_image_new_from_icon_name (icon_name, + GtkWidget *icon = gtk_image_new_from_icon_name (mode_icon_name[mode], GTK_ICON_SIZE_DIALOG); - hildon_button_set_image (HILDON_BUTTON (priv->button), icon); - - // Show a notification banner (only if updating) - if (update) { - GtkWidget *banner = hildon_banner_show_informationf (priv->button, NULL, - dgettext (GETTEXT_DOM, "Changed display blanking mode to: %s"), - _DisplayBlankingDescription[mode]); - hildon_banner_set_timeout (HILDON_BANNER (banner), 5000); + hildon_button_set_image (HILDON_BUTTON (priv->mode_button), icon); +} + +static void +on_mode_dialog_button_clicked (GtkWidget *button, GtkDialog *dialog) +{ + const gchar *title = hildon_button_get_title (HILDON_BUTTON (button)); + + gint *mode = (gint *) g_object_get_data (G_OBJECT(dialog), "mode"); + g_assert (mode != NULL); + + for (*mode = 0; *mode < BLANKING_MODES; (*mode)++) { + if (strcmp (title, _DisplayBlankingDescription[*mode]) == 0) + break; } + g_assert (*mode < BLANKING_MODES); + + gtk_dialog_response (dialog, GTK_RESPONSE_OK); } static void -display_blanking_status_plugin_on_button_clicked (GtkWidget *button, - DisplayBlankingStatusPlugin *plugin) +on_mode_button_clicked (GtkWidget *button, + DisplayBlankingStatusPluginPrivate *priv) { - display_blanking_status_plugin_mode_set ( - DISPLAY_BLANKING_STATUS_PLUGIN_GET_PRIVATE (plugin), TRUE); + GtkWidget *parent = gtk_widget_get_ancestor (GTK_WIDGET (priv->mode_button), + GTK_TYPE_WINDOW); + gtk_widget_hide (parent); + + g_assert (priv->mode_dialog == NULL); + priv->mode_dialog = gtk_dialog_new (); + gtk_window_set_modal (GTK_WINDOW (priv->mode_dialog), TRUE); + gtk_window_set_title (GTK_WINDOW (priv->mode_dialog), + dgettext (GETTEXT_DOM, "Select display blanking mode")); + + GtkWidget *pan_area = hildon_pannable_area_new (); + g_assert (pan_area != NULL); + + GtkWidget *vbox = gtk_vbox_new (FALSE, 0); + g_assert (vbox != NULL); + + hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (pan_area), + vbox); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (priv->mode_dialog)->vbox), + pan_area, TRUE, TRUE, 0); + + g_object_set (G_OBJECT (pan_area), "height-request", + MIN (350, BLANKING_MODES * 70), NULL); + + gint mode = BLANKING_MODES; + for (int i = 0; i < BLANKING_MODES; i++) { + GtkWidget *button = + hildon_button_new_with_text (HILDON_SIZE_FINGER_HEIGHT, + HILDON_BUTTON_ARRANGEMENT_VERTICAL, + _DisplayBlankingDescription[i], NULL); + GtkWidget *icon = gtk_image_new_from_icon_name (mode_icon_name[i], + GTK_ICON_SIZE_DIALOG); + hildon_button_set_image (HILDON_BUTTON (button), icon); + gtk_button_set_alignment (GTK_BUTTON (button), 0.0f, 0.5f); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + g_signal_connect (button, "clicked", + G_CALLBACK (on_mode_dialog_button_clicked), priv->mode_dialog); + } + + gtk_widget_show_all (priv->mode_dialog); + + g_object_set_data (G_OBJECT (priv->mode_dialog), "mode", &mode); + gtk_dialog_run (GTK_DIALOG (priv->mode_dialog)); + + if (mode != BLANKING_MODES) { + // will trigger the gconf notify signal + GError *error = NULL; + gconf_client_set_int (priv->gconf_client, MODE_GCONF_KEY, mode, &error); + g_assert (error == NULL); + } + + gtk_widget_destroy (priv->mode_dialog); + priv->mode_dialog = NULL; } static void -display_blanking_status_plugin_init (DisplayBlankingStatusPlugin *plugin) +on_gconf_notify (GConfClient* client, guint cnxn_id, GConfEntry* entry, + DisplayBlankingStatusPluginPrivate* priv) +{ + const gchar* key = gconf_entry_get_key (entry); + g_assert (key != NULL); + + // Ignore notification about keys we don't care about + if (strcmp (key, MODE_GCONF_KEY) != 0) + return; + + const GConfValue* value = gconf_entry_get_value (entry); + g_assert (value != NULL); + g_assert (GCONF_VALUE_TYPE_VALID (value->type)); + g_assert (value->type == GCONF_VALUE_INT); + + gint mode = gconf_value_get_int (value); + update_mode_gui (mode, priv); +} + +static void +init_gconf (DisplayBlankingStatusPluginPrivate *priv) { - plugin->priv = DISPLAY_BLANKING_STATUS_PLUGIN_GET_PRIVATE (plugin); + GError* error = NULL; - plugin->priv->gconf_client = gconf_client_get_default(); - g_assert(GCONF_IS_CLIENT(plugin->priv->gconf_client)); + priv->gconf_client = gconf_client_get_default (); + g_assert (GCONF_IS_CLIENT (priv->gconf_client)); - plugin->priv->button = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT | + gconf_client_add_dir (priv->gconf_client, MODE_GCONF_ROOT, + GCONF_CLIENT_PRELOAD_NONE, &error); + g_assert (error == NULL); + + gconf_client_notify_add (priv->gconf_client, MODE_GCONF_KEY, + (GConfClientNotifyFunc) &on_gconf_notify, priv, NULL, &error); + g_assert (error == NULL); +} + +static void +init_mode_gui (DisplayBlankingStatusPluginPrivate *priv) +{ + priv->mode_dialog = NULL; + priv->mode_button = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH, HILDON_BUTTON_ARRANGEMENT_VERTICAL); - gtk_button_set_alignment (GTK_BUTTON (plugin->priv->button), 0, 0); - hildon_button_set_style (HILDON_BUTTON (plugin->priv->button), + gtk_button_set_alignment (GTK_BUTTON (priv->mode_button), 0, 0); + hildon_button_set_style (HILDON_BUTTON (priv->mode_button), HILDON_BUTTON_STYLE_PICKER); - hildon_button_set_title (HILDON_BUTTON (plugin->priv->button), + hildon_button_set_title (HILDON_BUTTON (priv->mode_button), dgettext (GETTEXT_DOM, "Display blanking mode")); - display_blanking_status_plugin_mode_set (plugin->priv, FALSE); + GError* error = NULL; + gint mode = gconf_client_get_int (priv->gconf_client, MODE_GCONF_KEY, + &error); + g_assert (error == NULL); + update_mode_gui (mode, priv); + + g_signal_connect (priv->mode_button, "clicked", + G_CALLBACK (on_mode_button_clicked), priv); +} + +static void +display_blanking_status_plugin_init (DisplayBlankingStatusPlugin *plugin) +{ + DisplayBlankingStatusPluginPrivate *priv; + + priv = DISPLAY_BLANKING_STATUS_PLUGIN_GET_PRIVATE (plugin); + plugin->priv = priv; - g_signal_connect (plugin->priv->button, "clicked", - G_CALLBACK (display_blanking_status_plugin_on_button_clicked), - plugin); + init_gconf (priv); + init_mode_gui (priv); - gtk_container_add (GTK_CONTAINER (plugin), plugin->priv->button); + gtk_container_add (GTK_CONTAINER (plugin), priv->mode_button); - gtk_widget_show_all (plugin->priv->button); + gtk_widget_show_all (priv->mode_button); gtk_widget_show (GTK_WIDGET (plugin)); }