summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
+}
+