/* * * Copyright (C) 2013 Sonal Santan * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include #include "xfpm-kbd-backlight.h" #include "xfpm-button.h" #include "xfpm-notify.h" #include "xfpm-power.h" static void xfpm_kbd_backlight_finalize (GObject *object); struct XfpmKbdBacklightPrivate { XfpmPower *power; XfpmButton *button; GDBusConnection *bus; GDBusProxy *proxy; gboolean dimmed; gboolean on_battery; gint32 max_level; gint min_level; gint step; XfpmNotify *notify; NotifyNotification *n; }; G_DEFINE_TYPE_WITH_PRIVATE (XfpmKbdBacklight, xfpm_kbd_backlight, G_TYPE_OBJECT) static gint calculate_step( gint max_level ) { if ( max_level < 20 ) return 1; else return max_level / 20; } static void xfpm_kbd_backlight_on_battery_changed_cb (XfpmPower *power, gboolean on_battery, XfpmKbdBacklight *backlight) { backlight->priv->on_battery = on_battery; } static void xfpm_kbd_backlight_init_max_level (XfpmKbdBacklight *backlight) { GError *error = NULL; GVariant *var; var = g_dbus_proxy_call_sync (backlight->priv->proxy, "GetMaxBrightness", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (var) { g_variant_get (var, "(i)", &backlight->priv->max_level); g_variant_unref (var); } if ( error ) { g_warning ("Failed to get keyboard max brightness level : %s", error->message); g_error_free (error); } } static void xfpm_kbd_backlight_show_notification (XfpmKbdBacklight *self, gfloat value) { gchar *summary; if ( self->priv->n == NULL ) { /* generate a human-readable summary for the notification */ summary = g_strdup_printf (_("Keyboard Brightness: %.0f percent"), value); self->priv->n = xfpm_notify_new_notification (self->priv->notify, _("Power Manager"), summary, "keyboard-brightness", XFPM_NOTIFY_NORMAL); g_free (summary); } /* add the brightness value to the notification */ notify_notification_set_hint (self->priv->n, "value", g_variant_new_int32 (value)); /* show the notification */ notify_notification_show (self->priv->n, NULL); } static gint xfpm_kbd_backlight_get_level (XfpmKbdBacklight *backlight) { GError *error = NULL; gint32 level = -1; GVariant *var; var = g_dbus_proxy_call_sync (backlight->priv->proxy, "GetBrightness", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (var) { g_variant_get (var, "(i)", &level); g_variant_unref (var); } if ( error ) { g_warning ("Failed to get keyboard brightness level : %s", error->message); g_error_free (error); } return level; } static void xfpm_kbd_backlight_set_level (XfpmKbdBacklight *backlight, gint32 level) { GError *error = NULL; gfloat percent; GVariant *var; var = g_dbus_proxy_call_sync (backlight->priv->proxy, "SetBrightness", g_variant_new("(i)", level), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (var) g_variant_unref (var); if ( error ) { g_warning ("Failed to set keyboard brightness level : %s", error->message); g_error_free (error); } else { percent = 100.0 * ((gfloat)level / (gfloat)backlight->priv->max_level); xfpm_kbd_backlight_show_notification (backlight, percent); } } static void xfpm_kbd_backlight_up (XfpmKbdBacklight *backlight) { gint level; level = xfpm_kbd_backlight_get_level (backlight); if ( level == -1) return; if ( level == backlight->priv->max_level ) return; level += backlight->priv->step; if ( level > backlight->priv->max_level ) level = backlight->priv->max_level; xfpm_kbd_backlight_set_level (backlight, level); } static void xfpm_kbd_backlight_down (XfpmKbdBacklight *backlight) { gint level; level = xfpm_kbd_backlight_get_level (backlight); if ( level == -1) return; if ( level == backlight->priv->min_level ) return; level -= backlight->priv->step; if ( level < backlight->priv->min_level ) level = backlight->priv->min_level; xfpm_kbd_backlight_set_level (backlight, level); } static void xfpm_kbd_backlight_button_pressed_cb (XfpmButton *button, XfpmButtonKey type, XfpmKbdBacklight *backlight) { if ( type == BUTTON_KBD_BRIGHTNESS_UP ) { xfpm_kbd_backlight_up (backlight); } else if ( type == BUTTON_KBD_BRIGHTNESS_DOWN ) { xfpm_kbd_backlight_down (backlight); } } static void xfpm_kbd_backlight_class_init (XfpmKbdBacklightClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = xfpm_kbd_backlight_finalize; } static void xfpm_kbd_backlight_init (XfpmKbdBacklight *backlight) { GError *error = NULL; backlight->priv = xfpm_kbd_backlight_get_instance_private (backlight); backlight->priv->bus = NULL; backlight->priv->proxy = NULL; backlight->priv->power = NULL; backlight->priv->button = NULL; backlight->priv->dimmed = FALSE; backlight->priv->on_battery = FALSE; backlight->priv->max_level = 0; backlight->priv->min_level = 0; backlight->priv->notify = NULL; backlight->priv->n = NULL; backlight->priv->bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if ( error ) { g_critical ("Unable to get system bus connection : %s", error->message); g_error_free (error); goto out; } backlight->priv->proxy = g_dbus_proxy_new_sync (backlight->priv->bus, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, NULL, "org.freedesktop.UPower", "/org/freedesktop/UPower/KbdBacklight", "org.freedesktop.UPower.KbdBacklight", NULL, NULL); if ( backlight->priv->proxy == NULL ) { g_warning ("Unable to get the interface, org.freedesktop.UPower.KbdBacklight"); goto out; } xfpm_kbd_backlight_init_max_level (backlight); if ( backlight->priv->max_level == 0 ) goto out; backlight->priv->step = calculate_step (backlight->priv->max_level); backlight->priv->power = xfpm_power_get (); backlight->priv->button = xfpm_button_new (); backlight->priv->notify = xfpm_notify_new (); g_signal_connect (backlight->priv->button, "button-pressed", G_CALLBACK (xfpm_kbd_backlight_button_pressed_cb), backlight); g_signal_connect (backlight->priv->power, "on-battery-changed", G_CALLBACK (xfpm_kbd_backlight_on_battery_changed_cb), backlight); g_object_get (G_OBJECT (backlight->priv->power), "on-battery", &backlight->priv->on_battery, NULL); out: ; } static void xfpm_kbd_backlight_finalize (GObject *object) { XfpmKbdBacklight *backlight = NULL; backlight = XFPM_KBD_BACKLIGHT (object); if ( backlight->priv->power ) g_object_unref (backlight->priv->power ); if ( backlight->priv->button ) g_object_unref (backlight->priv->button); if ( backlight->priv->notify ) g_object_unref (backlight->priv->notify); if ( backlight->priv->n ) g_object_unref (backlight->priv->n); if ( backlight->priv->proxy ) g_object_unref (backlight->priv->proxy); if ( backlight->priv->bus ) g_object_unref (backlight->priv->bus); G_OBJECT_CLASS (xfpm_kbd_backlight_parent_class)->finalize (object); } XfpmKbdBacklight * xfpm_kbd_backlight_new (void) { XfpmKbdBacklight *backlight = NULL; backlight = g_object_new (XFPM_TYPE_KBD_BACKLIGHT, NULL); return backlight; } gboolean xfpm_kbd_backlight_has_hw (XfpmKbdBacklight *backlight) { return ( backlight->priv->proxy == NULL ) ? FALSE : TRUE; }