[gnome-color-manager] Make the GcmSensor get_ambient() and sample() functions GIO async, and provide sync versions



commit 2da86284a96b28d51a808db7e992d7470c333514
Author: Richard Hughes <richard hughsie com>
Date:   Tue Aug 3 13:02:58 2010 +0100

    Make the GcmSensor get_ambient() and sample() functions GIO async, and provide sync versions

 libcolor-glib/gcm-self-test.c    |    8 +-
 libcolor-glib/gcm-sensor-dummy.c |  194 +++++++++++++++++++++---
 libcolor-glib/gcm-sensor-huey.c  |  281 ++++++++++++++++++++++++++++++-----
 libcolor-glib/gcm-sensor.c       |  312 ++++++++++++++++++++++++-------------
 libcolor-glib/gcm-sensor.h       |   56 +++++--
 src/gcm-picker.c                 |    4 +-
 tools/gcm-sensor-colormunki.c    |    9 +-
 tools/gcm-sensor-example.c       |   18 +--
 8 files changed, 679 insertions(+), 203 deletions(-)
---
diff --git a/libcolor-glib/gcm-self-test.c b/libcolor-glib/gcm-self-test.c
index 0951472..d036c3e 100644
--- a/libcolor-glib/gcm-self-test.c
+++ b/libcolor-glib/gcm-self-test.c
@@ -167,10 +167,6 @@ gcm_test_sensor_func (void)
 	sensor = gcm_sensor_dummy_new ();
 	g_signal_connect (sensor, "button-pressed", G_CALLBACK (gcm_test_sensor_button_pressed_cb), &signal_count);
 
-	ret = gcm_sensor_startup (sensor, &error);
-	g_assert_no_error (error);
-	g_assert (ret);
-
 	/* set LEDs */
 	ret = gcm_sensor_set_leds (sensor, 0x0f, &error);
 	g_assert_no_error (error);
@@ -181,14 +177,14 @@ gcm_test_sensor_func (void)
 	g_assert_cmpint (gcm_sensor_get_output_type (sensor), ==, GCM_SENSOR_OUTPUT_TYPE_LCD);
 
 	/* get ambient */
-	ret = gcm_sensor_get_ambient (sensor, &value, &error);
+	ret = gcm_sensor_get_ambient (sensor, NULL, &value, &error);
 	g_assert_cmpint (signal_count, ==, 0);
 	g_assert_no_error (error);
 	g_assert (ret);
 	g_debug ("ambient = %.1lf Lux", value);
 
 	/* sample color */
-	ret = gcm_sensor_sample (sensor, &values, &error);
+	ret = gcm_sensor_sample (sensor, NULL, &values, &error);
 	g_assert_cmpint (signal_count, ==, 1);
 	g_assert_no_error (error);
 	g_assert (ret);
diff --git a/libcolor-glib/gcm-sensor-dummy.c b/libcolor-glib/gcm-sensor-dummy.c
index 5bf1faf..95324eb 100644
--- a/libcolor-glib/gcm-sensor-dummy.c
+++ b/libcolor-glib/gcm-sensor-dummy.c
@@ -34,45 +34,200 @@
 
 G_DEFINE_TYPE (GcmSensorDummy, gcm_sensor_dummy, GCM_TYPE_SENSOR)
 
+/* async state for the sensor readings */
+typedef struct {
+	gboolean		 ret;
+	gdouble			 ambient_value;
+	GcmColorXYZ		*sample;
+	GSimpleAsyncResult	*res;
+	GcmSensor		*sensor;
+} GcmSensorAsyncState;
+
 /**
- * gcm_sensor_dummy_get_ambient:
+ * gcm_sensor_dummy_get_ambient_state_finish:
+ **/
+static void
+gcm_sensor_dummy_get_ambient_state_finish (GcmSensorAsyncState *state, const GError *error)
+{
+	gdouble *result;
+
+	/* set result to temp memory location */
+	if (state->ret) {
+		result = g_new0 (gdouble, 1);
+		*result = state->ambient_value;
+		g_simple_async_result_set_op_res_gpointer (state->res, result, (GDestroyNotify) g_free);
+	} else {
+		g_simple_async_result_set_from_error (state->res, error);
+	}
+
+	/* complete */
+	g_simple_async_result_complete_in_idle (state->res);
+
+	g_object_unref (state->res);
+	g_object_unref (state->sensor);
+	g_slice_free (GcmSensorAsyncState, state);
+}
+
+/**
+ * gcm_sensor_dummy_get_ambient_small_wait_cb:
  **/
 static gboolean
-gcm_sensor_dummy_get_ambient (GcmSensor *sensor, gdouble *value, GError **error)
+gcm_sensor_dummy_get_ambient_small_wait_cb (GcmSensorAsyncState *state)
 {
-	*value = 17.0f;
-	return TRUE;
+	state->ret = TRUE;
+	state->ambient_value = 7.7f;
+
+	/* just return without a problem */
+	gcm_sensor_dummy_get_ambient_state_finish (state, NULL);
+	return FALSE;
 }
 
 /**
- * gcm_sensor_dummy_set_leds:
+ * gcm_sensor_dummy_get_ambient_async:
+ **/
+static void
+gcm_sensor_dummy_get_ambient_async (GcmSensor *sensor, GCancellable *cancellable, GAsyncResult *res)
+{
+	GcmSensorAsyncState *state;
+
+	g_return_if_fail (GCM_IS_SENSOR (sensor));
+	g_return_if_fail (res != NULL);
+
+	/* save state */
+	state = g_slice_new0 (GcmSensorAsyncState);
+	state->res = g_object_ref (res);
+	state->sensor = g_object_ref (sensor);
+
+	/* just complete in idle */
+	g_timeout_add_seconds (2, (GSourceFunc) gcm_sensor_dummy_get_ambient_small_wait_cb, state);
+}
+
+/**
+ * gcm_sensor_dummy_get_ambient_finish:
  **/
 static gboolean
-gcm_sensor_dummy_set_leds (GcmSensor *sensor, guint8 value, GError **error)
+gcm_sensor_dummy_get_ambient_finish (GcmSensor *sensor, GAsyncResult *res, gdouble *value, GError **error)
 {
-	return TRUE;
+	GSimpleAsyncResult *simple;
+	gboolean ret = TRUE;
+
+	g_return_val_if_fail (GCM_IS_SENSOR (sensor), FALSE);
+	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* failed */
+	simple = G_SIMPLE_ASYNC_RESULT (res);
+	if (g_simple_async_result_propagate_error (simple, error)) {
+		ret = FALSE;
+		goto out;
+	}
+
+	/* grab detail */
+	if (value != NULL)
+		*value = *((gdouble*) g_simple_async_result_get_op_res_gpointer (simple));
+out:
+	return ret;
 }
 
+
 /**
- * gcm_sensor_dummy_sample:
+ * gcm_sensor_dummy_sample_state_finish:
+ **/
+static void
+gcm_sensor_dummy_sample_state_finish (GcmSensorAsyncState *state, const GError *error)
+{
+	GcmColorXYZ *result;
+
+	/* set result to temp memory location */
+	if (state->ret) {
+		result = g_new0 (GcmColorXYZ, 1);
+		gcm_color_copy_XYZ (state->sample, result);
+		g_simple_async_result_set_op_res_gpointer (state->res, result, (GDestroyNotify) g_free);
+	} else {
+		g_simple_async_result_set_from_error (state->res, error);
+	}
+
+	/* complete */
+	g_simple_async_result_complete_in_idle (state->res);
+
+	g_object_unref (state->res);
+	g_object_unref (state->sensor);
+	g_free (state->sample);
+	g_slice_free (GcmSensorAsyncState, state);
+}
+
+/**
+ * gcm_sensor_dummy_sample_small_wait_cb:
  **/
 static gboolean
-gcm_sensor_dummy_sample (GcmSensor *sensor, GcmColorXYZ *value, GError **error)
+gcm_sensor_dummy_sample_small_wait_cb (GcmSensorAsyncState *state)
 {
-	value->X = 17.0f;
-	value->Y = 18.0f;
-	value->Z = 19.0f;
+	state->ret = TRUE;
+	state->sample->X = 0.1;
+	state->sample->Y = 0.2;
+	state->sample->Z = 0.3;
 
 	/* emulate */
-	gcm_sensor_button_pressed (sensor);
-	return TRUE;
+	gcm_sensor_button_pressed (state->sensor);
+
+	/* just return without a problem */
+	gcm_sensor_dummy_sample_state_finish (state, NULL);
+	return FALSE;
 }
 
 /**
- * gcm_sensor_dummy_startup:
+ * gcm_sensor_dummy_sample_async:
+ **/
+static void
+gcm_sensor_dummy_sample_async (GcmSensor *sensor, GCancellable *cancellable, GAsyncResult *res)
+{
+	GcmSensorAsyncState *state;
+
+	g_return_if_fail (GCM_IS_SENSOR (sensor));
+	g_return_if_fail (res != NULL);
+
+	/* save state */
+	state = g_slice_new0 (GcmSensorAsyncState);
+	state->res = g_object_ref (res);
+	state->sensor = g_object_ref (sensor);
+	state->sample = g_new0 (GcmColorXYZ, 1);
+
+	/* just complete in idle */
+	g_timeout_add_seconds (2, (GSourceFunc) gcm_sensor_dummy_sample_small_wait_cb, state);
+}
+
+/**
+ * gcm_sensor_dummy_sample_finish:
+ **/
+static gboolean
+gcm_sensor_dummy_sample_finish (GcmSensor *sensor, GAsyncResult *res, GcmColorXYZ *value, GError **error)
+{
+	GSimpleAsyncResult *simple;
+	gboolean ret = TRUE;
+
+	g_return_val_if_fail (GCM_IS_SENSOR (sensor), FALSE);
+	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* failed */
+	simple = G_SIMPLE_ASYNC_RESULT (res);
+	if (g_simple_async_result_propagate_error (simple, error)) {
+		ret = FALSE;
+		goto out;
+	}
+
+	/* grab detail */
+	if (value != NULL)
+		gcm_color_copy_XYZ ((GcmColorXYZ*) g_simple_async_result_get_op_res_gpointer (simple), value);
+out:
+	return ret;
+}
+
+/**
+ * gcm_sensor_dummy_set_leds:
  **/
 static gboolean
-gcm_sensor_dummy_startup (GcmSensor *sensor, GError **error)
+gcm_sensor_dummy_set_leds (GcmSensor *sensor, guint8 value, GError **error)
 {
 	return TRUE;
 }
@@ -86,10 +241,11 @@ gcm_sensor_dummy_class_init (GcmSensorDummyClass *klass)
 	GcmSensorClass *parent_class = GCM_SENSOR_CLASS (klass);
 
 	/* setup klass links */
-	parent_class->get_ambient = gcm_sensor_dummy_get_ambient;
+	parent_class->get_ambient_async = gcm_sensor_dummy_get_ambient_async;
+	parent_class->get_ambient_finish = gcm_sensor_dummy_get_ambient_finish;
+	parent_class->sample_async = gcm_sensor_dummy_sample_async;
+	parent_class->sample_finish = gcm_sensor_dummy_sample_finish;
 	parent_class->set_leds = gcm_sensor_dummy_set_leds;
-	parent_class->sample = gcm_sensor_dummy_sample;
-	parent_class->startup = gcm_sensor_dummy_startup;
 }
 
 /**
diff --git a/libcolor-glib/gcm-sensor-huey.c b/libcolor-glib/gcm-sensor-huey.c
index f78f57a..c2955da 100644
--- a/libcolor-glib/gcm-sensor-huey.c
+++ b/libcolor-glib/gcm-sensor-huey.c
@@ -50,6 +50,7 @@ static void     gcm_sensor_huey_finalize	(GObject     *object);
  **/
 struct _GcmSensorHueyPrivate
 {
+	gboolean			 done_startup;
 	GcmUsb				*usb;
 	GcmMat3x3			 calibration_matrix1;
 	GcmMat3x3			 calibration_matrix2;
@@ -58,6 +59,18 @@ struct _GcmSensorHueyPrivate
 	gchar				 unlock_string[5];
 };
 
+/* async state for the sensor readings */
+typedef struct {
+	gboolean			 ret;
+	gdouble				 ambient_value;
+	gulong				 cancellable_id;
+	GCancellable			*cancellable;
+	GSimpleAsyncResult		*res;
+	GcmSensor			*sensor;
+} GcmSensorAsyncState;
+
+static gboolean gcm_sensor_huey_startup (GcmSensor *sensor, GError **error);
+
 G_DEFINE_TYPE (GcmSensorHuey, gcm_sensor_huey, GCM_TYPE_SENSOR)
 
 #define HUEY_VENDOR_ID			0x0971
@@ -595,12 +608,53 @@ out:
 	return ret;
 }
 
+#if 0
 /**
- * gcm_sensor_huey_get_ambient:
+ * gcm_sensor_huey_get_ambient_state_finish:
  **/
-static gboolean
-gcm_sensor_huey_get_ambient (GcmSensor *sensor, gdouble *value, GError **error)
+static void
+gcm_sensor_huey_get_ambient_state_finish (GcmSensorAsyncState *state, const GError *error)
 {
+	gdouble *result;
+
+	/* set result to temp memory location */
+	if (state->ret) {
+		result = g_new0 (gdouble, 1);
+		*result = state->ambient_value;
+		g_simple_async_result_set_op_res_gpointer (state->res, result, (GDestroyNotify) g_free);
+	} else {
+		g_simple_async_result_set_from_error (state->res, error);
+	}
+
+	/* complete */
+	g_simple_async_result_complete_in_idle (state->res);
+
+	/* deallocate */
+	if (state->cancellable != NULL) {
+		g_cancellable_disconnect (state->cancellable, state->cancellable_id);
+		g_object_unref (state->cancellable);
+	}
+	g_object_unref (state->res);
+	g_object_unref (state->sensor);
+	g_slice_free (GcmSensorAsyncState, state);
+}
+#endif
+
+/**
+ * gcm_sensor_huey_cancellable_cancel_cb:
+ **/
+static void
+gcm_sensor_huey_cancellable_cancel_cb (GCancellable *cancellable, GcmSensorAsyncState *state)
+{
+	g_warning ("cancelled huey");
+}
+
+static void
+gcm_sensor_huey_get_ambient_thread_cb (GSimpleAsyncResult *res, GObject *object, GCancellable *cancellable)
+{
+	GcmSensor *sensor = GCM_SENSOR (object);
+	gdouble *result;
+	GError *error = NULL;
 	guchar reply[8];
 	gboolean ret = FALSE;
 	gsize reply_read;
@@ -608,20 +662,34 @@ gcm_sensor_huey_get_ambient (GcmSensor *sensor, gdouble *value, GError **error)
 	guchar request[] = { HUEY_COMMAND_GET_AMBIENT, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 	GcmSensorHuey *sensor_huey = GCM_SENSOR_HUEY (sensor);
 
+	/* ensure sensor is started */
+	if (!sensor_huey->priv->done_startup) {
+		ret = gcm_sensor_huey_startup (sensor, &error);
+		if (!ret) {
+			g_simple_async_result_set_from_error (res, error);
+			g_error_free (error);
+			goto out;
+		}
+	}
+
 	/* no hardware support */
 	if (gcm_sensor_get_output_type (sensor) == GCM_SENSOR_OUTPUT_TYPE_PROJECTOR) {
-		g_set_error_literal (error, GCM_SENSOR_ERROR,
+		g_set_error_literal (&error, GCM_SENSOR_ERROR,
 				     GCM_SENSOR_ERROR_NO_SUPPORT,
 				     "HUEY cannot measure ambient light in projector mode");
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
 	}
 
 	/* ensure the user set this */
 	output_type = gcm_sensor_get_output_type (sensor);
 	if (output_type == GCM_SENSOR_OUTPUT_TYPE_UNKNOWN) {
-		g_set_error_literal (error, GCM_SENSOR_ERROR,
+		g_set_error_literal (&error, GCM_SENSOR_ERROR,
 				     GCM_SENSOR_ERROR_INTERNAL,
 				     "output sensor type was not set");
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
 	}
 
@@ -630,15 +698,70 @@ gcm_sensor_huey_get_ambient (GcmSensor *sensor, gdouble *value, GError **error)
 
 	/* hit hardware */
 	request[2] = (output_type == GCM_SENSOR_OUTPUT_TYPE_LCD) ? 0x00 : 0x02;
-	ret = gcm_sensor_huey_send_data (sensor_huey, request, 8, reply, 8, &reply_read, error);
-	if (!ret)
+	ret = gcm_sensor_huey_send_data (sensor_huey, request, 8, reply, 8, &reply_read, &error);
+	if (!ret) {
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
+	}
 
 	/* parse the value */
-	*value = (gdouble) gcm_buffer_read_uint16_be (reply+5) / HUEY_AMBIENT_UNITS_TO_LUX;
+	result = g_new0 (gdouble, 1);
+	*result = (gdouble) gcm_buffer_read_uint16_be (reply+5) / HUEY_AMBIENT_UNITS_TO_LUX;
+	g_simple_async_result_set_op_res_gpointer (res, result, (GDestroyNotify) g_free);
 out:
 	/* set state */
 	gcm_sensor_set_state (sensor, GCM_SENSOR_STATE_IDLE);
+}
+
+/**
+ * gcm_sensor_huey_get_ambient_async:
+ **/
+static void
+gcm_sensor_huey_get_ambient_async (GcmSensor *sensor, GCancellable *cancellable, GAsyncResult *res)
+{
+	GcmSensorAsyncState *state;
+
+	g_return_if_fail (GCM_IS_SENSOR (sensor));
+	g_return_if_fail (res != NULL);
+
+	/* save state */
+	state = g_slice_new0 (GcmSensorAsyncState);
+	state->res = g_object_ref (res);
+	state->sensor = g_object_ref (sensor);
+	if (cancellable != NULL) {
+		state->cancellable = g_object_ref (cancellable);
+		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (gcm_sensor_huey_cancellable_cancel_cb), state, NULL);
+	}
+
+	/* run in a thread */
+	g_simple_async_result_run_in_thread (G_SIMPLE_ASYNC_RESULT (res), gcm_sensor_huey_get_ambient_thread_cb, 0, cancellable);
+}
+
+/**
+ * gcm_sensor_huey_get_ambient_finish:
+ **/
+static gboolean
+gcm_sensor_huey_get_ambient_finish (GcmSensor *sensor, GAsyncResult *res, gdouble *value, GError **error)
+{
+	GSimpleAsyncResult *simple;
+	gboolean ret = TRUE;
+
+	g_return_val_if_fail (GCM_IS_SENSOR (sensor), FALSE);
+	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* failed */
+	simple = G_SIMPLE_ASYNC_RESULT (res);
+	if (g_simple_async_result_propagate_error (simple, error)) {
+		ret = FALSE;
+		goto out;
+	}
+
+	/* grab detail */
+	if (value != NULL)
+		*value = *((gdouble*) g_simple_async_result_get_op_res_gpointer (simple));
+out:
 	return ret;
 }
 
@@ -711,27 +834,38 @@ out:
 #define HUEY_ABSOLUTE_OFFSET_GREEN	0.000119
 #define HUEY_ABSOLUTE_OFFSET_BLUE	0.000018
 
-/**
- * gcm_sensor_huey_sample:
- *
- * Sample the data in two passes.
- **/
-static gboolean
-gcm_sensor_huey_sample (GcmSensor *sensor, GcmColorXYZ *value, GError **error)
+static void
+gcm_sensor_huey_sample_thread_cb (GSimpleAsyncResult *res, GObject *object, GCancellable *cancellable)
 {
+	GcmSensor *sensor = GCM_SENSOR (object);
+	GError *error = NULL;
 	gboolean ret = FALSE;
 	gdouble precision_value;
-	GcmColorRGB native;
+	GcmColorRGB color_native;
+	GcmColorXYZ color_result;
+	GcmColorXYZ *tmp;
 	GcmSensorHueyMultiplier multiplier;
-	GcmVec3 *input = (GcmVec3 *) &native;
-	GcmVec3 *output = (GcmVec3 *) value;
 	GcmSensorHuey *sensor_huey = GCM_SENSOR_HUEY (sensor);
+	GcmVec3 *color_native_vec3;
+	GcmVec3 *color_result_vec3;
+
+	/* ensure sensor is started */
+	if (!sensor_huey->priv->done_startup) {
+		ret = gcm_sensor_huey_startup (sensor, &error);
+		if (!ret) {
+			g_simple_async_result_set_from_error (res, error);
+			g_error_free (error);
+			goto out;
+		}
+	}
 
 	/* no hardware support */
 	if (gcm_sensor_get_output_type (sensor) == GCM_SENSOR_OUTPUT_TYPE_PROJECTOR) {
-		g_set_error_literal (error, GCM_SENSOR_ERROR,
+		g_set_error_literal (&error, GCM_SENSOR_ERROR,
 				     GCM_SENSOR_ERROR_NO_SUPPORT,
 				     "HUEY cannot measure ambient light in projector mode");
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
 	}
 
@@ -742,16 +876,19 @@ gcm_sensor_huey_sample (GcmSensor *sensor, GcmColorXYZ *value, GError **error)
 	multiplier.R = 1;
 	multiplier.G = 1;
 	multiplier.B = 1;
-	ret = gcm_sensor_huey_sample_for_threshold (sensor_huey, &multiplier, &native, error);
-	if (!ret)
+	ret = gcm_sensor_huey_sample_for_threshold (sensor_huey, &multiplier, &color_native, &error);
+	if (!ret) {
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
-	egg_debug ("initial values: red=%0.6lf, green=%0.6lf, blue=%0.6lf", native.R, native.G, native.B);
+	}
+	egg_debug ("initial values: red=%0.6lf, green=%0.6lf, blue=%0.6lf", color_native.R, color_native.G, color_native.B);
 
 	/* compromise between the amount of time and the precision */
 	precision_value = (gdouble) HUEY_PRECISION_TIME_VALUE;
-	multiplier.R = precision_value * native.R;
-	multiplier.G = precision_value * native.G;
-	multiplier.B = precision_value * native.B;
+	multiplier.R = precision_value * color_native.R;
+	multiplier.G = precision_value * color_native.G;
+	multiplier.B = precision_value * color_native.B;
 
 	/* don't allow a value of zero */
 	if (multiplier.R == 0)
@@ -761,23 +898,86 @@ gcm_sensor_huey_sample (GcmSensor *sensor, GcmColorXYZ *value, GError **error)
 	if (multiplier.B == 0)
 		multiplier.B = 1;
 	egg_debug ("using multiplier factor: red=%i, green=%i, blue=%i", multiplier.R, multiplier.G, multiplier.B);
-	ret = gcm_sensor_huey_sample_for_threshold (sensor_huey, &multiplier, &native, error);
-	if (!ret)
+	ret = gcm_sensor_huey_sample_for_threshold (sensor_huey, &multiplier, &color_native, &error);
+	if (!ret) {
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
-	egg_debug ("scaled values: red=%0.6lf, green=%0.6lf, blue=%0.6lf", native.R, native.G, native.B);
-	egg_debug ("PRE MULTIPLY: %s\n", gcm_vec3_to_string (input));
+	}
+
+	/* get colors as vectors */
+	color_native_vec3 = gcm_color_get_RGB_Vec3 (&color_native);
+	color_result_vec3 = gcm_color_get_XYZ_Vec3 (&color_result);
+
+	egg_debug ("scaled values: red=%0.6lf, green=%0.6lf, blue=%0.6lf", color_native.R, color_native.G, color_native.B);
+	egg_debug ("PRE MULTIPLY: %s\n", gcm_vec3_to_string (color_native_vec3));
 
 	/* it would be rediculous for the device to emit RGB, it would be completely arbitrary --
 	 * we assume the matrix of data is designed to convert to LAB or XYZ */
-	gcm_mat33_vector_multiply (&sensor_huey->priv->calibration_matrix1, input, output);
+	gcm_mat33_vector_multiply (&sensor_huey->priv->calibration_matrix1, color_native_vec3, color_result_vec3);
 
 	/* scale correct */
-	gcm_vec3_scalar_multiply (output, HUEY_XYZ_POST_MULTIPLY_SCALE_FACTOR, output);
+	gcm_vec3_scalar_multiply (color_result_vec3, HUEY_XYZ_POST_MULTIPLY_SCALE_FACTOR, color_result_vec3);
 
-	egg_debug ("POST MULTIPLY: %s\n", gcm_vec3_to_string (output));
+	egg_debug ("POST MULTIPLY: %s\n", gcm_vec3_to_string (color_result_vec3));
+
+	/* save result */
+	tmp = g_new0 (GcmColorXYZ, 1);
+	gcm_color_copy_XYZ (&color_result, tmp);
+	g_simple_async_result_set_op_res_gpointer (res, tmp, (GDestroyNotify) g_free);
 out:
 	/* set state */
 	gcm_sensor_set_state (sensor, GCM_SENSOR_STATE_IDLE);
+}
+
+/**
+ * gcm_sensor_huey_sample_async:
+ **/
+static void
+gcm_sensor_huey_sample_async (GcmSensor *sensor, GCancellable *cancellable, GAsyncResult *res)
+{
+	GcmSensorAsyncState *state;
+
+	g_return_if_fail (GCM_IS_SENSOR (sensor));
+	g_return_if_fail (res != NULL);
+
+	/* save state */
+	state = g_slice_new0 (GcmSensorAsyncState);
+	state->res = g_object_ref (res);
+	state->sensor = g_object_ref (sensor);
+	if (cancellable != NULL) {
+		state->cancellable = g_object_ref (cancellable);
+		state->cancellable_id = g_cancellable_connect (cancellable, G_CALLBACK (gcm_sensor_huey_cancellable_cancel_cb), state, NULL);
+	}
+
+	/* run in a thread */
+	g_simple_async_result_run_in_thread (G_SIMPLE_ASYNC_RESULT (res), gcm_sensor_huey_sample_thread_cb, 0, cancellable);
+}
+
+/**
+ * gcm_sensor_huey_sample_finish:
+ **/
+static gboolean
+gcm_sensor_huey_sample_finish (GcmSensor *sensor, GAsyncResult *res, GcmColorXYZ *value, GError **error)
+{
+	GSimpleAsyncResult *simple;
+	gboolean ret = TRUE;
+
+	g_return_val_if_fail (GCM_IS_SENSOR (sensor), FALSE);
+	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* failed */
+	simple = G_SIMPLE_ASYNC_RESULT (res);
+	if (g_simple_async_result_propagate_error (simple, error)) {
+		ret = FALSE;
+		goto out;
+	}
+
+	/* grab detail */
+	if (value != NULL)
+		gcm_color_copy_XYZ ((GcmColorXYZ*) g_simple_async_result_get_op_res_gpointer (simple), value);
+out:
 	return ret;
 }
 
@@ -883,6 +1083,9 @@ gcm_sensor_huey_startup (GcmSensor *sensor, GError **error)
 			goto out;
 		g_usleep (50000);
 	}
+
+	/* success */
+	sensor_huey->priv->done_startup = TRUE;
 out:
 	/* set state */
 	gcm_sensor_set_state (sensor, GCM_SENSOR_STATE_IDLE);
@@ -902,6 +1105,13 @@ gcm_sensor_huey_dump (GcmSensor *sensor, GString *data, GError **error)
 	guint i;
 	guint8 value;
 
+	/* ensure sensor is started */
+	if (!priv->done_startup) {
+		ret = gcm_sensor_huey_startup (sensor, error);
+		if (!ret)
+			goto out;
+	}
+
 	/* dump the unlock string */
 	g_string_append_printf (data, "huey-dump-version:%i\n", 2);
 	g_string_append_printf (data, "unlock-string:%s\n", priv->unlock_string);
@@ -934,10 +1144,11 @@ gcm_sensor_huey_class_init (GcmSensorHueyClass *klass)
 	object_class->finalize = gcm_sensor_huey_finalize;
 
 	/* setup klass links */
-	parent_class->get_ambient = gcm_sensor_huey_get_ambient;
+	parent_class->get_ambient_async = gcm_sensor_huey_get_ambient_async;
+	parent_class->get_ambient_finish = gcm_sensor_huey_get_ambient_finish;
 	parent_class->set_leds = gcm_sensor_huey_set_leds;
-	parent_class->sample = gcm_sensor_huey_sample;
-	parent_class->startup = gcm_sensor_huey_startup;
+	parent_class->sample_async = gcm_sensor_huey_sample_async;
+	parent_class->sample_finish = gcm_sensor_huey_sample_finish;
 	parent_class->dump = gcm_sensor_huey_dump;
 
 	g_type_class_add_private (klass, sizeof (GcmSensorHueyPrivate));
diff --git a/libcolor-glib/gcm-sensor.c b/libcolor-glib/gcm-sensor.c
index 01e10e4..6dd3a0b 100644
--- a/libcolor-glib/gcm-sensor.c
+++ b/libcolor-glib/gcm-sensor.c
@@ -46,7 +46,6 @@ struct _GcmSensorPrivate
 {
 	gboolean			 native;
 	GcmSensorState			 state;
-	gboolean			 done_startup;
 	GcmSensorKind			 kind;
 	GcmSensorOutputType		 output_type;
 	gboolean			 supports_display;
@@ -59,6 +58,16 @@ struct _GcmSensorPrivate
 	gchar				*device;
 };
 
+
+/* tiny helper to help us do the async operation */
+typedef struct {
+	GError		**error;
+	GMainLoop	*loop;
+	gboolean	 ret;
+	gdouble		 ambient_value;
+	GcmColorXYZ	*sample;
+} GcmSensorHelper;
+
 enum {
 	PROP_0,
 	PROP_NATIVE,
@@ -344,99 +353,123 @@ gcm_sensor_set_from_device (GcmSensor *sensor, GUdevDevice *device, GError **err
 }
 
 /**
- * gcm_sensor_startup:
+ * gcm_sensor_sample_async:
  * @sensor: a valid #GcmSensor instance
- * @error: a #GError or %NULL
+ * @cancellable: a #GCancellable or %NULL
+ * @callback: the function to run on completion
+ * @user_data: the data to pass to @callback
  *
- * Starts up the device, which can mean connecting to it and uploading
- * firmware, or just reading configuration details for it.
- *
- * You probably don't need to use this function manually, as it is done
- * automatically as soon as the sensor is required.
+ * Sample the color and store as a XYZ value.
  *
- * Return value: %TRUE for success.
+ * Since: 0.0.1
  **/
-gboolean
-gcm_sensor_startup (GcmSensor *sensor, GError **error)
+void
+gcm_sensor_sample_async (GcmSensor *sensor, GCancellable *cancellable,
+			 GAsyncReadyCallback callback, gpointer user_data)
 {
+	GSimpleAsyncResult *res = NULL;
 	GcmSensorClass *klass = GCM_SENSOR_GET_CLASS (sensor);
-	gboolean ret = FALSE;
+	GError *error = NULL;
 
-	/* already done */
-	if (sensor->priv->done_startup) {
-		g_set_error_literal (error,
-				     GCM_SENSOR_ERROR,
-				     GCM_SENSOR_ERROR_INTERNAL,
-				     "already started");
-		goto out;
-	}
-
-	/* not a native device */
-	if (!sensor->priv->native) {
-		g_set_error_literal (error,
-				     GCM_SENSOR_ERROR,
-				     GCM_SENSOR_ERROR_INTERNAL,
-				     "not a native device, you have to use GcmCalibrate...");
-		goto out;
-	}
+	/* new async request */
+	res = g_simple_async_result_new (G_OBJECT (sensor), callback, user_data, gcm_sensor_sample_async);
 
 	/* coldplug source */
-	if (klass->startup == NULL) {
-		g_set_error_literal (error,
+	if (klass->sample_async == NULL) {
+		g_set_error_literal (&error,
 				     GCM_SENSOR_ERROR,
 				     GCM_SENSOR_ERROR_INTERNAL,
 				     "no klass support");
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
 	}
 
 	/* proxy */
-	ret = klass->startup (sensor, error);
-	if (!ret)
-		goto out;
-
-	/* success */
-	sensor->priv->done_startup = TRUE;
+	klass->sample_async (sensor, cancellable, G_ASYNC_RESULT (res));
 out:
-	return ret;
+	g_object_unref (res);
+	return;
 }
 
 /**
- * gcm_sensor_get_ambient:
+ * gcm_sensor_sample_finish:
  * @sensor: a valid #GcmSensor instance
- * @value: The returned value
- * @error: a #GError or %NULL
+ * @res: the #GAsyncResult
+ * @value: the brightness in Lux, return value.
+ * @error: A #GError or %NULL
  *
- * Gets the ambient light level of the sensor in Lux.
+ * Gets the result from the asynchronous function.
  *
- * Return value: %TRUE for success.
+ * Return value: %FALSE for an error
+ *
+ * Since: 0.0.1
  **/
 gboolean
-gcm_sensor_get_ambient (GcmSensor *sensor, gdouble *value, GError **error)
+gcm_sensor_sample_finish (GcmSensor *sensor, GAsyncResult *res, GcmColorXYZ *value, GError **error)
 {
 	GcmSensorClass *klass = GCM_SENSOR_GET_CLASS (sensor);
-	gboolean ret = FALSE;
+	return klass->sample_finish (sensor, res, value, error);
+}
 
-	/* do startup if not yet done */
-	if (!sensor->priv->done_startup) {
-		ret = gcm_sensor_startup (sensor, error);
-		if (!ret)
-			goto out;
-	}
+/**
+ * gcm_sensor_get_ambient_async:
+ * @sensor: a valid #GcmSensor instance
+ * @cancellable: a #GCancellable or %NULL
+ * @callback: the function to run on completion
+ * @user_data: the data to pass to @callback
+ *
+ * Asks the hardware to get the ambient light value.
+ *
+ * Since: 0.0.1
+ **/
+void
+gcm_sensor_get_ambient_async (GcmSensor	 *sensor, GCancellable *cancellable,
+			      GAsyncReadyCallback callback, gpointer user_data)
+{
+	GSimpleAsyncResult *res = NULL;
+	GcmSensorClass *klass = GCM_SENSOR_GET_CLASS (sensor);
+	GError *error = NULL;
+
+	/* new async request */
+	res = g_simple_async_result_new (G_OBJECT (sensor), callback, user_data, gcm_sensor_get_ambient_async);
 
 	/* coldplug source */
-	if (klass->get_ambient == NULL) {
-		ret = FALSE;
-		g_set_error_literal (error,
+	if (klass->get_ambient_async == NULL) {
+		g_set_error_literal (&error,
 				     GCM_SENSOR_ERROR,
 				     GCM_SENSOR_ERROR_INTERNAL,
 				     "no klass support");
+		g_simple_async_result_set_from_error (res, error);
+		g_error_free (error);
 		goto out;
 	}
 
 	/* proxy */
-	ret = klass->get_ambient (sensor, value, error);
+	klass->get_ambient_async (sensor, cancellable, G_ASYNC_RESULT (res));
 out:
-	return ret;
+	g_object_unref (res);
+	return;
+}
+
+/**
+ * gcm_sensor_get_ambient_finish:
+ * @sensor: a valid #GcmSensor instance
+ * @res: the #GAsyncResult
+ * @value: the brightness in Lux, return value.
+ * @error: A #GError or %NULL
+ *
+ * Gets the result from the asynchronous function.
+ *
+ * Return value: %FALSE for an error
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_sensor_get_ambient_finish (GcmSensor *sensor, GAsyncResult *res, gdouble *value, GError **error)
+{
+	GcmSensorClass *klass = GCM_SENSOR_GET_CLASS (sensor);
+	return klass->get_ambient_finish (sensor, res, value, error);
 }
 
 /**
@@ -454,14 +487,7 @@ gcm_sensor_dump (GcmSensor *sensor, GString *data, GError **error)
 {
 	GcmSensorClass *klass = GCM_SENSOR_GET_CLASS (sensor);
 	GcmSensorPrivate *priv = sensor->priv;
-	gboolean ret = FALSE;
-
-	/* do startup if not yet done */
-	if (!sensor->priv->done_startup) {
-		ret = gcm_sensor_startup (sensor, error);
-		if (!ret)
-			goto out;
-	}
+	gboolean ret = TRUE;
 
 	/* write common sensor details */
 	g_string_append (data, "// AUTOMATICALLY GENERATED -- DO NOT EDIT\n");
@@ -489,45 +515,6 @@ out:
 }
 
 /**
- * gcm_sensor_sample:
- * @sensor: a valid #GcmSensor instance
- * @value: The returned value
- * @error: a #GError or %NULL
- *
- * Sample the color and store as a XYZ value.
- *
- * Return value: %TRUE for success.
- **/
-gboolean
-gcm_sensor_sample (GcmSensor *sensor, GcmColorXYZ *value, GError **error)
-{
-	GcmSensorClass *klass = GCM_SENSOR_GET_CLASS (sensor);
-	gboolean ret = FALSE;
-
-	/* do startup if not yet done */
-	if (!sensor->priv->done_startup) {
-		ret = gcm_sensor_startup (sensor, error);
-		if (!ret)
-			goto out;
-	}
-
-	/* coldplug source */
-	if (klass->sample == NULL) {
-		ret = FALSE;
-		g_set_error_literal (error,
-				     GCM_SENSOR_ERROR,
-				     GCM_SENSOR_ERROR_INTERNAL,
-				     "no klass support");
-		goto out;
-	}
-
-	/* proxy */
-	ret = klass->sample (sensor, value, error);
-out:
-	return ret;
-}
-
-/**
  * gcm_sensor_set_leds:
  * @sensor: a valid #GcmSensor instance
  * @value: The LED bitmask
@@ -543,13 +530,6 @@ gcm_sensor_set_leds (GcmSensor *sensor, guint8 value, GError **error)
 	GcmSensorClass *klass = GCM_SENSOR_GET_CLASS (sensor);
 	gboolean ret = FALSE;
 
-	/* do startup if not yet done */
-	if (!sensor->priv->done_startup) {
-		ret = gcm_sensor_startup (sensor, error);
-		if (!ret)
-			goto out;
-	}
-
 	/* set LEDs */
 	if (klass->set_leds == NULL) {
 		g_set_error_literal (error,
@@ -634,6 +614,118 @@ gcm_sensor_kind_from_string (const gchar *sensor_kind)
 }
 
 /**
+ * gcm_sensor_sample_sync_cb:
+ **/
+static void
+gcm_sensor_sample_sync_cb (GcmSensor *sensor, GAsyncResult *res, GcmSensorHelper *helper)
+{
+	/* get the result */
+	helper->ret = gcm_sensor_sample_finish (sensor, res, helper->sample, helper->error);
+	g_main_loop_quit (helper->loop);
+}
+
+/**
+ * gcm_sensor_sample:
+ * @sensor: a valid #GcmSensor instance
+ * @cancellable: a #GCancellable or %NULL
+ * @value: the sensor brightness in Lux.
+ * @error: A #GError or %NULL
+ *
+ * Sample the color and store as a XYZ value.
+ * Warning: this function is synchronous, and may block. Do not use it in GUI
+ * applications.
+ *
+ * Return value: %TRUE if the ambient value was obtained.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_sensor_sample (GcmSensor *sensor, GCancellable *cancellable, GcmColorXYZ *value, GError **error)
+{
+	GcmSensorHelper *helper;
+	gboolean ret;
+
+	g_return_val_if_fail (GCM_IS_SENSOR (sensor), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* create temp object */
+	helper = g_new0 (GcmSensorHelper, 1);
+	helper->loop = g_main_loop_new (NULL, FALSE);
+	helper->error = error;
+	helper->sample = g_new0 (GcmColorXYZ, 1);
+
+	/* run async method */
+	gcm_sensor_sample_async (sensor, cancellable, (GAsyncReadyCallback) gcm_sensor_sample_sync_cb, helper);
+	g_main_loop_run (helper->loop);
+
+	ret = helper->ret;
+	if (ret && value != NULL)
+		gcm_color_copy_XYZ (helper->sample, value);
+
+	/* free temp object */
+	g_main_loop_unref (helper->loop);
+	g_free (helper->sample);
+	g_free (helper);
+
+	return ret;
+}
+
+/**
+ * gcm_sensor_get_ambient_sync_cb:
+ **/
+static void
+gcm_sensor_get_ambient_sync_cb (GcmSensor *sensor, GAsyncResult *res, GcmSensorHelper *helper)
+{
+	/* get the result */
+	helper->ret = gcm_sensor_get_ambient_finish (sensor, res, &helper->ambient_value, helper->error);
+	g_main_loop_quit (helper->loop);
+}
+
+/**
+ * gcm_sensor_get_ambient:
+ * @sensor: a valid #GcmSensor instance
+ * @cancellable: a #GCancellable or %NULL
+ * @value: the sensor brightness in Lux.
+ * @error: A #GError or %NULL
+ *
+ * Gets the ambient light reading.
+ * Warning: this function is synchronous, and may block. Do not use it in GUI
+ * applications.
+ *
+ * Return value: %TRUE if the ambient value was obtained.
+ *
+ * Since: 0.0.1
+ **/
+gboolean
+gcm_sensor_get_ambient (GcmSensor *sensor, GCancellable *cancellable, gdouble *value, GError **error)
+{
+	GcmSensorHelper *helper;
+	gboolean ret;
+
+	g_return_val_if_fail (GCM_IS_SENSOR (sensor), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	/* create temp object */
+	helper = g_new0 (GcmSensorHelper, 1);
+	helper->loop = g_main_loop_new (NULL, FALSE);
+	helper->error = error;
+
+	/* run async method */
+	gcm_sensor_get_ambient_async (sensor, cancellable, (GAsyncReadyCallback) gcm_sensor_get_ambient_sync_cb, helper);
+	g_main_loop_run (helper->loop);
+
+	ret = helper->ret;
+	if (value != NULL)
+		*value = helper->ambient_value;
+
+	/* free temp object */
+	g_main_loop_unref (helper->loop);
+	g_free (helper);
+
+	return ret;
+}
+
+/**
  * gcm_sensor_get_property:
  **/
 static void
diff --git a/libcolor-glib/gcm-sensor.h b/libcolor-glib/gcm-sensor.h
index ba5844d..e210828 100644
--- a/libcolor-glib/gcm-sensor.h
+++ b/libcolor-glib/gcm-sensor.h
@@ -28,7 +28,7 @@
 
 #include <glib-object.h>
 #include <gudev/gudev.h>
-
+#include <gio/gio.h>
 #include <gcm-color.h>
 
 G_BEGIN_DECLS
@@ -54,16 +54,22 @@ struct _GcmSensorClass
 {
 	GObjectClass	parent_class;
 	/* vtable */
-	gboolean	 (*get_ambient)			(GcmSensor	*sensor,
+	void		 (*get_ambient_async)		(GcmSensor	*sensor,
+							 GCancellable	*cancellable,
+							 GAsyncResult	*res);
+	gboolean	 (*get_ambient_finish)		(GcmSensor	*sensor,
+							 GAsyncResult	*res,
 							 gdouble	*value,
 							 GError		**error);
-	gboolean	 (*set_leds)			(GcmSensor	*sensor,
-							 guint8		 value,
-							 GError		**error);
-	gboolean	 (*sample)			(GcmSensor	*sensor,
+	void		 (*sample_async)		(GcmSensor	*sensor,
+							 GCancellable	*cancellable,
+							 GAsyncResult	*res);
+	gboolean	 (*sample_finish)		(GcmSensor	*sensor,
+							 GAsyncResult	*res,
 							 GcmColorXYZ	*value,
 							 GError		**error);
-	gboolean	 (*startup)			(GcmSensor	*sensor,
+	gboolean	 (*set_leds)			(GcmSensor	*sensor,
+							 guint8		 value,
 							 GError		**error);
 	gboolean	 (*dump)			(GcmSensor	*sensor,
 							 GString	*data,
@@ -145,17 +151,9 @@ GcmSensorState		 gcm_sensor_get_state		(GcmSensor		*sensor);
 gboolean		 gcm_sensor_dump		(GcmSensor		*sensor,
 							 GString		*data,
 							 GError			**error);
-gboolean		 gcm_sensor_get_ambient		(GcmSensor		*sensor,
-							 gdouble		*value,
-							 GError			**error);
 gboolean		 gcm_sensor_set_leds		(GcmSensor		*sensor,
 							 guint8			 value,
 							 GError			**error);
-gboolean		 gcm_sensor_sample		(GcmSensor		*sensor,
-							 GcmColorXYZ		*value,
-							 GError			**error);
-gboolean		 gcm_sensor_startup		(GcmSensor		*sensor,
-							 GError			**error);
 gboolean		 gcm_sensor_set_from_device	(GcmSensor		*sensor,
 							 GUdevDevice		*device,
 							 GError			**error);
@@ -176,6 +174,34 @@ gboolean		 gcm_sensor_is_native		(GcmSensor		*sensor);
 const gchar		*gcm_sensor_kind_to_string	(GcmSensorKind		 sensor_kind);
 GcmSensorKind		 gcm_sensor_kind_from_string	(const gchar		*sensor_kind);
 
+/* async sampling functions that take a lot of time */
+void			 gcm_sensor_get_ambient_async	(GcmSensor		*sensor,
+							 GCancellable		*cancellable,
+							 GAsyncReadyCallback	 callback,
+							 gpointer		 user_data);
+gboolean		 gcm_sensor_get_ambient_finish	(GcmSensor		*sensor,
+							 GAsyncResult		*res,
+							 gdouble		*value,
+							 GError			**error);
+void			 gcm_sensor_sample_async	(GcmSensor		*sensor,
+							 GCancellable		*cancellable,
+							 GAsyncReadyCallback	 callback,
+							 gpointer		 user_data);
+gboolean		 gcm_sensor_sample_finish	(GcmSensor		*sensor,
+							 GAsyncResult		*res,
+							 GcmColorXYZ		*value,
+							 GError			**error);
+
+/* sync versions */
+gboolean		 gcm_sensor_get_ambient		(GcmSensor		*sensor,
+							 GCancellable		*cancellable,
+							 gdouble		*value,
+							 GError			**error);
+gboolean		 gcm_sensor_sample		(GcmSensor		*sensor,
+							 GCancellable		*cancellable,
+							 GcmColorXYZ		*value,
+							 GError			**error);
+
 G_END_DECLS
 
 #endif /* __GCM_SENSOR_H */
diff --git a/src/gcm-picker.c b/src/gcm-picker.c
index f0377e7..b223c29 100644
--- a/src/gcm-picker.c
+++ b/src/gcm-picker.c
@@ -226,7 +226,7 @@ gcm_picker_measure_cb (GtkWidget *widget, gpointer data)
 		gcm_sensor_set_output_type (sensor, GCM_SENSOR_OUTPUT_TYPE_LCD);
 
 		/* get ambient */
-		ret = gcm_sensor_get_ambient (sensor, &last_ambient, &error);
+		ret = gcm_sensor_get_ambient (sensor, NULL, &last_ambient, &error);
 		if (!ret) {
 			g_warning ("failed to get ambient: %s", error->message);
 			g_error_free (error);
@@ -234,7 +234,7 @@ gcm_picker_measure_cb (GtkWidget *widget, gpointer data)
 		}
 
 		/* sample color */
-		ret = gcm_sensor_sample (sensor, &last_sample, &error);
+		ret = gcm_sensor_sample (sensor, NULL, &last_sample, &error);
 		if (!ret) {
 			egg_warning ("failed to measure: %s", error->message);
 			g_error_free (error);
diff --git a/tools/gcm-sensor-colormunki.c b/tools/gcm-sensor-colormunki.c
index 9e7f9c0..0451e05 100644
--- a/tools/gcm-sensor-colormunki.c
+++ b/tools/gcm-sensor-colormunki.c
@@ -463,6 +463,7 @@ out:
 	return ret;
 }
 
+#if 0
 /**
  * gcm_sensor_colormunki_get_ambient:
  **/
@@ -497,7 +498,7 @@ gcm_sensor_colormunki_get_ambient (GcmSensor *sensor, gdouble *value, GError **e
 out:
 	return ret;
 }
-
+#endif
 
 /**
  * gcm_sensor_huey_dump:
@@ -553,10 +554,9 @@ gcm_sensor_colormunki_class_init (GcmSensorColormunkiClass *klass)
 	object_class->finalize = gcm_sensor_colormunki_finalize;
 
 	/* setup klass links */
-	parent_class->get_ambient = gcm_sensor_colormunki_get_ambient;
+//	parent_class->get_ambient = gcm_sensor_colormunki_get_ambient;
 //	parent_class->set_leds = gcm_sensor_colormunki_set_leds;
 //	parent_class->sample = gcm_sensor_colormunki_sample;
-	parent_class->startup = gcm_sensor_colormunki_startup;
 	parent_class->dump = gcm_sensor_colormunki_dump;
 
 	g_type_class_add_private (klass, sizeof (GcmSensorColormunkiPrivate));
@@ -573,6 +573,9 @@ gcm_sensor_colormunki_init (GcmSensorColormunki *sensor)
 	priv->transfer_interrupt = libusb_alloc_transfer (0);
 	priv->transfer_state = libusb_alloc_transfer (0);
 	priv->usb = gcm_usb_new ();
+
+	//FIXME
+	gcm_sensor_colormunki_startup (GCM_SENSOR (sensor), NULL);
 }
 
 /**
diff --git a/tools/gcm-sensor-example.c b/tools/gcm-sensor-example.c
index 764d2ea..082ea2d 100644
--- a/tools/gcm-sensor-example.c
+++ b/tools/gcm-sensor-example.c
@@ -73,19 +73,8 @@ main (int argc, char **argv)
 	/* set mode */
 	gcm_sensor_set_output_type (sensor, GCM_SENSOR_OUTPUT_TYPE_LCD);
 
-	/* start sensor */
-	ret = gcm_sensor_startup (sensor, &error);
-	if (!ret) {
-		egg_warning ("failed to startup: %s", error->message);
-		g_error_free (error);
-		goto out;
-	}
-
-	/* spin the loop */
-	g_main_loop_run (loop);
-
 	/* get ambient */
-	ret = gcm_sensor_get_ambient (sensor, &value, &error);
+	ret = gcm_sensor_get_ambient (sensor, NULL, &value, &error);
 	if (!ret) {
 		egg_warning ("failed to get ambient: %s", error->message);
 		g_error_free (error);
@@ -94,7 +83,7 @@ main (int argc, char **argv)
 	g_debug ("ambient = %.1lf Lux", value);
 
 	/* sample color */
-	ret = gcm_sensor_sample (sensor, &values, &error);
+	ret = gcm_sensor_sample (sensor, NULL, &values, &error);
 	if (!ret) {
 		egg_warning ("failed to measure: %s", error->message);
 		g_error_free (error);
@@ -102,6 +91,9 @@ main (int argc, char **argv)
 	}
 	g_debug ("X=%0.4lf, Y=%0.4lf, Z=%0.4lf", values.X, values.Y, values.Z);
 
+	/* spin the loop */
+	g_main_loop_run (loop);
+
 out:
 	g_main_loop_unref (loop);
 	g_object_unref (sensor);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]