[gnome-color-manager] Detect printers by connecting to CUPS rather than scraping the HPLIP properties
- From: Richard Hughes <rhughes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Detect printers by connecting to CUPS rather than scraping the HPLIP properties
- Date: Thu, 4 Feb 2010 17:14:29 +0000 (UTC)
commit 510d92de0fc5f031fc839a67a7988f5551228a52
Author: Richard Hughes <richard hughsie com>
Date: Thu Feb 4 16:12:34 2010 +0000
Detect printers by connecting to CUPS rather than scraping the HPLIP properties
po/POTFILES.in | 1 +
rules/95-gnome-color-manager.rules | 3 -
src/gcm-client.c | 84 +++++++++++++++++++++++++++++++++--
src/gcm-device-cups.c | 86 +++++++++++++++++++++++++++++++++++-
src/gcm-device-cups.h | 6 ++-
5 files changed, 168 insertions(+), 12 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 921d13c..d58b084 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,6 +10,7 @@ src/gcm-calibrate-manual.c
src/gcm-client.c
src/gcm-dump-edid.c
src/gcm-dump-profile.c
+src/gcm-device-xrandr.c
src/gcm-fix-profile.c
src/gcm-install-system-wide.c
src/gcm-import.c
diff --git a/rules/95-gnome-color-manager.rules b/rules/95-gnome-color-manager.rules
index f844c4c..14c8ee5 100644
--- a/rules/95-gnome-color-manager.rules
+++ b/rules/95-gnome-color-manager.rules
@@ -7,9 +7,6 @@
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
-# HP Printers
-SUBSYSTEM=="usb", ENV{ID_HPLIP}!="", ENV{GCM_DEVICE}="1", ENV{GCM_TYPE}="printer"
-
# USB SANE scanners
SUBSYSTEM=="usb", ENV{libsane_matched}!="", ENV{GCM_DEVICE}="1", ENV{GCM_TYPE}="scanner"
diff --git a/src/gcm-client.c b/src/gcm-client.c
index 38c89f6..471e7c9 100644
--- a/src/gcm-client.c
+++ b/src/gcm-client.c
@@ -33,6 +33,7 @@
#include <glib-object.h>
#include <gudev/gudev.h>
#include <libgnomeui/gnome-rr.h>
+#include <cups/cups.h>
#include "gcm-client.h"
#include "gcm-device-xrandr.h"
@@ -60,6 +61,7 @@ struct _GcmClientPrivate
GPtrArray *array;
GUdevClient *gudev_client;
GcmScreen *screen;
+ http_t *http;
};
enum {
@@ -255,10 +257,10 @@ gcm_client_uevent_cb (GUdevClient *gudev_client, const gchar *action, GUdevDevic
}
/**
- * gcm_client_add_connected_devices_usb:
+ * gcm_client_add_connected_devices_udev:
**/
static gboolean
-gcm_client_add_connected_devices_usb (GcmClient *client, GError **error)
+gcm_client_add_connected_devices_udev (GcmClient *client, GError **error)
{
GList *devices;
GList *l;
@@ -497,6 +499,66 @@ gcm_client_add_connected_devices_xrandr (GcmClient *client, GError **error)
}
/**
+ * gcm_client_cups_add:
+ **/
+static void
+gcm_client_cups_add (GcmClient *client, cups_dest_t dest)
+{
+ gboolean ret;
+ GError *error = NULL;
+ GcmDevice *device = NULL;
+ GcmClientPrivate *priv = client->priv;
+
+ /* create new device */
+ device = gcm_device_xrandr_new ();
+ ret = gcm_device_cups_set_from_dest (device, priv->http, dest, &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_cups:
+ **/
+static gboolean
+gcm_client_add_connected_devices_cups (GcmClient *client, GError **error)
+{
+ gint num_dests;
+ cups_dest_t *dests;
+ gint i;
+ GcmClientPrivate *priv = client->priv;
+
+ num_dests = cupsGetDests2 (priv->http, &dests);
+ egg_debug ("got %i printers", num_dests);
+
+ /* get printers on the local server */
+ for (i = 0; i < num_dests; i++)
+ gcm_client_cups_add (client, dests[i]);
+ cupsFreeDests (num_dests, dests);
+ return TRUE;
+}
+
+/**
* gcm_client_add_unconnected_device:
**/
static void
@@ -609,15 +671,20 @@ gcm_client_add_connected (GcmClient *client, GError **error)
g_return_val_if_fail (GCM_IS_CLIENT (client), FALSE);
- /* usb */
- ret = gcm_client_add_connected_devices_usb (client, error);
+ /* udev */
+ ret = gcm_client_add_connected_devices_udev (client, error);
if (!ret)
goto out;
- /* xorg */
+ /* xrandr */
ret = gcm_client_add_connected_devices_xrandr (client, error);
if (!ret)
goto out;
+
+ /* cups */
+ ret = gcm_client_add_connected_devices_cups (client, error);
+ if (!ret)
+ goto out;
out:
return ret;
}
@@ -817,6 +884,12 @@ gcm_client_init (GcmClient *client)
client->priv->gudev_client = g_udev_client_new (subsystems);
g_signal_connect (client->priv->gudev_client, "uevent",
G_CALLBACK (gcm_client_uevent_cb), client);
+
+ /* for CUPS */
+ httpInitialize();
+
+ /* should be okay for localhost */
+ client->priv->http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ());
}
/**
@@ -832,6 +905,7 @@ gcm_client_finalize (GObject *object)
g_ptr_array_unref (priv->array);
g_object_unref (priv->gudev_client);
g_object_unref (priv->screen);
+ httpClose (priv->http);
G_OBJECT_CLASS (gcm_client_parent_class)->finalize (object);
}
diff --git a/src/gcm-device-cups.c b/src/gcm-device-cups.c
index bcf3fa8..e7f5042 100644
--- a/src/gcm-device-cups.c
+++ b/src/gcm-device-cups.c
@@ -26,6 +26,8 @@
#include <cups/ppd.h>
#include "gcm-device-cups.h"
+#include "gcm-enum.h"
+#include "gcm-utils.h"
#include "egg-debug.h"
@@ -52,11 +54,91 @@ enum {
G_DEFINE_TYPE (GcmDeviceCups, gcm_device_cups, GCM_TYPE_DEVICE)
/**
- * gcm_device_cups_set_from_instance:
+ * gcm_device_cups_set_from_dest:
**/
gboolean
-gcm_device_cups_set_from_instance (GcmDevice *device, gpointer instance, GError **error)
+gcm_device_cups_set_from_dest (GcmDevice *device, http_t *http, cups_dest_t dest, GError **error)
{
+ gint i;
+ ppd_file_t *ppd_file;
+ const gchar *ppd_file_location;
+ gchar *id = NULL;
+ gchar *device_id = NULL;
+ gchar *title = NULL;
+ gchar *serial = NULL;
+ gchar *manufacturer = NULL;
+ gchar *model = NULL;
+ GcmColorspaceEnum colorspace = GCM_COLORSPACE_ENUM_UNKNOWN;
+
+ egg_debug ("name: %s", dest.name);
+ egg_debug ("instance: %s", dest.instance);
+ egg_debug ("num_options: %i", dest.num_options);
+
+ ppd_file_location = cupsGetPPD2 (http, dest.name);
+ ppd_file = ppdOpenFile (ppd_file_location);
+
+ egg_debug ("ppd_file_location=%s", ppd_file_location);
+
+ for (i = 0; i < ppd_file->num_attrs; i++) {
+ const gchar *keyword;
+ const gchar *value;
+
+ /* get the keyword and value */
+ keyword = ppd_file->attrs[i]->name;
+ value = ppd_file->attrs[i]->value;
+
+ /* ignore some */
+ if (g_strcmp0 (keyword, "Font") == 0)
+ continue;
+ if (g_strcmp0 (keyword, "Product") == 0)
+ continue;
+ if (g_strcmp0 (keyword, "ParamCustomPageSize") == 0)
+ continue;
+
+ /* check to see if there is anything interesting */
+ if (g_strcmp0 (keyword, "Manufacturer") == 0) {
+ manufacturer = g_strdup (value);
+ } else if (g_strcmp0 (keyword, "ModelName") == 0) {
+ model = g_strdup (value);
+ } else if (g_strcmp0 (keyword, "ShortNickName") == 0) {
+ title = g_strdup (value);
+ } else if (g_strcmp0 (keyword, "1284DeviceID") == 0) {
+ device_id = g_strdup (value);
+ } else if (g_strcmp0 (keyword, "DefaultColorSpace") == 0) {
+ if (g_strcmp0 (value, "RGB") == 0)
+ colorspace = GCM_COLORSPACE_ENUM_RGB;
+ else if (g_strcmp0 (value, "CMYK") == 0)
+ colorspace = GCM_COLORSPACE_ENUM_CMYK;
+ else
+ egg_warning ("colorspace not recognised: %s", value);
+ }
+
+ egg_debug ("keyword: %s, value: %s, spec: %s", keyword, value, ppd_file->attrs[i]->spec);
+ }
+
+ /* convert device_id 'MFG:HP;MDL:deskjet d1300 series;DES:deskjet d1300 series;' to suitable id */
+ id = g_strdup_printf ("cups_%s", device_id);
+ gcm_utils_alphanum_lcase (id);
+
+ g_object_set (device,
+ "type", GCM_DEVICE_TYPE_ENUM_PRINTER,
+ "colorspace", colorspace,
+ "id", id,
+ "connected", TRUE,
+// "serial", serial,
+ "model", model,
+ "manufacturer", manufacturer,
+ "title", title,
+ "native-device", device_id,
+ NULL);
+
+ g_free (serial);
+ g_free (manufacturer);
+ g_free (model);
+ g_free (id);
+ g_free (device_id);
+ g_free (title);
+ ppdClose (ppd_file);
return TRUE;
}
diff --git a/src/gcm-device-cups.h b/src/gcm-device-cups.h
index 573d19b..5cd7c19 100644
--- a/src/gcm-device-cups.h
+++ b/src/gcm-device-cups.h
@@ -23,6 +23,7 @@
#define __GCM_DEVICE_CUPS_H
#include <glib-object.h>
+#include <cups/cups.h>
#include "gcm-device.h"
@@ -49,8 +50,9 @@ struct _GcmDeviceCupsClass
GType gcm_device_cups_get_type (void);
GcmDevice *gcm_device_cups_new (void);
-gboolean gcm_device_cups_set_from_instance (GcmDevice *device,
- gpointer instance,
+gboolean gcm_device_cups_set_from_dest (GcmDevice *device,
+ http_t *http,
+ cups_dest_t dest,
GError **error);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]