[gnome-color-manager] Add a udev prober that makes DDC/CI i2c devices available for the user to use
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Add a udev prober that makes DDC/CI i2c devices available for the user to use
- Date: Tue, 10 Aug 2010 10:51:18 +0000 (UTC)
commit a5a4d5a8c1817fe7c829fd09ffc6ec105b0d9a74
Author: Richard Hughes <richard hughsie com>
Date: Tue Aug 10 11:33:59 2010 +0100
Add a udev prober that makes DDC/CI i2c devices available for the user to use
contrib/gnome-color-manager.spec.in | 1 +
libcolor-glib/gcm-ddc-client.c | 10 +++--
libcolor-glib/gcm-ddc-control.c | 6 ++-
libcolor-glib/gcm-ddc-control.h | 4 +-
libcolor-glib/gcm-ddc-device.c | 22 ++++++-----
libcolor-glib/gcm-self-test.c | 16 ++++++++
rules/.gitignore | 4 ++
rules/55-gcm-i2c.rules | 18 +++++++++
rules/Makefile.am | 27 ++++++++++++-
rules/gcm-udev-ddc.c | 72 +++++++++++++++++++++++++++++++++++
10 files changed, 161 insertions(+), 19 deletions(-)
---
diff --git a/contrib/gnome-color-manager.spec.in b/contrib/gnome-color-manager.spec.in
index c6cee42..7e2a846 100644
--- a/contrib/gnome-color-manager.spec.in
+++ b/contrib/gnome-color-manager.spec.in
@@ -91,6 +91,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &> /dev/null || :
%defattr(-,root,root,-)
%doc AUTHORS COPYING NEWS README
/lib/udev/rules.d/*.rules
+/lib/udev/gcm-*
%{_bindir}/gcm-*
%{_libexecdir}/*
%dir %{_datadir}/gnome-color-manager
diff --git a/libcolor-glib/gcm-ddc-client.c b/libcolor-glib/gcm-ddc-client.c
index 7fe1fc8..2d8d3d5 100644
--- a/libcolor-glib/gcm-ddc-client.c
+++ b/libcolor-glib/gcm-ddc-client.c
@@ -35,6 +35,8 @@
#include <gcm-ddc-client.h>
#include <gcm-ddc-device.h>
+#include "egg-debug.h"
+
static void gcm_ddc_client_finalize (GObject *object);
#define GCM_DDC_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_DDC_CLIENT, GcmDdcClientPrivate))
@@ -98,12 +100,12 @@ gcm_ddc_client_ensure_coldplug (GcmDdcClient *client, GError **error)
gcm_ddc_device_set_verbose (device, client->priv->verbose);
ret = gcm_ddc_device_open (device, filename, &error_local);
if (!ret) {
- if (client->priv->verbose == GCM_VERBOSE_OVERVIEW)
- g_warning ("failed to open %s: %s", filename, error_local->message);
+ if (client->priv->verbose >= GCM_VERBOSE_OVERVIEW)
+ egg_debug ("failed to open %s: %s", filename, error_local->message);
g_clear_error (&error_local);
} else {
- if (client->priv->verbose == GCM_VERBOSE_OVERVIEW)
- g_debug ("success, adding %s", filename);
+ if (client->priv->verbose >= GCM_VERBOSE_OVERVIEW)
+ egg_debug ("success, adding %s", filename);
any_found = TRUE;
g_ptr_array_add (client->priv->devices, g_object_ref (device));
}
diff --git a/libcolor-glib/gcm-ddc-control.c b/libcolor-glib/gcm-ddc-control.c
index 3cb724a..680b834 100644
--- a/libcolor-glib/gcm-ddc-control.c
+++ b/libcolor-glib/gcm-ddc-control.c
@@ -34,6 +34,8 @@
#include <gcm-ddc-device.h>
#include <gcm-ddc-control.h>
+#include "egg-debug.h"
+
static void gcm_ddc_control_finalize (GObject *object);
#define GCM_DDC_CONTROL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_DDC_CONTROL, GcmDdcControlPrivate))
@@ -311,7 +313,7 @@ gcm_ddc_control_parse (GcmDdcControl *control, guchar id, const gchar *values)
/* just save this */
control->priv->id = id;
if (control->priv->verbose == GCM_VERBOSE_OVERVIEW)
- g_debug ("add control 0x%02x (%s)", id, gcm_ddc_control_get_description (control));
+ egg_debug ("add control 0x%02x (%s)", id, gcm_ddc_control_get_description (control));
/* do we have any values to parse */
if (values == NULL)
@@ -322,7 +324,7 @@ gcm_ddc_control_parse (GcmDdcControl *control, guchar id, const gchar *values)
for (i=0; split[i] != NULL; i++) {
value = atoi (split[i]);
if (control->priv->verbose == GCM_VERBOSE_OVERVIEW)
- g_debug ("add value %i to control 0x%02x", value, id);
+ egg_debug ("add value %i to control 0x%02x", value, id);
g_array_append_val (control->priv->values, value);
}
out:
diff --git a/libcolor-glib/gcm-ddc-control.h b/libcolor-glib/gcm-ddc-control.h
index 75ca1a7..3c40106 100644
--- a/libcolor-glib/gcm-ddc-control.h
+++ b/libcolor-glib/gcm-ddc-control.h
@@ -97,7 +97,7 @@ void gcm_ddc_control_set_verbose (GcmDdcControl *control,
GcmVerbose verbose);
gboolean gcm_ddc_control_run (GcmDdcControl *control,
GError **error);
-gboolean gcm_ddc_control_request (GcmDdcControl *control,
+gboolean gcm_ddc_control_request (GcmDdcControl *control,
guint16 *value,
guint16 *maximum,
GError **error);
@@ -107,7 +107,7 @@ gboolean gcm_ddc_control_set (GcmDdcControl *control,
gboolean gcm_ddc_control_reset (GcmDdcControl *control,
GError **error);
guchar gcm_ddc_control_get_id (GcmDdcControl *control);
-const gchar *gcm_ddc_control_get_description (GcmDdcControl *control);
+const gchar *gcm_ddc_control_get_description (GcmDdcControl *control);
GArray *gcm_ddc_control_get_values (GcmDdcControl *control);
G_END_DECLS
diff --git a/libcolor-glib/gcm-ddc-device.c b/libcolor-glib/gcm-ddc-device.c
index f7a3347..6d8d59b 100644
--- a/libcolor-glib/gcm-ddc-device.c
+++ b/libcolor-glib/gcm-ddc-device.c
@@ -45,6 +45,8 @@
#include <gcm-ddc-device.h>
#include <gcm-ddc-control.h>
+#include "egg-debug.h"
+
static void gcm_ddc_device_finalize (GObject *object);
#define GCM_DDC_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_DDC_DEVICE, GcmDdcDevicePrivate))
@@ -385,7 +387,7 @@ gcm_ddc_device_read (GcmDdcDevice *device, guchar *data, gsize data_length, gsiz
if ((buf[1] & GCM_MAGIC_BYTE2) == 0) {
/* Fujitsu Siemens P19-2 and NEC LCD 1970NX send wrong magic when reading caps. */
- g_debug ( "Invalid response, magic is 0x%02x, correcting", buf[1]);
+ egg_debug ( "Invalid response, magic is 0x%02x, correcting", buf[1]);
}
len = buf[1] & ~GCM_MAGIC_BYTE2;
@@ -464,8 +466,8 @@ gcm_ddc_device_add_control (GcmDdcDevice *device, const gchar *index_str, const
static gboolean
gcm_ddc_device_set_device_property (GcmDdcDevice *device, const gchar *key, const gchar *value)
{
- if (device->priv->verbose == GCM_VERBOSE_OVERVIEW)
- g_debug ("key=%s, value=%s", key, value);
+ if (device->priv->verbose >= GCM_VERBOSE_OVERVIEW)
+ egg_debug ("key=%s, value=%s", key, value);
if (g_strcmp0 (key, "type") == 0) {
if (g_strcmp0 (value, "lcd") == 0)
device->priv->kind = GCM_DDC_DEVICE_KIND_LCD;
@@ -567,16 +569,16 @@ gcm_ddc_device_ensure_controls (GcmDdcDevice *device, GError **error)
/* try to read */
ret = gcm_ddc_device_capabilities_request (device, offset, buf, sizeof(buf), &len, error);
if (!ret) {
- if (device->priv->verbose == GCM_VERBOSE_PROTOCOL)
- g_warning ("Failed to read capabilities offset 0x%02x.", offset);
+ if (device->priv->verbose >= GCM_VERBOSE_PROTOCOL)
+ egg_warning ("Failed to read capabilities offset 0x%02x.", offset);
retries--;
continue;
}
/* not enough data */
if (len < 3) {
- if (device->priv->verbose == GCM_VERBOSE_PROTOCOL)
- g_warning ("Not enough capabilities data at offset 0x%02x.", offset);
+ if (device->priv->verbose >= GCM_VERBOSE_PROTOCOL)
+ egg_debug ("Not enough capabilities data at offset 0x%02x.", offset);
retries--;
continue;
}
@@ -584,7 +586,7 @@ gcm_ddc_device_ensure_controls (GcmDdcDevice *device, GError **error)
/* check response */
if (buf[0] != GCM_CAPABILITIES_REPLY) {
if (device->priv->verbose == GCM_VERBOSE_PROTOCOL)
- g_warning ("Not correct capabilities reply at offset 0x%02x.", offset);
+ egg_warning ("Not correct capabilities reply at offset 0x%02x.", offset);
retries--;
continue;
}
@@ -592,7 +594,7 @@ gcm_ddc_device_ensure_controls (GcmDdcDevice *device, GError **error)
/* check offset */
if ((buf[1] * 256 + buf[2]) != offset) {
if (device->priv->verbose == GCM_VERBOSE_PROTOCOL)
- g_warning ("Not correct capabilities offset at offset 0x%02x.", offset);
+ egg_warning ("Not correct capabilities offset at offset 0x%02x.", offset);
retries--;
continue;
}
@@ -604,7 +606,7 @@ gcm_ddc_device_ensure_controls (GcmDdcDevice *device, GError **error)
} while (len != 3);
if (device->priv->verbose == GCM_VERBOSE_OVERVIEW)
- g_debug ("raw caps: %s", string->str);
+ egg_debug ("raw caps: %s", string->str);
/* parse */
ret = gcm_ddc_device_parse_caps (device, string->str);
diff --git a/libcolor-glib/gcm-self-test.c b/libcolor-glib/gcm-self-test.c
index 2c229e6..a72e8f7 100644
--- a/libcolor-glib/gcm-self-test.c
+++ b/libcolor-glib/gcm-self-test.c
@@ -141,10 +141,26 @@ gcm_test_ddc_device_func (void)
static void
gcm_test_ddc_client_func (void)
{
+ gboolean ret;
+ GPtrArray *array;
+ GError *error = NULL;
GcmDdcClient *client;
client = gcm_ddc_client_new ();
g_assert (client != NULL);
+ gcm_ddc_client_set_verbose (client, GCM_VERBOSE_OVERVIEW);
+
+ array = gcm_ddc_client_get_devices (client, &error);
+ g_assert_no_error (error);
+ g_assert (array != NULL);
+
+ /* ensure we have at least one usable device */
+ g_assert_cmpint (array->len, >, 0);
+ g_ptr_array_unref (array);
+
+ ret = gcm_ddc_client_close (client, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
g_object_unref (client);
}
diff --git a/rules/.gitignore b/rules/.gitignore
new file mode 100644
index 0000000..c4433c9
--- /dev/null
+++ b/rules/.gitignore
@@ -0,0 +1,4 @@
+.deps
+.libs
+*.o
+gcm-udev-ddc
diff --git a/rules/55-gcm-i2c.rules b/rules/55-gcm-i2c.rules
new file mode 100644
index 0000000..d6255a7
--- /dev/null
+++ b/rules/55-gcm-i2c.rules
@@ -0,0 +1,18 @@
+##############################################################################################################
+# Copyright (C) 2010 Richard Hughes <richard hughsie com>
+#
+# 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.
+#
+# Ensure i2c-dev is loaded and the permissions of DDC/CI devices are
+# relaxed for any i2c devices so we can interact with them from userspace.
+
+# ensure userspace driver is loaded
+SUBSYSTEM=="i2c-adapter", ACTION=="add", RUN+="/sbin/modprobe i2c-dev"
+
+# make acl managed if a DDC device
+SUBSYSTEM=="i2c-dev", ACTION=="add", PROGRAM="gcm-udev-ddc /dev/%k", ENV{DDC_DEVICE}="1"
diff --git a/rules/Makefile.am b/rules/Makefile.am
index e2fea9a..8df12e9 100644
--- a/rules/Makefile.am
+++ b/rules/Makefile.am
@@ -1,7 +1,32 @@
+INCLUDES = \
+ $(GLIB_CFLAGS) \
+ $(GUDEV_CFLAGS) \
+ $(GTK_CFLAGS) \
+ -I$(top_srcdir)/libcolor-glib \
+ -DI_KNOW_THE_LIBCOLOR_GLIB_API_IS_SUBJECT_TO_CHANGE
+
+COLOR_GLIB_LIBS = \
+ $(top_builddir)/libcolor-glib/libcolor-glib.la
+
udevrulesdir = $(slashlibdir)/udev/rules.d
udevrules_DATA = \
95-gcm-colorimeters.rules \
- 95-gcm-devices.rules
+ 95-gcm-devices.rules \
+ 55-gcm-i2c.rules
+
+udevproberdir = $(slashlibdir)/udev
+udevprober_PROGRAMS = \
+ gcm-udev-ddc
+
+gcm_udev_ddc_SOURCES = \
+ gcm-udev-ddc.c
+
+gcm_udev_ddc_LDADD = \
+ $(COLOR_GLIB_LIBS) \
+ -lm
+
+gcm_udev_ddc_CFLAGS = \
+ $(WARNINGFLAGS_C)
EXTRA_DIST = \
$(udevrules_DATA)
diff --git a/rules/gcm-udev-ddc.c b/rules/gcm-udev-ddc.c
new file mode 100644
index 0000000..7af7f9d
--- /dev/null
+++ b/rules/gcm-udev-ddc.c
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2010 Richard Hughes <richard hughsie com>
+ *
+ * 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 "config.h"
+
+#include <glib.h>
+#include <libcolor-glib.h>
+
+/**
+ * main:
+ **/
+int
+main (int argc, char **argv)
+{
+ guint retval = 1;
+ gboolean ret;
+ GError *error = NULL;
+ GcmDdcDevice *device;
+ const gchar *edid_md5;
+
+ g_type_init ();
+
+ /* find devices */
+ device = gcm_ddc_device_new ();
+
+ /* check we got a device */
+ if (argv[1] == NULL) {
+ g_printerr ("FAILED get device\n");
+ goto out;
+ }
+
+ /* get the default device */
+ ret = gcm_ddc_device_open (device, argv[1], &error);
+ if (!ret) {
+ g_printerr ("FAILED to open device: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* check we can use it */
+ edid_md5 = gcm_ddc_device_get_edid_md5 (device, &error);
+ if (edid_md5 == NULL) {
+ g_print ("FAILED to get edid: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* success */
+ retval = 0;
+out:
+ g_object_unref (device);
+ return retval;
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]