aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Szulecki <opensuse@sukimashita.com>2008-03-13 20:38:18 +0100
committerDanny Kukawka <danny.kukawka@web.de>2008-03-13 20:38:18 +0100
commitee68b0ebfcadf60bf31dd1b3163f52741dce25f1 (patch)
tree46d32fdd68c152a69cb3744696df46540b12c936
parentfix policy file for org.freedesktop.hal.dockstation.* (diff)
downloadgentoo-hal-ee68b0ebfcadf60bf31dd1b3163f52741dce25f1.tar.gz
gentoo-hal-ee68b0ebfcadf60bf31dd1b3163f52741dce25f1.tar.bz2
gentoo-hal-ee68b0ebfcadf60bf31dd1b3163f52741dce25f1.zip
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.
-rw-r--r--configure.in25
-rw-r--r--fdi/policy/10osvendor/10-imac-backlight.fdi32
-rw-r--r--hald/linux/addons/Makefile.am6
-rw-r--r--hald/linux/addons/addon-imac-backlight.c224
4 files changed, 287 insertions, 0 deletions
diff --git a/configure.in b/configure.in
index f4a1aac7..013e2b32 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 00000000..56d343e4
--- /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 8546f02c..37beba45 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 00000000..46cac6db
--- /dev/null
+++ b/hald/linux/addons/addon-imac-backlight.c
@@ -0,0 +1,224 @@
+/*
+ * Apple iMac Backlight control
+ *
+ * Copyright (C) 2007 Martin Szulecki <opensuse@sukimashita.com>
+ * Copyright (C) 2006 Nicolas Boichat <nicolas@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;
+}
+