hal: Branch 'master'

Danny Kukawka dkukawka at kemper.freedesktop.org
Thu Mar 13 12:38:27 PDT 2008


 configure.in                                |   25 +++
 fdi/policy/10osvendor/10-imac-backlight.fdi |   32 ++++
 hald/linux/addons/Makefile.am               |    6 
 hald/linux/addons/addon-imac-backlight.c    |  224 ++++++++++++++++++++++++++++
 4 files changed, 287 insertions(+)

New commits:
commit ee68b0ebfcadf60bf31dd1b3163f52741dce25f1
Author: Martin Szulecki <opensuse at sukimashita.com>
Date:   Thu Mar 13 20:38:18 2008 +0100

    add iMac (x86 linux) backlight addon
    
    Added iMac (x86 linux) backlight addon.
    
    On my way to control the hardcore radioactive backlight of the newer
    iMac 24" aluminum models some older code from the mactel guys appeared
    to work (while the brightness level range lacks on the 24" but is good
    on the 20" ones, compared to Mac OS).
    
    I glued a patch which exposes the control like the other Macbook and
    Macbook Pro addons. People reported that it apparently also worked on
    other iMac models which I added to the corresponding fdi.
    
    With the lately upstreamed hid patches to support the new aluminum apple
    keyboard (really nice!) one can control the backlight of the display
    nicely.

diff --git a/configure.in b/configure.in
index f4a1aac..013e2b3 100644
--- a/configure.in
+++ b/configure.in
@@ -838,6 +838,30 @@ elif test "x$with_macbook" = "x" ; then
 fi
 AM_CONDITIONAL(BUILD_MACBOOK, [test x$BUILD_MACBOOK = xyes])
 
+dnl imac backlight
+AC_ARG_WITH([imac],
+            AS_HELP_STRING([--with-imac],
+                           [Whether to build iMac (x86 only) backlight (auto)]))
+BUILD_IMAC=no
+if test "x$with_imac" = "xyes" ; then
+   BUILD_IMAC=yes
+elif test "x$with_imac" = "x" ; then
+    case "${HALD_BACKEND}" in
+      linux) 
+        case "${host}" in
+          i[[3456]]86-*-*|x86_64-*-*)
+            BUILD_IMAC=yes
+            ;;
+          *)
+            ;;
+        esac
+        ;;
+      *)
+        ;;
+    esac
+fi
+AM_CONDITIONAL(BUILD_IMAC, [test x$BUILD_IMAC = xyes])
+
 AC_ARG_WITH([omap],
 	    AS_HELP_STRING([--with-omap],
 			   [Whether to build OMAP utils (auto)]))
@@ -1064,6 +1088,7 @@ echo "
 
         Macbook backlight support:        ${BUILD_MACBOOK} (Linux only, x86 only, requires libpci)
         Macbook Pro utils:                ${BUILD_MACBOOKPRO} (Linux only, x86 only, requires libpci)
+        iMac backlight support:           ${BUILD_IMAC} (Linux only, x86)
         OMAP utils:                       ${BUILD_OMAP} (Linux only, arm only)
         CPU frequency scaling:            ${BUILD_CPUFREQ} (Linux only)
         Re-map multimedia keys:           ${BUILD_KEYMAPS} (Linux only, requires gperf)
diff --git a/fdi/policy/10osvendor/10-imac-backlight.fdi b/fdi/policy/10osvendor/10-imac-backlight.fdi
new file mode 100644
index 0000000..56d343e
--- /dev/null
+++ b/fdi/policy/10osvendor/10-imac-backlight.fdi
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+  <device>
+    <match key="system.kernel.name" string="Linux">
+      <match key="system.hardware.vendor" contains="Apple">
+	<!-- iMac (Core 2 Duo) -->
+	<match key="system.hardware.product" string="iMac5,1">
+          <spawn udi="/org/freedesktop/Hal/devices/imac_backlight"/>
+        </match>
+	<!-- iMac (24-inch Core 2 Duo) -->
+	<match key="system.hardware.product" string="iMac6,1">
+          <spawn udi="/org/freedesktop/Hal/devices/imac_backlight"/>
+        </match>
+	<!-- iMac (Alu 24-inch Core 2 Duo) -->
+        <match key="system.hardware.product" string="iMac7,1">
+          <spawn udi="/org/freedesktop/Hal/devices/imac_backlight"/>
+        </match>
+      </match>
+    </match>
+  </device>
+  <device>
+    <match key="info.udi" string="/org/freedesktop/Hal/devices/imac_backlight">
+      <append key="info.capabilities" type="strlist">laptop_panel</append>
+      <merge key="info.category" type="string">laptop_panel</merge>
+      <merge key="info.product" type="string">iMac Backlight Control</merge>
+      <merge key="laptop_panel.access_method" type="string">custom</merge>
+      <merge key="laptop_panel.num_levels" type="int">15</merge>
+      <append key="info.addons" type="strlist">hald-addon-imac-backlight</append>
+    </match>
+  </device>
+</deviceinfo>
diff --git a/hald/linux/addons/Makefile.am b/hald/linux/addons/Makefile.am
index 8546f02..37beba4 100644
--- a/hald/linux/addons/Makefile.am
+++ b/hald/linux/addons/Makefile.am
@@ -35,6 +35,12 @@ hald_addon_omap_backlight_SOURCES = addon-omap-backlight.c ../../logger.c ../../
 hald_addon_omap_backlight_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@
 endif
 
+if BUILD_IMAC
+libexec_PROGRAMS += hald-addon-imac-backlight
+hald_addon_imac_backlight_SOURCES = addon-imac-backlight.c ../../logger.c
+hald_addon_imac_backlight_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@
+endif
+
 if BUILD_MACBOOKPRO
 libexec_PROGRAMS += hald-addon-macbookpro-backlight
 hald_addon_macbookpro_backlight_SOURCES = addon-macbookpro-backlight.c ../../logger.c
diff --git a/hald/linux/addons/addon-imac-backlight.c b/hald/linux/addons/addon-imac-backlight.c
new file mode 100644
index 0000000..46cac6d
--- /dev/null
+++ b/hald/linux/addons/addon-imac-backlight.c
@@ -0,0 +1,224 @@
+/*
+ * Apple iMac Backlight control
+ *
+ * Copyright (C) 2007 Martin Szulecki <opensuse at sukimashita.com>
+ * Copyright (C) 2006 Nicolas Boichat <nicolas at boichat.ch>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/io.h>
+
+#include <glib/gmain.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "libhal/libhal.h"
+#include "../../logger.h"
+
+static void
+backlight_set(int value)
+{
+	outb(0x04 | (value << 4), 0xB3);
+	outb(0xBF, 0xB2);
+}
+
+static int
+backlight_get(void)
+{
+	outb(0x03, 0xB3);
+	outb(0xBF, 0xB2);
+	return inb(0xB3) >> 4;
+}
+
+static gboolean
+check_priv (DBusConnection *connection, DBusMessage *message, const char *udi, const char *privilege)
+#ifdef HAVE_POLKIT
+{
+        gboolean ret;
+        char *polkit_result;
+        const char *invoked_by_syscon_name;
+        DBusMessage *reply;
+        DBusError error;
+
+        ret = FALSE;
+        polkit_result = NULL;
+
+        invoked_by_syscon_name = dbus_message_get_sender (message);
+        
+        dbus_error_init (&error);
+        polkit_result = libhal_device_is_caller_privileged (halctx,
+                                                            udi,
+                                                            privilege,
+                                                            invoked_by_syscon_name,
+                                                            &error);
+        if (polkit_result == NULL) {
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.Error",
+                                                       "Cannot determine if caller is privileged",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+        if (strcmp (polkit_result, "yes") != 0) {
+
+                reply = dbus_message_new_error_printf (message,
+                                                       "org.freedesktop.Hal.Device.PermissionDeniedByPolicy",
+                                                       "%s %s <-- (privilege, result)",
+                                                       privilege, polkit_result);
+                dbus_connection_send (connection, reply, NULL);
+                goto out;
+        }
+
+        ret = TRUE;
+
+out:
+        if (polkit_result != NULL)
+                libhal_free_string (polkit_result);
+        return ret;
+}
+#else
+{
+        return TRUE;
+}
+#endif
+
+#define BACKLIGHT_OBJECT \
+  "/org/freedesktop/Hal/devices/imac_backlight"
+#define BACKLIGHT_IFACE \
+  "org.freedesktop.Hal.Device.LaptopPanel"
+#define INTERFACE_DESCRIPTION \
+  "    <method name=\"SetBrightness\">\n" \
+  "      <arg name=\"brightness_value\" direction=\"in\" type=\"i\"/>\n" \
+  "      <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n" \
+  "    </method>\n" \
+  "    <method name=\"GetBrightness\">\n" \
+  "      <arg name=\"brightness_value\" direction=\"out\" type=\"i\"/>\n" \
+  "    </method>\n"
+
+static DBusHandlerResult
+filter_function (DBusConnection * connection, DBusMessage * message, void *userdata)
+{
+	DBusMessage *reply;
+	DBusError err;
+	int level;
+	int ret;
+
+        if (!check_priv (connection, message, dbus_message_get_path (message), "org.freedesktop.hal.power-management.lcd-panel")) {
+                return DBUS_HANDLER_RESULT_HANDLED;
+        }
+
+	reply = NULL;
+	ret = 0;
+
+	dbus_error_init (&err);
+
+	if (dbus_message_is_method_call (message, BACKLIGHT_IFACE, "SetBrightness")) {
+
+		if (dbus_message_get_args (message, &err, DBUS_TYPE_INT32,
+					   &level, DBUS_TYPE_INVALID)) {
+			if (level < 0 || level > 15) {
+				reply = dbus_message_new_error (message,
+								"org.freedesktop.Hal.Device.LaptopPanel.Invalid",
+								"Brightness has to be between 0 and 15!");
+
+			} else {
+				backlight_set (level);
+
+				if ((reply = dbus_message_new_method_return (message)))
+					dbus_message_append_args (reply, DBUS_TYPE_INT32,
+								  &ret, DBUS_TYPE_INVALID);
+			}
+		}
+	} else if (dbus_message_is_method_call (message, BACKLIGHT_IFACE, "GetBrightness")) {
+		if (dbus_message_get_args (message, &err, DBUS_TYPE_INVALID)) {
+			level = backlight_get();
+			if (level < 0)
+				level = 0;
+			if (level > 15)
+				level = 15;
+
+			if ((reply = dbus_message_new_method_return (message)))
+				dbus_message_append_args (reply, DBUS_TYPE_INT32,
+							  &level, DBUS_TYPE_INVALID);
+		}
+	}
+
+	if (reply) {
+		dbus_connection_send (connection, reply, NULL);
+		return DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+int
+main (int argc, char **argv)
+{
+	LibHalContext *halctx;
+	DBusConnection *conn;
+	GMainLoop *main_loop;
+	const char *udi;
+	DBusError err;
+
+	setup_logger ();
+	udi = getenv ("UDI");
+	
+	HAL_DEBUG (("udi=%s", udi));
+	if (udi == NULL)
+	{
+		HAL_ERROR (("No device specified"));
+		return -2;
+	}
+
+	dbus_error_init (&err);
+	if ((halctx = libhal_ctx_init_direct (&err)) == NULL)
+	{
+		HAL_ERROR (("Cannot connect to hald"));
+		return -3;
+	}
+
+	dbus_error_init (&err);
+	if (!libhal_device_addon_is_ready (halctx, udi, &err))
+		return -4;
+
+	if (ioperm(0xB2, 0xB3, 1) < 0)
+	{
+		HAL_ERROR (("ioperm failed (you should be root)."));
+		exit(1);
+	}
+
+	conn = libhal_ctx_get_dbus_connection (halctx);
+	dbus_connection_setup_with_g_main (conn, NULL);
+
+	dbus_connection_add_filter (conn, filter_function, NULL, NULL);
+
+	if (!libhal_device_claim_interface (halctx, BACKLIGHT_OBJECT,
+					    BACKLIGHT_IFACE, INTERFACE_DESCRIPTION, &err))
+	{
+		HAL_ERROR (("Cannot claim interface 'org.freedesktop.Hal.Device.LaptopPanel'"));
+		return -4;
+	}
+
+	main_loop = g_main_loop_new (NULL, FALSE);
+	g_main_loop_run (main_loop);
+	return 0;
+}
+


More information about the hal-commit mailing list