[gnome-color-manager] Use libsane to get our scanners, which means remote devices are now supported
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Use libsane to get our scanners, which means remote devices are now supported
- Date: Tue, 23 Mar 2010 20:00:48 +0000 (UTC)
commit cb1454576fe83de635c4f60924eeaff76270dfea
Author: Richard Hughes <richard hughsie com>
Date: Tue Mar 23 20:00:26 2010 +0000
Use libsane to get our scanners, which means remote devices are now supported
configure.ac | 4 +
contrib/gnome-color-manager.spec.in | 2 +
rules/95-gcm-devices.rules | 3 -
src/Makefile.am | 10 +++
src/gcm-client.c | 96 +++++++++++++++++++++++++++-
src/gcm-device-sane.c | 121 ++++++++++++++++++++++++++++++++++-
src/gcm-device-sane.h | 10 ++-
7 files changed, 238 insertions(+), 8 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 762e8c7..c8cf3c1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -157,6 +157,10 @@ PKG_CHECK_MODULES(X11, x11)
AC_SUBST(X11_CFLAGS)
AC_SUBST(X11_LIBS)
+PKG_CHECK_MODULES(SANE, sane-backends)
+AC_SUBST(SANE_CFLAGS)
+AC_SUBST(SANE_LIBS)
+
PKG_CHECK_MODULES(CANBERRA, libcanberra-gtk >= $CANBERRA_REQUIRED)
AC_SUBST(CANBERRA_CFLAGS)
AC_SUBST(CANBERRA_LIBS)
diff --git a/contrib/gnome-color-manager.spec.in b/contrib/gnome-color-manager.spec.in
index 8e34422..f22416b 100644
--- a/contrib/gnome-color-manager.spec.in
+++ b/contrib/gnome-color-manager.spec.in
@@ -25,6 +25,7 @@ Requires: udev
Requires: vte
Requires: lcms
Requires: cups
+Requires: sane-backends-libs
Requires: polkit
Requires: PackageKit
Requires: shared-color-profiles
@@ -52,6 +53,7 @@ BuildRequires: libXrandr-devel
BuildRequires: gnome-desktop-devel
BuildRequires: lcms-devel
BuildRequires: cups-devel
+BuildRequires: sane-backends-devel
BuildRequires: libtiff-devel
BuildRequires: libcanberra-devel >= %{libcanberra_version}
diff --git a/rules/95-gcm-devices.rules b/rules/95-gcm-devices.rules
index e1ee7fd..857fbf5 100644
--- a/rules/95-gcm-devices.rules
+++ b/rules/95-gcm-devices.rules
@@ -14,9 +14,6 @@
# GCM_DEVICE (Can be assinged a profile)
# GCM_TYPE (The type of device)
-# USB SANE scanners
-SUBSYSTEM=="usb", ENV{libsane_matched}!="", ENV{GCM_DEVICE}="1", ENV{GCM_TYPE}="scanner"
-
# Cameras with gphoto drivers
SUBSYSTEM=="usb", ENV{ID_GPHOTO2}!="", ENV{GCM_DEVICE}="1", ENV{GCM_TYPE}="camera"
diff --git a/src/Makefile.am b/src/Makefile.am
index bece432..72c5f56 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@ INCLUDES = \
$(LCMS_CFLAGS) \
$(XORG_CFLAGS) \
$(CUPS_CFLAGS) \
+ $(SANE_CFLAGS) \
$(TIFF_CFLAGS) \
$(CANBERRA_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
@@ -117,6 +118,7 @@ gcm_dump_edid_LDADD = \
$(XORG_LIBS) \
$(DBUS_GLIB_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
-lm
@@ -137,6 +139,7 @@ gcm_dump_profile_LDADD = \
$(XORG_LIBS) \
$(DBUS_GLIB_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
-lm
@@ -151,6 +154,7 @@ gcm_fix_profile_LDADD = \
$(X11_LIBS) \
$(LCMS_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
-lm
@@ -171,6 +175,7 @@ gcm_inspect_LDADD = \
$(XORG_LIBS) \
$(DBUS_GLIB_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
-lm
@@ -191,6 +196,7 @@ gcm_apply_LDADD = \
$(XORG_LIBS) \
$(DBUS_GLIB_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
-lm
@@ -211,6 +217,7 @@ gcm_import_LDADD = \
$(XORG_LIBS) \
$(DBUS_GLIB_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
-lm
@@ -243,6 +250,7 @@ gcm_prefs_LDADD = \
$(DBUS_GLIB_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
$(TIFF_LIBS) \
$(CANBERRA_LIBS) \
@@ -268,6 +276,7 @@ gcm_session_LDADD = \
$(DBUS_GLIB_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
-lm
@@ -315,6 +324,7 @@ gcm_self_test_LDADD = \
$(DBUS_GLIB_LIBS) \
$(XORG_LIBS) \
$(GTK_LIBS) \
+ $(SANE_LIBS) \
$(CUPS_LIBS) \
$(TIFF_LIBS) \
-lm
diff --git a/src/gcm-client.c b/src/gcm-client.c
index 306e96a..040a806 100644
--- a/src/gcm-client.c
+++ b/src/gcm-client.c
@@ -34,6 +34,7 @@
#include <gudev/gudev.h>
#include <libgnomeui/gnome-rr.h>
#include <cups/cups.h>
+#include <sane/sane.h>
#include "gcm-client.h"
#include "gcm-device-xrandr.h"
@@ -629,6 +630,81 @@ gcm_client_add_connected_devices_cups_thrd (GcmClient *client)
}
/**
+ * gcm_client_sane_add:
+ **/
+static void
+gcm_client_sane_add (GcmClient *client, const SANE_Device *sane_device)
+{
+ gboolean ret;
+ GError *error = NULL;
+ GcmDevice *device = NULL;
+ GcmClientPrivate *priv = client->priv;
+
+ /* create new device */
+ device = gcm_device_sane_new ();
+ ret = gcm_device_sane_set_from_device (device, sane_device, &error);
+ if (!ret) {
+ egg_debug ("failed to set for output: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* load the device */
+ ret = gcm_device_load (device, &error);
+ if (!ret) {
+ egg_warning ("failed to load: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* add to the array */
+ g_ptr_array_add (priv->array, g_object_ref (device));
+
+ /* signal the addition */
+ egg_debug ("emit: added %s to device list", gcm_device_get_id (device));
+ g_signal_emit (client, signals[SIGNAL_ADDED], 0, device);
+out:
+ if (device != NULL)
+ g_object_unref (device);
+}
+
+/**
+ * gcm_client_add_connected_devices_sane:
+ **/
+static gboolean
+gcm_client_add_connected_devices_sane (GcmClient *client, GError **error)
+{
+ gint i;
+ SANE_Status status;
+ const SANE_Device **device_list;
+
+ /* get scanners on the local server */
+ status = sane_get_devices (&device_list, FALSE);
+ if (status != SANE_STATUS_GOOD) {
+ egg_warning ("failed to get devices from SANE: %s", sane_strstatus (status));
+ goto out;
+ }
+
+ /* add them */
+ for (i=0; device_list[i] != NULL; i++)
+ gcm_client_sane_add (client, device_list[i]);
+out:
+ /* inform the UI */
+ gcm_client_done_loading (client);
+ return TRUE;
+}
+
+/**
+ * gcm_client_add_connected_devices_sane_thrd:
+ **/
+static gpointer
+gcm_client_add_connected_devices_sane_thrd (GcmClient *client)
+{
+ gcm_client_add_connected_devices_sane (client, NULL);
+ return NULL;
+}
+
+/**
* gcm_client_add_unconnected_device:
**/
static void
@@ -782,7 +858,7 @@ gcm_client_add_connected (GcmClient *client, GError **error)
goto out;
/* inform UI if we are loading devces still */
- client->priv->loading_refcount = 2;
+ client->priv->loading_refcount = 3;
gcm_client_set_loading (client, TRUE);
/* UDEV */
@@ -806,6 +882,17 @@ gcm_client_add_connected (GcmClient *client, GError **error)
if (!ret)
goto out;
}
+
+ /* SANE */
+ if (client->priv->use_threads) {
+ thread = g_thread_create ((GThreadFunc) gcm_client_add_connected_devices_sane_thrd, client, FALSE, error);
+ if (thread == NULL)
+ goto out;
+ } else {
+ ret = gcm_client_add_connected_devices_sane (client, error);
+ if (!ret)
+ goto out;
+ }
out:
return ret;
}
@@ -1071,6 +1158,7 @@ static void
gcm_client_init (GcmClient *client)
{
const gchar *subsystems[] = {"usb", "video4linux", NULL};
+ SANE_Status status;
client->priv = GCM_CLIENT_GET_PRIVATE (client);
client->priv->display_name = NULL;
@@ -1089,6 +1177,11 @@ gcm_client_init (GcmClient *client)
/* for CUPS */
httpInitialize();
+ /* for SANE */
+ status = sane_init (NULL, NULL);
+ if (status != SANE_STATUS_GOOD)
+ egg_warning ("failed to init SANE: %s", sane_strstatus (status));
+
/* should be okay for localhost */
client->priv->http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ());
}
@@ -1107,6 +1200,7 @@ gcm_client_finalize (GObject *object)
g_object_unref (priv->gudev_client);
g_object_unref (priv->screen);
httpClose (priv->http);
+ sane_exit ();
G_OBJECT_CLASS (gcm_client_parent_class)->finalize (object);
}
diff --git a/src/gcm-device-sane.c b/src/gcm-device-sane.c
index 1942b44..5deb1aa 100644
--- a/src/gcm-device-sane.c
+++ b/src/gcm-device-sane.c
@@ -22,6 +22,7 @@
#include "config.h"
#include <glib-object.h>
+#include <sane/sane.h>
#include "gcm-device-sane.h"
#include "gcm-enum.h"
@@ -29,6 +30,8 @@
#include "egg-debug.h"
+static void gcm_device_sane_finalize (GObject *object);
+
#define GCM_DEVICE_SANE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_DEVICE_SANE, GcmDeviceSanePrivate))
/**
@@ -43,10 +46,11 @@ struct _GcmDeviceSanePrivate
enum {
PROP_0,
+ PROP_NATIVE_DEVICE,
PROP_LAST
};
-G_DEFINE_TYPE (GcmDeviceSane, gcm_device_sane, GCM_TYPE_DEVICE_UDEV)
+G_DEFINE_TYPE (GcmDeviceSane, gcm_device_sane, GCM_TYPE_DEVICE)
typedef struct {
gchar *key;
@@ -158,6 +162,51 @@ out:
}
/**
+ * gcm_device_sane_set_from_device:
+ **/
+gboolean
+gcm_device_sane_set_from_device (GcmDevice *device, const SANE_Device *sane_device, GError **error)
+{
+ gchar *id = NULL;
+ gchar *manufacturer = NULL;
+ gchar *model = NULL;
+ gchar *title = NULL;
+
+ egg_debug ("name=%s", sane_device->name);
+ egg_debug ("vendor=%s", sane_device->vendor);
+ egg_debug ("model=%s", sane_device->model);
+ egg_debug ("type=%s", sane_device->type);
+
+ /* convert device_id 'plustek:libusb:004:002' to suitable id */
+ id = g_strdup_printf ("sane_%s", sane_device->name);
+ gcm_utils_alphanum_lcase (id);
+
+ /* make safe strings */
+ manufacturer = g_strdup (sane_device->vendor);
+ model = g_strdup (sane_device->model);
+ title = g_strdup_printf ("%s - %s", manufacturer, model);
+
+ /* set properties on device */
+ g_object_set (device,
+ "type", GCM_DEVICE_TYPE_ENUM_SCANNER,
+ "colorspace", GCM_COLORSPACE_ENUM_RGB,
+ "id", id,
+ "connected", TRUE,
+// "serial", serial,
+ "model", model,
+ "manufacturer", manufacturer,
+ "title", title,
+ "native-device", sane_device->name,
+ NULL);
+
+ g_free (manufacturer);
+ g_free (model);
+ g_free (id);
+ g_free (title);
+ return TRUE;
+}
+
+/**
* gcm_device_sane_apply_global:
*
* Return value: %TRUE for success;
@@ -299,13 +348,68 @@ out:
}
/**
+ * gcm_device_sane_get_property:
+ **/
+static void
+gcm_device_sane_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GcmDeviceSane *device_sane = GCM_DEVICE_SANE (object);
+ GcmDeviceSanePrivate *priv = device_sane->priv;
+
+ switch (prop_id) {
+ case PROP_NATIVE_DEVICE:
+ g_value_set_string (value, priv->native_device);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * gcm_device_sane_set_property:
+ **/
+static void
+gcm_device_sane_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GcmDeviceSane *device_sane = GCM_DEVICE_SANE (object);
+ GcmDeviceSanePrivate *priv = device_sane->priv;
+
+ switch (prop_id) {
+ case PROP_NATIVE_DEVICE:
+ g_free (priv->native_device);
+ priv->native_device = g_strdup (g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
* gcm_device_sane_class_init:
**/
static void
gcm_device_sane_class_init (GcmDeviceSaneClass *klass)
{
+ GParamSpec *pspec;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
GcmDeviceClass *device_class = GCM_DEVICE_CLASS (klass);
+
+ object_class->finalize = gcm_device_sane_finalize;
+ object_class->get_property = gcm_device_sane_get_property;
+ object_class->set_property = gcm_device_sane_set_property;
+
device_class->apply = gcm_device_sane_apply;
+
+ /**
+ * GcmDeviceSane:native-device:
+ */
+ pspec = g_param_spec_string ("native-device", NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_NATIVE_DEVICE, pspec);
+
g_type_class_add_private (klass, sizeof (GcmDeviceSanePrivate));
}
@@ -316,6 +420,21 @@ static void
gcm_device_sane_init (GcmDeviceSane *device_sane)
{
device_sane->priv = GCM_DEVICE_SANE_GET_PRIVATE (device_sane);
+ device_sane->priv->native_device = NULL;
+}
+
+/**
+ * gcm_device_sane_finalize:
+ **/
+static void
+gcm_device_sane_finalize (GObject *object)
+{
+ GcmDeviceSane *device_sane = GCM_DEVICE_SANE (object);
+ GcmDeviceSanePrivate *priv = device_sane->priv;
+
+ g_free (priv->native_device);
+
+ G_OBJECT_CLASS (gcm_device_sane_parent_class)->finalize (object);
}
/**
diff --git a/src/gcm-device-sane.h b/src/gcm-device-sane.h
index b92fc5f..6f7f28d 100644
--- a/src/gcm-device-sane.h
+++ b/src/gcm-device-sane.h
@@ -23,8 +23,9 @@
#define __GCM_DEVICE_SANE_H
#include <glib-object.h>
+#include <sane/sane.h>
-#include "gcm-device-udev.h"
+#include "gcm-device.h"
G_BEGIN_DECLS
@@ -38,17 +39,20 @@ typedef struct _GcmDeviceSaneClass GcmDeviceSaneClass;
struct _GcmDeviceSane
{
- GcmDeviceUdev parent;
+ GcmDevice parent;
GcmDeviceSanePrivate *priv;
};
struct _GcmDeviceSaneClass
{
- GcmDeviceUdevClass parent_class;
+ GcmDeviceClass parent_class;
};
GType gcm_device_sane_get_type (void);
GcmDevice *gcm_device_sane_new (void);
+gboolean gcm_device_sane_set_from_device (GcmDevice *device,
+ const SANE_Device *sane_device,
+ GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]