From ffaf526a28c84587590cfab283bd8f144258651e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 19 Aug 2013 20:03:01 -0500 Subject: add ib-brightness-control for phone menu --- configure.ac | 5 +- debian/control | 3 +- src/Makefile.am | 4 ++ src/ib-brightness-control.c | 149 ++++++++++++++++++++++++++++++++++++++++++++ src/ib-brightness-control.h | 33 ++++++++++ src/service.c | 87 ++++++++++++++++++++++++-- src/unity-menu-item.c | 74 ++++++++++++++++++++++ src/unity-menu-item.h | 35 +++++++++++ 8 files changed, 381 insertions(+), 9 deletions(-) create mode 100644 src/ib-brightness-control.c create mode 100644 src/ib-brightness-control.h create mode 100644 src/unity-menu-item.c create mode 100644 src/unity-menu-item.h diff --git a/configure.ac b/configure.ac index 81b6f9f..ba39dec 100644 --- a/configure.ac +++ b/configure.ac @@ -35,11 +35,12 @@ LT_INIT GLIB_REQUIRED_VERSION=2.35.4 GIO_REQUIRED_VERSION=2.26 GIO_UNIX_REQUIRED_VERSION=2.26 -GSD_REQUIRED_VERSION=3.1.4 +GUDEV_REQUIRED_VERSION=204 PKG_CHECK_MODULES([SERVICE_DEPS],[glib-2.0 >= $GLIB_REQUIRED_VERSION gio-2.0 >= $GIO_REQUIRED_VERSION - gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION]) + gio-unix-2.0 >= $GIO_UNIX_REQUIRED_VERSION + gudev-1.0 >= $GUDEV_REQUIRED_VERSION]) ########################### # GSETTINGS diff --git a/debian/control b/debian/control index 1a81e88..fc1c924 100644 --- a/debian/control +++ b/debian/control @@ -7,7 +7,8 @@ Build-Depends: debhelper (>= 9), autopoint, intltool, libgtest-dev, - libglib2.0-dev (>= 2.35.4), + libglib2.0-dev (>= 2.36), + libgudev-1.0-dev, python, Standards-Version: 3.9.2 Homepage: https://launchpad.net/indicator-power diff --git a/src/Makefile.am b/src/Makefile.am index 0bd4dc3..eb87ea7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -63,6 +63,10 @@ libindicatorpower_upower_a_CFLAGS = \ libindciatorpower_upower_a_LDFLAGS = $(COVERAGE_LDFLAGS) libindicatorpower_service_a_SOURCES = \ + ib-brightness-control.c \ + ib-brightness-control.h \ + unity-menu-item.c \ + unity-menu-item.h \ device-provider.c \ device-provider.h \ device.c \ diff --git a/src/ib-brightness-control.c b/src/ib-brightness-control.c new file mode 100644 index 0000000..cf1e5ad --- /dev/null +++ b/src/ib-brightness-control.c @@ -0,0 +1,149 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Renato Araujo Oliveira Filho + */ + +#include +#include +#include +#include + +#include "ib-brightness-control.h" + +struct _IbBrightnessControl +{ + gchar *path; +}; + +IbBrightnessControl* +ib_brightness_control_new (void) +{ + IbBrightnessControl *control; + GUdevClient *client; + gchar *path = NULL; + GList *devices; + + // detect device + client = g_udev_client_new (NULL); + devices = g_udev_client_query_by_subsystem (client, "backlight"); + if (devices != NULL) { + GList *device; + const gchar *device_type; + + for (device = devices; device != NULL; device = device->next) { + device_type = g_udev_device_get_sysfs_attr (device->data, "type"); + if ((g_strcmp0 (device_type, "firmware") == 0) || + (g_strcmp0 (device_type, "platform") == 0) || + (g_strcmp0 (device_type, "raw") == 0)) { + path = g_strdup (g_udev_device_get_sysfs_path (device->data)); + g_print ("found: %s\n", path); + break; + } + } + + g_list_free_full (devices, g_object_unref); + } + else { + g_warning ("Fail to query backlight devices."); + } + + control = g_new0 (IbBrightnessControl, 1); + control->path = path; + + g_object_unref (client); + return control; +} + +void +ib_brightness_control_set_value (IbBrightnessControl* self, gint value) +{ + gint fd; + gchar *filename; + gchar *svalue; + gint length; + + if (self->path == NULL) + return; + + filename = g_build_filename (self->path, "brightness", NULL); + fd = open(filename, O_WRONLY); + if (fd < 0) { + g_warning ("Fail to set brightness."); + g_free (filename); + return; + } + + svalue = g_strdup_printf ("%i", value); + length = strlen (svalue); + + if (write (fd, svalue, length) != length) { + g_warning ("Fail to write brightness information."); + } + + close (fd); + g_free (svalue); + g_free (filename); +} + +gint +ib_brightness_control_get_value_from_file (IbBrightnessControl *self, const gchar *file) +{ + GError *error; + gchar *svalue; + gint value; + gchar *filename; + + if (self->path == NULL) + return 0; + + svalue = NULL; + error = NULL; + filename = g_build_filename (self->path, file, NULL); + g_file_get_contents (filename, &svalue, NULL, &error); + if (error) { + g_warning ("Fail to get brightness value: %s", error->message); + value = -1; + g_error_free (error); + } else { + value = atoi (svalue); + } + + g_free (filename); + + return value; + +} + +gint +ib_brightness_control_get_value (IbBrightnessControl* self) +{ + return ib_brightness_control_get_value_from_file (self, "brightness"); +} + +gint +ib_brightness_control_get_max_value (IbBrightnessControl* self) +{ + return ib_brightness_control_get_value_from_file (self, "max_brightness"); +} + +void +ib_brightness_control_free (IbBrightnessControl *self) +{ + g_free (self->path); + g_free (self); +} + diff --git a/src/ib-brightness-control.h b/src/ib-brightness-control.h new file mode 100644 index 0000000..87711e4 --- /dev/null +++ b/src/ib-brightness-control.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Renato Araujo Oliveira Filho + */ + +#ifndef __IB_BRIGHTNESS_CONTROL_H__ +#define __IB_BRIGHTNESS_CONTROL_H__ + +#include + +typedef struct _IbBrightnessControl IbBrightnessControl; + +IbBrightnessControl* ib_brightness_control_new (void); +void ib_brightness_control_set_value (IbBrightnessControl* self, gint value); +gint ib_brightness_control_get_value (IbBrightnessControl* self); +gint ib_brightness_control_get_max_value (IbBrightnessControl* self); +void ib_brightness_control_free (IbBrightnessControl *self); + +#endif diff --git a/src/service.c b/src/service.c index 6c9a9c6..1c61cb2 100644 --- a/src/service.c +++ b/src/service.c @@ -25,7 +25,9 @@ #include "device.h" #include "device-provider.h" +#include "ib-brightness-control.h" #include "service.h" +#include "unity-menu-item.h" #define BUS_NAME "com.canonical.indicator.power" #define BUS_PATH "/com/canonical/indicator/power" @@ -100,6 +102,8 @@ struct _IndicatorPowerServicePrivate GSettings * settings; + IbBrightnessControl * brightness_control; + guint own_id; guint actions_export_id; GDBusConnection * conn; @@ -110,6 +114,7 @@ struct _IndicatorPowerServicePrivate GSimpleAction * header_action; GSimpleAction * show_time_action; GSimpleAction * battery_level_action; + GSimpleAction * brightness_action; IndicatorPowerDevice * primary_device; GList * devices; /* IndicatorPowerDevice */ @@ -441,6 +446,43 @@ create_phone_devices_section (IndicatorPowerService * self G_GNUC_UNUSED) **** ***/ +static GMenuItem * +create_brightness_menuitem (IndicatorPowerService * self) +{ + priv_t * p = self->priv; + const int max_value = ib_brightness_control_get_max_value (p->brightness_control); + const int min_value = max_value * 0.05; /* 5% */ + GIcon * icon; + GMenuItem * item; + + icon = g_themed_icon_new_with_default_fallbacks ("display-brightness-symbolic"); + + item = unity_menu_item_slider_new (NULL, + "indicator.brightness", + (min_value <= 0 ? 1 : min_value), + max_value, + NULL, + g_icon_serialize (icon)); + + g_object_unref (icon); + return item; +} + +static GVariant * +action_state_for_brightness (IndicatorPowerService * self) +{ + priv_t * p = self->priv; + double value = ib_brightness_control_get_value (p->brightness_control); + return g_variant_new_double (value); +} + +static void +update_brightness_action_state (IndicatorPowerService * self) +{ + g_simple_action_set_state (self->priv->brightness_action, + action_state_for_brightness (self)); +} + static GMenuModel * create_desktop_settings_section (IndicatorPowerService * self G_GNUC_UNUSED) { @@ -460,13 +502,19 @@ create_desktop_settings_section (IndicatorPowerService * self G_GNUC_UNUSED) static GMenuModel * create_phone_settings_section (IndicatorPowerService * self G_GNUC_UNUSED) { - GMenu * menu = g_menu_new (); + GMenu * section; + GMenuItem * item; - g_menu_append (menu, - _("Battery settingsā€¦"), - "indicator.activate-settings"); + section = g_menu_new (); - return G_MENU_MODEL (menu); + item = create_brightness_menuitem (self); + g_menu_append_item (section, item); + update_brightness_action_state (self); + g_object_unref (item); + + g_menu_append (section, _("Battery settingsā€¦"), "indicator.activate-settings"); + + return G_MENU_MODEL (section); } /*** @@ -492,6 +540,7 @@ static void rebuild_now (IndicatorPowerService * self, guint sections) { priv_t * p = self->priv; + struct ProfileMenuInfo * phone = &p->menus[PROFILE_PHONE]; struct ProfileMenuInfo * desktop = &p->menus[PROFILE_DESKTOP]; struct ProfileMenuInfo * greeter = &p->menus[PROFILE_DESKTOP_GREETER]; @@ -512,6 +561,7 @@ rebuild_now (IndicatorPowerService * self, guint sections) if (sections & SECTION_SETTINGS) { rebuild_section (desktop->submenu, 1, create_desktop_settings_section (self)); + rebuild_section (phone->submenu, 1, create_desktop_settings_section (self)); } } @@ -628,6 +678,19 @@ on_statistics_activated (GSimpleAction * a G_GNUC_UNUSED, execute_command ("gnome-power-statistics"); } +static void +on_brightness_change_requested (GSimpleAction * action G_GNUC_UNUSED, + GVariant * parameter, + gpointer gself) +{ + const double value = g_variant_get_double (parameter); + IndicatorPowerService * self = INDICATOR_POWER_SERVICE (gself); + + g_debug ("setting brightness value: %f", value); + ib_brightness_control_set_value (self->priv->brightness_control, (int)value); + update_brightness_action_state (self); +} + /* FIXME: use a GBinding to tie the gaction's state and the GSetting together? */ static void @@ -687,7 +750,7 @@ init_gactions (IndicatorPowerService * self) GActionEntry entries[] = { { "activate-settings", on_settings_activated }, - { "activate-statistics", on_statistics_activated } + { "activate-statistics", on_statistics_activated }, }; p->actions = g_simple_action_group_new (); @@ -708,6 +771,13 @@ init_gactions (IndicatorPowerService * self) g_simple_action_group_insert (p->actions, G_ACTION(a)); p->battery_level_action = a; + /* add the brightness action */ + a = g_simple_action_new_stateful ("brightness", NULL, action_state_for_brightness (self)); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + g_signal_connect (a, "change-state", G_CALLBACK(on_brightness_change_requested), self); + //{ "brightness", NULL, G_TYPE_DOUBLE, "0.0", on_brightness_change_requested } + p->brightness_action = a; + /* add the show-time action */ show_time = g_settings_get_boolean (p->settings, SETTINGS_SHOW_TIME_S); a = g_simple_action_new_stateful ("show-time", @@ -930,6 +1000,7 @@ my_dispose (GObject * o) g_clear_object (&p->show_time_action); } + g_clear_object (&p->brightness_action); g_clear_object (&p->battery_level_action); g_clear_object (&p->header_action); g_clear_object (&p->show_time_action); @@ -937,6 +1008,8 @@ my_dispose (GObject * o) g_clear_object (&p->conn); + g_clear_pointer (&p->brightness_control, ib_brightness_control_free); + indicator_power_service_set_device_provider (self, NULL); G_OBJECT_CLASS (indicator_power_service_parent_class)->dispose (o); @@ -958,6 +1031,8 @@ indicator_power_service_init (IndicatorPowerService * self) p->settings = g_settings_new ("com.canonical.indicator.power"); + p->brightness_control = ib_brightness_control_new (); + init_gactions (self); g_signal_connect_swapped (p->settings, "changed::" SETTINGS_ICON_POLICY_S, diff --git a/src/unity-menu-item.c b/src/unity-menu-item.c new file mode 100644 index 0000000..e2b9b8f --- /dev/null +++ b/src/unity-menu-item.c @@ -0,0 +1,74 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Renato Araujo Oliveira Filho + */ + +#include "unity-menu-item.h" + +GMenuItem* +unity_menu_item_slider_new (const gchar *label, + const gchar *value_action, + int min_value, + int max_value, + GVariant * left_icon, + GVariant * right_icon) +{ + GMenuItem *menu_item = g_menu_item_new (label, value_action); + + g_menu_item_set_attribute (menu_item, + "x-canonical-type", + "s", + "com.canonical.unity.slider"); + g_menu_item_set_attribute (menu_item, + "x-canonical-min", + "i", + min_value); + g_menu_item_set_attribute (menu_item, + "x-canonical-max", + "i", + max_value); + if (left_icon != NULL) { + g_menu_item_set_attribute (menu_item, + "min-icon", + "*", + left_icon); + } + + if (right_icon != NULL) { + g_menu_item_set_attribute (menu_item, + "max-icon", + "*", + right_icon); + } + + return menu_item; +} + + +GMenuItem* +unity_menu_item_switch_new (const gchar *label, + const gchar *state_action) +{ + GMenuItem *menu_item = g_menu_item_new (label, state_action); + + g_menu_item_set_attribute (menu_item, + "x-canonical-type", + "s", + "com.canonical.unity.switch"); + + return menu_item; +} diff --git a/src/unity-menu-item.h b/src/unity-menu-item.h new file mode 100644 index 0000000..ab1f1d5 --- /dev/null +++ b/src/unity-menu-item.h @@ -0,0 +1,35 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * Authors: + * Renato Araujo Oliveira Filho + */ + +#ifndef __UNITY_MENU_ITEM_H_ +#define __UNITY_MENU_ITEM_H_ + +#include + +GMenuItem* unity_menu_item_slider_new (const gchar *label, + const gchar *value_action, + int min_value, + int max_value, + GVariant * left_icon, + GVariant * right_icon); + +GMenuItem* unity_menu_item_switch_new (const gchar *label, + const gchar *state_action); + +#endif -- cgit v1.2.3