summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2011-01-12 14:34:58 +0000
committerRichard Hughes <richard@hughsie.com>2011-01-13 11:17:14 +0000
commit2f83888a2bf3f32f6aa57bc62e71af96ce27c9e9 (patch)
tree67d88457da908b6757743c531402395c1b4640fd
parent385e680fb6d4fc414d7382c43b3feb33cac52982 (diff)
downloadcolord-2f83888a2bf3f32f6aa57bc62e71af96ce27c9e9.tar.gz
Add a libcolord shared library that can be used in the client tools
This also allows us to create a self test framework, which uncovered many bugs in the process.
-rw-r--r--Makefile.am1
-rw-r--r--client/.gitignore1
-rw-r--r--client/Makefile.am7
-rw-r--r--client/cd-gui.c3
-rw-r--r--client/cd-util.c708
-rwxr-xr-xclient/test.sh14
-rw-r--r--configure.ac36
-rw-r--r--contrib/colord.spec.in22
-rw-r--r--data/Makefile.am4
-rw-r--r--data/tests/Makefile.am2
-rw-r--r--data/tests/ibm-t61.iccbin0 -> 25120 bytes
-rwxr-xr-xdoc/create.sh4
-rw-r--r--libcolord/.gitignore8
-rw-r--r--libcolord/Makefile.am64
-rw-r--r--libcolord/cd-client.c1011
-rw-r--r--libcolord/cd-client.h134
-rw-r--r--libcolord/cd-device.c909
-rw-r--r--libcolord/cd-device.h120
-rw-r--r--libcolord/cd-enum.c94
-rw-r--r--libcolord/cd-enum.h (renamed from client/cd-common.h)33
-rw-r--r--libcolord/cd-profile.c709
-rw-r--r--libcolord/cd-profile.h107
-rw-r--r--libcolord/cd-self-test.c296
-rw-r--r--libcolord/cd-version.h.in69
-rw-r--r--libcolord/colord.h46
-rw-r--r--libcolord/colord.pc.in12
-rw-r--r--src/cd-device.c169
-rw-r--r--src/cd-device.h5
-rw-r--r--src/cd-main.c22
-rw-r--r--src/cd-profile.c48
-rw-r--r--src/org.freedesktop.ColorManager.Device.xml3
-rw-r--r--src/org.freedesktop.ColorManager.xml51
32 files changed, 4228 insertions, 484 deletions
diff --git a/Makefile.am b/Makefile.am
index 27346cb..ea435cf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,6 +9,7 @@ SUBDIRS = \
policy \
data \
man \
+ libcolord \
client \
src
diff --git a/client/.gitignore b/client/.gitignore
index b205447..9ac9527 100644
--- a/client/.gitignore
+++ b/client/.gitignore
@@ -1,4 +1,5 @@
colorgui
colormgr
.deps
+.libs
*.o
diff --git a/client/Makefile.am b/client/Makefile.am
index 83a91dc..823c55d 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -1,6 +1,8 @@
INCLUDES = \
$(GLIB_CFLAGS) \
$(GTK_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/libcolord \
-DG_LOG_DOMAIN=\"Cd\" \
-DLIBEXECDIR=\"$(libexecdir)\" \
-DDATADIR=\"$(datadir)\" \
@@ -8,6 +10,8 @@ INCLUDES = \
-DVERSION="\"$(VERSION)\"" \
-DLOCALEDIR=\""$(localedir)"\"
+COLORD_LIBS = $(top_builddir)/libcolord/libcolord.la
+
bin_PROGRAMS = \
colormgr
@@ -15,6 +19,7 @@ colormgr_SOURCES = \
cd-util.c
colormgr_LDADD = \
+ $(COLORD_LIBS) \
$(GLIB_LIBS)
colormgr_CFLAGS = \
@@ -24,9 +29,9 @@ if CD_BUILD_GUI
noinst_PROGRAMS = colorgui
colorgui_SOURCES = \
- cd-common.h \
cd-gui.c
colorgui_LDADD = \
+ $(COLORD_LIBS) \
$(GLIB_LIBS) \
$(GTK_LIBS)
colorgui_CFLAGS = $(WARNINGFLAGS_C)
diff --git a/client/cd-gui.c b/client/cd-gui.c
index 419bfa9..65e6c17 100644
--- a/client/cd-gui.c
+++ b/client/cd-gui.c
@@ -25,8 +25,7 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <locale.h>
-
-#include "cd-common.h"
+#include <colord.h>
static gchar *current_device = NULL;
static gchar *current_profile = NULL;
diff --git a/client/cd-util.c b/client/cd-util.c
index ceaa260..49d5040 100644
--- a/client/cd-util.c
+++ b/client/cd-util.c
@@ -24,164 +24,55 @@
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <locale.h>
-
-#include "cd-common.h"
+#include <colord.h>
/**
* cd_util_show_profile:
**/
static void
-cd_util_show_profile (const gchar *object_path)
+cd_util_show_profile (CdProfile *profile)
{
- const gchar *filename = NULL;
- const gchar *profile_id = NULL;
- const gchar *qualifier = NULL;
- const gchar *title = NULL;
- GDBusProxy *proxy;
- GError *error = NULL;
- GVariant *variant_filename = NULL;
- GVariant *variant_profile_id = NULL;
- GVariant *variant_qualifier = NULL;
- GVariant *variant_title = NULL;
-
- g_print ("Object Path: %s\n", object_path);
-
- /* get proxy */
- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- NULL,
- COLORD_DBUS_SERVICE,
- object_path,
- COLORD_DBUS_INTERFACE_PROFILE,
- NULL,
- &error);
- if (proxy == NULL) {
- g_print ("Failed to get profile properties: %s",
- error->message);
- g_error_free (error);
- goto out;
- }
-
- /* print profile id */
- variant_profile_id = g_dbus_proxy_get_cached_property (proxy, "ProfileId");
- if (variant_profile_id != NULL)
- profile_id = g_variant_get_string (variant_profile_id, NULL);
- g_print ("ProfileId:\t\t%s\n", profile_id);
-
- /* print title */
- variant_title = g_dbus_proxy_get_cached_property (proxy, "Title");
- if (variant_title != NULL)
- title = g_variant_get_string (variant_title, NULL);
- g_print ("Title:\t\t%s\n", title);
-
- /* print qualifier */
- variant_qualifier = g_dbus_proxy_get_cached_property (proxy, "Qualifier");
- if (variant_qualifier != NULL)
- qualifier = g_variant_get_string (variant_qualifier, NULL);
- g_print ("Qualifier:\t\t%s\n", qualifier);
-
- /* print filename */
- variant_filename = g_dbus_proxy_get_cached_property (proxy, "Filename");
- if (variant_filename != NULL)
- filename = g_variant_get_string (variant_filename, NULL);
- g_print ("Filename:\t\t%s\n", filename);
-out:
- if (variant_profile_id != NULL)
- g_variant_unref (variant_profile_id);
- if (variant_title != NULL)
- g_variant_unref (variant_title);
- if (variant_qualifier != NULL)
- g_variant_unref (variant_qualifier);
- if (variant_filename != NULL)
- g_variant_unref (variant_filename);
- if (proxy != NULL)
- g_object_unref (proxy);
+ g_print ("Object Path: %s\n",
+ cd_profile_get_object_path (profile));
+ g_print ("Created:\t%" G_GUINT64_FORMAT "\n",
+ cd_profile_get_created (profile));
+ g_print ("Qualifier:\t\t%s\n",
+ cd_profile_get_qualifier (profile));
+ g_print ("Filename:\t\t%s\n",
+ cd_profile_get_filename (profile));
+ g_print ("Profile ID:\t%s\n",
+ cd_profile_get_id (profile));
}
/**
* cd_util_show_device:
**/
static void
-cd_util_show_device (const gchar *object_path)
+cd_util_show_device (CdDevice *device)
{
- const gchar *device_id;
- const gchar *kind;
- const gchar *model;
- gchar *profile_tmp;
- GDBusProxy *proxy;
- GError *error = NULL;
- gsize len;
- guint64 created;
+ CdProfile *profile_tmp;
+ GPtrArray *profiles;
guint i;
- GVariantIter iter;
- GVariant *variant_created = NULL;
- GVariant *variant_device_id = NULL;
- GVariant *variant_kind = NULL;
- GVariant *variant_model = NULL;
- GVariant *variant_profiles = NULL;
-
- g_print ("Object Path: %s\n", object_path);
-
- /* get proxy */
- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
- NULL,
- COLORD_DBUS_SERVICE,
- object_path,
- COLORD_DBUS_INTERFACE_DEVICE,
- NULL,
- &error);
- if (proxy == NULL) {
- g_print ("Failed to get device properties: %s",
- error->message);
- g_error_free (error);
- goto out;
- }
-
- /* print created date */
- variant_created = g_dbus_proxy_get_cached_property (proxy, "Created");
- created = g_variant_get_uint64 (variant_created);
- g_print ("Created:\t%" G_GUINT64_FORMAT "\n", created);
-
- /* print kind */
- variant_kind = g_dbus_proxy_get_cached_property (proxy, "Kind");
- if (variant_kind != NULL) {
- kind = g_variant_get_string (variant_kind, NULL);
- g_print ("Kind:\t\t%s\n", kind);
- }
- /* print model */
- variant_model = g_dbus_proxy_get_cached_property (proxy, "Model");
- model = g_variant_get_string (variant_model, NULL);
- g_print ("Model:\t\t%s\n", model);
-
- /* print device id */
- variant_device_id = g_dbus_proxy_get_cached_property (proxy, "DeviceId");
- device_id = g_variant_get_string (variant_device_id, NULL);
- g_print ("Device ID:\t%s\n", device_id);
+ g_print ("Object Path: %s\n",
+ cd_device_get_object_path (device));
+ g_print ("Created:\t%" G_GUINT64_FORMAT "\n",
+ cd_device_get_created (device));
+ g_print ("Kind:\t\t%s\n",
+ cd_device_kind_to_string (cd_device_get_kind (device)));
+ g_print ("Model:\t\t%s\n",
+ cd_device_get_model (device));
+ g_print ("Device ID:\t%s\n",
+ cd_device_get_id (device));
/* print profiles */
- variant_profiles = g_dbus_proxy_get_cached_property (proxy, "Profiles");
- len = g_variant_iter_init (&iter, variant_profiles);
- if (len == 0)
- g_print ("No assigned profiles!\n");
- for (i=0; i<len; i++) {
- g_variant_get_child (variant_profiles, i,
- "o", &profile_tmp);
- g_print ("Profile %i:\t%s\n", i+1, profile_tmp);
- g_free (profile_tmp);
+ profiles = cd_device_get_profiles (device);
+ for (i=0; i<profiles->len; i++) {
+ profile_tmp = g_ptr_array_index (profiles, i);
+ g_print ("Profile %i:\t%s\n",
+ i+1,
+ cd_profile_get_object_path (profile_tmp));
}
-out:
- if (variant_created != NULL)
- g_variant_unref (variant_created);
- if (variant_model != NULL)
- g_variant_unref (variant_model);
- if (variant_device_id != NULL)
- g_variant_unref (variant_device_id);
- if (variant_profiles != NULL)
- g_variant_unref (variant_profiles);
- if (proxy != NULL)
- g_object_unref (proxy);
}
/**
@@ -206,18 +97,18 @@ cd_util_mask_from_string (const gchar *value)
int
main (int argc, char *argv[])
{
- const gchar *object_path;
- gchar *object_path_tmp = NULL;
- GDBusConnection *connection;
+ CdClient *client = NULL;
+ CdDevice *device = NULL;
+ CdDevice *device_tmp;
+ CdProfile *profile = NULL;
+ CdProfile *profile_tmp;
+ gboolean ret;
GError *error = NULL;
GOptionContext *context;
- gsize len;
+ GPtrArray *array = NULL;
guint i;
guint mask;
guint retval = 1;
- GVariantIter iter;
- GVariant *response_child = NULL;
- GVariant *response = NULL;
setlocale (LC_ALL, "");
@@ -234,11 +125,12 @@ main (int argc, char *argv[])
g_option_context_parse (context, &argc, &argv, NULL);
g_option_context_free (context);
- /* get a session bus connection */
- connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
- if (connection == NULL) {
- /* TRANSLATORS: no DBus system bus */
- g_print ("%s %s\n", _("Failed to connect to system bus:"), error->message);
+ /* get connection to colord */
+ client = cd_client_new ();
+ ret = cd_client_connect_sync (client, NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("No connection to colord:"), error->message);
g_error_free (error);
goto out;
}
@@ -252,30 +144,16 @@ main (int argc, char *argv[])
if (g_strcmp0 (argv[1], "get-devices") == 0) {
/* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "GetDevices",
- NULL,
- G_VARIANT_TYPE ("(ao)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ array = cd_client_get_devices_sync (client, NULL, &error);
+ if (array == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to get devices:"), error->message);
g_error_free (error);
goto out;
}
-
- /* print each device */
- response_child = g_variant_get_child_value (response, 0);
- len = g_variant_iter_init (&iter, response_child);
- for (i=0; i < len; i++) {
- g_variant_get_child (response_child, i,
- "o", &object_path_tmp);
- cd_util_show_device (object_path_tmp);
- g_free (object_path_tmp);
+ for (i=0; i < array->len; i++) {
+ device_tmp = g_ptr_array_index (array, i);
+ cd_util_show_device (device_tmp);
}
} else if (g_strcmp0 (argv[1], "get-devices-by-kind") == 0) {
@@ -286,59 +164,34 @@ main (int argc, char *argv[])
}
/* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "GetDevicesByKind",
- g_variant_new ("(s)", argv[2]),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ array = cd_client_get_devices_by_kind_sync (client,
+ cd_device_kind_from_string (argv[2]),
+ NULL,
+ &error);
+ if (array == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to get devices:"), error->message);
g_error_free (error);
goto out;
}
-
- /* print each device */
- response_child = g_variant_get_child_value (response, 0);
- len = g_variant_iter_init (&iter, response_child);
- for (i=0; i < len; i++) {
- g_variant_get_child (response_child, i,
- "o", &object_path_tmp);
- cd_util_show_device (object_path_tmp);
- g_free (object_path_tmp);
+ for (i=0; i < array->len; i++) {
+ device_tmp = g_ptr_array_index (array, i);
+ cd_util_show_device (device_tmp);
}
} else if (g_strcmp0 (argv[1], "get-profiles") == 0) {
/* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "GetProfiles",
- NULL,
- G_VARIANT_TYPE ("(ao)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ array = cd_client_get_profiles_sync (client, NULL, &error);
+ if (array == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to get profiles:"), error->message);
g_error_free (error);
goto out;
}
-
- /* print each device */
- response_child = g_variant_get_child_value (response, 0);
- len = g_variant_iter_init (&iter, response_child);
- for (i=0; i < len; i++) {
- g_variant_get_child (response_child, i,
- "o", &object_path_tmp);
- cd_util_show_profile (object_path_tmp);
- g_free (object_path_tmp);
+ for (i=0; i < array->len; i++) {
+ profile_tmp = g_ptr_array_index (array, i);
+ cd_util_show_profile (profile_tmp);
}
} else if (g_strcmp0 (argv[1], "create-device") == 0) {
@@ -350,28 +203,16 @@ main (int argc, char *argv[])
/* execute sync method */
mask = cd_util_mask_from_string (argv[3]);
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "CreateDevice",
- g_variant_new ("(su)",
- argv[2],
- mask),
- G_VARIANT_TYPE ("(o)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ device = cd_client_create_device_sync (client, argv[2],
+ mask, NULL, &error);
+ if (device == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create device:"), error->message);
g_error_free (error);
goto out;
}
-
- /* print the device */
- response_child = g_variant_get_child_value (response, 0);
- object_path = g_variant_get_string (response_child, NULL);
- g_print ("Created device %s\n", object_path);
+ g_print ("Created device:\n");
+ cd_util_show_device (device);
} else if (g_strcmp0 (argv[1], "find-device") == 0) {
@@ -381,27 +222,15 @@ main (int argc, char *argv[])
}
/* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "FindDeviceById",
- g_variant_new ("(s)",
- argv[2]),
- G_VARIANT_TYPE ("(o)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ device = cd_client_find_device_sync (client, argv[2],
+ NULL, &error);
+ if (device == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to find device:"), error->message);
g_error_free (error);
goto out;
}
-
- /* print the device */
- response_child = g_variant_get_child_value (response, 0);
- object_path = g_variant_get_string (response_child, NULL);
- g_print ("Got device %s\n", object_path);
+ cd_util_show_device (device);
} else if (g_strcmp0 (argv[1], "find-profile") == 0) {
@@ -411,26 +240,15 @@ main (int argc, char *argv[])
}
/* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "FindProfileById",
- g_variant_new ("(s)", argv[2]),
- G_VARIANT_TYPE ("(o)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ profile = cd_client_find_profile_sync (client, argv[2],
+ NULL, &error);
+ if (profile == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to find profile:"), error->message);
g_error_free (error);
goto out;
}
-
- /* print the device */
- response_child = g_variant_get_child_value (response, 0);
- object_path = g_variant_get_string (response_child, NULL);
- g_print ("Got profile %s\n", object_path);
+ cd_util_show_profile (profile);
} else if (g_strcmp0 (argv[1], "create-profile") == 0) {
@@ -441,28 +259,97 @@ main (int argc, char *argv[])
/* execute sync method */
mask = cd_util_mask_from_string (argv[3]);
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "CreateProfile",
- g_variant_new ("(su)",
- argv[2],
- mask),
- G_VARIANT_TYPE ("(o)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ profile = cd_client_create_profile_sync (client, argv[2],
+ mask, NULL, &error);
+ if (profile == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create profile:"), error->message);
g_error_free (error);
goto out;
}
+ g_print ("Created profile:\n");
+ cd_util_show_profile (profile);
+
+ } else if (g_strcmp0 (argv[1], "device-add-profile") == 0) {
- /* print the device */
- response_child = g_variant_get_child_value (response, 0);
- object_path = g_variant_get_string (response_child, NULL);
- g_print ("Created profile %s\n", object_path);
+ if (argc < 3) {
+ g_print ("Not enough arguments\n");
+ goto out;
+ }
+
+ device = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ profile = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile,
+ argv[3],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create profile:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_device_add_profile_sync (device, profile, NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to add profile to device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ } else if (g_strcmp0 (argv[1], "device-make-profile-default") == 0) {
+
+ if (argc < 3) {
+ g_print ("Not enough arguments\n");
+ goto out;
+ }
+
+ device = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ profile = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile,
+ argv[3],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create profile:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_device_make_profile_default_sync (device, profile,
+ NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to add profile to device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
} else if (g_strcmp0 (argv[1], "delete-device") == 0) {
@@ -471,127 +358,204 @@ main (int argc, char *argv[])
goto out;
}
- /* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- COLORD_DBUS_PATH,
- COLORD_DBUS_INTERFACE,
- "DeleteDevice",
- g_variant_new ("(s)", argv[2]),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ device = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_client_delete_device_sync (client, device,
+ NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to delete device:"),
+ error->message);
g_error_free (error);
goto out;
}
- } else if (g_strcmp0 (argv[1], "device-add-profile") == 0) {
+ } else if (g_strcmp0 (argv[1], "delete-profile") == 0) {
+
+ if (argc < 2) {
+ g_print ("Not enough arguments\n");
+ goto out;
+ }
+
+ profile = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create profile:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_client_delete_profile_sync (client, profile,
+ NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to delete profile:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ } else if (g_strcmp0 (argv[1], "profile-set-qualifier") == 0) {
if (argc < 3) {
g_print ("Not enough arguments\n");
goto out;
}
- /* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- argv[2],
- COLORD_DBUS_INTERFACE_DEVICE,
- "AddProfile",
- g_variant_new ("(o)", argv[3]),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ profile = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create profile:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_profile_set_qualifier_sync (profile, argv[3],
+ NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to set property on profile:"),
+ error->message);
g_error_free (error);
goto out;
}
- } else if (g_strcmp0 (argv[1], "profile-set-property") == 0) {
+ } else if (g_strcmp0 (argv[1], "profile-set-filename") == 0) {
- if (argc < 5) {
+ if (argc < 3) {
g_print ("Not enough arguments\n");
goto out;
}
- /* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- argv[2],
- COLORD_DBUS_INTERFACE_PROFILE,
- "SetProperty",
- g_variant_new ("(ss)",
- argv[3],
- argv[4]),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ profile = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create profile:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_profile_set_filename_sync (profile, argv[3],
+ NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to set property on profile:"),
+ error->message);
g_error_free (error);
goto out;
}
- } else if (g_strcmp0 (argv[1], "device-set-property") == 0) {
+ } else if (g_strcmp0 (argv[1], "device-set-model") == 0) {
- if (argc < 5) {
+ if (argc < 3) {
g_print ("Not enough arguments\n");
goto out;
}
- /* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- argv[2],
- COLORD_DBUS_INTERFACE_DEVICE,
- "SetProperty",
- g_variant_new ("(ss)",
- argv[3],
- argv[4]),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ device = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_device_set_model_sync (device, argv[3],
+ NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to set property on device:"),
+ error->message);
g_error_free (error);
goto out;
}
- } else if (g_strcmp0 (argv[1], "device-get-profile-for-qualifier") == 0) {
+ } else if (g_strcmp0 (argv[1], "device-set-kind") == 0) {
- if (argc < 4) {
+ if (argc < 3) {
g_print ("Not enough arguments\n");
goto out;
}
- /* execute sync method */
- response = g_dbus_connection_call_sync (connection,
- COLORD_DBUS_SERVICE,
- argv[2],
- COLORD_DBUS_INTERFACE_DEVICE,
- "GetProfileForQualifier",
- g_variant_new ("(s)", argv[3]),
- G_VARIANT_TYPE ("(o)"),
- G_DBUS_CALL_FLAGS_NONE,
- -1, NULL, &error);
- if (response == NULL) {
- /* TRANSLATORS: the DBus method failed */
- g_print ("%s %s\n", _("The request failed:"), error->message);
+ device = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = cd_device_set_kind_sync (device, cd_device_kind_from_string (argv[3]),
+ NULL, &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to set property on device:"),
+ error->message);
g_error_free (error);
goto out;
}
- /* print the device */
- response_child = g_variant_get_child_value (response, 0);
- object_path = g_variant_get_string (response_child, NULL);
- cd_util_show_profile (object_path);
+ } else if (g_strcmp0 (argv[1], "device-get-profile-for-qualifier") == 0) {
+
+ if (argc < 3) {
+ g_print ("Not enough arguments\n");
+ goto out;
+ }
+
+ device = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device,
+ argv[2],
+ NULL,
+ &error);
+ if (!ret) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to create device:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ profile = cd_device_get_profile_for_qualifier_sync (device,
+ argv[3],
+ NULL,
+ &error);
+ if (profile == NULL) {
+ /* TRANSLATORS: no colord available */
+ g_print ("%s %s\n", _("Failed to get a profile for the qualifier:"),
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ cd_util_show_profile (profile);
} else {
@@ -602,8 +566,14 @@ main (int argc, char *argv[])
/* success */
retval = 0;
out:
- if (response != NULL)
- g_variant_unref (response);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (client != NULL)
+ g_object_unref (client);
+ if (device != NULL)
+ g_object_unref (device);
+ if (profile != NULL)
+ g_object_unref (profile);
return retval;
}
diff --git a/client/test.sh b/client/test.sh
deleted file mode 100755
index 5574045..0000000
--- a/client/test.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-./colormgr create-device dave normal
-./colormgr get-devices
-./colormgr create-profile norman normal
-./colormgr create-profile victorian temp
-./colormgr get-profiles
-./colormgr device-add-profile /org/freedesktop/ColorManager/dave /org/freedesktop/ColorManager/norman
-./colormgr find-device dave
-./colormgr find-profile norman
-./colormgr profile-set-property /org/freedesktop/ColorManager/norman Filename /home/hughsie/Code/colord/data/test.icc
-./colormgr profile-set-property /org/freedesktop/ColorManager/norman Qualifier "RGB.Plain.300dpi"
-./colormgr get-devices
-./colormgr device-get-profile-for-qualifier /org/freedesktop/ColorManager/dave "RGB.*.300dpi"
-./colormgr delete-device dave
-./colormgr get-profiles
diff --git a/configure.ac b/configure.ac
index 4ed3b76..573a10a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,12 +1,42 @@
# Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
AC_PREREQ(2.63)
-AC_INIT([colord],0.1.0,[http://hughsie.com])
+m4_define([cd_major_version], [0])
+m4_define([cd_minor_version], [1])
+m4_define([cd_micro_version], [0])
+m4_define([cd_version],
+ [cd_major_version.cd_minor_version.cd_micro_version])
+
+AC_INIT([colord],[cd_version],[http://hughsie.com])
AC_CONFIG_SRCDIR(src)
AM_INIT_AUTOMAKE([1.9 tar-ustar dist-bzip2])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
+# use this in cd-version.h
+CD_MAJOR_VERSION=cd_major_version
+CD_MINOR_VERSION=cd_minor_version
+CD_MICRO_VERSION=cd_micro_version
+AC_SUBST(VERSION)
+AC_SUBST(CD_MAJOR_VERSION)
+AC_SUBST(CD_MINOR_VERSION)
+AC_SUBST(CD_MICRO_VERSION)
+
+# libtool versioning - this applies to libcolord
+#
+# See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details
+#
+# increment;
+# CURRENT If the API or ABI interface has changed (reset REVISION to 0)
+# REVISION If the API and ABI remains the same, but bugs are fixed.
+# AGE Don't use.
+LT_CURRENT=1
+LT_REVISION=0
+LT_AGE=0
+AC_SUBST(LT_CURRENT)
+AC_SUBST(LT_REVISION)
+AC_SUBST(LT_AGE)
+
# enable nice build output on automake1.11
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
@@ -118,10 +148,14 @@ AC_CONFIG_FILES([
Makefile
man/Makefile
data/Makefile
+data/tests/Makefile
policy/Makefile
po/Makefile.in
src/Makefile
client/Makefile
+libcolord/cd-version.h
+libcolord/colord.pc
+libcolord/Makefile
])
AC_OUTPUT
diff --git a/contrib/colord.spec.in b/contrib/colord.spec.in
index a2f81e4..03b351b 100644
--- a/contrib/colord.spec.in
+++ b/contrib/colord.spec.in
@@ -19,6 +19,13 @@ BuildRequires: polkit-devel
colord is a low level system activated daemon that maps color devices
to color profiles in the system context.
+%package devel
+Summary: Development package for %{name}
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Files for development with %{name}.
+
%prep
%setup -q
@@ -33,8 +40,16 @@ make %{?_smp_mflags}
%install
make install DESTDIR=$RPM_BUILD_ROOT
+# Remove static libs and libtool archives.
+find %{buildroot} -name '*.la' -exec rm -f {} ';'
+find %{buildroot} -name '*.a' -exec rm -f {} ';'
+
%find_lang %{name}
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
%files -f %{name}.lang
%defattr(-,root,root,-)
%doc README AUTHORS NEWS COPYING
@@ -45,6 +60,13 @@ make install DESTDIR=$RPM_BUILD_ROOT
%{_datadir}/polkit-1/actions/org.freedesktop.color.policy
%{_datadir}/dbus-1/system-services/org.freedesktop.ColorManager.service
%{_datadir}/man/man1/colormgr.1.gz
+%{_libdir}/libcolord.so.*
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/libcolord/*.h
+%{_libdir}/libcolord.so
+%{_libdir}/pkgconfig/colord.pc
%changelog
* #LONGDATE# Richard Hughes <richard@hughsie.com> #VERSION#-0.#BUILD##ALPHATAG#
diff --git a/data/Makefile.am b/data/Makefile.am
index 970cb38..1c8965b 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,3 +1,7 @@
+
+SUBDIRS = \
+ tests
+
dbusdir = $(sysconfdir)/dbus-1/system.d
dist_dbus_DATA = org.freedesktop.ColorManager.conf
diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
new file mode 100644
index 0000000..9096c39
--- /dev/null
+++ b/data/tests/Makefile.am
@@ -0,0 +1,2 @@
+EXTRA_DIST = \
+ ibm-t61.icc
diff --git a/data/tests/ibm-t61.icc b/data/tests/ibm-t61.icc
new file mode 100644
index 0000000..93c39f8
--- /dev/null
+++ b/data/tests/ibm-t61.icc
Binary files differ
diff --git a/doc/create.sh b/doc/create.sh
index e8e7e9c..570ba88 100755
--- a/doc/create.sh
+++ b/doc/create.sh
@@ -4,5 +4,5 @@
../client/colormgr device-add-profile /org/freedesktop/ColorManager/t61xrandr /org/freedesktop/ColorManager/t61xrandr_default
../client/colormgr device-set-property /org/freedesktop/ColorManager/t61xrandr Model "Cray 3000"
../client/colormgr device-set-property /org/freedesktop/ColorManager/t61xrandr Kind "printer"
-../client/colormgr profile-set-property /org/freedesktop/ColorManager/t61xrandr_default Filename /home/hughsie/.color/icc/ibm-t61.icc
-../client/colormgr profile-set-property /org/freedesktop/ColorManager/t61xrandr_default Qualifier "RGB.Plain.300dpi"
+../client/colormgr profile-set-filename /org/freedesktop/ColorManager/t61xrandr_default /home/hughsie/.color/icc/ibm-t61.icc
+../client/colormgr profile-set-qualifier /org/freedesktop/ColorManager/t61xrandr_default "RGB.Plain.300dpi"
diff --git a/libcolord/.gitignore b/libcolord/.gitignore
new file mode 100644
index 0000000..a20b776
--- /dev/null
+++ b/libcolord/.gitignore
@@ -0,0 +1,8 @@
+.deps
+.libs
+*.o
+*.la
+*.lo
+*.pc
+cd-version.h
+cd-self-test
diff --git a/libcolord/Makefile.am b/libcolord/Makefile.am
new file mode 100644
index 0000000..925fd21
--- /dev/null
+++ b/libcolord/Makefile.am
@@ -0,0 +1,64 @@
+INCLUDES = \
+ $(GLIB_CFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/libcolord \
+ -DCD_COMPILATION \
+ -DG_LOG_DOMAIN=\"libcolord\" \
+ -DTESTDATADIR=\""$(top_srcdir)/data/tests"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\"
+
+lib_LTLIBRARIES = \
+ libcolord.la
+
+libcolord_includedir = $(includedir)/libcolord
+libcolord_include_HEADERS = \
+ colord.h \
+ cd-version.h \
+ cd-enum.h \
+ cd-device.h \
+ cd-profile.h \
+ cd-client.h
+
+libcolord_la_SOURCES = \
+ cd-enum.c \
+ cd-client.c \
+ cd-profile.c \
+ cd-device.c
+
+libcolord_la_LIBADD = \
+ $(GLIB_LIBS)
+
+libcolord_la_LDFLAGS = \
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -export-dynamic \
+ -no-undefined \
+ -export-symbols-regex '^cd_.*'
+
+libcolord_la_CFLAGS = \
+ $(WARNINGFLAGS_C)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = colord.pc
+
+check_PROGRAMS = \
+ cd-self-test
+
+cd_self_test_SOURCES = \
+ cd-self-test.c
+
+cd_self_test_LDADD = \
+ $(GLIB_LIBS) \
+ $(lib_LTLIBRARIES)
+
+cd_self_test_CFLAGS = $(WARNINGFLAGS_C)
+
+TESTS = cd-self-test
+
+EXTRA_DIST = \
+ cd-version.h.in \
+ colord.pc.in
+
+CLEANFILES = $(BUILT_SOURCES)
+
+clean-local:
+ rm -f *~
diff --git a/libcolord/cd-client.c b/libcolord/cd-client.c
new file mode 100644
index 0000000..c92645b
--- /dev/null
+++ b/libcolord/cd-client.c
@@ -0,0 +1,1011 @@
+/* -*- 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.
+ */
+
+/**
+ * SECTION:cd-client
+ * @short_description: Main client object for accessing the colord daemon
+ *
+ * A helper GObject to use for accessing colord information, and to be notified
+ * when it is changed.
+ *
+ * See also: #CdDevice
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "cd-client.h"
+#include "cd-device.h"
+
+static void cd_client_class_init (CdClientClass *klass);
+static void cd_client_init (CdClient *client);
+static void cd_client_finalize (GObject *object);
+
+#define CD_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CD_TYPE_CLIENT, CdClientPrivate))
+
+/**
+ * CdClientPrivate:
+ *
+ * Private #CdClient data
+ **/
+struct _CdClientPrivate
+{
+ GDBusProxy *proxy;
+ gchar *daemon_version;
+};
+
+enum {
+ CD_CLIENT_CHANGED,
+ CD_CLIENT_DEVICE_ADDED,
+ CD_CLIENT_DEVICE_REMOVED,
+ CD_CLIENT_LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+ PROP_DAEMON_VERSION,
+ PROP_LAST
+};
+
+static guint signals [CD_CLIENT_LAST_SIGNAL] = { 0 };
+static gpointer cd_client_object = NULL;
+
+G_DEFINE_TYPE (CdClient, cd_client, G_TYPE_OBJECT)
+
+/**
+ * cd_client_error_quark:
+ *
+ * Return value: An error quark.
+ *
+ * Since: 0.1.0
+ **/
+GQuark
+cd_client_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("cd_client_error");
+ return quark;
+}
+
+/**
+ * cd_client_get_device_array_from_variant:
+ **/
+static GPtrArray *
+cd_client_get_device_array_from_variant (GVariant *result,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdDevice *device;
+ gboolean ret;
+ gchar *object_path_tmp;
+ GError *error_local = NULL;
+ GPtrArray *array = NULL;
+ GPtrArray *array_tmp = NULL;
+ guint i;
+ guint len;
+ GVariant *child = NULL;
+ GVariantIter iter;
+
+ /* add each device */
+ array_tmp = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ child = g_variant_get_child_value (result, 0);
+ len = g_variant_iter_init (&iter, child);
+ for (i=0; i < len; i++) {
+ g_variant_get_child (child, i,
+ "o", &object_path_tmp);
+ g_debug ("%s", object_path_tmp);
+
+ /* create device and add to the array */
+ device = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device,
+ object_path_tmp,
+ cancellable,
+ &error_local);
+ if (!ret) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to set device object path: %s",
+ error_local->message);
+ g_error_free (error_local);
+ g_object_unref (device);
+ goto out;
+ }
+ g_ptr_array_add (array_tmp, device);
+ g_free (object_path_tmp);
+ }
+
+ /* success */
+ array = g_ptr_array_ref (array_tmp);
+out:
+ if (child != NULL)
+ g_variant_unref (child);
+ if (array_tmp != NULL)
+ g_ptr_array_unref (array_tmp);
+ return array;
+}
+
+/**
+ * cd_client_get_devices_sync:
+ * @client: a #CdClient instance.
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Get an array of the device objects.
+ *
+ * Return value: (transfer full): an array of #CdDevice objects,
+ * free with g_ptr_array_unref()
+ *
+ * Since: 0.1.0
+ **/
+GPtrArray *
+cd_client_get_devices_sync (CdClient *client,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *error_local = NULL;
+ GPtrArray *array = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (client->priv->proxy != NULL, NULL);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "GetDevices",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to GetDevices: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* convert to array of CdDevice's */
+ array = cd_client_get_device_array_from_variant (result,
+ cancellable,
+ error);
+ if (array == NULL)
+ goto out;
+out:
+ if (result != NULL)
+ g_variant_unref (result);
+ return array;
+}
+
+/**
+ * cd_client_create_device_sync:
+ * @client: a #CdClient instance.
+ * @id: identifier for the device
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Creates a color device.
+ *
+ * Return value: A #CdDevice object, or %NULL for error
+ *
+ * Since: 0.1.0
+ **/
+CdDevice *
+cd_client_create_device_sync (CdClient *client,
+ const gchar *id,
+ guint options,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdDevice *device = NULL;
+ CdDevice *device_tmp = NULL;
+ gboolean ret;
+ gchar *object_path = NULL;
+ GError *error_local = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (client->priv->proxy != NULL, NULL);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "CreateDevice",
+ g_variant_new ("(su)",
+ id,
+ options),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to CreateDevice: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* create thick CdDevice object */
+ g_variant_get (result, "(o)",
+ &object_path);
+ device_tmp = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device_tmp,
+ object_path,
+ cancellable,
+ error);
+ if (!ret)
+ goto out;
+
+ /* success */
+ device = g_object_ref (device_tmp);
+out:
+ g_free (object_path);
+ if (device_tmp != NULL)
+ g_object_unref (device_tmp);
+ if (result != NULL)
+ g_variant_unref (result);
+ return device;
+}
+
+/**
+ * cd_client_create_profile_sync:
+ * @client: a #CdClient instance.
+ * @id: identifier for the device
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Creates a color profile.
+ *
+ * Return value: A #CdProfile object, or %NULL for error
+ *
+ * Since: 0.1.0
+ **/
+CdProfile *
+cd_client_create_profile_sync (CdClient *client,
+ const gchar *id,
+ guint options,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdProfile *profile = NULL;
+ CdProfile *profile_tmp = NULL;
+ gboolean ret;
+ gchar *object_path = NULL;
+ GError *error_local = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (client->priv->proxy != NULL, NULL);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "CreateProfile",
+ g_variant_new ("(su)",
+ id,
+ options),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to CreateProfile: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* create thick CdDevice object */
+ g_variant_get (result, "(o)",
+ &object_path);
+ profile_tmp = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile_tmp,
+ object_path,
+ cancellable,
+ error);
+ if (!ret)
+ goto out;
+
+ /* success */
+ profile = g_object_ref (profile_tmp);
+out:
+ g_free (object_path);
+ if (profile_tmp != NULL)
+ g_object_unref (profile_tmp);
+ if (result != NULL)
+ g_variant_unref (result);
+ return profile;
+}
+
+/**
+ * cd_client_delete_device_sync:
+ * @client: a #CdClient instance.
+ * @device: a #CdDevice instance.
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Deletes a color device.
+ *
+ * Return value: %TRUE is the device was deleted
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_client_delete_device_sync (CdClient *client,
+ CdDevice *device,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
+ g_return_val_if_fail (CD_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (client->priv->proxy != NULL, FALSE);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "DeleteDevice",
+ g_variant_new ("(s)",
+ cd_device_get_object_path (device)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to DeleteDevice: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+out:
+ if (result != NULL)
+ g_variant_unref (result);
+ return ret;
+}
+
+/**
+ * cd_client_delete_profile_sync:
+ * @client: a #CdClient instance.
+ * @profile: a #CdProfile instance.
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Deletes a color profile.
+ *
+ * Return value: %TRUE is the profile was deleted
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_client_delete_profile_sync (CdClient *client,
+ CdProfile *profile,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
+ g_return_val_if_fail (CD_IS_PROFILE (profile), FALSE);
+ g_return_val_if_fail (client->priv->proxy != NULL, FALSE);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "DeleteProfile",
+ g_variant_new ("(s)",
+ cd_profile_get_object_path (profile)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to DeleteProfile: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+out:
+ if (result != NULL)
+ g_variant_unref (result);
+ return ret;
+}
+
+/**
+ * cd_client_find_device_sync:
+ * @client: a #CdClient instance.
+ * @id: identifier for the device
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Finds a color device.
+ *
+ * Return value: A #CdDevice object, or %NULL for error
+ *
+ * Since: 0.1.0
+ **/
+CdDevice *
+cd_client_find_device_sync (CdClient *client,
+ const gchar *id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdDevice *device = NULL;
+ CdDevice *device_tmp = NULL;
+ gboolean ret;
+ gchar *object_path = NULL;
+ GError *error_local = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (client->priv->proxy != NULL, NULL);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "FindDeviceById",
+ g_variant_new ("(s)", id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to FindDeviceById: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* create GObject CdDevice object */
+ g_variant_get (result, "(o)",
+ &object_path);
+ device_tmp = cd_device_new ();
+ ret = cd_device_set_object_path_sync (device_tmp,
+ object_path,
+ cancellable,
+ error);
+ if (!ret)
+ goto out;
+
+ /* success */
+ device = g_object_ref (device_tmp);
+out:
+ g_free (object_path);
+ if (device_tmp != NULL)
+ g_object_unref (device_tmp);
+ if (result != NULL)
+ g_variant_unref (result);
+ return device;
+}
+
+/**
+ * cd_client_find_profile_sync:
+ * @client: a #CdClient instance.
+ * @id: identifier for the device
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Finds a color profile.
+ *
+ * Return value: A #CdProfile object, or %NULL for error
+ *
+ * Since: 0.1.0
+ **/
+CdProfile *
+cd_client_find_profile_sync (CdClient *client,
+ const gchar *id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdProfile *profile = NULL;
+ CdProfile *profile_tmp = NULL;
+ gboolean ret;
+ gchar *object_path = NULL;
+ GError *error_local = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (client->priv->proxy != NULL, NULL);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "FindProfileById",
+ g_variant_new ("(s)", id),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to FindProfileById: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* create GObject CdDevice object */
+ g_variant_get (result, "(o)",
+ &object_path);
+ profile_tmp = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile_tmp,
+ object_path,
+ cancellable,
+ error);
+ if (!ret)
+ goto out;
+
+ /* success */
+ profile = g_object_ref (profile_tmp);
+out:
+ g_free (object_path);
+ if (profile_tmp != NULL)
+ g_object_unref (profile_tmp);
+ if (result != NULL)
+ g_variant_unref (result);
+ return profile;
+}
+
+/**
+ * cd_client_get_devices_by_kind_sync:
+ * @client: a #CdClient instance.
+ * @kind: a #CdDeviceKind, e.g. %CD_DEVICE_KIND_DISPLAY
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Get an array of the device objects of a specified kind.
+ *
+ * Return value: (transfer full): an array of #CdDevice objects,
+ * free with g_ptr_array_unref()
+ *
+ * Since: 0.1.0
+ **/
+GPtrArray *
+cd_client_get_devices_by_kind_sync (CdClient *client,
+ CdDeviceKind kind,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *error_local = NULL;
+ GPtrArray *array = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (client->priv->proxy != NULL, NULL);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "GetDevicesByKind",
+ g_variant_new ("(s)",
+ cd_device_kind_to_string (kind)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to GetDevicesByKind: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* convert to array of CdDevice's */
+ array = cd_client_get_device_array_from_variant (result,
+ cancellable,
+ error);
+ if (array == NULL)
+ goto out;
+out:
+ if (result != NULL)
+ g_variant_unref (result);
+ return array;
+}
+
+/**
+ * cd_client_get_profile_array_from_variant:
+ **/
+static GPtrArray *
+cd_client_get_profile_array_from_variant (GVariant *result,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdProfile *profile;
+ gboolean ret;
+ gchar *object_path_tmp;
+ GError *error_local = NULL;
+ GPtrArray *array = NULL;
+ GPtrArray *array_tmp = NULL;
+ guint i;
+ guint len;
+ GVariant *child = NULL;
+ GVariantIter iter;
+
+ /* add each profile */
+ array_tmp = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ child = g_variant_get_child_value (result, 0);
+ len = g_variant_iter_init (&iter, child);
+ for (i=0; i < len; i++) {
+ g_variant_get_child (child, i,
+ "o", &object_path_tmp);
+ g_debug ("%s", object_path_tmp);
+
+ /* create profile and add to the array */
+ profile = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile,
+ object_path_tmp,
+ cancellable,
+ &error_local);
+ if (!ret) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to set profile object path: %s",
+ error_local->message);
+ g_error_free (error_local);
+ g_object_unref (profile);
+ goto out;
+ }
+ g_ptr_array_add (array_tmp, profile);
+ g_free (object_path_tmp);
+ }
+
+ /* success */
+ array = g_ptr_array_ref (array_tmp);
+out:
+ if (child != NULL)
+ g_variant_unref (child);
+ if (array_tmp != NULL)
+ g_ptr_array_unref (array_tmp);
+ return array;
+}
+
+/**
+ * cd_client_get_profiles_sync:
+ * @client: a #CdClient instance.
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Get an array of the profile objects.
+ *
+ * Return value: (transfer full): an array of #CdProfile objects,
+ * free with g_ptr_array_unref()
+ *
+ * Since: 0.1.0
+ **/
+GPtrArray *
+cd_client_get_profiles_sync (CdClient *client,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *error_local = NULL;
+ GPtrArray *array = NULL;
+ GVariant *result;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (client->priv->proxy != NULL, NULL);
+
+ result = g_dbus_proxy_call_sync (client->priv->proxy,
+ "GetProfiles",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ &error_local);
+ if (result == NULL) {
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to GetProfiles: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* convert to array of CdProfile's */
+ array = cd_client_get_profile_array_from_variant (result,
+ cancellable,
+ error);
+ if (array == NULL)
+ goto out;
+out:
+ if (result != NULL)
+ g_variant_unref (result);
+ return array;
+}
+
+/**
+ * cd_client_dbus_signal_cb:
+ **/
+static void
+cd_client_dbus_signal_cb (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ CdClient *client)
+{
+ gchar *object_path_tmp = NULL;
+
+ if (g_strcmp0 (signal_name, "Changed") == 0) {
+ g_warning ("changed");
+ } else if (g_strcmp0 (signal_name, "DeviceAdded") == 0) {
+ g_variant_get (parameters, "(o)", &object_path_tmp);
+ //EMIT
+ } else if (g_strcmp0 (signal_name, "DeviceRemoved") == 0) {
+ g_variant_get (parameters, "(o)", &object_path_tmp);
+ //EMIT
+ } else if (g_strcmp0 (signal_name, "ProfileAdded") == 0) {
+ g_variant_get (parameters, "(o)", &object_path_tmp);
+ //EMIT
+ } else if (g_strcmp0 (signal_name, "ProfileRemoved") == 0) {
+ g_variant_get (parameters, "(o)", &object_path_tmp);
+ //EMIT
+ } else {
+ g_warning ("unhandled signal '%s'", signal_name);
+ }
+ g_free (object_path_tmp);
+}
+
+/**
+ * cd_client_connect_sync:
+ * @client: a #CdClient instance.
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Connects to the colord daemon.
+ *
+ * Return value: %TRUE for success, else %FALSE.
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_client_connect_sync (CdClient *client, GCancellable *cancellable, GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *daemon_version = NULL;
+
+ g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
+ g_return_val_if_fail (client->priv->proxy == NULL, FALSE);
+
+ /* connect to the daemon */
+ client->priv->proxy =
+ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ COLORD_DBUS_SERVICE,
+ COLORD_DBUS_PATH,
+ COLORD_DBUS_INTERFACE,
+ cancellable,
+ &error_local);
+ if (client->priv->proxy == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_CLIENT_ERROR,
+ CD_CLIENT_ERROR_FAILED,
+ "Failed to connect to colord: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* get daemon version */
+ daemon_version = g_dbus_proxy_get_cached_property (client->priv->proxy,
+ "Title");
+ if (daemon_version != NULL)
+ client->priv->daemon_version = g_variant_dup_string (daemon_version, NULL);
+
+ /* get signals from DBus */
+ g_signal_connect (client->priv->proxy,
+ "g-signal",
+ G_CALLBACK (cd_client_dbus_signal_cb),
+ client);
+
+ /* success */
+ g_debug ("Connected to colord daemon version %s",
+ client->priv->daemon_version);
+out:
+ if (daemon_version != NULL)
+ g_variant_unref (daemon_version);
+ return ret;
+}
+
+/**
+ * cd_client_get_daemon_version:
+ * @client: a #CdClient instance.
+ *
+ * Get colord daemon version.
+ *
+ * Return value: string containing the daemon version, e.g. 0.1.0
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+cd_client_get_daemon_version (CdClient *client)
+{
+ g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
+ return client->priv->daemon_version;
+}
+
+/*
+ * cd_client_get_property:
+ */
+static void
+cd_client_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ CdClient *client;
+ client = CD_CLIENT (object);
+
+ switch (prop_id) {
+ case PROP_DAEMON_VERSION:
+ g_value_set_string (value, client->priv->daemon_version);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/*
+ * cd_client_class_init:
+ */
+static void
+cd_client_class_init (CdClientClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = cd_client_get_property;
+ object_class->finalize = cd_client_finalize;
+
+ /**
+ * CdClient:daemon-version:
+ *
+ * The daemon version.
+ *
+ * Since: 0.1.0
+ */
+ g_object_class_install_property (object_class,
+ PROP_DAEMON_VERSION,
+ g_param_spec_string ("daemon-version",
+ "Daemon version",
+ NULL,
+ NULL,
+ G_PARAM_READABLE));
+
+ /**
+ * CdClient::device-added:
+ * @client: the #CdClient instance that emitted the signal
+ * @device: the #CdDevice that was added.
+ *
+ * The ::device-added signal is emitted when a device is added.
+ *
+ * Since: 0.1.0
+ **/
+ signals [CD_CLIENT_DEVICE_ADDED] =
+ g_signal_new ("device-added",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CdClientClass, device_added),
+ NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, CD_TYPE_DEVICE);
+
+ /**
+ * CdClient::device-removed:
+ * @client: the #CdClient instance that emitted the signal
+ * @device: the #CdDevice that was removed.
+ *
+ * The ::device-added signal is emitted when a device is removed.
+ *
+ * Since: 0.1.0
+ **/
+ signals [CD_CLIENT_DEVICE_REMOVED] =
+ g_signal_new ("device-removed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CdClientClass, device_removed),
+ NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, CD_TYPE_DEVICE);
+
+ /**
+ * CdClient::changed:
+ * @client: the #CdDevice instance that emitted the signal
+ *
+ * The ::changed signal is emitted when properties may have changed.
+ *
+ * Since: 0.1.0
+ **/
+ signals [CD_CLIENT_CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CdClientClass, changed),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private (klass, sizeof (CdClientPrivate));
+}
+
+/*
+ * cd_client_init:
+ */
+static void
+cd_client_init (CdClient *client)
+{
+ client->priv = CD_CLIENT_GET_PRIVATE (client);
+}
+
+/*
+ * cd_client_finalize:
+ */
+static void
+cd_client_finalize (GObject *object)
+{
+ CdClient *client = CD_CLIENT (object);
+
+ g_return_if_fail (CD_IS_CLIENT (object));
+
+ g_free (client->priv->daemon_version);
+ if (client->priv->proxy != NULL)
+ g_object_unref (client->priv->proxy);
+
+ G_OBJECT_CLASS (cd_client_parent_class)->finalize (object);
+}
+
+/**
+ * cd_client_new:
+ *
+ * Creates a new #CdClient object.
+ *
+ * Return value: a new CdClient object.
+ *
+ * Since: 0.1.0
+ **/
+CdClient *
+cd_client_new (void)
+{
+ if (cd_client_object != NULL) {
+ g_object_ref (cd_client_object);
+ } else {
+ cd_client_object = g_object_new (CD_TYPE_CLIENT, NULL);
+ g_object_add_weak_pointer (cd_client_object, &cd_client_object);
+ }
+ return CD_CLIENT (cd_client_object);
+}
+
diff --git a/libcolord/cd-client.h b/libcolord/cd-client.h
new file mode 100644
index 0000000..a2ea5d6
--- /dev/null
+++ b/libcolord/cd-client.h
@@ -0,0 +1,134 @@
+/* -*- 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.
+ */
+
+#if !defined (__COLORD_H_INSIDE__) && !defined (CD_COMPILATION)
+#error "Only <colord.h> can be included directly."
+#endif
+
+#ifndef __CD_CLIENT_H
+#define __CD_CLIENT_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <libcolord/cd-device.h>
+#include <libcolord/cd-profile.h>
+
+G_BEGIN_DECLS
+
+#define CD_TYPE_CLIENT (cd_client_get_type ())
+#define CD_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CD_TYPE_CLIENT, CdClient))
+#define CD_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CD_TYPE_CLIENT, CdClientClass))
+#define CD_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CD_TYPE_CLIENT))
+#define CD_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CD_TYPE_CLIENT))
+#define CD_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CD_TYPE_CLIENT, CdClientClass))
+#define CD_CLIENT_ERROR (cd_client_error_quark ())
+#define CD_CLIENT_TYPE_ERROR (cd_client_error_get_type ())
+
+typedef struct _CdClientPrivate CdClientPrivate;
+
+typedef struct
+{
+ GObject parent;
+ CdClientPrivate *priv;
+} CdClient;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (*device_added) (CdClient *client,
+ CdDevice *device);
+ void (*device_removed) (CdClient *client,
+ CdDevice *device);
+ void (*changed) (CdClient *client);
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*_cd_client_reserved1) (void);
+ void (*_cd_client_reserved2) (void);
+ void (*_cd_client_reserved3) (void);
+ void (*_cd_client_reserved4) (void);
+ void (*_cd_client_reserved5) (void);
+ void (*_cd_client_reserved6) (void);
+ void (*_cd_client_reserved7) (void);
+ void (*_cd_client_reserved8) (void);
+} CdClientClass;
+
+/**
+ * CdClientError:
+ * @CD_CLIENT_ERROR_FAILED: the transaction failed for an unknown reason
+ *
+ * Errors that can be thrown
+ */
+typedef enum
+{
+ CD_CLIENT_ERROR_FAILED,
+ CD_CLIENT_ERROR_LAST
+} CdClientError;
+
+GType cd_client_get_type (void);
+GQuark cd_client_error_quark (void);
+CdClient *cd_client_new (void);
+
+CdDevice *cd_client_create_device_sync (CdClient *client,
+ const gchar *id,
+ guint options,
+ GCancellable *cancellable,
+ GError **error);
+CdProfile *cd_client_create_profile_sync (CdClient *client,
+ const gchar *id,
+ guint options,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_client_delete_device_sync (CdClient *client,
+ CdDevice *device,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_client_delete_profile_sync (CdClient *client,
+ CdProfile *profile,
+ GCancellable *cancellable,
+ GError **error);
+CdDevice *cd_client_find_device_sync (CdClient *client,
+ const gchar *id,
+ GCancellable *cancellable,
+ GError **error);
+CdProfile *cd_client_find_profile_sync (CdClient *client,
+ const gchar *id,
+ GCancellable *cancellable,
+ GError **error);
+GPtrArray *cd_client_get_devices_sync (CdClient *client,
+ GCancellable *cancellable,
+ GError **error);
+GPtrArray *cd_client_get_profiles_sync (CdClient *client,
+ GCancellable *cancellable,
+ GError **error);
+GPtrArray *cd_client_get_devices_by_kind_sync (CdClient *client,
+ CdDeviceKind kind,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_client_connect_sync (CdClient *client,
+ GCancellable *cancellable,
+ GError **error);
+const gchar *cd_client_get_daemon_version (CdClient *client);
+
+G_END_DECLS
+
+#endif /* __CD_CLIENT_H */
+
diff --git a/libcolord/cd-device.c b/libcolord/cd-device.c
new file mode 100644
index 0000000..4edfcae
--- /dev/null
+++ b/libcolord/cd-device.c
@@ -0,0 +1,909 @@
+/* -*- 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.
+ */
+
+/**
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+
+#include "cd-device.h"
+#include "cd-profile.h"
+
+static void cd_device_class_init (CdDeviceClass *klass);
+static void cd_device_init (CdDevice *device);
+static void cd_device_finalize (GObject *object);
+
+#define CD_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CD_TYPE_DEVICE, CdDevicePrivate))
+
+/**
+ * CdDevicePrivate:
+ *
+ * Private #PkDevice data
+ **/
+struct _CdDevicePrivate
+{
+ GDBusProxy *proxy;
+ gchar *object_path;
+ gchar *id;
+ gchar *model;
+ guint64 created;
+ GPtrArray *profiles;
+ CdDeviceKind kind;
+};
+
+enum {
+ PROP_0,
+ PROP_CREATED,
+ PROP_ID,
+ PROP_MODEL,
+ PROP_KIND,
+ PROP_LAST
+};
+
+enum {
+ SIGNAL_CHANGED,
+ SIGNAL_LAST
+};
+
+static guint signals [SIGNAL_LAST] = { 0 };
+
+G_DEFINE_TYPE (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_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)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), NULL);
+ return device->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)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), NULL);
+ return device->priv->model;
+}
+
+/**
+ * cd_device_get_created:
+ * @device: a #CdDevice instance.
+ *
+ * Gets the device ID.
+ *
+ * Return value: A value in seconds, or 0 for invalid
+ *
+ * Since: 0.1.0
+ **/
+guint64
+cd_device_get_created (CdDevice *device)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), 0);
+ return device->priv->created;
+}
+
+/**
+ * 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)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), CD_DEVICE_KIND_UNKNOWN);
+ return device->priv->kind;
+}
+
+/**
+ * cd_device_get_profiles:
+ * @device: a #CdDevice instance.
+ *
+ * Gets the device profiles.
+ *
+ * Return value: An array of #CdProfile's, free with g_ptr_array_unref()
+ *
+ * Since: 0.1.0
+ **/
+GPtrArray *
+cd_device_get_profiles (CdDevice *device)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), NULL);
+ if (device->priv->profiles == NULL)
+ return NULL;
+ return g_ptr_array_ref (device->priv->profiles);
+}
+
+/**
+ * cd_device_set_profiles_array_from_variant:
+ **/
+static gboolean
+cd_device_set_profiles_array_from_variant (CdDevice *device,
+ GVariant *profiles,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdProfile *profile_tmp;
+ gboolean ret = TRUE;
+ gchar *object_path_tmp;
+ GError *error_local = NULL;
+ gsize len;
+ guint i;
+ GVariantIter iter;
+
+ g_ptr_array_set_size (device->priv->profiles, 0);
+ len = g_variant_iter_init (&iter, profiles);
+ for (i=0; i<len; i++) {
+ g_variant_get_child (profiles, i,
+ "o", &object_path_tmp);
+ profile_tmp = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile_tmp,
+ object_path_tmp,
+ cancellable,
+ &error_local);
+ if (!ret) {
+ g_set_error (error,
+ CD_DEVICE_ERROR,
+ CD_DEVICE_ERROR_FAILED,
+ "Failed to set profile object path: %s",
+ error_local->message);
+ g_error_free (error_local);
+ g_object_unref (profile_tmp);
+ goto out;
+ }
+ g_ptr_array_add (device->priv->profiles, profile_tmp);
+ g_free (object_path_tmp);
+ }
+out:
+ return ret;
+}
+
+/**
+ * cd_device_dbus_properties_changed:
+ **/
+static void
+cd_device_dbus_properties_changed (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ const gchar * const *invalidated_properties,
+ CdDevice *device)
+{
+ guint i;
+ guint len;
+ GVariantIter iter;
+ gchar *property_name;
+ GVariant *property_value;
+
+ 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, "Model") == 0) {
+ g_free (device->priv->model);
+ device->priv->model = g_variant_dup_string (property_value, NULL);
+ } else if (g_strcmp0 (property_name, "Kind") == 0) {
+ device->priv->kind =
+ cd_device_kind_from_string (g_variant_get_string (property_value, NULL));
+ } else if (g_strcmp0 (property_name, "Profiles") == 0) {
+ cd_device_set_profiles_array_from_variant (device,
+ property_value,
+ NULL,
+ NULL);
+ } else {
+ g_warning ("%s property unhandled", property_name);
+ }
+ g_variant_unref (property_value);
+ }
+}
+
+/**
+ * cd_device_dbus_signal_cb:
+ **/
+static void
+cd_device_dbus_signal_cb (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ CdDevice *device)
+{
+ gchar *object_path_tmp = NULL;
+
+ if (g_strcmp0 (signal_name, "Changed") == 0) {
+ g_debug ("emit Changed on %s", device->priv->object_path);
+ g_signal_emit (device, signals[SIGNAL_CHANGED], 0);
+ } else {
+ g_warning ("unhandled signal '%s'", signal_name);
+ }
+ g_free (object_path_tmp);
+}
+
+/**
+ * cd_device_set_object_path_sync:
+ * @device: a #CdDevice instance.
+ * @object_path: The colord object path.
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Sets the object path of the object and fills up initial properties.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_device_set_object_path_sync (CdDevice *device,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *created = NULL;
+ GVariant *id = NULL;
+ GVariant *kind = NULL;
+ GVariant *model = NULL;
+ GVariant *profiles = NULL;
+
+ g_return_val_if_fail (CD_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (device->priv->proxy == NULL, FALSE);
+
+ /* connect to the daemon */
+ device->priv->proxy =
+ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ COLORD_DBUS_SERVICE,
+ object_path,
+ COLORD_DBUS_INTERFACE_DEVICE,
+ cancellable,
+ &error_local);
+ if (device->priv->proxy == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_DEVICE_ERROR,
+ CD_DEVICE_ERROR_FAILED,
+ "Failed to connect to device %s: %s",
+ object_path,
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* save object path */
+ device->priv->object_path = g_strdup (object_path);
+
+ /* get device id */
+ id = g_dbus_proxy_get_cached_property (device->priv->proxy,
+ "DeviceId");
+ if (id != NULL)
+ device->priv->id = g_variant_dup_string (id, NULL);
+
+ /* get kind */
+ kind = g_dbus_proxy_get_cached_property (device->priv->proxy,
+ "Kind");
+ if (kind != NULL)
+ device->priv->kind =
+ cd_device_kind_from_string (g_variant_get_string (kind, NULL));
+
+ /* get model */
+ model = g_dbus_proxy_get_cached_property (device->priv->proxy,
+ "Model");
+ if (model != NULL)
+ device->priv->model = g_variant_dup_string (model, NULL);
+
+ /* get created */
+ created = g_dbus_proxy_get_cached_property (device->priv->proxy,
+ "Created");
+ if (created != NULL)
+ device->priv->created = g_variant_get_uint64 (created);
+
+ /* get profiles */
+ profiles = g_dbus_proxy_get_cached_property (device->priv->proxy,
+ "Profiles");
+ ret = cd_device_set_profiles_array_from_variant (device,
+ profiles,
+ cancellable,
+ error);
+ if (!ret)
+ goto out;
+
+ /* get signals from DBus */
+ g_signal_connect (device->priv->proxy,
+ "g-signal",
+ G_CALLBACK (cd_device_dbus_signal_cb),
+ device);
+
+ /* watch if any remote properties change */
+ g_signal_connect (device->priv->proxy,
+ "g-properties-changed",
+ G_CALLBACK (cd_device_dbus_properties_changed),
+ device);
+
+ /* success */
+ g_debug ("Connected to device %s",
+ device->priv->id);
+out:
+ if (id != NULL)
+ g_variant_unref (id);
+ if (model != NULL)
+ g_variant_unref (model);
+ if (created != NULL)
+ g_variant_unref (created);
+ if (kind != NULL)
+ g_variant_unref (kind);
+ if (profiles != NULL)
+ g_variant_unref (profiles);
+ return ret;
+}
+
+/**
+ * cd_device_set_property_sync:
+ **/
+static gboolean
+cd_device_set_property_sync (CdDevice *device,
+ const gchar *name,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *response = NULL;
+
+ /* execute sync method */
+ response = g_dbus_proxy_call_sync (device->priv->proxy,
+ "SetProperty",
+ g_variant_new ("(ss)",
+ name,
+ value),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error_local);
+ if (response == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_DEVICE_ERROR,
+ CD_DEVICE_ERROR_FAILED,
+ "Failed to set profile object path: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+out:
+ if (response != NULL)
+ g_variant_unref (response);
+ return ret;
+}
+
+/**
+ * cd_device_set_model_sync:
+ * @device: a #CdDevice instance.
+ * @value: The model.
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Sets the device model.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_device_set_model_sync (CdDevice *device,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (device->priv->proxy != NULL, FALSE);
+
+ /* execute sync helper */
+ return cd_device_set_property_sync (device, "Model", value,
+ cancellable, error);
+}
+
+/**
+ * cd_device_set_kind_sync:
+ * @device: a #CdDevice instance.
+ * @kind: The device kind, e.g. #CD_DEVICE_KIND_DISPLAY
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Sets the device kind.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_device_set_kind_sync (CdDevice *device,
+ CdDeviceKind kind,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (device->priv->proxy != NULL, FALSE);
+
+ /* execute sync helper */
+ return cd_device_set_property_sync (device, "Kind",
+ cd_device_kind_to_string (kind),
+ cancellable, error);
+}
+
+/**
+ * cd_device_add_profile_sync:
+ * @device: a #CdDevice instance.
+ * @profile: a #CdProfile instance
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Adds a profile to a device.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_device_add_profile_sync (CdDevice *device,
+ CdProfile *profile,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *response = NULL;
+
+ g_return_val_if_fail (CD_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (CD_IS_PROFILE (profile), FALSE);
+ g_return_val_if_fail (device->priv->proxy != NULL, FALSE);
+
+ /* execute sync method */
+ response = g_dbus_proxy_call_sync (device->priv->proxy,
+ "AddProfile",
+ g_variant_new ("(o)",
+ cd_profile_get_object_path (profile)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error_local);
+ if (response == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_DEVICE_ERROR,
+ CD_DEVICE_ERROR_FAILED,
+ "Failed to add profile to device: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+out:
+ if (response != NULL)
+ g_variant_unref (response);
+ return ret;
+}
+
+/**
+ * cd_device_make_profile_default_sync:
+ * @device: a #CdDevice instance.
+ * @profile: a #CdProfile instance
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Makes an already added profile default for a device.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_device_make_profile_default_sync (CdDevice *device,
+ CdProfile *profile,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *response = NULL;
+
+ g_return_val_if_fail (CD_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (CD_IS_PROFILE (profile), FALSE);
+ g_return_val_if_fail (device->priv->proxy != NULL, FALSE);
+
+ /* execute sync method */
+ response = g_dbus_proxy_call_sync (device->priv->proxy,
+ "MakeProfileDefault",
+ g_variant_new ("(s)",
+ cd_profile_get_id (profile)),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error_local);
+ if (response == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_DEVICE_ERROR,
+ CD_DEVICE_ERROR_FAILED,
+ "Failed to make profile default on device: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+out:
+ if (response != NULL)
+ g_variant_unref (response);
+ return ret;
+}
+
+/**
+ * cd_device_get_profile_for_qualifier_sync:
+ * @device: a #CdDevice instance.
+ * @qualifier: a qualifier that can included wildcards
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Gets the prefered profile for a qualifier.
+ *
+ * Return value: a #CdProfile, free with g_object_unref()
+ *
+ * Since: 0.1.0
+ **/
+CdProfile *
+cd_device_get_profile_for_qualifier_sync (CdDevice *device,
+ const gchar *qualifier,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CdProfile *profile = NULL;
+ CdProfile *profile_tmp = NULL;
+ gboolean ret;
+ gchar *object_path = NULL;
+ GError *error_local = NULL;
+ GVariant *response = NULL;
+
+ g_return_val_if_fail (CD_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (qualifier != NULL, NULL);
+ g_return_val_if_fail (device->priv->proxy != NULL, NULL);
+
+ /* execute sync method */
+ response = g_dbus_proxy_call_sync (device->priv->proxy,
+ "GetProfileForQualifier",
+ g_variant_new ("(s)",
+ qualifier),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error_local);
+ if (response == NULL) {
+ g_set_error (error,
+ CD_DEVICE_ERROR,
+ CD_DEVICE_ERROR_FAILED,
+ "Failed to get a suitable profile: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* create thick CdDevice object */
+ g_variant_get (response, "(o)",
+ &object_path);
+ profile_tmp = cd_profile_new ();
+ ret = cd_profile_set_object_path_sync (profile_tmp,
+ object_path,
+ cancellable,
+ error);
+ if (!ret)
+ goto out;
+
+ /* success */
+ profile = g_object_ref (profile_tmp);
+out:
+ g_free (object_path);
+ if (profile_tmp != NULL)
+ g_object_unref (profile_tmp);
+ if (response != NULL)
+ g_variant_unref (response);
+ return profile;
+}
+
+/**
+ * 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)
+{
+ g_return_val_if_fail (CD_IS_DEVICE (device), NULL);
+ return device->priv->object_path;
+}
+
+/**
+ * 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)
+{
+ 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) device->priv->created;
+ time_tm = localtime (&t);
+ strftime (time_buf, sizeof time_buf, "%c", time_tm);
+
+ string = g_string_new ("");
+ g_string_append_printf (string, " object-path: %s\n",
+ device->priv->object_path);
+ g_string_append_printf (string, " created: %s\n",
+ time_buf);
+
+ return g_string_free (string, FALSE);
+}
+
+/*
+ * 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);
+
+ switch (prop_id) {
+ case PROP_ID:
+ g_free (device->priv->id);
+ device->priv->id = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_MODEL:
+ g_free (device->priv->model);
+ device->priv->model = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_CREATED:
+ device->priv->created = g_value_get_uint64 (value);
+ break;
+ case PROP_KIND:
+ device->priv->kind = g_value_get_uint (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);
+
+ switch (prop_id) {
+ case PROP_CREATED:
+ g_value_set_uint64 (value, device->priv->created);
+ break;
+ case PROP_ID:
+ g_value_set_string (value, device->priv->id);
+ break;
+ case PROP_MODEL:
+ g_value_set_string (value, device->priv->model);
+ break;
+ case PROP_KIND:
+ g_value_set_uint (value, device->priv->kind);
+ 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:created:
+ *
+ * The last time the device was updated.
+ *
+ * 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_READWRITE));
+ /**
+ * 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_READWRITE));
+ /**
+ * 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_READWRITE));
+ /**
+ * CdDevice:kind:
+ *
+ * The device kind, e.g. %CD_DEVICE_KIND_KEYBOARD.
+ *
+ * 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_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (CdDevicePrivate));
+}
+
+/*
+ * cd_device_init:
+ */
+static void
+cd_device_init (CdDevice *device)
+{
+ device->priv = CD_DEVICE_GET_PRIVATE (device);
+ device->priv->profiles = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+}
+
+/*
+ * cd_device_finalize:
+ */
+static void
+cd_device_finalize (GObject *object)
+{
+ CdDevice *device;
+
+ g_return_if_fail (CD_IS_DEVICE (object));
+
+ device = CD_DEVICE (object);
+
+ g_free (device->priv->object_path);
+ g_free (device->priv->id);
+ g_free (device->priv->model);
+ g_ptr_array_unref (device->priv->profiles);
+ if (device->priv->proxy != NULL)
+ g_object_unref (device->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);
+}
+
diff --git a/libcolord/cd-device.h b/libcolord/cd-device.h
new file mode 100644
index 0000000..8208e7e
--- /dev/null
+++ b/libcolord/cd-device.h
@@ -0,0 +1,120 @@
+/* -*- 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.
+ */
+
+#if !defined (__COLORD_H_INSIDE__) && !defined (CD_COMPILATION)
+#error "Only <colord.h> can be included directly."
+#endif
+
+#ifndef __CD_DEVICE_H
+#define __CD_DEVICE_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <libcolord/cd-enum.h>
+#include <libcolord/cd-profile.h>
+
+G_BEGIN_DECLS
+
+#define CD_TYPE_DEVICE (cd_device_get_type ())
+#define CD_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CD_TYPE_DEVICE, CdDevice))
+#define CD_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CD_TYPE_DEVICE, CdDeviceClass))
+#define CD_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CD_TYPE_DEVICE))
+#define CD_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CD_TYPE_DEVICE))
+#define CD_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CD_TYPE_DEVICE, CdDeviceClass))
+#define CD_DEVICE_ERROR (cd_device_error_quark ())
+#define CD_DEVICE_TYPE_ERROR (cd_device_error_get_type ())
+
+typedef struct _CdDevicePrivate CdDevicePrivate;
+
+typedef struct
+{
+ GObject parent;
+ CdDevicePrivate *priv;
+} CdDevice;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (*changed) (CdDevice *device);
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*_cd_device_reserved1) (void);
+ void (*_cd_device_reserved2) (void);
+ void (*_cd_device_reserved3) (void);
+ void (*_cd_device_reserved4) (void);
+ void (*_cd_device_reserved5) (void);
+ void (*_cd_device_reserved6) (void);
+ void (*_cd_device_reserved7) (void);
+ void (*_cd_device_reserved8) (void);
+} CdDeviceClass;
+
+/**
+ * CdDeviceError:
+ * @CD_DEVICE_ERROR_FAILED: the transaction failed for an unknown reason
+ *
+ * Errors that can be thrown
+ */
+typedef enum
+{
+ CD_DEVICE_ERROR_FAILED,
+ CD_DEVICE_ERROR_LAST
+} CdDeviceError;
+
+GType cd_device_get_type (void);
+GQuark cd_device_error_quark (void);
+CdDevice *cd_device_new (void);
+gchar *cd_device_to_string (CdDevice *device);
+gboolean cd_device_set_object_path_sync (CdDevice *device,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_device_set_model_sync (CdDevice *device,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_device_set_kind_sync (CdDevice *device,
+ CdDeviceKind kind,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_device_add_profile_sync (CdDevice *device,
+ CdProfile *profile,
+ GCancellable *cancellable,
+ GError **error);
+CdProfile *cd_device_get_profile_for_qualifier_sync (CdDevice *device,
+ const gchar *qualifier,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_device_make_profile_default_sync (CdDevice *device,
+ CdProfile *profile,
+ GCancellable *cancellable,
+ GError **error);
+const gchar *cd_device_get_id (CdDevice *device);
+const gchar *cd_device_get_model (CdDevice *device);
+guint64 cd_device_get_created (CdDevice *device);
+CdDeviceKind cd_device_get_kind (CdDevice *device);
+GPtrArray *cd_device_get_profiles (CdDevice *device);
+const gchar *cd_device_get_object_path (CdDevice *device);
+
+G_END_DECLS
+
+#endif /* __CD_DEVICE_H */
+
diff --git a/libcolord/cd-enum.c b/libcolord/cd-enum.c
new file mode 100644
index 0000000..0fa1526
--- /dev/null
+++ b/libcolord/cd-enum.c
@@ -0,0 +1,94 @@
+/* -*- 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.
+ */
+
+/**
+ * SECTION:cd-types
+ * @short_description: Types used by colord and libcolord
+ *
+ * These helper functions provide a way to marshal enumerated values to
+ * text and back again.
+ *
+ * See also: #CdClient, #CdDevice
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "cd-enum.h"
+
+/**
+ * cd_device_kind_to_string:
+ *
+ * Converts a #CdDeviceKind to a string.
+ *
+ * Return value: identifier string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+cd_device_kind_to_string (CdDeviceKind kind_enum)
+{
+ const gchar *kind = NULL;
+ switch (kind_enum) {
+ case CD_DEVICE_KIND_DISPLAY:
+ kind = "display";
+ break;
+ case CD_DEVICE_KIND_SCANNER:
+ kind = "scanner";
+ break;
+ case CD_DEVICE_KIND_PRINTER:
+ kind = "printer";
+ break;
+ case CD_DEVICE_KIND_CAMERA:
+ kind = "camera";
+ break;
+ default:
+ kind = "unknown";
+ break;
+ }
+ return kind;
+}
+
+/**
+ * cd_device_kind_from_string:
+ *
+ * Converts a string to a #CdDeviceKind.
+ *
+ * Return value: enumerated value
+ *
+ * Since: 0.1.0
+ **/
+CdDeviceKind
+cd_device_kind_from_string (const gchar *type)
+{
+ if (type == NULL)
+ return CD_DEVICE_KIND_UNKNOWN;
+ if (g_strcmp0 (type, "display") == 0)
+ return CD_DEVICE_KIND_DISPLAY;
+ if (g_strcmp0 (type, "scanner") == 0)
+ return CD_DEVICE_KIND_SCANNER;
+ if (g_strcmp0 (type, "printer") == 0)
+ return CD_DEVICE_KIND_PRINTER;
+ if (g_strcmp0 (type, "camera") == 0)
+ return CD_DEVICE_KIND_CAMERA;
+ return CD_DEVICE_KIND_UNKNOWN;
+}
diff --git a/client/cd-common.h b/libcolord/cd-enum.h
index b8f74b8..66bffad 100644
--- a/client/cd-common.h
+++ b/libcolord/cd-enum.h
@@ -19,10 +19,30 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef __CD_COMMON_H__
-#define __CD_COMMON_H__
+#if !defined (__COLORD_H_INSIDE__) && !defined (CD_COMPILATION)
+#error "Only <colord.h> can be included directly."
+#endif
-#include "config.h"
+#ifndef __CD_TYPES_H
+#define __CD_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * CdDeviceKind:
+ *
+ * The device type.
+ **/
+typedef enum {
+ CD_DEVICE_KIND_UNKNOWN,
+ CD_DEVICE_KIND_DISPLAY,
+ CD_DEVICE_KIND_SCANNER,
+ CD_DEVICE_KIND_PRINTER,
+ CD_DEVICE_KIND_CAMERA,
+ CD_DEVICE_KIND_LAST
+} CdDeviceKind;
#define COLORD_DBUS_SERVICE "org.freedesktop.ColorManager"
#define COLORD_DBUS_PATH "/org/freedesktop/ColorManager"
@@ -34,5 +54,10 @@
#define CD_DBUS_OPTIONS_MASK_TEMP 1
#define CD_DBUS_OPTIONS_MASK_DISK 2
-#endif /* __CD_COMMON_H__ */
+const gchar *cd_device_kind_to_string (CdDeviceKind kind_enum);
+CdDeviceKind cd_device_kind_from_string (const gchar *kind);
+
+G_END_DECLS
+
+#endif /* __CD_TYPES_H */
diff --git a/libcolord/cd-profile.c b/libcolord/cd-profile.c
new file mode 100644
index 0000000..f94cea3
--- /dev/null
+++ b/libcolord/cd-profile.c
@@ -0,0 +1,709 @@
+/* -*- 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.
+ */
+
+/**
+ * SECTION:cd-profile
+ * @short_description: Client object for accessing information about colord profiles
+ *
+ * A helper GObject to use for accessing colord profiles, and to be notified
+ * when it is changed.
+ *
+ * See also: #CdClient
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <string.h>
+
+#include "cd-profile.h"
+
+static void cd_profile_class_init (CdProfileClass *klass);
+static void cd_profile_init (CdProfile *profile);
+static void cd_profile_finalize (GObject *object);
+
+#define CD_PROFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CD_TYPE_PROFILE, CdProfilePrivate))
+
+/**
+ * CdProfilePrivate:
+ *
+ * Private #PkProfile data
+ **/
+struct _CdProfilePrivate
+{
+ gchar *filename;
+ gchar *id;
+ gchar *object_path;
+ gchar *qualifier;
+ gchar *title;
+ GDBusProxy *proxy;
+ guint64 created;
+};
+
+enum {
+ PROP_0,
+ PROP_CREATED,
+ PROP_ID,
+ PROP_FILENAME,
+ PROP_QUALIFIER,
+ PROP_TITLE,
+ PROP_LAST
+};
+
+enum {
+ SIGNAL_CHANGED,
+ SIGNAL_LAST
+};
+
+static guint signals [SIGNAL_LAST] = { 0 };
+
+G_DEFINE_TYPE (CdProfile, cd_profile, G_TYPE_OBJECT)
+
+/**
+ * cd_profile_error_quark:
+ *
+ * Return value: An error quark.
+ *
+ * Since: 0.1.0
+ **/
+GQuark
+cd_profile_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("cd_profile_error");
+ return quark;
+}
+
+/**
+ * cd_profile_get_id:
+ * @profile: a #CdProfile instance.
+ *
+ * Gets the profile ID.
+ *
+ * Return value: A string, or %NULL for invalid
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+cd_profile_get_id (CdProfile *profile)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), NULL);
+ return profile->priv->id;
+}
+
+/**
+ * cd_profile_get_filename:
+ * @profile: a #CdProfile instance.
+ *
+ * Gets the profile filename.
+ *
+ * Return value: A string, or %NULL for invalid
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+cd_profile_get_filename (CdProfile *profile)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), NULL);
+ return profile->priv->filename;
+}
+
+/**
+ * cd_profile_get_qualifier:
+ * @profile: a #CdProfile instance.
+ *
+ * Gets the profile qualifier.
+ *
+ * Return value: A string, or %NULL for invalid
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+cd_profile_get_qualifier (CdProfile *profile)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), NULL);
+ return profile->priv->qualifier;
+}
+
+/**
+ * cd_profile_get_title:
+ * @profile: a #CdProfile instance.
+ *
+ * Gets the profile title.
+ *
+ * Return value: A string, or %NULL for invalid
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+cd_profile_get_title (CdProfile *profile)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), NULL);
+ return profile->priv->title;
+}
+
+/**
+ * cd_profile_get_created:
+ * @profile: a #CdProfile instance.
+ *
+ * Gets the profile ID.
+ *
+ * Return value: A value in seconds, or 0 for invalid
+ *
+ * Since: 0.1.0
+ **/
+guint64
+cd_profile_get_created (CdProfile *profile)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), 0);
+ return profile->priv->created;
+}
+
+/**
+ * cd_profile_dbus_properties_changed:
+ **/
+static void
+cd_profile_dbus_properties_changed (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ const gchar * const *invalidated_properties,
+ CdProfile *profile)
+{
+ guint i;
+ guint len;
+ GVariantIter iter;
+ gchar *property_name;
+ GVariant *property_value;
+
+ 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, "Qualifier") == 0) {
+ g_free (profile->priv->qualifier);
+ profile->priv->qualifier = g_variant_dup_string (property_value, NULL);
+ } else if (g_strcmp0 (property_name, "Filename") == 0) {
+ g_free (profile->priv->filename);
+ profile->priv->filename = g_variant_dup_string (property_value, NULL);
+ } else if (g_strcmp0 (property_name, "Title") == 0) {
+ g_free (profile->priv->title);
+ profile->priv->title = g_variant_dup_string (property_value, NULL);
+ } else {
+ g_warning ("%s property unhandled", property_name);
+ }
+ g_variant_unref (property_value);
+ }
+}
+
+/**
+ * cd_profile_dbus_signal_cb:
+ **/
+static void
+cd_profile_dbus_signal_cb (GDBusProxy *proxy,
+ gchar *sender_name,
+ gchar *signal_name,
+ GVariant *parameters,
+ CdProfile *profile)
+{
+ gchar *object_path_tmp = NULL;
+
+ if (g_strcmp0 (signal_name, "Changed") == 0) {
+ g_debug ("emit Changed on %s", profile->priv->object_path);
+ g_signal_emit (profile, signals[SIGNAL_CHANGED], 0);
+ } else {
+ g_warning ("unhandled signal '%s'", signal_name);
+ }
+ g_free (object_path_tmp);
+}
+
+/**
+ * cd_profile_set_object_path_sync:
+ * @profile: a #CdProfile instance.
+ * @object_path: The colord object path.
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Sets the object path of the object and fills up initial properties.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_profile_set_object_path_sync (CdProfile *profile,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *created = NULL;
+ GVariant *filename = NULL;
+ GVariant *id = NULL;
+ GVariant *profiles = NULL;
+ GVariant *qualifier = NULL;
+ GVariant *title = NULL;
+
+ g_return_val_if_fail (CD_IS_PROFILE (profile), FALSE);
+ g_return_val_if_fail (profile->priv->proxy == NULL, FALSE);
+
+ /* connect to the daemon */
+ profile->priv->proxy =
+ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ COLORD_DBUS_SERVICE,
+ object_path,
+ COLORD_DBUS_INTERFACE_PROFILE,
+ cancellable,
+ &error_local);
+ if (profile->priv->proxy == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_PROFILE_ERROR,
+ CD_PROFILE_ERROR_FAILED,
+ "Failed to connect to profile %s: %s",
+ object_path,
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+
+ /* save object path */
+ profile->priv->object_path = g_strdup (object_path);
+
+ /* get profile id */
+ id = g_dbus_proxy_get_cached_property (profile->priv->proxy,
+ "ProfileId");
+ if (id != NULL)
+ profile->priv->id = g_variant_dup_string (id, NULL);
+
+ /* get filename */
+ filename = g_dbus_proxy_get_cached_property (profile->priv->proxy,
+ "Filename");
+ if (filename != NULL)
+ profile->priv->filename = g_variant_dup_string (filename, NULL);
+
+ /* get qualifier */
+ qualifier = g_dbus_proxy_get_cached_property (profile->priv->proxy,
+ "Qualifier");
+ if (qualifier != NULL)
+ profile->priv->qualifier = g_variant_dup_string (qualifier, NULL);
+
+ /* get title */
+ title = g_dbus_proxy_get_cached_property (profile->priv->proxy,
+ "Title");
+ if (title != NULL)
+ profile->priv->title = g_variant_dup_string (title, NULL);
+
+ /* get created */
+ created = g_dbus_proxy_get_cached_property (profile->priv->proxy,
+ "Created");
+ if (created != NULL)
+ profile->priv->created = g_variant_get_uint64 (created);
+
+ /* get signals from DBus */
+ g_signal_connect (profile->priv->proxy,
+ "g-signal",
+ G_CALLBACK (cd_profile_dbus_signal_cb),
+ profile);
+
+ /* watch if any remote properties change */
+ g_signal_connect (profile->priv->proxy,
+ "g-properties-changed",
+ G_CALLBACK (cd_profile_dbus_properties_changed),
+ profile);
+
+ /* success */
+ g_debug ("Connected to profile %s",
+ profile->priv->id);
+out:
+ if (id != NULL)
+ g_variant_unref (id);
+ if (filename != NULL)
+ g_variant_unref (filename);
+ if (created != NULL)
+ g_variant_unref (created);
+ if (qualifier != NULL)
+ g_variant_unref (qualifier);
+ if (title != NULL)
+ g_variant_unref (title);
+ if (profiles != NULL)
+ g_variant_unref (profiles);
+ return ret;
+}
+
+/**
+ * cd_profile_set_property_sync:
+ **/
+static gboolean
+cd_profile_set_property_sync (CdProfile *profile,
+ const gchar *name,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *error_local = NULL;
+ GVariant *response = NULL;
+
+ /* execute sync method */
+ response = g_dbus_proxy_call_sync (profile->priv->proxy,
+ "SetProperty",
+ g_variant_new ("(ss)",
+ name,
+ value),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, NULL, &error_local);
+ if (response == NULL) {
+ ret = FALSE;
+ g_set_error (error,
+ CD_PROFILE_ERROR,
+ CD_PROFILE_ERROR_FAILED,
+ "Failed to set property: %s",
+ error_local->message);
+ g_error_free (error_local);
+ goto out;
+ }
+out:
+ if (response != NULL)
+ g_variant_unref (response);
+ return ret;
+}
+
+/**
+ * cd_profile_set_filename_sync:
+ * @profile: a #CdProfile instance.
+ * @value: The filename.
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Sets the profile model.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_profile_set_filename_sync (CdProfile *profile,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), FALSE);
+ g_return_val_if_fail (profile->priv->proxy != NULL, FALSE);
+
+ /* execute sync helper */
+ return cd_profile_set_property_sync (profile, "Filename", value,
+ cancellable, error);
+}
+
+/**
+ * cd_profile_set_qualifier_sync:
+ * @profile: a #CdProfile instance.
+ * @value: The qualifier.
+ * @cancellable: a #GCancellable or %NULL
+ * @error: a #GError, or %NULL.
+ *
+ * Sets the profile model.
+ *
+ * Return value: #TRUE for success, else #FALSE and @error is used
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+cd_profile_set_qualifier_sync (CdProfile *profile,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), FALSE);
+ g_return_val_if_fail (profile->priv->proxy != NULL, FALSE);
+
+ /* execute sync helper */
+ return cd_profile_set_property_sync (profile, "Qualifier", value,
+ cancellable, error);
+}
+
+/**
+ * cd_profile_get_object_path:
+ * @profile: a #CdProfile instance.
+ *
+ * Gets the object path for the profile.
+ *
+ * Return value: the object path, or %NULL
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+cd_profile_get_object_path (CdProfile *profile)
+{
+ g_return_val_if_fail (CD_IS_PROFILE (profile), NULL);
+ return profile->priv->object_path;
+}
+
+/**
+ * cd_profile_to_string:
+ * @profile: a #CdProfile instance.
+ *
+ * Converts the profile to a string description.
+ *
+ * Return value: text representation of #CdProfile
+ *
+ * Since: 0.1.0
+ **/
+gchar *
+cd_profile_to_string (CdProfile *profile)
+{
+ struct tm *time_tm;
+ time_t t;
+ gchar time_buf[256];
+ GString *string;
+
+ g_return_val_if_fail (CD_IS_PROFILE (profile), NULL);
+
+ /* get a human readable time */
+ t = (time_t) profile->priv->created;
+ time_tm = localtime (&t);
+ strftime (time_buf, sizeof time_buf, "%c", time_tm);
+
+ string = g_string_new ("");
+ g_string_append_printf (string, " object-path: %s\n",
+ profile->priv->object_path);
+ g_string_append_printf (string, " created: %s\n",
+ time_buf);
+
+ return g_string_free (string, FALSE);
+}
+
+/*
+ * cd_profile_set_property:
+ */
+static void
+cd_profile_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ CdProfile *profile = CD_PROFILE (object);
+
+ switch (prop_id) {
+ case PROP_ID:
+ g_free (profile->priv->id);
+ profile->priv->id = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_FILENAME:
+ g_free (profile->priv->filename);
+ profile->priv->filename = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_QUALIFIER:
+ g_free (profile->priv->qualifier);
+ profile->priv->qualifier = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_TITLE:
+ g_free (profile->priv->title);
+ profile->priv->title = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_CREATED:
+ profile->priv->created = g_value_get_uint64 (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/*
+ * cd_profile_get_property:
+ */
+static void
+cd_profile_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ CdProfile *profile = CD_PROFILE (object);
+
+ switch (prop_id) {
+ case PROP_CREATED:
+ g_value_set_uint64 (value, profile->priv->created);
+ break;
+ case PROP_ID:
+ g_value_set_string (value, profile->priv->id);
+ break;
+ case PROP_FILENAME:
+ g_value_set_string (value, profile->priv->filename);
+ break;
+ case PROP_QUALIFIER:
+ g_value_set_string (value, profile->priv->qualifier);
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, profile->priv->title);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/*
+ * cd_profile_class_init:
+ */
+static void
+cd_profile_class_init (CdProfileClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = cd_profile_finalize;
+ object_class->set_property = cd_profile_set_property;
+ object_class->get_property = cd_profile_get_property;
+
+ /**
+ * CdProfile::changed:
+ * @profile: the #CdProfile instance that emitted the signal
+ *
+ * The ::changed signal is emitted when the profile 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 (CdProfileClass, changed),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * CdProfile:created:
+ *
+ * The last time the profile was updated.
+ *
+ * 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_READWRITE));
+ /**
+ * CdProfile:id:
+ *
+ * The profile ID.
+ *
+ * Since: 0.1.0
+ **/
+ g_object_class_install_property (object_class,
+ PROP_ID,
+ g_param_spec_string ("id",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+ /**
+ * CdProfile:filename:
+ *
+ * The profile filename.
+ *
+ * Since: 0.1.0
+ **/
+ g_object_class_install_property (object_class,
+ PROP_FILENAME,
+ g_param_spec_string ("filename",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+ /**
+ * CdProfile:qualifier:
+ *
+ * The profile qualifier.
+ *
+ * Since: 0.1.0
+ **/
+ g_object_class_install_property (object_class,
+ PROP_QUALIFIER,
+ g_param_spec_string ("qualifier",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * CdProfile:title:
+ *
+ * The profile title.
+ *
+ * Since: 0.1.0
+ **/
+ g_object_class_install_property (object_class,
+ PROP_TITLE,
+ g_param_spec_string ("title",
+ NULL, NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (CdProfilePrivate));
+}
+
+/*
+ * cd_profile_init:
+ */
+static void
+cd_profile_init (CdProfile *profile)
+{
+ profile->priv = CD_PROFILE_GET_PRIVATE (profile);
+}
+
+/*
+ * cd_profile_finalize:
+ */
+static void
+cd_profile_finalize (GObject *object)
+{
+ CdProfile *profile;
+
+ g_return_if_fail (CD_IS_PROFILE (object));
+
+ profile = CD_PROFILE (object);
+
+ g_free (profile->priv->object_path);
+ g_free (profile->priv->id);
+ g_free (profile->priv->filename);
+ g_free (profile->priv->qualifier);
+ g_free (profile->priv->title);
+ if (profile->priv->proxy != NULL)
+ g_object_unref (profile->priv->proxy);
+
+ G_OBJECT_CLASS (cd_profile_parent_class)->finalize (object);
+}
+
+/**
+ * cd_profile_new:
+ *
+ * Creates a new #CdProfile object.
+ *
+ * Return value: a new CdProfile object.
+ *
+ * Since: 0.1.0
+ **/
+CdProfile *
+cd_profile_new (void)
+{
+ CdProfile *profile;
+ profile = g_object_new (CD_TYPE_PROFILE, NULL);
+ return CD_PROFILE (profile);
+}
+
diff --git a/libcolord/cd-profile.h b/libcolord/cd-profile.h
new file mode 100644
index 0000000..2ceb543
--- /dev/null
+++ b/libcolord/cd-profile.h
@@ -0,0 +1,107 @@
+/* -*- 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.
+ */
+
+#if !defined (__COLORD_H_INSIDE__) && !defined (CD_COMPILATION)
+#error "Only <colord.h> can be included directly."
+#endif
+
+#ifndef __CD_PROFILE_H
+#define __CD_PROFILE_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <libcolord/cd-enum.h>
+
+G_BEGIN_DECLS
+
+#define CD_TYPE_PROFILE (cd_profile_get_type ())
+#define CD_PROFILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CD_TYPE_PROFILE, CdProfile))
+#define CD_PROFILE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CD_TYPE_PROFILE, CdProfileClass))
+#define CD_IS_PROFILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CD_TYPE_PROFILE))
+#define CD_IS_PROFILE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CD_TYPE_PROFILE))
+#define CD_PROFILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CD_TYPE_PROFILE, CdProfileClass))
+#define CD_PROFILE_ERROR (cd_profile_error_quark ())
+#define CD_PROFILE_TYPE_ERROR (cd_profile_error_get_type ())
+
+typedef struct _CdProfilePrivate CdProfilePrivate;
+
+typedef struct
+{
+ GObject parent;
+ CdProfilePrivate *priv;
+} CdProfile;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (*changed) (CdProfile *profile);
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*_cd_profile_reserved1) (void);
+ void (*_cd_profile_reserved2) (void);
+ void (*_cd_profile_reserved3) (void);
+ void (*_cd_profile_reserved4) (void);
+ void (*_cd_profile_reserved5) (void);
+ void (*_cd_profile_reserved6) (void);
+ void (*_cd_profile_reserved7) (void);
+ void (*_cd_profile_reserved8) (void);
+} CdProfileClass;
+
+/**
+ * CdProfileError:
+ * @CD_PROFILE_ERROR_FAILED: the transaction failed for an unknown reason
+ *
+ * Errors that can be thrown
+ */
+typedef enum
+{
+ CD_PROFILE_ERROR_FAILED,
+ CD_PROFILE_ERROR_LAST
+} CdProfileError;
+
+GType cd_profile_get_type (void);
+GQuark cd_profile_error_quark (void);
+CdProfile *cd_profile_new (void);
+gchar *cd_profile_to_string (CdProfile *profile);
+gboolean cd_profile_set_object_path_sync (CdProfile *profile,
+ const gchar *object_path,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_profile_set_filename_sync (CdProfile *profile,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error);
+gboolean cd_profile_set_qualifier_sync (CdProfile *profile,
+ const gchar *value,
+ GCancellable *cancellable,
+ GError **error);
+const gchar *cd_profile_get_id (CdProfile *profile);
+const gchar *cd_profile_get_filename (CdProfile *profile);
+const gchar *cd_profile_get_qualifier (CdProfile *profile);
+const gchar *cd_profile_get_title (CdProfile *profile);
+guint64 cd_profile_get_created (CdProfile *profile);
+const gchar *cd_profile_get_object_path (CdProfile *profile);
+
+G_END_DECLS
+
+#endif /* __CD_PROFILE_H */
+
diff --git a/libcolord/cd-self-test.c b/libcolord/cd-self-test.c
new file mode 100644
index 0000000..8490ead
--- /dev/null
+++ b/libcolord/cd-self-test.c
@@ -0,0 +1,296 @@
+/* -*- 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 <limits.h>
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "cd-client.h"
+
+/** ver:1.0 ***********************************************************/
+static GMainLoop *_test_loop = NULL;
+static guint _test_loop_timeout_id = 0;
+
+static gboolean
+_g_test_hang_check_cb (gpointer user_data)
+{
+ g_main_loop_quit (_test_loop);
+ _test_loop_timeout_id = 0;
+ return FALSE;
+}
+
+/**
+ * _g_test_loop_run_with_timeout:
+ **/
+static void
+_g_test_loop_run_with_timeout (guint timeout_ms)
+{
+ g_assert (_test_loop_timeout_id == 0);
+ _test_loop = g_main_loop_new (NULL, FALSE);
+ _test_loop_timeout_id = g_timeout_add (timeout_ms, _g_test_hang_check_cb, NULL);
+ g_main_loop_run (_test_loop);
+}
+
+/**
+ * _g_test_realpath:
+ **/
+static gchar *
+_g_test_realpath (const gchar *relpath)
+{
+ gchar *full;
+ char full_tmp[PATH_MAX];
+ realpath (relpath, full_tmp);
+ full = g_strdup (full_tmp);
+ return full;
+}
+
+/**********************************************************************/
+
+static void
+colord_client_func (void)
+{
+ CdClient *client;
+ CdDevice *device;
+ CdProfile *profile;
+ CdProfile *profile_tmp;
+ gboolean ret;
+ gchar *filename;
+ GError *error = NULL;
+ GPtrArray *array;
+ GPtrArray *devices;
+ GPtrArray *profiles;
+
+ /* create */
+ client = cd_client_new ();
+ g_assert (client != NULL);
+
+ /* connect */
+ ret = cd_client_connect_sync (client, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* get number of devices */
+ devices = cd_client_get_devices_sync (client, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (devices != NULL);
+
+ /* get number of profiles */
+ profiles = cd_client_get_profiles_sync (client, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (profiles != NULL);
+
+ /* create device */
+ device = cd_client_create_device_sync (client,
+ "device-self-test",
+ CD_DBUS_OPTIONS_MASK_TEMP,
+ NULL,
+ &error);
+
+ g_assert_cmpstr (cd_device_get_object_path (device), ==,
+ "/org/freedesktop/ColorManager/device_self_test");
+ g_assert_cmpstr (cd_device_get_id (device), ==, "device-self-test");
+
+ /* get new number of devices */
+ array = cd_client_get_devices_sync (client, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (array != NULL);
+ g_assert_cmpint (devices->len + 1, ==, array->len);
+ g_ptr_array_unref (array);
+
+ /* set device model */
+ ret = cd_device_set_model_sync (device, "CRAY 3000", NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* set device model */
+ ret = cd_device_set_kind_sync (device, CD_DEVICE_KIND_DISPLAY,
+ NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* wait for daemon */
+ _g_test_loop_run_with_timeout (50);
+
+ /* check device model */
+ g_assert_cmpstr (cd_device_get_model (device), ==, "CRAY 3000");
+
+ /* check device kind */
+ g_assert_cmpint (cd_device_get_kind (device), ==, CD_DEVICE_KIND_DISPLAY);
+
+ /* create profile */
+ profile = cd_client_create_profile_sync (client,
+ "profile-self-test",
+ CD_DBUS_OPTIONS_MASK_TEMP,
+ NULL,
+ &error);
+
+ g_assert_cmpstr (cd_profile_get_object_path (profile), ==,
+ "/org/freedesktop/ColorManager/profile_self_test");
+ g_assert_cmpstr (cd_profile_get_id (profile), ==, "profile-self-test");
+
+ /* get new number of profiles */
+ array = cd_client_get_profiles_sync (client, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (array != NULL);
+ g_assert_cmpint (profiles->len + 1, ==, array->len);
+ g_ptr_array_unref (array);
+
+ /* set profile filename */
+ filename = _g_test_realpath (TESTDATADIR "/ibm-t61.icc");
+ ret = cd_profile_set_filename_sync (profile, filename, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* set profile qualifier */
+ ret = cd_profile_set_qualifier_sync (profile, "Epson.RGB.300dpi",
+ NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* wait for daemon */
+ _g_test_loop_run_with_timeout (50);
+
+ /* check profile filename */
+ g_assert (g_str_has_suffix (cd_profile_get_filename (profile), "data/tests/ibm-t61.icc"));
+
+ /* check profile qualifier */
+ g_assert_cmpstr (cd_profile_get_qualifier (profile), ==, "Epson.RGB.300dpi");
+
+ /* check profile title set from ICC profile */
+ g_assert_cmpstr (cd_profile_get_title (profile), ==, "Huey, LENOVO - 6464Y1H - 15\" (2009-12-23)");
+
+ /* check none assigned */
+ array = cd_device_get_profiles (device);
+ g_assert_cmpint (array->len, ==, 0);
+ g_ptr_array_unref (array);
+
+ /* check nothing matches qualifier */
+ profile_tmp = cd_device_get_profile_for_qualifier_sync (device,
+ "Epson.RGB.300dpi",
+ NULL,
+ &error);
+ g_assert_error (error, CD_DEVICE_ERROR, CD_DEVICE_ERROR_FAILED);
+ g_assert (profile_tmp == NULL);
+ g_clear_error (&error);
+
+ /* assign profile to device */
+ ret = cd_device_add_profile_sync (device, profile, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* wait for daemon */
+ _g_test_loop_run_with_timeout (50);
+
+ /* check profile assigned */
+ array = cd_device_get_profiles (device);
+ g_assert (array != NULL);
+ g_assert_cmpint (array->len, ==, 1);
+ profile_tmp = g_ptr_array_index (array, 0);
+ g_assert_cmpstr (cd_profile_get_qualifier (profile_tmp), ==, "Epson.RGB.300dpi");
+ g_ptr_array_unref (array);
+
+ /* make profile default */
+ ret = cd_device_make_profile_default_sync (device, profile, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* check matches exact qualifier */
+ profile_tmp = cd_device_get_profile_for_qualifier_sync (device,
+ "Epson.RGB.300dpi",
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (profile_tmp != NULL);
+ g_assert_cmpstr (cd_profile_get_object_path (profile), ==,
+ "/org/freedesktop/ColorManager/profile_self_test");
+ g_object_unref (profile_tmp);
+
+ /* check matches wildcarded qualifier */
+ profile_tmp = cd_device_get_profile_for_qualifier_sync (device,
+ "Epson.RGB.*",
+ NULL,
+ &error);
+ g_assert_no_error (error);
+ g_assert (profile_tmp != NULL);
+ g_assert_cmpstr (cd_profile_get_object_path (profile), ==,
+ "/org/freedesktop/ColorManager/profile_self_test");
+ g_object_unref (profile_tmp);
+
+ /* delete profile */
+ ret = cd_client_delete_profile_sync (client, profile, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* get new number of profiles */
+ array = cd_client_get_profiles_sync (client, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (array != NULL);
+ g_assert_cmpint (profiles->len, ==, array->len);
+ g_ptr_array_unref (array);
+
+ /* wait for daemon */
+ _g_test_loop_run_with_timeout (50);
+
+ /* ensure device no longer lists deleted profile */
+ array = cd_device_get_profiles (device);
+ g_assert (array != NULL);
+ g_assert_cmpint (array->len, ==, 0);
+ g_ptr_array_unref (array);
+
+ /* delete device */
+ ret = cd_client_delete_device_sync (client, device, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* get new number of devices */
+ array = cd_client_get_devices_sync (client, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (array != NULL);
+ g_assert_cmpint (devices->len, ==, array->len);
+ g_ptr_array_unref (array);
+
+ g_free (filename);
+ g_ptr_array_unref (devices);
+ g_ptr_array_unref (profiles);
+ g_object_unref (device);
+ g_object_unref (profile);
+ g_object_unref (client);
+}
+
+int
+main (int argc, char **argv)
+{
+ g_type_init ();
+ g_thread_init (NULL);
+ g_test_init (&argc, &argv, NULL);
+
+ /* only critical and error are fatal */
+ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
+
+ /* tests go here */
+ g_test_add_func ("/colord/client", colord_client_func);
+ return g_test_run ();
+}
+
diff --git a/libcolord/cd-version.h.in b/libcolord/cd-version.h.in
new file mode 100644
index 0000000..592fb10
--- /dev/null
+++ b/libcolord/cd-version.h.in
@@ -0,0 +1,69 @@
+/* -*- 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.
+ */
+
+/**
+ * SECTION:cd-version
+ * @short_description: Obtains the version for the installed colord
+ *
+ * These compile time macros allow the user to enable parts of client code
+ * depending on the version of libcolord installed.
+ *
+ * See also: #CdClient, #CdDevice
+ */
+
+#if !defined (__COLORD_H_INSIDE__) && !defined (CD_COMPILATION)
+#error "Only <colord.h> can be included directly."
+#endif
+
+#ifndef __CD_VERSION_H
+#define __CD_VERSION_H
+
+/**
+ * CD_CHECK_VERSION:
+ *
+ * The compile-time major version
+ */
+#define CD_MAJOR_VERSION (@CD_MAJOR_VERSION@)
+
+/**
+ * CD_CHECK_MINOR:
+ *
+ * The compile-time minor version
+ */
+#define CD_MINOR_VERSION (@CD_MINOR_VERSION@)
+
+/**
+ * CD_MICRO_VERSION:
+ *
+ * The compile-time micro version
+ */
+#define CD_MICRO_VERSION (@CD_MICRO_VERSION@)
+
+/* check whether a colord version equal to or greater than
+ * major.minor.micro.
+ */
+#define CD_CHECK_VERSION(major,minor,micro) \
+ (CD_MAJOR_VERSION > (major) || \
+ (CD_MAJOR_VERSION == (major) && CD_MINOR_VERSION > (minor)) || \
+ (CD_MAJOR_VERSION == (major) && CD_MINOR_VERSION == (minor) && \
+ CD_MICRO_VERSION >= (micro)))
+
+#endif /* __CD_VERSION_H */
diff --git a/libcolord/colord.h b/libcolord/colord.h
new file mode 100644
index 0000000..de11f29
--- /dev/null
+++ b/libcolord/colord.h
@@ -0,0 +1,46 @@
+/* -*- 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.
+ */
+
+/**
+ * SECTION:colord
+ * @short_description: Client objects for accessing colord
+ *
+ * These objects allow client programs to get access to devices that can
+ * be color managed and profiles for changing them.
+ *
+ * See also: #CdClient, #CdDevice
+ */
+
+#ifndef __COLORD_H__
+#define __COLORD_H__
+
+#define __COLORD_H_INSIDE__
+
+#include <libcolord/cd-client.h>
+#include <libcolord/cd-device.h>
+#include <libcolord/cd-enum.h>
+#include <libcolord/cd-profile.h>
+#include <libcolord/cd-version.h>
+
+#undef __COLORD_H_INSIDE__
+
+#endif /* __COLORD_H__ */
+
diff --git a/libcolord/colord.pc.in b/libcolord/colord.pc.in
new file mode 100644
index 0000000..a4ae9f4
--- /dev/null
+++ b/libcolord/colord.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: colord
+Description: colord is a system daemon for managing color devices
+Version: @VERSION@
+Requires.private: dbus-1, gthread-2.0
+Requires: glib-2.0, gobject-2.0
+Libs: -L${libdir} -lcolord
+Cflags: -I${includedir}/libcolord
diff --git a/src/cd-device.c b/src/cd-device.c
index 4c1d161..867a482 100644
--- a/src/cd-device.c
+++ b/src/cd-device.c
@@ -145,13 +145,36 @@ cd_device_set_profiles (CdDevice *device, GPtrArray *profiles)
}
/**
- * cd_device_dbus_emit_changed:
+ * cd_device_dbus_emit_property_changed:
**/
static void
-cd_device_dbus_emit_changed (CdDevice *device)
+cd_device_dbus_emit_property_changed (CdDevice *device,
+ const gchar *property_name,
+ GVariant *property_value)
{
gboolean ret;
- GError *error = NULL;
+ GError *error_local = NULL;
+ GVariantBuilder builder;
+ GVariantBuilder invalidated_builder;
+
+ /* build the dict */
+ g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (&builder,
+ "{sv}",
+ property_name,
+ property_value);
+ g_dbus_connection_emit_signal (device->priv->connection,
+ NULL,
+ device->priv->object_path,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ g_variant_new ("(sa{sv}as)",
+ COLORD_DBUS_INTERFACE_DEVICE,
+ &builder,
+ &invalidated_builder),
+ &error_local);
+ g_assert_no_error (error_local);
/* emit signal */
ret = g_dbus_connection_emit_signal (device->priv->connection,
@@ -160,10 +183,10 @@ cd_device_dbus_emit_changed (CdDevice *device)
COLORD_DBUS_INTERFACE_DEVICE,
"Changed",
NULL,
- &error);
+ &error_local);
if (!ret) {
- g_warning ("failed to send signal %s", error->message);
- g_error_free (error);
+ g_warning ("failed to send signal %s", error_local->message);
+ g_error_free (error_local);
}
}
@@ -219,6 +242,76 @@ out:
}
/**
+ * cd_device_get_profiles_as_variant:
+ **/
+static GVariant *
+cd_device_get_profiles_as_variant (CdDevice *device)
+{
+ CdProfile *profile;
+ guint i;
+ GVariant **profiles = NULL;
+ GVariant *value;
+
+ /* copy the object paths */
+ profiles = g_new0 (GVariant *, device->priv->profiles->len + 1);
+ for (i=0; i<device->priv->profiles->len; i++) {
+ profile = g_ptr_array_index (device->priv->profiles, i);
+ profiles[i] = g_variant_new_object_path (cd_profile_get_object_path (profile));
+ }
+
+ /* format the value */
+ value = g_variant_new_array (G_VARIANT_TYPE_OBJECT_PATH,
+ profiles,
+ device->priv->profiles->len);
+ g_free (profiles);
+ return value;
+}
+
+/**
+ * cd_device_remove_profile:
+ **/
+gboolean
+cd_device_remove_profile (CdDevice *device,
+ const gchar *profile_object_path,
+ GError **error)
+{
+ CdDevicePrivate *priv = device->priv;
+ CdProfile *profile_tmp;
+ gboolean ret = FALSE;
+ guint i;
+
+ /* check the profile exists on this device */
+ for (i=0; i<priv->profiles->len; i++) {
+ profile_tmp = g_ptr_array_index (priv->profiles, i);
+ if (g_strcmp0 (profile_object_path,
+ cd_profile_get_object_path (profile_tmp)) == 0) {
+ ret = TRUE;
+ break;
+ }
+ }
+ if (!ret) {
+ g_set_error (error,
+ CD_MAIN_ERROR,
+ CD_MAIN_ERROR_FAILED,
+ "profile object path '%s' does not exist on '%s'",
+ profile_object_path,
+ priv->object_path);
+ goto out;
+ }
+
+ /* remove from the array */
+ ret = g_ptr_array_remove (priv->profiles, profile_tmp);
+ g_assert (ret);
+
+ /* emit */
+ cd_device_dbus_emit_property_changed (device,
+ "Profiles",
+ cd_device_get_profiles_as_variant (device));
+out:
+ return ret;
+}
+
+/**
* cd_device_dbus_method_call:
**/
static void
@@ -237,6 +330,7 @@ cd_device_dbus_method_call (GDBusConnection *connection_, const gchar *sender,
gchar *property_name = NULL;
gchar *property_value = NULL;
gchar *regex = NULL;
+ GError *error = NULL;
guint i;
GVariant *tuple = NULL;
GVariant *value = NULL;
@@ -283,7 +377,35 @@ cd_device_dbus_method_call (GDBusConnection *connection_, const gchar *sender,
g_ptr_array_add (priv->profiles, profile);
/* emit */
- cd_device_dbus_emit_changed (device);
+ cd_device_dbus_emit_property_changed (device,
+ "Profiles",
+ cd_device_get_profiles_as_variant (device));
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ goto out;
+ }
+
+ if (g_strcmp0 (method_name, "RemoveProfile") == 0) {
+
+ /* require auth */
+ ret = cd_main_sender_authenticated (invocation,
+ sender,
+ "org.freedesktop.color-manager.modify-device");
+ if (!ret)
+ goto out;
+
+ /* try to remove */
+ g_variant_get (parameters, "(o)",
+ &profile_object_path);
+ ret = cd_device_remove_profile (device,
+ profile_object_path,
+ &error);
+ if (!ret) {
+ g_dbus_method_invocation_return_gerror (invocation,
+ error);
+ g_error_free (error);
+ goto out;
+ }
+
g_dbus_method_invocation_return_value (invocation, NULL);
goto out;
}
@@ -359,7 +481,9 @@ cd_device_dbus_method_call (GDBusConnection *connection_, const gchar *sender,
}
/* emit */
- cd_device_dbus_emit_changed (device);
+ cd_device_dbus_emit_property_changed (device,
+ "Profiles",
+ cd_device_get_profiles_as_variant (device));
g_dbus_method_invocation_return_value (invocation, NULL);
goto out;
}
@@ -378,17 +502,23 @@ cd_device_dbus_method_call (GDBusConnection *connection_, const gchar *sender,
g_variant_get (parameters, "(ss)",
&property_name,
&property_value);
+ g_debug ("Attempting to set %s to %s",
+ property_name, property_value);
if (g_strcmp0 (property_name, "Model") == 0) {
g_free (priv->model);
priv->model = g_strdup (property_value);
- cd_device_dbus_emit_changed (device);
+ cd_device_dbus_emit_property_changed (device,
+ property_name,
+ g_variant_new_string (priv->model));
g_dbus_method_invocation_return_value (invocation, NULL);
goto out;
}
if (g_strcmp0 (property_name, "Kind") == 0) {
g_free (priv->kind);
priv->kind = g_strdup (property_value);
- cd_device_dbus_emit_changed (device);
+ cd_device_dbus_emit_property_changed (device,
+ property_name,
+ g_variant_new_string (priv->kind));
g_dbus_method_invocation_return_value (invocation, NULL);
goto out;
}
@@ -419,10 +549,8 @@ cd_device_dbus_get_property (GDBusConnection *connection_, const gchar *sender,
const gchar *property_name, GError **error,
gpointer user_data)
{
- CdDevicePrivate *priv = CD_DEVICE (user_data)->priv;
- CdProfile *profile;
- guint i;
- GVariant **profiles = NULL;
+ CdDevice *device = CD_DEVICE (user_data);
+ CdDevicePrivate *priv = device->priv;
GVariant *retval = NULL;
if (g_strcmp0 (property_name, "Created") == 0) {
@@ -448,18 +576,7 @@ cd_device_dbus_get_property (GDBusConnection *connection_, const gchar *sender,
goto out;
}
if (g_strcmp0 (property_name, "Profiles") == 0) {
-
- /* copy the object paths */
- profiles = g_new0 (GVariant *, priv->profiles->len + 1);
- for (i=0; i<priv->profiles->len; i++) {
- profile = g_ptr_array_index (priv->profiles, i);
- profiles[i] = g_variant_new_object_path (cd_profile_get_object_path (profile));
- }
-
- /* format the value */
- retval = g_variant_new_array (G_VARIANT_TYPE_OBJECT_PATH,
- profiles,
- priv->profiles->len);
+ retval = cd_device_get_profiles_as_variant (device);
goto out;
}
diff --git a/src/cd-device.h b/src/cd-device.h
index f9b5bdf..b47bcaf 100644
--- a/src/cd-device.h
+++ b/src/cd-device.h
@@ -24,6 +24,8 @@
#include <glib-object.h>
+#include "cd-profile.h"
+
G_BEGIN_DECLS
#define CD_TYPE_DEVICE (cd_device_get_type ())
@@ -61,6 +63,9 @@ void cd_device_set_id (CdDevice *device,
GPtrArray *cd_device_get_profiles (CdDevice *device);
void cd_device_set_profiles (CdDevice *device,
GPtrArray *profiles);
+gboolean cd_device_remove_profile (CdDevice *device,
+ const gchar *profile_object_path,
+ GError **error);
const gchar *cd_device_get_object_path (CdDevice *device);
gboolean cd_device_register_object (CdDevice *device,
GDBusConnection *connection,
diff --git a/src/cd-main.c b/src/cd-main.c
index fce326e..5095815 100644
--- a/src/cd-main.c
+++ b/src/cd-main.c
@@ -47,12 +47,29 @@ cd_main_profile_removed (CdProfile *profile)
{
gboolean ret;
gchar *object_path_tmp;
+ CdDevice *device_tmp;
GError *error = NULL;
+ GPtrArray *devices;
+ guint i;
/* remove from the array before emitting */
object_path_tmp = g_strdup (cd_profile_get_object_path (profile));
cd_profile_array_remove (profiles_array, profile);
+ /* try to remove this profile from all devices */
+ devices = cd_device_array_get_array (devices_array);
+ for (i=0; i<devices->len; i++) {
+ device_tmp = g_ptr_array_index (devices, i);
+ ret = cd_device_remove_profile (device_tmp,
+ object_path_tmp,
+ NULL);
+ if (ret) {
+ g_debug ("automatically removing %s from %s as removed",
+ object_path_tmp,
+ cd_device_get_object_path (device_tmp));
+ }
+ }
+
/* emit signal */
g_debug ("Emitting ProfileRemoved(%s)", object_path_tmp);
ret = g_dbus_connection_emit_signal (connection,
@@ -68,6 +85,7 @@ cd_main_profile_removed (CdProfile *profile)
g_error_free (error);
}
g_free (object_path_tmp);
+ g_ptr_array_unref (devices);
}
/**
@@ -534,10 +552,6 @@ out:
g_object_unref (device);
if (profile != NULL)
g_object_unref (profile);
- if (tuple != NULL)
- g_variant_unref (tuple);
- if (value != NULL)
- g_variant_unref (value);
return;
}
diff --git a/src/cd-profile.c b/src/cd-profile.c
index 276d466..1f98b4b 100644
--- a/src/cd-profile.c
+++ b/src/cd-profile.c
@@ -114,13 +114,36 @@ cd_profile_get_filename (CdProfile *profile)
}
/**
- * cd_profile_dbus_emit_changed:
+ * cd_profile_dbus_emit_property_changed:
**/
static void
-cd_profile_dbus_emit_changed (CdProfile *profile)
+cd_profile_dbus_emit_property_changed (CdProfile *profile,
+ const gchar *property_name,
+ GVariant *property_value)
{
gboolean ret;
- GError *error = NULL;
+ GError *error_local = NULL;
+ GVariantBuilder builder;
+ GVariantBuilder invalidated_builder;
+
+ /* build the dict */
+ g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as"));
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (&builder,
+ "{sv}",
+ property_name,
+ property_value);
+ g_dbus_connection_emit_signal (profile->priv->connection,
+ NULL,
+ profile->priv->object_path,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ g_variant_new ("(sa{sv}as)",
+ COLORD_DBUS_INTERFACE_PROFILE,
+ &builder,
+ &invalidated_builder),
+ &error_local);
+ g_assert_no_error (error_local);
/* emit signal */
ret = g_dbus_connection_emit_signal (profile->priv->connection,
@@ -129,10 +152,10 @@ cd_profile_dbus_emit_changed (CdProfile *profile)
COLORD_DBUS_INTERFACE_PROFILE,
"Changed",
NULL,
- &error);
+ &error_local);
if (!ret) {
- g_warning ("failed to send signal %s", error->message);
- g_error_free (error);
+ g_warning ("failed to send signal %s", error_local->message);
+ g_error_free (error_local);
}
}
@@ -165,6 +188,8 @@ cd_profile_dbus_method_call (GDBusConnection *connection_, const gchar *sender,
g_variant_get (parameters, "(ss)",
&property_name,
&property_value);
+ g_debug ("Attempting to set %s to %s",
+ property_name, property_value);
if (g_strcmp0 (property_name, "Filename") == 0) {
ret = cd_profile_set_filename (profile, property_value, &error);
if (!ret) {
@@ -173,13 +198,20 @@ cd_profile_dbus_method_call (GDBusConnection *connection_, const gchar *sender,
g_error_free (error);
goto out;
}
- cd_profile_dbus_emit_changed (profile);
+ cd_profile_dbus_emit_property_changed (profile,
+ property_name,
+ g_variant_new_string (property_value));
+ cd_profile_dbus_emit_property_changed (profile,
+ "Title",
+ g_variant_new_string (profile->priv->title));
g_dbus_method_invocation_return_value (invocation, NULL);
goto out;
}
if (g_strcmp0 (property_name, "Qualifier") == 0) {
cd_profile_set_qualifier (profile, property_value);
- cd_profile_dbus_emit_changed (profile);
+ cd_profile_dbus_emit_property_changed (profile,
+ property_name,
+ g_variant_new_string (property_value));
g_dbus_method_invocation_return_value (invocation, NULL);
goto out;
}
diff --git a/src/org.freedesktop.ColorManager.Device.xml b/src/org.freedesktop.ColorManager.Device.xml
index ca52c00..745ff53 100644
--- a/src/org.freedesktop.ColorManager.Device.xml
+++ b/src/org.freedesktop.ColorManager.Device.xml
@@ -68,7 +68,6 @@
</doc:doc>
</property>
-
<!--***********************************************************-->
<method name='SetProperty'>
<annotation name='org.freedesktop.DBus.GLib.Async' value=''/>
@@ -141,7 +140,7 @@
</doc:para>
</doc:description>
</doc:doc>
- <arg type='o' name='profile_id' direction='in'>
+ <arg type='o' name='object_path' direction='in'>
<doc:doc>
<doc:summary>
<doc:para>
diff --git a/src/org.freedesktop.ColorManager.xml b/src/org.freedesktop.ColorManager.xml
index 4370154..054862e 100644
--- a/src/org.freedesktop.ColorManager.xml
+++ b/src/org.freedesktop.ColorManager.xml
@@ -24,48 +24,6 @@
<!--***********************************************************-->
<!--
- <method name='GetProfilesForType'>
- <annotation name='org.freedesktop.DBus.GLib.Async' value=''/>
- <doc:doc>
- <doc:description>
- <doc:para>
- Gets the profiles for a device type.
- </doc:para>
- </doc:description>
- </doc:doc>
- <arg type='s' name='type' direction='in'>
- <doc:doc>
- <doc:summary>
- <doc:para>
- A device type, e.g. <doc:tt>scanner</doc:tt>, <doc:tt>display</doc:tt>,
- <doc:tt>printer</doc:tt> or <doc:tt>camera</doc:tt>.
- </doc:para>
- </doc:summary>
- </doc:doc>
- </arg>
- <arg type='s' name='options' direction='in'>
- <doc:doc>
- <doc:summary>
- <doc:para>
- Options to give hints about what profiles to choose. Currently unused.
- </doc:para>
- </doc:summary>
- </doc:doc>
- </arg>
- <arg type='ao' name='profiles' direction='out'>
- <doc:doc>
- <doc:summary>
- <doc:para>
- An array of profile paths to use with this type of device.
- </doc:para>
- </doc:summary>
- </doc:doc>
- </arg>
- </method>
--->
-
- <!--***********************************************************-->
-<!--
<method name='GetProfilesForFile'>
<annotation name='org.freedesktop.DBus.GLib.Async' value=''/>
<doc:doc>
@@ -84,15 +42,6 @@
</doc:summary>
</doc:doc>
</arg>
- <arg type='s' name='options' direction='in'>
- <doc:doc>
- <doc:summary>
- <doc:para>
- Options to give hints about what profiles to choose. Currently unused.
- </doc:para>
- </doc:summary>
- </doc:doc>
- </arg>
<arg type='ao' name='profiles' direction='out'>
<doc:doc>
<doc:summary>