[gnome-power-manager] As we no longer have more than one backlight mechanism, remove a ton of abstract code
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-power-manager] As we no longer have more than one backlight mechanism, remove a ton of abstract code
- Date: Thu, 29 Apr 2010 14:16:26 +0000 (UTC)
commit 176df6b38f26936d05705a548f3ea2356c2b42b1
Author: Richard Hughes <richard hughsie com>
Date: Thu Apr 29 15:13:33 2010 +0100
As we no longer have more than one backlight mechanism, remove a ton of abstract code
po/POTFILES.in | 1 -
src/Makefile.am | 3 -
src/gpm-brightness-xrandr.c | 757 -------------------------------------------
src/gpm-brightness-xrandr.h | 67 ----
src/gpm-brightness.c | 680 ++++++++++++++++++++++++++++++++-------
src/gpm-brightness.h | 3 -
6 files changed, 571 insertions(+), 940 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 49150fc..41e6ee0 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -13,7 +13,6 @@ data/gnome-power-statistics.desktop.in.in
[type: gettext/glade]data/gpm-statistics.ui
[type: gettext/glade]data/gpm-prefs.ui
src/gpm-backlight.c
-src/gpm-brightness-xrandr.c
src/gpm-button.c
src/gpm-control.c
src/gpm-common.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 2dc76f5..1e7f1f4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -35,7 +35,6 @@ INCLUDES = \
-DEGG_LOGGING="\"GPM_LOGGING\"" \
-DEGG_CONSOLE="\"GPM_CONSOLE\"" \
-I$(top_srcdir) \
- -I$(top_srcdir)/libhal-glib \
$(NULL)
bin_PROGRAMS = \
@@ -141,8 +140,6 @@ gnome_power_manager_SOURCES = \
gpm-button.c \
gpm-brightness.h \
gpm-brightness.c \
- gpm-brightness-xrandr.h \
- gpm-brightness-xrandr.c \
gpm-main.c \
gpm-manager.h \
gpm-manager.c \
diff --git a/src/gpm-brightness.c b/src/gpm-brightness.c
index d1804a7..5396966 100644
--- a/src/gpm-brightness.c
+++ b/src/gpm-brightness.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
- * Copyright (C) 2008 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2008-2010 Richard Hughes <richard hughsie com>
*
* Licensed under the GNU General Public License Version 2
*
@@ -28,6 +28,11 @@
#include <time.h>
#include <errno.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -35,10 +40,11 @@
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
+#include "egg-discrete.h"
+#include "egg-debug.h"
+
#include "gpm-brightness.h"
-#include "gpm-brightness-xrandr.h"
#include "gpm-common.h"
-#include "egg-debug.h"
#include "gpm-marshal.h"
#define GPM_BRIGHTNESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPM_TYPE_BRIGHTNESS, GpmBrightnessPrivate))
@@ -46,11 +52,20 @@
struct GpmBrightnessPrivate
{
- gboolean use_xrandr;
gboolean has_changed_events;
gboolean cache_trusted;
guint cache_percentage;
- GpmBrightnessXRandR *xrandr;
+ guint last_set_hw;
+ Atom backlight;
+ Display *dpy;
+ guint shared_value;
+ gboolean has_extension;
+#ifdef HAVE_XRANDR_13
+ gboolean has_randr13;
+#endif
+ gboolean hw_changed;
+ /* A cache of XRRScreenResources is used as XRRGetScreenResources is expensive */
+ GPtrArray *resources;
};
enum {
@@ -58,6 +73,13 @@ enum {
LAST_SIGNAL
};
+typedef enum {
+ ACTION_BACKLIGHT_GET,
+ ACTION_BACKLIGHT_SET,
+ ACTION_BACKLIGHT_INC,
+ ACTION_BACKLIGHT_DEC
+} GpmXRandROp;
+
G_DEFINE_TYPE (GpmBrightness, gpm_brightness, G_TYPE_OBJECT)
static guint signals [LAST_SIGNAL] = { 0 };
static gpointer gpm_brightness_object = NULL;
@@ -67,7 +89,7 @@ static gpointer gpm_brightness_object = NULL;
* @levels: The number of levels supported
* Return value: the amount of hardware steps to do on each increment or decrement
**/
-guint
+static guint
gpm_brightness_get_step (guint levels)
{
/* macbook pro has a bazzillion brightness levels, do in 5% steps */
@@ -77,6 +99,377 @@ gpm_brightness_get_step (guint levels)
}
/**
+ * gpm_brightness_output_get_internal:
+ **/
+static gboolean
+gpm_brightness_output_get_internal (GpmBrightness *brightness, RROutput output, guint *cur)
+{
+ unsigned long nitems;
+ unsigned long bytes_after;
+ guint *prop;
+ Atom actual_type;
+ int actual_format;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ if (XRRGetOutputProperty (brightness->priv->dpy, output, brightness->priv->backlight,
+ 0, 4, False, False, None,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, ((unsigned char **)&prop)) != Success) {
+ egg_debug ("failed to get property");
+ return FALSE;
+ }
+ if (actual_type == XA_INTEGER && nitems == 1 && actual_format == 32) {
+ memcpy (cur, prop, sizeof (guint));
+ ret = TRUE;
+ }
+ XFree (prop);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_set_internal:
+ **/
+static gboolean
+gpm_brightness_output_set_internal (GpmBrightness *brightness, RROutput output, guint value)
+{
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* don't abort on error */
+ gdk_error_trap_push ();
+ XRRChangeOutputProperty (brightness->priv->dpy, output, brightness->priv->backlight, XA_INTEGER, 32,
+ PropModeReplace, (unsigned char *) &value, 1);
+ XFlush (brightness->priv->dpy);
+ gdk_flush ();
+ if (gdk_error_trap_pop ()) {
+ egg_warning ("failed to XRRChangeOutputProperty for brightness %i", value);
+ ret = FALSE;
+ }
+ /* we changed the hardware */
+ if (ret)
+ brightness->priv->hw_changed = TRUE;
+ return ret;
+}
+
+/**
+ * gpm_brightness_setup_display:
+ **/
+static gboolean
+gpm_brightness_setup_display (GpmBrightness *brightness)
+{
+ gint major, minor;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* get the display */
+ brightness->priv->dpy = GDK_DISPLAY();
+ if (!brightness->priv->dpy) {
+ egg_error ("Cannot open display");
+ return FALSE;
+ }
+ /* is XRandR new enough? */
+ if (!XRRQueryVersion (brightness->priv->dpy, &major, &minor)) {
+ egg_debug ("RandR extension missing");
+ return FALSE;
+ }
+ if (major < 1 || (major == 1 && minor < 2)) {
+ egg_debug ("RandR version %d.%d too old", major, minor);
+ return FALSE;
+ }
+ /* can we support BACKLIGHT */
+ brightness->priv->backlight = XInternAtom (brightness->priv->dpy, "BACKLIGHT", True);
+ if (brightness->priv->backlight == None) {
+ egg_debug ("No outputs have backlight property");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#ifdef HAVE_XRANDR_13
+/**
+ * gpm_brightness_setup_version: Check whether xserver really supports xrandr-1.3 features.
+ **/
+static gboolean
+gpm_brightness_setup_version (GpmBrightness *brightness)
+{
+ gint major, minor;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* get the display */
+ brightness->priv->dpy = GDK_DISPLAY();
+ if (!brightness->priv->dpy) {
+ egg_error ("Cannot open display");
+ return FALSE;
+ }
+ if (!XRRQueryVersion (brightness->priv->dpy, &major, &minor)) {
+ return FALSE;
+ }
+ if (major == 1 && minor < 3) {
+ egg_debug ("RandR version %d.%d does not support XRRGetScreenResourcesCurrent", major, minor);
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
+/**
+ * gpm_brightness_output_get_limits:
+ **/
+static gboolean
+gpm_brightness_output_get_limits (GpmBrightness *brightness, RROutput output,
+ guint *min, guint *max)
+{
+ XRRPropertyInfo *info;
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ info = XRRQueryOutputProperty (brightness->priv->dpy, output, brightness->priv->backlight);
+ if (info == NULL) {
+ egg_debug ("could not get output property");
+ return FALSE;
+ }
+ if (!info->range || info->num_values != 2) {
+ egg_debug ("was not range");
+ ret = FALSE;
+ goto out;
+ }
+ *min = info->values[0];
+ *max = info->values[1];
+out:
+ XFree (info);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_get_percentage:
+ **/
+static gboolean
+gpm_brightness_output_get_percentage (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ gboolean ret;
+ guint min, max;
+ guint percentage;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ percentage = egg_discrete_to_percent (cur, (max-min)+1);
+ egg_debug ("percentage %i", percentage);
+ brightness->priv->shared_value = percentage;
+ return TRUE;
+}
+
+/**
+ * gpm_brightness_output_down:
+ **/
+static gboolean
+gpm_brightness_output_down (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ guint step;
+ gboolean ret;
+ guint min, max;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ if (cur == min) {
+ egg_debug ("already min");
+ return TRUE;
+ }
+ step = gpm_brightness_get_step ((max-min)+1);
+ if (cur < step) {
+ egg_debug ("truncating to %i", min);
+ cur = min;
+ } else {
+ cur -= step;
+ }
+ ret = gpm_brightness_output_set_internal (brightness, output, cur);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_up:
+ **/
+static gboolean
+gpm_brightness_output_up (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ gboolean ret;
+ guint min, max;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ if (cur == max) {
+ egg_debug ("already max");
+ return TRUE;
+ }
+ cur += gpm_brightness_get_step ((max-min)+1);
+ if (cur > max) {
+ egg_debug ("truncating to %i", max);
+ cur = max;
+ }
+ ret = gpm_brightness_output_set_internal (brightness, output, cur);
+ return ret;
+}
+
+/**
+ * gpm_brightness_output_set:
+ **/
+static gboolean
+gpm_brightness_output_set (GpmBrightness *brightness, RROutput output)
+{
+ guint cur;
+ gboolean ret;
+ guint min, max;
+ gint i;
+ gint shared_value_abs;
+ guint step;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ ret = gpm_brightness_output_get_internal (brightness, output, &cur);
+ if (!ret)
+ return FALSE;
+ ret = gpm_brightness_output_get_limits (brightness, output, &min, &max);
+ if (!ret || min == max)
+ return FALSE;
+
+ shared_value_abs = egg_discrete_from_percent (brightness->priv->shared_value, (max-min)+1);
+ egg_debug ("percent=%i, absolute=%i", brightness->priv->shared_value, shared_value_abs);
+
+ egg_debug ("hard value=%i, min=%i, max=%i", cur, min, max);
+ if (shared_value_abs > (gint) max)
+ shared_value_abs = max;
+ if (shared_value_abs < (gint) min)
+ shared_value_abs = min;
+ if ((gint) cur == shared_value_abs) {
+ egg_debug ("already set %i", cur);
+ return TRUE;
+ }
+
+ /* step the correct way */
+ if ((gint) cur < shared_value_abs) {
+
+ /* some adaptors have a large number of steps */
+ step = gpm_brightness_get_step (shared_value_abs - cur);
+ egg_debug ("using step of %i", step);
+
+ /* going up */
+ for (i=cur; i<=shared_value_abs; i+=step) {
+ ret = gpm_brightness_output_set_internal (brightness, output, i);
+ if (!ret)
+ break;
+ if ((gint) cur != shared_value_abs)
+ g_usleep (1000 * GPM_BRIGHTNESS_DIM_INTERVAL);
+ }
+ } else {
+
+ /* some adaptors have a large number of steps */
+ step = gpm_brightness_get_step (cur - shared_value_abs);
+ egg_debug ("using step of %i", step);
+
+ /* going down */
+ for (i=cur; i>=shared_value_abs; i-=step) {
+ ret = gpm_brightness_output_set_internal (brightness, output, i);
+ if (!ret)
+ break;
+ if ((gint) cur != shared_value_abs)
+ g_usleep (1000 * GPM_BRIGHTNESS_DIM_INTERVAL);
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * gpm_brightness_foreach_resource:
+ **/
+static gboolean
+gpm_brightness_foreach_resource (GpmBrightness *brightness, GpmXRandROp op, XRRScreenResources *resources)
+{
+ gint i;
+ gboolean ret;
+ gboolean success_any = FALSE;
+ RROutput output;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* do for each output */
+ for (i=0; i<resources->noutput; i++) {
+ output = resources->outputs[i];
+ egg_debug ("resource %i of %i", i+1, resources->noutput);
+ if (op==ACTION_BACKLIGHT_GET) {
+ ret = gpm_brightness_output_get_percentage (brightness, output);
+ } else if (op==ACTION_BACKLIGHT_INC) {
+ ret = gpm_brightness_output_up (brightness, output);
+ } else if (op==ACTION_BACKLIGHT_DEC) {
+ ret = gpm_brightness_output_down (brightness, output);
+ } else if (op==ACTION_BACKLIGHT_SET) {
+ ret = gpm_brightness_output_set (brightness, output);
+ } else {
+ ret = FALSE;
+ egg_warning ("op not known");
+ }
+ if (ret) {
+ success_any = TRUE;
+ }
+ }
+ return success_any;
+}
+
+/**
+ * gpm_brightness_foreach_screen:
+ **/
+static gboolean
+gpm_brightness_foreach_screen (GpmBrightness *brightness, GpmXRandROp op)
+{
+ guint i;
+ guint length;
+ XRRScreenResources *resource;
+ gboolean ret;
+ gboolean success_any = FALSE;
+
+ g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
+
+ /* do for each screen */
+ length = brightness->priv->resources->len;
+ for (i=0; i<length; i++) {
+ resource = (XRRScreenResources *) g_ptr_array_index (brightness->priv->resources, i);
+ egg_debug ("using resource %p", resource);
+ ret = gpm_brightness_foreach_resource (brightness, op, resource);
+ if (ret)
+ success_any = TRUE;
+ }
+ XSync (brightness->priv->dpy, False);
+ return success_any;
+}
+
+/**
* gpm_brightness_trust_cache:
* @brightness: This brightness class instance
* Return value: if we can trust the cache
@@ -113,7 +506,6 @@ gpm_brightness_set (GpmBrightness *brightness, guint percentage, gboolean *hw_ch
{
gboolean ret = FALSE;
gboolean trust_cache;
- gboolean hw_changed_local = FALSE;
g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
@@ -124,25 +516,21 @@ gpm_brightness_set (GpmBrightness *brightness, guint percentage, gboolean *hw_ch
return TRUE;
}
- /* set the hardware */
- if (brightness->priv->use_xrandr) {
- ret = gpm_brightness_xrandr_set (brightness->priv->xrandr, percentage, &hw_changed_local);
- if (ret)
- goto out;
- egg_warning ("failed to set using xrandr, falling back to HAL");
- brightness->priv->use_xrandr = FALSE;
- }
- egg_debug ("no hardware support");
- return FALSE;
-out:
+ /* set the value we want */
+ brightness->priv->shared_value = percentage;
+
+ /* reset to not-changed */
+ brightness->priv->hw_changed = FALSE;
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_SET);
+
+ /* did the hardware have to be modified? */
+ if (ret && hw_changed != NULL)
+ *hw_changed = brightness->priv->hw_changed;
+
/* we did something to the hardware, so untrusted */
if (ret)
brightness->priv->cache_trusted = FALSE;
- /* is the caller interested? */
- if (ret && hw_changed != NULL)
- *hw_changed = hw_changed_local;
-
return ret;
}
@@ -172,21 +560,15 @@ gpm_brightness_get (GpmBrightness *brightness, guint *percentage)
}
/* get the brightness from hardware -- slow */
- if (brightness->priv->use_xrandr) {
- ret = gpm_brightness_xrandr_get (brightness->priv->xrandr, &percentage_local);
- if (ret)
- goto out;
- egg_warning ("failed to set using xrandr, falling back to HAL");
- brightness->priv->use_xrandr = FALSE;
- }
- egg_debug ("no hardware support");
- return FALSE;
-out:
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_GET);
+ percentage_local = brightness->priv->shared_value;
+
/* valid? */
if (percentage_local > 100) {
egg_warning ("percentage value of %i will be ignored", percentage_local);
ret = FALSE;
}
+
/* a new value is always trusted if the method and checks succeed */
if (ret) {
brightness->priv->cache_percentage = percentage_local;
@@ -210,27 +592,21 @@ gboolean
gpm_brightness_up (GpmBrightness *brightness, gboolean *hw_changed)
{
gboolean ret = FALSE;
- gboolean hw_changed_local = FALSE;
g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
- if (brightness->priv->use_xrandr) {
- ret = gpm_brightness_xrandr_up (brightness->priv->xrandr, &hw_changed_local);
- if (ret)
- goto out;
- egg_warning ("failed to set using xrandr, falling back to HAL");
- brightness->priv->use_xrandr = FALSE;
- }
- egg_debug ("no hardware support");
- return FALSE;
-out:
+ /* reset to not-changed */
+ brightness->priv->hw_changed = FALSE;
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_INC);
+
+ /* did the hardware have to be modified? */
+ if (ret && hw_changed != NULL)
+ *hw_changed = brightness->priv->hw_changed;
+
/* we did something to the hardware, so untrusted */
if (ret)
brightness->priv->cache_trusted = FALSE;
- /* is the caller interested? */
- if (ret && hw_changed != NULL) {
- *hw_changed = hw_changed_local;
- }
+
return ret;
}
@@ -246,30 +622,123 @@ gboolean
gpm_brightness_down (GpmBrightness *brightness, gboolean *hw_changed)
{
gboolean ret = FALSE;
- gboolean hw_changed_local = FALSE;
g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
- if (brightness->priv->use_xrandr) {
- ret = gpm_brightness_xrandr_down (brightness->priv->xrandr, &hw_changed_local);
- if (ret)
- goto out;
- egg_warning ("failed to set using xrandr, falling back to HAL");
- brightness->priv->use_xrandr = FALSE;
- }
- egg_debug ("no hardware support");
- return FALSE;
-out:
+ /* reset to not-changed */
+ brightness->priv->hw_changed = FALSE;
+ ret = gpm_brightness_foreach_screen (brightness, ACTION_BACKLIGHT_DEC);
+
+ /* did the hardware have to be modified? */
+ if (ret && hw_changed != NULL)
+ *hw_changed = brightness->priv->hw_changed;
+
/* we did something to the hardware, so untrusted */
if (ret)
brightness->priv->cache_trusted = FALSE;
- /* is the caller interested? */
- if (ret && hw_changed != NULL)
- *hw_changed = hw_changed_local;
return ret;
}
+
+/**
+ * gpm_brightness_may_have_changed:
+ **/
+static void
+gpm_brightness_may_have_changed (GpmBrightness *brightness)
+{
+ gboolean ret;
+ guint percentage;
+ ret = gpm_brightness_get (brightness, &percentage);
+ if (!ret) {
+ egg_warning ("failed to get output");
+ return;
+ }
+ egg_debug ("emitting brightness-changed (%i)", percentage);
+ g_signal_emit (brightness, signals [BRIGHTNESS_CHANGED], 0, percentage);
+}
+
+/**
+ * gpm_brightness_filter_xevents:
+ **/
+static GdkFilterReturn
+gpm_brightness_filter_xevents (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ GpmBrightness *brightness = GPM_BRIGHTNESS (data);
+ if (event->type == GDK_NOTHING)
+ return GDK_FILTER_CONTINUE;
+ gpm_brightness_may_have_changed (brightness);
+ return GDK_FILTER_CONTINUE;
+}
+
+
+static void gpm_brightness_update_cache (GpmBrightness *brightness);
+
+/**
+ * gpm_brightness_monitors_changed:
+ **/
+static void
+gpm_brightness_monitors_changed (GdkScreen *screen, GpmBrightness *brightness)
+{
+ g_return_if_fail (GPM_IS_BRIGHTNESS (brightness));
+ gpm_brightness_update_cache (brightness);
+}
+
+/**
+ * gpm_brightness_update_cache:
+ **/
+static void
+gpm_brightness_update_cache (GpmBrightness *brightness)
+{
+ guint length;
+ gint screen;
+ Window root;
+ GdkScreen *gscreen;
+ GdkDisplay *display;
+ XRRScreenResources *resource;
+
+ g_return_if_fail (GPM_IS_BRIGHTNESS (brightness));
+
+ /* invalidate and remove all the previous entries */
+ length = brightness->priv->resources->len;
+ if (length > 0)
+ g_ptr_array_set_size (brightness->priv->resources, 0);
+
+ /* do for each screen */
+ display = gdk_display_get_default ();
+ length = ScreenCount (brightness->priv->dpy);
+ for (screen = 0; screen < (gint) length; screen++) {
+ egg_debug ("screen %i of %i", screen+1, length);
+ gscreen = gdk_display_get_screen (display, screen);
+
+ /* if we have not setup the changed on the monitor, set it here */
+ if (g_object_get_data (G_OBJECT (gscreen), "gpk-set-monitors-changed") == NULL) {
+ egg_debug ("watching ::monitors_changed on %p", gscreen);
+ g_object_set_data (G_OBJECT (gscreen), "gpk-set-monitors-changed", (gpointer) "true");
+ g_signal_connect (G_OBJECT (gscreen), "monitors_changed",
+ G_CALLBACK (gpm_brightness_monitors_changed), brightness);
+ }
+
+ root = RootWindow (brightness->priv->dpy, screen);
+ /* XRRGetScreenResourcesCurrent is less expensive than
+ XRRGetScreenResources, however it is available only
+ in RandR 1.3 or higher and of course xserver needs
+ to support it.
+ */
+#ifdef HAVE_XRANDR_13
+ if (brightness->priv->has_randr13)
+ resource = XRRGetScreenResourcesCurrent (brightness->priv->dpy, root);
+ else
+#endif
+ resource = XRRGetScreenResources (brightness->priv->dpy, root);
+
+ if (resource != NULL) {
+ egg_debug ("adding resource %p", resource);
+ g_ptr_array_add (brightness->priv->resources, resource);
+ }
+ }
+}
+
/**
* gpm_brightness_has_hw:
**/
@@ -277,7 +746,7 @@ gboolean
gpm_brightness_has_hw (GpmBrightness *brightness)
{
g_return_val_if_fail (GPM_IS_BRIGHTNESS (brightness), FALSE);
- return brightness->priv->use_xrandr;
+ return brightness->priv->has_extension;
}
/**
@@ -290,7 +759,7 @@ gpm_brightness_finalize (GObject *object)
g_return_if_fail (object != NULL);
g_return_if_fail (GPM_IS_BRIGHTNESS (object));
brightness = GPM_BRIGHTNESS (object);
- g_object_unref (brightness->priv->xrandr);
+ g_ptr_array_unref (brightness->priv->resources);
G_OBJECT_CLASS (gpm_brightness_parent_class)->finalize (object);
}
@@ -314,65 +783,58 @@ gpm_brightness_class_init (GpmBrightnessClass *klass)
}
/**
- * gpm_brightness_changed:
- * This callback is called when the brightness value changes.
- **/
-static void
-gpm_brightness_changed (GpmBrightness *brightness, guint percentage)
-{
- g_return_if_fail (GPM_IS_BRIGHTNESS (brightness));
- brightness->priv->cache_trusted = TRUE;
-
- /* valid? */
- if (percentage > 100) {
- egg_warning ("percentage value of %i will be ignored", percentage);
- /* no longer trust the cache */
- brightness->priv->has_changed_events = FALSE;
- brightness->priv->cache_trusted = FALSE;
- return;
- }
-
- brightness->priv->has_changed_events = TRUE;
- brightness->priv->cache_trusted = TRUE;
- brightness->priv->cache_percentage = percentage;
- /* ONLY EMIT THIS SIGNAL WHEN SOMETHING _ELSE_ HAS CHANGED THE BACKLIGHT */
- egg_debug ("emitting brightness-changed (%i)", percentage);
- g_signal_emit (brightness, signals [BRIGHTNESS_CHANGED], 0, percentage);
-}
-
-/**
- * gpm_brightness_xrandr_changed_cb:
- * This callback is called when the brightness value changes.
- **/
-static void
-gpm_brightness_xrandr_changed_cb (GpmBrightnessXRandR *xrandr, guint percentage, GpmBrightness *brightness)
-{
- g_return_if_fail (GPM_IS_BRIGHTNESS (brightness));
- if (brightness->priv->use_xrandr)
- gpm_brightness_changed (brightness, percentage);
-}
-
-/**
* gpm_brightness_init:
* @brightness: This brightness class instance
**/
static void
gpm_brightness_init (GpmBrightness *brightness)
{
+ GdkScreen *screen;
+ GdkWindow *window;
+ GdkDisplay *display;
+ int event_base;
+ int ignore;
+
brightness->priv = GPM_BRIGHTNESS_GET_PRIVATE (brightness);
- brightness->priv->use_xrandr = FALSE;
brightness->priv->cache_trusted = FALSE;
brightness->priv->has_changed_events = FALSE;
brightness->priv->cache_percentage = 0;
+ brightness->priv->hw_changed = FALSE;
+ brightness->priv->resources = g_ptr_array_new_with_free_func ((GDestroyNotify) XRRFreeScreenResources);
+
+ /* can we do this */
+ brightness->priv->has_extension = gpm_brightness_setup_display (brightness);
+#ifdef HAVE_XRANDR_13
+ brightness->priv->has_randr13 = gpm_brightness_setup_version (brightness);
+#endif
+ if (brightness->priv->has_extension == FALSE) {
+ egg_debug ("no XRANDR extension, so aborting init");
+ return;
+ }
+
+ screen = gdk_screen_get_default ();
+ window = gdk_screen_get_root_window (screen);
+ display = gdk_display_get_default ();
- brightness->priv->xrandr = gpm_brightness_xrandr_new ();
- if (gpm_brightness_xrandr_has_hw (brightness->priv->xrandr)) {
- egg_debug ("detected XRANDR hardware");
- brightness->priv->use_xrandr = TRUE;
+ /* as we a filtering by a window, we have to add an event type */
+ if (!XRRQueryExtension (GDK_DISPLAY(), &event_base, &ignore)) {
+ egg_error ("can't get event_base for XRR");
}
- g_signal_connect (brightness->priv->xrandr, "brightness-changed",
- G_CALLBACK (gpm_brightness_xrandr_changed_cb), brightness);
+ gdk_x11_register_standard_event_type (display, event_base, RRNotify + 1);
+ gdk_window_add_filter (window, gpm_brightness_filter_xevents, (gpointer) brightness);
+
+ /* don't abort on error */
+ gdk_error_trap_push ();
+ XRRSelectInput (GDK_DISPLAY(), GDK_WINDOW_XID (window),
+ RRScreenChangeNotifyMask |
+ RROutputPropertyNotifyMask); /* <--- the only one we need, but see rh:345551 */
+ gdk_flush ();
+ if (gdk_error_trap_pop ())
+ egg_warning ("failed to select XRRSelectInput");
+
+ /* create cache of XRRScreenResources as XRRGetScreenResources() is slow */
+ gpm_brightness_update_cache (brightness);
}
/**
diff --git a/src/gpm-brightness.h b/src/gpm-brightness.h
index 65665fa..918793d 100644
--- a/src/gpm-brightness.h
+++ b/src/gpm-brightness.h
@@ -64,9 +64,6 @@ gboolean gpm_brightness_set (GpmBrightness *brightness,
guint percentage,
gboolean *hw_changed);
-/* not designed to be used outside of gpm-brightness-*.c */
-guint gpm_brightness_get_step (guint levels);
-
G_END_DECLS
#endif /* __GPM_BRIGHTNESS_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]