/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2012 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:cd-device * @short_description: Client object for accessing information about colord devices * * A helper GObject to use for accessing colord devices, and to be notified * when it is changed. * * See also: #CdClient */ #include "config.h" #include #include #include #include #include "cd-device.h" #include "cd-profile.h" #include "cd-profile-sync.h" static void cd_device_class_init (CdDeviceClass *klass); static void cd_device_init (CdDevice *device); static void cd_device_finalize (GObject *object); #define GET_PRIVATE(o) (cd_device_get_instance_private (o)) #define COLORD_DBUS_SERVICE "org.freedesktop.ColorManager" #define COLORD_DBUS_INTERFACE_DEVICE "org.freedesktop.ColorManager.Device" /** * CdDevicePrivate: * * Private #CdDevice data **/ typedef struct { GDBusProxy *proxy; gchar *object_path; gchar *id; gchar *model; gchar *serial; gchar *seat; gchar *format; gchar *vendor; gchar **profiling_inhibitors; guint64 created; guint64 modified; GPtrArray *profiles; CdDeviceKind kind; CdColorspace colorspace; CdDeviceMode mode; CdObjectScope scope; gboolean enabled; gboolean embedded; guint owner; GHashTable *metadata; } CdDevicePrivate; enum { PROP_0, PROP_OBJECT_PATH, PROP_CONNECTED, PROP_CREATED, PROP_MODIFIED, PROP_ID, PROP_MODEL, PROP_VENDOR, PROP_SERIAL, PROP_SEAT, PROP_FORMAT, PROP_KIND, PROP_COLORSPACE, PROP_MODE, PROP_SCOPE, PROP_OWNER, PROP_PROFILING_INHIBITORS, PROP_ENABLED, PROP_EMBEDDED, PROP_LAST }; enum { SIGNAL_CHANGED, SIGNAL_LAST }; static guint signals [SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE (CdDevice, cd_device, G_TYPE_OBJECT) /** * cd_device_error_quark: * * Return value: An error quark. * * Since: 0.1.0 **/ GQuark cd_device_error_quark (void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("cd_device_error"); return quark; } /** * cd_device_set_object_path: * @device: a #CdDevice instance. * @object_path: The colord object path. * * Sets the object path of the device. * * Since: 0.1.8 **/ void cd_device_set_object_path (CdDevice *device, const gchar *object_path) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (priv->object_path == NULL); priv->object_path = g_strdup (object_path); } /** * cd_device_get_id: * @device: a #CdDevice instance. * * Gets the device ID. * * Return value: A string, or %NULL for invalid * * Since: 0.1.0 **/ const gchar * cd_device_get_id (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return priv->id; } /** * cd_device_get_model: * @device: a #CdDevice instance. * * Gets the device model. * * Return value: A string, or %NULL for invalid * * Since: 0.1.0 **/ const gchar * cd_device_get_model (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return priv->model; } /** * cd_device_get_vendor: * @device: a #CdDevice instance. * * Gets the device vendor. * * Return value: A string, or %NULL for invalid * * Since: 0.1.1 **/ const gchar * cd_device_get_vendor (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return priv->vendor; } /** * cd_device_get_serial: * @device: a #CdDevice instance. * * Gets the device serial number. * * Return value: A string, or %NULL for invalid * * Since: 0.1.0 **/ const gchar * cd_device_get_serial (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return priv->serial; } /** * cd_device_get_seat: * @device: a #CdDevice instance. * * Gets the device seat identifier. * * Return value: A string, or %NULL for invalid * * Since: 0.1.24 **/ const gchar * cd_device_get_seat (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return priv->seat; } /** * cd_device_get_format: * @device: a #CdDevice instance. * * Gets the device format. * * Return value: A string, or %NULL for invalid * * Since: 0.1.9 **/ const gchar * cd_device_get_format (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return priv->format; } /** * cd_device_get_profiling_inhibitors: * @device: a #CdDevice instance. * * Gets any profiling inhibitors for the device. * * Return value: (transfer none): A strv, or %NULL for invalid * * Since: 0.1.17 **/ const gchar ** cd_device_get_profiling_inhibitors (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return (const gchar **) priv->profiling_inhibitors; } /** * cd_device_get_created: * @device: a #CdDevice instance. * * Gets the device creation date. * * Return value: A value in microseconds, or 0 for invalid * * Since: 0.1.0 **/ guint64 cd_device_get_created (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), 0); g_return_val_if_fail (priv->proxy != NULL, 0); return priv->created; } /** * cd_device_get_modified: * @device: a #CdDevice instance. * * Gets the device modified date. * * Return value: A value in microseconds, or 0 for invalid * * Since: 0.1.1 **/ guint64 cd_device_get_modified (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), 0); g_return_val_if_fail (priv->proxy != NULL, 0); return priv->modified; } /** * cd_device_get_kind: * @device: a #CdDevice instance. * * Gets the device kind. * * Return value: A device kind, e.g. %CD_DEVICE_KIND_DISPLAY * * Since: 0.1.0 **/ CdDeviceKind cd_device_get_kind (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), CD_DEVICE_KIND_UNKNOWN); g_return_val_if_fail (priv->proxy != NULL, CD_DEVICE_KIND_UNKNOWN); return priv->kind; } /** * cd_device_get_colorspace: * @device: a #CdDevice instance. * * Gets the device colorspace. * * Return value: A colorspace, e.g. %CD_COLORSPACE_RGB * * Since: 0.1.1 **/ CdColorspace cd_device_get_colorspace (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), CD_COLORSPACE_UNKNOWN); g_return_val_if_fail (priv->proxy != NULL, CD_COLORSPACE_UNKNOWN); return priv->colorspace; } /** * cd_device_get_mode: * @device: a #CdDevice instance. * * Gets the device mode. * * Return value: A colorspace, e.g. %CD_DEVICE_MODE_VIRTUAL * * Since: 0.1.2 **/ CdDeviceMode cd_device_get_mode (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), CD_DEVICE_MODE_UNKNOWN); g_return_val_if_fail (priv->proxy != NULL, CD_DEVICE_MODE_UNKNOWN); return priv->mode; } /** * cd_device_get_enabled: * @device: a #CdDevice instance. * * Gets the device enabled state. * * Return value: %TRUE if the device is enabled * * Since: 0.1.26 **/ gboolean cd_device_get_enabled (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), FALSE); g_return_val_if_fail (priv->proxy != NULL, FALSE); return priv->enabled; } /** * cd_device_get_embedded: * @device: a #CdDevice instance. * * Returns if the device is embedded in the computer and cannot be * removed. * * Return value: %TRUE if embedded. * * Since: 0.1.27 **/ gboolean cd_device_get_embedded (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), FALSE); g_return_val_if_fail (priv->proxy != NULL, FALSE); return priv->embedded; } /** * cd_device_get_scope: * @device: a #CdDevice instance. * * Gets the device scope. * * Return value: An object scope, e.g. %CD_OBJECT_SCOPE_TEMP * * Since: 0.1.10 **/ CdObjectScope cd_device_get_scope (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), CD_OBJECT_SCOPE_UNKNOWN); g_return_val_if_fail (priv->proxy != NULL, CD_OBJECT_SCOPE_UNKNOWN); return priv->scope; } /** * cd_device_get_owner: * @device: a #CdDevice instance. * * Gets the device owner. * * Return value: The UID of the user that created the device * * Since: 0.1.13 **/ guint cd_device_get_owner (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), G_MAXUINT); g_return_val_if_fail (priv->proxy != NULL, G_MAXUINT); return priv->owner; } /** * cd_device_get_profiles: * @device: a #CdDevice instance. * * Gets the device profiles. * * Return value: (element-type CdProfile) (transfer container): An array of #CdProfile's * * Since: 0.1.0 **/ GPtrArray * cd_device_get_profiles (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); if (priv->profiles == NULL) return NULL; return g_ptr_array_ref (priv->profiles); } /** * cd_device_get_default_profile: * @device: a #CdDevice instance. * * Gets the default device profile. A profile will not be returned * if the device is being profiled or is disabled. * * Return value: (transfer full): A #CdProfile's or NULL * * Since: 0.1.1 **/ CdProfile * cd_device_get_default_profile (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); if (priv->profiles == NULL) return NULL; if (priv->profiles->len == 0) return NULL; if (!priv->enabled) return NULL; if (g_strv_length (priv->profiling_inhibitors) > 0) return NULL; return g_object_ref (g_ptr_array_index (priv->profiles, 0)); } static void cd_device_set_profiles_array_from_variant (CdDevice *device, GVariant *profiles) { CdDevicePrivate *priv = GET_PRIVATE (device); CdProfile *profile_tmp; gsize len; guint i; g_ptr_array_set_size (priv->profiles, 0); if (profiles == NULL) return; len = g_variant_n_children (profiles); for (i = 0; i < len; i++) { g_autofree gchar *object_path_tmp = NULL; g_variant_get_child (profiles, i, "o", &object_path_tmp); profile_tmp = cd_profile_new_with_object_path (object_path_tmp); g_ptr_array_add (priv->profiles, profile_tmp); } } /** * cd_device_get_metadata: * @device: a #CdDevice instance. * * Returns the device metadata. * * Return value: (transfer container) (element-type utf8 utf8): a * #GHashTable. * * Since: 0.1.5 **/ GHashTable * cd_device_get_metadata (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return g_hash_table_ref (priv->metadata); } /** * cd_device_get_metadata_item: * @device: a #CdDevice instance. * @key: a key for the metadata dictionary * * Returns the device metadata for a specific key. * * Return value: the metadata value, or %NULL if not set. * * Since: 0.1.5 **/ const gchar * cd_device_get_metadata_item (CdDevice *device, const gchar *key) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); g_return_val_if_fail (priv->proxy != NULL, NULL); return g_hash_table_lookup (priv->metadata, key); } static void cd_device_set_metadata_from_variant (CdDevice *device, GVariant *variant) { CdDevicePrivate *priv = GET_PRIVATE (device); GVariantIter iter; const gchar *prop_key; const gchar *prop_value; /* remove old entries */ g_hash_table_remove_all (priv->metadata); /* insert the new metadata */ g_variant_iter_init (&iter, variant); while (g_variant_iter_loop (&iter, "{ss}", &prop_key, &prop_value)) { g_hash_table_insert (priv->metadata, g_strdup (prop_key), g_strdup (prop_value)); } } /** * cd_device_get_nullable_str: * * We can't get nullable types from a GVariant yet. Work around... **/ static gchar * cd_device_get_nullable_str (GVariant *value) { const gchar *tmp; tmp = g_variant_get_string (value, NULL); if (tmp == NULL) return NULL; if (tmp[0] == '\0') return NULL; return g_strdup (tmp); } static void cd_device_dbus_properties_changed_cb (GDBusProxy *proxy, GVariant *changed_properties, const gchar * const *invalidated_properties, CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); guint i; guint len; GVariantIter iter; gchar *property_name; GVariant *property_value; g_return_if_fail (CD_IS_DEVICE (device)); len = g_variant_iter_init (&iter, changed_properties); for (i = 0; i < len; i++) { g_variant_get_child (changed_properties, i, "{sv}", &property_name, &property_value); if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_MODEL) == 0) { g_free (priv->model); priv->model = cd_device_get_nullable_str (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_SERIAL) == 0) { g_free (priv->serial); priv->serial = cd_device_get_nullable_str (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_SEAT) == 0) { g_free (priv->seat); priv->seat = cd_device_get_nullable_str (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_FORMAT) == 0) { g_free (priv->format); priv->format = cd_device_get_nullable_str (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_VENDOR) == 0) { g_free (priv->vendor); priv->vendor = cd_device_get_nullable_str (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_PROFILING_INHIBITORS) == 0) { g_free (priv->profiling_inhibitors); priv->profiling_inhibitors = g_variant_dup_strv (property_value, NULL); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_KIND) == 0) { priv->kind = cd_device_kind_from_string (g_variant_get_string (property_value, NULL)); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_COLORSPACE) == 0) { priv->colorspace = cd_colorspace_from_string (g_variant_get_string (property_value, NULL)); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_MODE) == 0) { priv->mode = cd_device_mode_from_string (g_variant_get_string (property_value, NULL)); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_PROFILES) == 0) { cd_device_set_profiles_array_from_variant (device, property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_CREATED) == 0) { priv->created = g_variant_get_uint64 (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_ENABLED) == 0) { priv->enabled = g_variant_get_boolean (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_EMBEDDED) == 0) { priv->embedded = g_variant_get_boolean (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_MODIFIED) == 0) { priv->modified = g_variant_get_uint64 (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_METADATA) == 0) { cd_device_set_metadata_from_variant (device, property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_OWNER) == 0) { priv->owner = g_variant_get_uint32 (property_value); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_SCOPE) == 0) { priv->scope = cd_object_scope_from_string (g_variant_get_string (property_value, NULL)); } else if (g_strcmp0 (property_name, CD_DEVICE_PROPERTY_ID) == 0) { /* ignore this, we don't support it changing */; } else { g_warning ("%s property unhandled", property_name); } g_free (property_name); g_variant_unref (property_value); } } static void cd_device_dbus_signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, CdDevice *device) { gchar *object_path_tmp = NULL; g_return_if_fail (CD_IS_DEVICE (device)); if (g_strcmp0 (signal_name, "Changed") == 0) { g_signal_emit (device, signals[SIGNAL_CHANGED], 0); } else { g_warning ("unhandled signal '%s'", signal_name); } g_free (object_path_tmp); } /**********************************************************************/ /** * cd_device_connect_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ gboolean cd_device_connect_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_connect_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { CdDevice *device; CdDevicePrivate *priv; g_autoptr(GError) error = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) colorspace = NULL; g_autoptr(GVariant) created = NULL; g_autoptr(GVariant) embedded = NULL; g_autoptr(GVariant) enabled = NULL; g_autoptr(GVariant) format = NULL; g_autoptr(GVariant) id = NULL; g_autoptr(GVariant) kind = NULL; g_autoptr(GVariant) metadata = NULL; g_autoptr(GVariant) model = NULL; g_autoptr(GVariant) mode = NULL; g_autoptr(GVariant) modified = NULL; g_autoptr(GVariant) owner = NULL; g_autoptr(GVariant) profiles = NULL; g_autoptr(GVariant) profiling_inhibitors = NULL; g_autoptr(GVariant) scope = NULL; g_autoptr(GVariant) seat = NULL; g_autoptr(GVariant) serial = NULL; g_autoptr(GVariant) vendor = NULL; device = CD_DEVICE (g_task_get_source_object (task)); priv = GET_PRIVATE (device); priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error); if (priv->proxy == NULL) { g_task_return_new_error (task, CD_DEVICE_ERROR, CD_DEVICE_ERROR_INTERNAL, "Failed to connect to device %s: %s", cd_device_get_object_path (device), error->message); return; } /* get device id */ id = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_ID); if (id != NULL) priv->id = cd_device_get_nullable_str (id); /* if the device is missing, then fail */ if (id == NULL) { g_task_return_new_error (task, CD_DEVICE_ERROR, CD_DEVICE_ERROR_INTERNAL, "Failed to connect to missing device %s", cd_device_get_object_path (device)); return; } /* get kind */ kind = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_KIND); if (kind != NULL) priv->kind = cd_device_kind_from_string (g_variant_get_string (kind, NULL)); /* get colorspace */ colorspace = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_COLORSPACE); if (colorspace != NULL) priv->colorspace = cd_colorspace_from_string (g_variant_get_string (colorspace, NULL)); /* get scope */ scope = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_SCOPE); if (scope != NULL) priv->scope = cd_object_scope_from_string (g_variant_get_string (scope, NULL)); /* get enabled */ enabled = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_ENABLED); if (enabled != NULL) priv->enabled = g_variant_get_boolean (enabled); /* get owner */ owner = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_OWNER); if (owner != NULL) priv->owner = g_variant_get_uint32 (owner); /* get mode */ mode = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_MODE); if (mode != NULL) priv->mode = cd_device_mode_from_string (g_variant_get_string (mode, NULL)); /* get model */ model = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_MODEL); if (model != NULL) priv->model = cd_device_get_nullable_str (model); /* get serial */ serial = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_SERIAL); if (serial != NULL) priv->serial = cd_device_get_nullable_str (serial); /* get seat */ seat = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_SEAT); if (seat != NULL) priv->seat = cd_device_get_nullable_str (seat); /* get format */ format = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_FORMAT); if (format != NULL) priv->format = cd_device_get_nullable_str (format); /* get vendor */ vendor = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_VENDOR); if (vendor != NULL) priv->vendor = cd_device_get_nullable_str (vendor); /* get profiling inhibitors */ profiling_inhibitors = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_PROFILING_INHIBITORS); if (profiling_inhibitors != NULL) priv->profiling_inhibitors = g_variant_dup_strv (profiling_inhibitors, NULL); /* get created */ created = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_CREATED); if (created != NULL) priv->created = g_variant_get_uint64 (created); /* get modified */ modified = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_MODIFIED); if (modified != NULL) priv->modified = g_variant_get_uint64 (modified); /* get profiles */ profiles = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_PROFILES); cd_device_set_profiles_array_from_variant (device, profiles); /* get embedded */ embedded = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_EMBEDDED); if (embedded != NULL) priv->embedded = g_variant_get_boolean (embedded); /* get metadata */ metadata = g_dbus_proxy_get_cached_property (priv->proxy, CD_DEVICE_PROPERTY_METADATA); if (metadata != NULL) cd_device_set_metadata_from_variant (device, metadata); /* get signals from DBus */ g_signal_connect_object (priv->proxy, "g-signal", G_CALLBACK (cd_device_dbus_signal_cb), device, 0); /* watch if any remote properties change */ g_signal_connect_object (priv->proxy, "g-properties-changed", G_CALLBACK (cd_device_dbus_properties_changed_cb), device, 0); /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_connect: * @device: a #CdDevice instance. * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Connects to the object and fills up initial properties. * * Since: 0.1.8 **/ void cd_device_connect (CdDevice *device, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); task = g_task_new (device, cancellable, callback, user_data); /* already connected */ if (priv->proxy != NULL) { g_task_return_boolean (task, TRUE); return; } g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, COLORD_DBUS_SERVICE, priv->object_path, COLORD_DBUS_INTERFACE_DEVICE, cancellable, cd_device_connect_cb, task); } /**********************************************************************/ /** * cd_device_set_property_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ gboolean cd_device_set_property_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_fixup_dbus_error (GError *error) { g_autofree gchar *name = NULL; g_return_if_fail (error != NULL); /* is a remote error? */ if (!g_dbus_error_is_remote_error (error)) return; /* parse the remote error */ name = g_dbus_error_get_remote_error (error); error->domain = CD_DEVICE_ERROR; error->code = cd_device_error_from_string (name); g_dbus_error_strip_remote_error (error); } static void cd_device_set_property_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) result = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_set_property: * @device: a #CdDevice instance. * @key: a property key * @value: a property key * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Sets a property on the device. * * Since: 0.1.8 **/ void cd_device_set_property (CdDevice *device, const gchar *key, const gchar *value, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (key != NULL); g_return_if_fail (value != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "SetProperty", g_variant_new ("(ss)", key, value), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_set_property_cb, task); } /**********************************************************************/ /** * cd_device_add_profile_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ gboolean cd_device_add_profile_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_add_profile_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) result = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_add_profile: * @device: a #CdDevice instance. * @relation: a #CdDeviceRelation, e.g. #CD_DEVICE_RELATION_HARD * @profile: a #CdProfile instance * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Adds a profile to a device. * * Since: 0.1.8 **/ void cd_device_add_profile (CdDevice *device, CdDeviceRelation relation, CdProfile *profile, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (CD_IS_PROFILE (profile)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "AddProfile", g_variant_new ("(so)", cd_device_relation_to_string (relation), cd_profile_get_object_path (profile)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_add_profile_cb, task); } /**********************************************************************/ /** * cd_device_remove_profile_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ gboolean cd_device_remove_profile_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_remove_profile_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) result = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_remove_profile: * @device: a #CdDevice instance. * @profile: a #CdProfile instance * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Removes a profile from a device. * * Since: 0.1.8 **/ void cd_device_remove_profile (CdDevice *device, CdProfile *profile, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (CD_IS_PROFILE (profile)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "RemoveProfile", g_variant_new ("(o)", cd_profile_get_object_path (profile)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_remove_profile_cb, task); } /**********************************************************************/ /** * cd_device_make_profile_default_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ gboolean cd_device_make_profile_default_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_make_profile_default_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) result = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_make_profile_default: * @device: a #CdDevice instance. * @profile: a #CdProfile instance * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Makes an already added profile default for a device. * * Since: 0.1.8 **/ void cd_device_make_profile_default (CdDevice *device, CdProfile *profile, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (CD_IS_PROFILE (profile)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "MakeProfileDefault", g_variant_new ("(o)", cd_profile_get_object_path (profile)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_make_profile_default_cb, task); } /**********************************************************************/ /** * cd_device_profiling_inhibit_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ gboolean cd_device_profiling_inhibit_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_profiling_inhibit_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) result = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_profiling_inhibit: * @device: a #CdDevice instance. * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Sets up the device for profiling and causes no profiles to be * returned if cd_device_get_profile_for_qualifiers_sync() is used. * * Since: 0.1.8 **/ void cd_device_profiling_inhibit (CdDevice *device, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "ProfilingInhibit", NULL, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_profiling_inhibit_cb, task); } /**********************************************************************/ /** * cd_device_profiling_uninhibit_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ gboolean cd_device_profiling_uninhibit_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_profiling_uninhibit_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GVariant) result = NULL; g_autoptr(GTask) task = G_TASK (user_data); result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_profiling_uninhibit: * @device: a #CdDevice instance. * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Restores the device after profiling and causes normal profiles to be * returned if cd_device_get_profile_for_qualifiers_sync() is used. * * Since: 0.1.8 **/ void cd_device_profiling_uninhibit (CdDevice *device, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "ProfilingUninhibit", NULL, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_profiling_uninhibit_cb, task); } /**********************************************************************/ /** * cd_device_get_profile_for_qualifiers_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: (transfer full): a #CdProfile or %NULL * * Since: 0.1.8 **/ CdProfile * cd_device_get_profile_for_qualifiers_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), NULL); return g_task_propagate_pointer (G_TASK (res), error); } static void cd_device_get_profile_for_qualifiers_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GVariant) result = NULL; CdProfile *profile; gchar *object_path = NULL; g_autoptr(GTask) task = G_TASK (user_data); result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* create CdProfile object */ g_variant_get (result, "(o)", &object_path); profile = cd_profile_new (); cd_profile_set_object_path (profile, object_path); /* success */ g_task_return_pointer (task, profile, (GDestroyNotify) g_object_unref); } /** * cd_device_get_profile_for_qualifiers: * @device: a #CdDevice instance. * @qualifiers: a set of qualifiers that can included wildcards * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Gets the preferred profile for some qualifiers. * * Since: 0.1.8 **/ void cd_device_get_profile_for_qualifiers (CdDevice *device, const gchar **qualifiers, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; guint i; GVariantBuilder builder; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (qualifiers != NULL); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); /* squash char** into an array of strings */ g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); for (i = 0; qualifiers[i] != NULL; i++) g_variant_builder_add (&builder, "s", qualifiers[i]); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "GetProfileForQualifiers", g_variant_new ("(as)", &builder), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_get_profile_for_qualifiers_cb, task); } /**********************************************************************/ /** * cd_device_get_profile_relation_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.8 **/ CdDeviceRelation cd_device_get_profile_relation_finish (CdDevice *device, GAsyncResult *res, GError **error) { gssize tmp; g_return_val_if_fail (g_task_is_valid (res, device), 0); tmp = g_task_propagate_int (G_TASK (res), error); if (tmp == -1) return CD_DEVICE_RELATION_UNKNOWN; return tmp; } static void cd_device_get_profile_relation_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { CdDeviceRelation relation; g_autoptr(GError) error = NULL; g_autofree gchar *relation_string = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) result = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_variant_get (result, "(s)", &relation_string); relation = cd_device_relation_from_string (relation_string); g_task_return_int (task, relation); } /** * cd_device_get_profile_relation: * @device: a #CdDevice instance. * @profile: a #CdProfile instance * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Gets the property relationship to the device. * * Since: 0.1.8 **/ void cd_device_get_profile_relation (CdDevice *device, CdProfile *profile, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (CD_IS_PROFILE (profile)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "GetProfileRelation", g_variant_new ("(o)", cd_profile_get_object_path (profile)), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_get_profile_relation_cb, task); } /**********************************************************************/ /** * cd_device_set_enabled_finish: * @device: a #CdDevice instance. * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: success * * Since: 0.1.26 **/ gboolean cd_device_set_enabled_finish (CdDevice *device, GAsyncResult *res, GError **error) { g_return_val_if_fail (g_task_is_valid (res, device), FALSE); return g_task_propagate_boolean (G_TASK (res), error); } static void cd_device_set_enabled_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { g_autoptr(GError) error = NULL; g_autoptr(GTask) task = G_TASK (user_data); g_autoptr(GVariant) result = NULL; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { cd_device_fixup_dbus_error (error); g_task_return_error (task, error); error = NULL; return; } /* success */ g_task_return_boolean (task, TRUE); } /** * cd_device_set_enabled: * @device: a #CdDevice instance. * @enabled: the enabled state * @cancellable: a #GCancellable, or %NULL * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Enables or disables a device. * * Since: 0.1.26 **/ void cd_device_set_enabled (CdDevice *device, gboolean enabled, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CdDevicePrivate *priv = GET_PRIVATE (device); GTask *task = NULL; g_return_if_fail (CD_IS_DEVICE (device)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (priv->proxy != NULL); task = g_task_new (device, cancellable, callback, user_data); g_dbus_proxy_call (priv->proxy, "SetEnabled", g_variant_new ("(b)", enabled), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, cd_device_set_enabled_cb, task); } /**********************************************************************/ /** * cd_device_get_object_path: * @device: a #CdDevice instance. * * Gets the object path for the device. * * Return value: the object path, or %NULL * * Since: 0.1.0 **/ const gchar * cd_device_get_object_path (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), NULL); return priv->object_path; } /** * cd_device_get_connected: * @device: a #CdDevice instance. * * Gets if the device has been connected. * * Return value: %TRUE if properties are valid * * Since: 0.1.9 **/ gboolean cd_device_get_connected (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (CD_IS_DEVICE (device), FALSE); return priv->proxy != NULL; } /** * cd_device_to_string: * @device: a #CdDevice instance. * * Converts the device to a string description. * * Return value: text representation of #CdDevice * * Since: 0.1.0 **/ gchar * cd_device_to_string (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); struct tm *time_tm; time_t t; gchar time_buf[256]; GString *string; g_return_val_if_fail (CD_IS_DEVICE (device), NULL); /* get a human readable time */ t = (time_t) priv->created; time_tm = localtime (&t); strftime (time_buf, sizeof time_buf, "%F %T", time_tm); string = g_string_new (""); g_string_append_printf (string, " object-path: %s\n", priv->object_path); g_string_append_printf (string, " created: %s\n", time_buf); return g_string_free (string, FALSE); } /** * cd_device_equal: * @device1: one #CdDevice instance. * @device2: another #CdDevice instance. * * Tests two devices for equality. * * Return value: %TRUE if the devices are the same device * * Since: 0.1.8 **/ gboolean cd_device_equal (CdDevice *device1, CdDevice *device2) { CdDevicePrivate *priv1 = GET_PRIVATE (device1); CdDevicePrivate *priv2 = GET_PRIVATE (device2); g_return_val_if_fail (CD_IS_DEVICE (device1), FALSE); g_return_val_if_fail (CD_IS_DEVICE (device2), FALSE); return g_strcmp0 (priv1->id, priv2->id) == 0; } /* * _cd_device_set_property: */ static void _cd_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { CdDevice *device = CD_DEVICE (object); CdDevicePrivate *priv = GET_PRIVATE (device); switch (prop_id) { case PROP_OBJECT_PATH: g_free (priv->object_path); priv->object_path = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /* * cd_device_get_property: */ static void cd_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { CdDevice *device = CD_DEVICE (object); CdDevicePrivate *priv = GET_PRIVATE (device); switch (prop_id) { case PROP_OBJECT_PATH: g_value_set_string (value, priv->object_path); break; case PROP_CONNECTED: g_value_set_boolean (value, priv->proxy != NULL); break; case PROP_CREATED: g_value_set_uint64 (value, priv->created); break; case PROP_MODIFIED: g_value_set_uint64 (value, priv->modified); break; case PROP_ID: g_value_set_string (value, priv->id); break; case PROP_MODEL: g_value_set_string (value, priv->model); break; case PROP_SERIAL: g_value_set_string (value, priv->serial); break; case PROP_SEAT: g_value_set_string (value, priv->seat); break; case PROP_FORMAT: g_value_set_string (value, priv->format); break; case PROP_VENDOR: g_value_set_string (value, priv->vendor); break; case PROP_PROFILING_INHIBITORS: g_value_set_boxed (value, priv->profiling_inhibitors); break; case PROP_KIND: g_value_set_uint (value, priv->kind); break; case PROP_COLORSPACE: g_value_set_uint (value, priv->colorspace); break; case PROP_MODE: g_value_set_uint (value, priv->mode); break; case PROP_SCOPE: g_value_set_uint (value, priv->scope); break; case PROP_ENABLED: g_value_set_boolean (value, priv->enabled); break; case PROP_OWNER: g_value_set_uint (value, priv->owner); break; case PROP_EMBEDDED: g_value_set_boolean (value, priv->embedded); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /* * cd_device_class_init: */ static void cd_device_class_init (CdDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = cd_device_finalize; object_class->set_property = _cd_device_set_property; object_class->get_property = cd_device_get_property; /** * CdDevice::changed: * @device: the #CdDevice instance that emitted the signal * * The ::changed signal is emitted when the device data has changed. * * Since: 0.1.0 **/ signals [SIGNAL_CHANGED] = g_signal_new ("changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (CdDeviceClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * CdDevice:object-path: * * The object path of the remote object * * Since: 0.1.8 **/ g_object_class_install_property (object_class, PROP_OBJECT_PATH, g_param_spec_string ("object-path", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); /** * CdDevice:connected: * * The if the object path has been connected as is valid for use. * * Since: 0.1.9 **/ g_object_class_install_property (object_class, PROP_CONNECTED, g_param_spec_string ("connected", NULL, NULL, NULL, G_PARAM_READABLE)); /** * CdDevice:created: * * The time the device was created. * * Since: 0.1.0 **/ g_object_class_install_property (object_class, PROP_CREATED, g_param_spec_uint64 ("created", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); /** * CdDevice:modified: * * The last time the device was modified. * * Since: 0.1.1 **/ g_object_class_install_property (object_class, PROP_MODIFIED, g_param_spec_uint64 ("modified", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); /** * CdDevice:id: * * The device ID. * * Since: 0.1.0 **/ g_object_class_install_property (object_class, PROP_ID, g_param_spec_string ("id", NULL, NULL, NULL, G_PARAM_READABLE)); /** * CdDevice:model: * * The device model. * * Since: 0.1.0 **/ g_object_class_install_property (object_class, PROP_MODEL, g_param_spec_string ("model", NULL, NULL, NULL, G_PARAM_READABLE)); /** * CdDevice:serial: * * The device serial number. * * Since: 0.1.1 **/ g_object_class_install_property (object_class, PROP_SERIAL, g_param_spec_string ("serial", NULL, NULL, NULL, G_PARAM_READABLE)); /** * CdDevice:seat: * * The device seat identifier. * * Since: 0.1.24 **/ g_object_class_install_property (object_class, PROP_SEAT, g_param_spec_string ("seat", NULL, NULL, NULL, G_PARAM_READABLE)); /** * CdDevice:format: * * The device format. * * Since: 0.1.9 **/ g_object_class_install_property (object_class, PROP_FORMAT, g_param_spec_string ("format", NULL, NULL, NULL, G_PARAM_READABLE)); /** * CdDevice:vendor: * * The device vendor. * * Since: 0.1.1 **/ g_object_class_install_property (object_class, PROP_VENDOR, g_param_spec_string ("vendor", NULL, NULL, NULL, G_PARAM_READABLE)); /** * CdDevice:profiling_inhibitors: * * Any profiling inhibitors. * * Since: 0.1.17 **/ g_object_class_install_property (object_class, PROP_PROFILING_INHIBITORS, g_param_spec_boxed ("profiling-inhibitors", NULL, NULL, G_TYPE_STRV, G_PARAM_READABLE)); /** * CdDevice:kind: * * The device kind, e.g. %CD_DEVICE_KIND_DISPLAY. * * Since: 0.1.0 **/ g_object_class_install_property (object_class, PROP_KIND, g_param_spec_uint ("kind", NULL, NULL, CD_DEVICE_KIND_UNKNOWN, CD_DEVICE_KIND_LAST, CD_DEVICE_KIND_UNKNOWN, G_PARAM_READABLE)); /** * CdDevice:colorspace: * * The device colorspace, e.g. %CD_COLORSPACE_RGB. * * Since: 0.1.1 **/ g_object_class_install_property (object_class, PROP_COLORSPACE, g_param_spec_uint ("colorspace", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); /** * CdDevice:mode: * * The device colorspace, e.g. %CD_DEVICE_MODE_VIRTUAL. * * Since: 0.1.2 **/ g_object_class_install_property (object_class, PROP_MODE, g_param_spec_uint ("mode", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); /** * CdDevice:scope: * * The device scope, e.g. %CD_OBJECT_SCOPE_TEMP. * * Since: 0.1.10 **/ g_object_class_install_property (object_class, PROP_SCOPE, g_param_spec_uint ("scope", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); /** * CdDevice:enabled: * * The device enabled state. * * Since: 0.1.26 **/ g_object_class_install_property (object_class, PROP_ENABLED, g_param_spec_boolean ("enabled", NULL, NULL, FALSE, G_PARAM_READABLE)); /** * CdDevice:owner: * * The device owner, e.g. 500. * * Since: 0.1.13 **/ g_object_class_install_property (object_class, PROP_OWNER, g_param_spec_uint ("owner", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); /** * CdDevice:embedded: * * If the device is embedded in the device and cannot be removed. * * Since: 0.1.27 **/ g_object_class_install_property (object_class, PROP_EMBEDDED, g_param_spec_string ("embedded", NULL, NULL, FALSE, G_PARAM_READABLE)); } /* * cd_device_init: */ static void cd_device_init (CdDevice *device) { CdDevicePrivate *priv = GET_PRIVATE (device); priv->profiles = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } /* * cd_device_finalize: */ static void cd_device_finalize (GObject *object) { CdDevice *device = CD_DEVICE (object); CdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (CD_IS_DEVICE (object)); g_hash_table_destroy (priv->metadata); g_free (priv->object_path); g_free (priv->id); g_free (priv->model); g_free (priv->serial); g_free (priv->seat); g_free (priv->format); g_free (priv->vendor); g_strfreev (priv->profiling_inhibitors); g_ptr_array_unref (priv->profiles); if (priv->proxy != NULL) g_object_unref (priv->proxy); G_OBJECT_CLASS (cd_device_parent_class)->finalize (object); } /** * cd_device_new: * * Creates a new #CdDevice object. * * Return value: a new CdDevice object. * * Since: 0.1.0 **/ CdDevice * cd_device_new (void) { CdDevice *device; device = g_object_new (CD_TYPE_DEVICE, NULL); return CD_DEVICE (device); } /** * cd_device_new_with_object_path: * @object_path: The colord object path. * * Creates a new #CdDevice object with a known object path. * * Return value: a new device object. * * Since: 0.1.8 **/ CdDevice * cd_device_new_with_object_path (const gchar *object_path) { CdDevice *device; device = g_object_new (CD_TYPE_DEVICE, "object-path", object_path, NULL); return CD_DEVICE (device); }