[gnome-control-center] printers: Add async method for listing print devices
- From: Marek KaÅÃk <mkasik src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] printers: Add async method for listing print devices
- Date: Tue, 4 Sep 2012 12:11:14 +0000 (UTC)
commit 0cb0dab3778d75c3edec5b6de956ee70ddb026b5
Author: Marek Kasik <mkasik redhat com>
Date: Mon Sep 3 19:50:31 2012 +0200
printers: Add async method for listing print devices
This commit adds asynchronous function get_cups_devices_async() which
sequentially executes CUPS' backends and returns found devices
by a callback. (#683229)
panels/printers/pp-utils.c | 286 ++++++++++++++++++++++++++++++++++++++++++++
panels/printers/pp-utils.h | 29 +++++
2 files changed, 315 insertions(+), 0 deletions(-)
---
diff --git a/panels/printers/pp-utils.c b/panels/printers/pp-utils.c
index 7c89b1f..2d6a5a8 100644
--- a/panels/printers/pp-utils.c
+++ b/panels/printers/pp-utils.c
@@ -4589,6 +4589,292 @@ printer_add_option_async (const gchar *printer_name,
typedef struct
{
+ GCancellable *cancellable;
+ GCDCallback callback;
+ gpointer user_data;
+ GList *backend_list;
+} GCDData;
+
+static gint
+get_suffix_index (gchar *string)
+{
+ gchar *number;
+ gchar *endptr;
+ gint index = -1;
+
+ number = g_strrstr (string, ":");
+ if (number)
+ {
+ number++;
+ index = g_ascii_strtoll (number, &endptr, 10);
+ if (index == 0 && endptr == number)
+ index = -1;
+ }
+
+ return index;
+}
+
+static void
+get_cups_devices_async_dbus_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+
+{
+ PpPrintDevice **devices = NULL;
+ GVariant *output;
+ GCDData *data = (GCDData *) user_data;
+ GError *error = NULL;
+ GList *result = NULL;
+ gint num_of_devices = 0;
+
+ output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
+ res,
+ &error);
+
+ if (output)
+ {
+ const gchar *ret_error;
+ GVariant *devices_variant = NULL;
+
+ g_variant_get (output, "(&s a{ss})",
+ &ret_error,
+ &devices_variant);
+
+ if (ret_error[0] != '\0')
+ {
+ g_warning ("%s", ret_error);
+ }
+
+ if (devices_variant)
+ {
+ GVariantIter *iter;
+ GVariant *item;
+ gchar *key;
+ gchar *value;
+ gint index = -1, max_index = -1, i;
+
+ g_variant_get (devices_variant, "a{ss}", &iter);
+ while ((item = g_variant_iter_next_value (iter)))
+ {
+ g_variant_get (item, "{ss}", &key, &value);
+
+ index = get_suffix_index (key);
+ if (index > max_index)
+ max_index = index;
+
+ g_free (key);
+ g_free (value);
+ g_variant_unref (item);
+ }
+
+ if (max_index >= 0)
+ {
+ num_of_devices = max_index + 1;
+ devices = g_new0 (PpPrintDevice *, num_of_devices);
+
+ g_variant_get (devices_variant, "a{ss}", &iter);
+ while ((item = g_variant_iter_next_value (iter)))
+ {
+ g_variant_get (item, "{ss}", &key, &value);
+
+ index = get_suffix_index (key);
+ if (index >= 0)
+ {
+ if (!devices[index])
+ devices[index] = g_new0 (PpPrintDevice, 1);
+
+ if (g_str_has_prefix (key, "device-class"))
+ devices[index]->device_class = g_strdup (value);
+ else if (g_str_has_prefix (key, "device-id"))
+ devices[index]->device_id = g_strdup (value);
+ else if (g_str_has_prefix (key, "device-info"))
+ devices[index]->device_info = g_strdup (value);
+ else if (g_str_has_prefix (key, "device-make-and-model"))
+ {
+ devices[index]->device_make_and_model = g_strdup (value);
+ devices[index]->device_name = g_strdup (value);
+ }
+ else if (g_str_has_prefix (key, "device-uri"))
+ devices[index]->device_uri = g_strdup (value);
+ else if (g_str_has_prefix (key, "device-location"))
+ devices[index]->device_location = g_strdup (value);
+
+ devices[index]->acquisition_method = ACQUISITION_METHOD_DEFAULT_CUPS_SERVER;
+ }
+
+ g_free (key);
+ g_free (value);
+ g_variant_unref (item);
+ }
+
+ for (i = 0; i < num_of_devices; i++)
+ result = g_list_append (result, devices[i]);
+
+ g_free (devices);
+ }
+
+ g_variant_unref (devices_variant);
+ }
+
+ g_variant_unref (output);
+ }
+ else
+ {
+ if (error->domain != G_IO_ERROR ||
+ error->code != G_IO_ERROR_CANCELLED)
+ g_warning ("%s", error->message);
+ g_error_free (error);
+
+ data->callback (result,
+ TRUE,
+ g_cancellable_is_cancelled (data->cancellable),
+ data->user_data);
+
+ g_list_free_full (data->backend_list, g_free);
+ data->backend_list = NULL;
+ g_object_unref (source_object);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ g_free (data);
+
+ return;
+ }
+
+ if (data->backend_list)
+ {
+ if (!g_cancellable_is_cancelled (data->cancellable))
+ {
+ GVariantBuilder include_scheme_builder;
+
+ data->callback (result,
+ FALSE,
+ FALSE,
+ data->user_data);
+
+ g_variant_builder_init (&include_scheme_builder, G_VARIANT_TYPE ("as"));
+ g_variant_builder_add (&include_scheme_builder, "s", data->backend_list->data);
+
+ g_free (data->backend_list->data);
+ data->backend_list = g_list_remove_link (data->backend_list, data->backend_list);
+
+ g_dbus_connection_call (G_DBUS_CONNECTION (g_object_ref (source_object)),
+ MECHANISM_BUS,
+ "/",
+ MECHANISM_BUS,
+ "DevicesGet",
+ g_variant_new ("(iiasas)",
+ 0,
+ 0,
+ &include_scheme_builder,
+ NULL),
+ G_VARIANT_TYPE ("(sa{ss})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT,
+ data->cancellable,
+ get_cups_devices_async_dbus_cb,
+ user_data);
+ return;
+ }
+ else
+ {
+ data->callback (result,
+ TRUE,
+ TRUE,
+ data->user_data);
+
+ g_list_free_full (data->backend_list, g_free);
+ data->backend_list = NULL;
+ }
+ }
+ else
+ {
+ data->callback (result,
+ TRUE,
+ g_cancellable_is_cancelled (data->cancellable),
+ data->user_data);
+ }
+
+ g_object_unref (source_object);
+ if (data->cancellable)
+ g_object_unref (data->cancellable);
+ g_free (data);
+}
+
+void
+get_cups_devices_async (GCancellable *cancellable,
+ GCDCallback callback,
+ gpointer user_data)
+{
+ GDBusConnection *bus;
+ GVariantBuilder include_scheme_builder;
+ GCDData *data;
+ GError *error = NULL;
+ gint i;
+ const gchar *backends[] =
+ {"hpfax", "ncp", "beh", "bluetooth", "snmp",
+ "dnssd", "hp", "ipp", "lpd", "parallel",
+ "serial", "socket", "usb", NULL};
+
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (!bus)
+ {
+ g_warning ("Failed to get system bus: %s", error->message);
+ g_error_free (error);
+ callback (NULL, TRUE, FALSE, user_data);
+ return;
+ }
+
+ data = g_new0 (GCDData, 1);
+ if (cancellable)
+ data->cancellable = g_object_ref (cancellable);
+ data->callback = callback;
+ data->user_data = user_data;
+ for (i = 0; backends[i]; i++)
+ data->backend_list = g_list_prepend (data->backend_list, g_strdup (backends[i]));
+
+ g_variant_builder_init (&include_scheme_builder, G_VARIANT_TYPE ("as"));
+ g_variant_builder_add (&include_scheme_builder, "s", data->backend_list->data);
+
+ g_free (data->backend_list->data);
+ data->backend_list = g_list_remove_link (data->backend_list, data->backend_list);
+
+ g_dbus_connection_call (bus,
+ MECHANISM_BUS,
+ "/",
+ MECHANISM_BUS,
+ "DevicesGet",
+ g_variant_new ("(iiasas)",
+ 0,
+ 0,
+ &include_scheme_builder,
+ NULL),
+ G_VARIANT_TYPE ("(sa{ss})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT,
+ cancellable,
+ get_cups_devices_async_dbus_cb,
+ data);
+}
+
+void
+pp_print_device_free (PpPrintDevice *device)
+{
+ if (device)
+ {
+ g_free (device->device_class);
+ g_free (device->device_id);
+ g_free (device->device_info);
+ g_free (device->device_make_and_model);
+ g_free (device->device_uri);
+ g_free (device->device_location);
+ g_free (device->device_name);
+ g_free (device->device_ppd);
+ g_free (device);
+ }
+}
+
+typedef struct
+{
gchar *printer_name;
gboolean my_jobs;
gint which_jobs;
diff --git a/panels/printers/pp-utils.h b/panels/printers/pp-utils.h
index 97860c3..a497f3f 100644
--- a/panels/printers/pp-utils.h
+++ b/panels/printers/pp-utils.h
@@ -46,6 +46,11 @@ enum
PPD_EXACT_CMD_MATCH
};
+enum
+{
+ ACQUISITION_METHOD_DEFAULT_CUPS_SERVER = 0
+};
+
typedef struct
{
gchar *ppd_name;
@@ -266,6 +271,30 @@ void job_set_hold_until_async (gint job_id,
GCancellable *cancellable,
JSHUCallback callback,
gpointer user_data);
+typedef struct{
+ gchar *device_class;
+ gchar *device_id;
+ gchar *device_info;
+ gchar *device_make_and_model;
+ gchar *device_uri;
+ gchar *device_location;
+ gchar *device_name;
+ gchar *device_ppd;
+ gchar *host_name;
+ gint host_port;
+ gint acquisition_method;
+} PpPrintDevice;
+
+void pp_print_device_free (PpPrintDevice *device);
+
+typedef void (*GCDCallback) (GList *devices,
+ gboolean finished,
+ gboolean cancelled,
+ gpointer user_data);
+
+void get_cups_devices_async (GCancellable *cancellable,
+ GCDCallback callback,
+ gpointer user_data);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]