[gnome-color-manager] Add a simple CIE display widget to display the gamut maps of profiles
- From: Richard Hughes <rhughes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Add a simple CIE display widget to display the gamut maps of profiles
- Date: Tue, 1 Dec 2009 14:46:31 +0000 (UTC)
commit 99c7c9eafdffa5c8b91f6511c7ae0a9f53d4ee65
Author: Richard Hughes <richard hughsie com>
Date: Tue Dec 1 14:39:19 2009 +0000
Add a simple CIE display widget to display the gamut maps of profiles
src/Makefile.am | 3 +
src/gcm-cie-widget.c | 1176 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/gcm-cie-widget.h | 56 +++
src/gcm-self-test.c | 4 +-
4 files changed, 1238 insertions(+), 1 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index c6b219b..c3774d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -120,6 +120,8 @@ gcm_prefs_SOURCES = \
gcm-calibrate.h \
gcm-brightness.c \
gcm-brightness.h \
+ gcm-cie-widget.c \
+ gcm-cie-widget.h \
gcm-prefs.c
gcm_prefs_LDADD = \
@@ -171,6 +173,7 @@ gcm_self_test_SOURCES = \
gcm-brightness.c \
gcm-clut.c \
gcm-dmi.c \
+ gcm-cie-widget.c \
egg-test.h \
egg-test.c \
$(NULL)
diff --git a/src/gcm-cie-widget.c b/src/gcm-cie-widget.c
new file mode 100644
index 0000000..3215fe2
--- /dev/null
+++ b/src/gcm-cie-widget.c
@@ -0,0 +1,1176 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2009 Richard Hughes <richard hughsie com>
+ *
+ * Color conversion algorithms taken from ppmcie:
+ * Copyright (C) 1999 John Walker <kelvin fourmilab ch>
+ * Copyright (C) 1999 Andrew J. S. Hamilton <Andrew Hamilton Colorado EDU>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "gcm-cie-widget.h"
+
+#include "egg-debug.h"
+
+G_DEFINE_TYPE (GcmCieWidget, gcm_cie_widget, GTK_TYPE_DRAWING_AREA);
+#define GCM_CIE_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_CIE_WIDGET, GcmCieWidgetPrivate))
+#define GCM_CIE_WIDGET_FONT "Sans 8"
+
+struct GcmCieWidgetPrivate
+{
+ gboolean use_grid;
+ guint chart_width;
+ guint chart_height;
+ cairo_t *cr;
+ PangoLayout *layout;
+ GPtrArray *tongue_buffer; /* min and max of the tongue shape */
+ guint x_offset;
+ guint y_offset;
+
+ /* CIE x and y coordinates of its three primary illuminants and the
+ * x and y coordinates of the white point. */
+ gdouble red_x;
+ gdouble red_y; /* red primary illuminant */
+ gdouble green_x;
+ gdouble green_y; /* green primary illuminant */
+ gdouble blue_x;
+ gdouble blue_y; /* blue primary illuminant */
+ gdouble white_x;
+ gdouble white_y; /* white point */
+ gdouble gamma; /* gamma of nonlinear correction */
+};
+
+/* The following table gives the spectral chromaticity co-ordinates
+ * for wavelengths in one nanometre increments from 380nm through 780nm */
+static const gdouble spectral_chromaticity[][3] = {
+ { 0.1741, 0.0050 }, /* 380 nm */
+ { 0.1741, 0.0050 },
+ { 0.1741, 0.0050 },
+ { 0.1741, 0.0050 },
+ { 0.1740, 0.0050 },
+ { 0.1740, 0.0050 },
+ { 0.1740, 0.0050 },
+ { 0.1739, 0.0049 },
+ { 0.1739, 0.0049 },
+ { 0.1738, 0.0049 },
+ { 0.1738, 0.0049 },
+ { 0.1738, 0.0049 },
+ { 0.1737, 0.0049 },
+ { 0.1737, 0.0049 },
+ { 0.1736, 0.0049 },
+ { 0.1736, 0.0049 },
+ { 0.1735, 0.0049 },
+ { 0.1735, 0.0049 },
+ { 0.1734, 0.0048 },
+ { 0.1734, 0.0048 },
+ { 0.1733, 0.0048 },
+ { 0.1733, 0.0048 },
+ { 0.1732, 0.0048 },
+ { 0.1732, 0.0048 },
+ { 0.1731, 0.0048 },
+ { 0.1730, 0.0048 },
+ { 0.1729, 0.0048 },
+ { 0.1728, 0.0048 },
+ { 0.1728, 0.0048 },
+ { 0.1727, 0.0048 },
+ { 0.1726, 0.0048 },
+ { 0.1725, 0.0048 },
+ { 0.1724, 0.0048 },
+ { 0.1723, 0.0048 },
+ { 0.1722, 0.0048 },
+ { 0.1721, 0.0048 },
+ { 0.1720, 0.0049 },
+ { 0.1719, 0.0049 },
+ { 0.1717, 0.0049 },
+ { 0.1716, 0.0050 },
+ { 0.1714, 0.0051 },
+ { 0.1712, 0.0052 },
+ { 0.1710, 0.0053 },
+ { 0.1708, 0.0055 },
+ { 0.1705, 0.0056 },
+ { 0.1703, 0.0058 },
+ { 0.1701, 0.0060 },
+ { 0.1698, 0.0062 },
+ { 0.1695, 0.0064 },
+ { 0.1692, 0.0066 },
+ { 0.1689, 0.0069 },
+ { 0.1685, 0.0072 },
+ { 0.1681, 0.0075 },
+ { 0.1677, 0.0078 },
+ { 0.1673, 0.0082 },
+ { 0.1669, 0.0086 },
+ { 0.1664, 0.0090 },
+ { 0.1660, 0.0094 },
+ { 0.1655, 0.0099 },
+ { 0.1650, 0.0104 },
+ { 0.1644, 0.0109 },
+ { 0.1638, 0.0114 },
+ { 0.1632, 0.0119 },
+ { 0.1626, 0.0125 },
+ { 0.1619, 0.0131 },
+ { 0.1611, 0.0138 },
+ { 0.1603, 0.0145 },
+ { 0.1595, 0.0152 },
+ { 0.1586, 0.0160 },
+ { 0.1576, 0.0168 },
+ { 0.1566, 0.0177 },
+ { 0.1556, 0.0186 },
+ { 0.1545, 0.0196 },
+ { 0.1534, 0.0206 },
+ { 0.1522, 0.0216 },
+ { 0.1510, 0.0227 },
+ { 0.1497, 0.0240 },
+ { 0.1483, 0.0252 },
+ { 0.1469, 0.0266 },
+ { 0.1455, 0.0281 },
+ { 0.1440, 0.0297 },
+ { 0.1424, 0.0314 },
+ { 0.1408, 0.0332 },
+ { 0.1391, 0.0352 },
+ { 0.1374, 0.0374 },
+ { 0.1355, 0.0399 },
+ { 0.1335, 0.0427 },
+ { 0.1314, 0.0459 },
+ { 0.1291, 0.0494 },
+ { 0.1267, 0.0534 },
+ { 0.1241, 0.0578 },
+ { 0.1215, 0.0626 },
+ { 0.1187, 0.0678 },
+ { 0.1158, 0.0736 },
+ { 0.1128, 0.0799 },
+ { 0.1096, 0.0868 },
+ { 0.1063, 0.0945 },
+ { 0.1028, 0.1029 },
+ { 0.0991, 0.1120 },
+ { 0.0953, 0.1219 },
+ { 0.0913, 0.1327 },
+ { 0.0871, 0.1443 },
+ { 0.0827, 0.1569 },
+ { 0.0781, 0.1704 },
+ { 0.0734, 0.1850 },
+ { 0.0687, 0.2007 },
+ { 0.0640, 0.2175 },
+ { 0.0593, 0.2353 },
+ { 0.0547, 0.2541 },
+ { 0.0500, 0.2740 },
+ { 0.0454, 0.2950 },
+ { 0.0408, 0.3170 },
+ { 0.0362, 0.3399 },
+ { 0.0318, 0.3636 },
+ { 0.0275, 0.3879 },
+ { 0.0235, 0.4127 },
+ { 0.0197, 0.4378 },
+ { 0.0163, 0.4630 },
+ { 0.0132, 0.4882 },
+ { 0.0105, 0.5134 },
+ { 0.0082, 0.5384 },
+ { 0.0063, 0.5631 },
+ { 0.0049, 0.5871 },
+ { 0.0040, 0.6104 },
+ { 0.0036, 0.6330 },
+ { 0.0039, 0.6548 },
+ { 0.0046, 0.6759 },
+ { 0.0060, 0.6961 },
+ { 0.0080, 0.7153 },
+ { 0.0106, 0.7334 },
+ { 0.0139, 0.7502 },
+ { 0.0178, 0.7656 },
+ { 0.0222, 0.7796 },
+ { 0.0273, 0.7921 },
+ { 0.0328, 0.8029 },
+ { 0.0389, 0.8120 },
+ { 0.0453, 0.8194 },
+ { 0.0522, 0.8252 },
+ { 0.0593, 0.8294 },
+ { 0.0667, 0.8323 },
+ { 0.0743, 0.8338 },
+ { 0.0821, 0.8341 },
+ { 0.0899, 0.8333 },
+ { 0.0979, 0.8316 },
+ { 0.1060, 0.8292 },
+ { 0.1142, 0.8262 },
+ { 0.1223, 0.8228 },
+ { 0.1305, 0.8189 },
+ { 0.1387, 0.8148 },
+ { 0.1468, 0.8104 },
+ { 0.1547, 0.8059 },
+ { 0.1625, 0.8012 },
+ { 0.1702, 0.7965 },
+ { 0.1778, 0.7917 },
+ { 0.1854, 0.7867 },
+ { 0.1929, 0.7816 },
+ { 0.2003, 0.7764 },
+ { 0.2077, 0.7711 },
+ { 0.2150, 0.7656 },
+ { 0.2223, 0.7600 },
+ { 0.2296, 0.7543 },
+ { 0.2369, 0.7485 },
+ { 0.2441, 0.7426 },
+ { 0.2514, 0.7366 },
+ { 0.2586, 0.7305 },
+ { 0.2658, 0.7243 },
+ { 0.2730, 0.7181 },
+ { 0.2801, 0.7117 },
+ { 0.2873, 0.7053 },
+ { 0.2945, 0.6988 },
+ { 0.3016, 0.6923 },
+ { 0.3088, 0.6857 },
+ { 0.3159, 0.6791 },
+ { 0.3231, 0.6724 },
+ { 0.3302, 0.6656 },
+ { 0.3374, 0.6588 },
+ { 0.3445, 0.6520 },
+ { 0.3517, 0.6452 },
+ { 0.3588, 0.6383 },
+ { 0.3660, 0.6314 },
+ { 0.3731, 0.6245 },
+ { 0.3802, 0.6175 },
+ { 0.3874, 0.6105 },
+ { 0.3945, 0.6036 },
+ { 0.4016, 0.5966 },
+ { 0.4087, 0.5896 },
+ { 0.4158, 0.5826 },
+ { 0.4229, 0.5756 },
+ { 0.4300, 0.5686 },
+ { 0.4370, 0.5617 },
+ { 0.4441, 0.5547 },
+ { 0.4511, 0.5478 },
+ { 0.4580, 0.5408 },
+ { 0.4650, 0.5339 },
+ { 0.4719, 0.5271 },
+ { 0.4788, 0.5202 },
+ { 0.4856, 0.5134 },
+ { 0.4924, 0.5066 },
+ { 0.4992, 0.4999 },
+ { 0.5058, 0.4932 },
+ { 0.5125, 0.4866 },
+ { 0.5191, 0.4800 },
+ { 0.5256, 0.4735 },
+ { 0.5321, 0.4671 },
+ { 0.5385, 0.4607 },
+ { 0.5448, 0.4544 },
+ { 0.5510, 0.4482 },
+ { 0.5572, 0.4421 },
+ { 0.5633, 0.4361 },
+ { 0.5693, 0.4301 },
+ { 0.5752, 0.4242 },
+ { 0.5810, 0.4184 },
+ { 0.5867, 0.4128 },
+ { 0.5922, 0.4072 },
+ { 0.5977, 0.4018 },
+ { 0.6029, 0.3965 },
+ { 0.6080, 0.3914 },
+ { 0.6130, 0.3865 },
+ { 0.6178, 0.3817 },
+ { 0.6225, 0.3770 },
+ { 0.6270, 0.3725 },
+ { 0.6315, 0.3680 },
+ { 0.6359, 0.3637 },
+ { 0.6402, 0.3594 },
+ { 0.6443, 0.3553 },
+ { 0.6482, 0.3514 },
+ { 0.6520, 0.3476 },
+ { 0.6557, 0.3440 },
+ { 0.6592, 0.3406 },
+ { 0.6625, 0.3372 },
+ { 0.6658, 0.3340 },
+ { 0.6689, 0.3309 },
+ { 0.6719, 0.3279 },
+ { 0.6747, 0.3251 },
+ { 0.6775, 0.3224 },
+ { 0.6801, 0.3197 },
+ { 0.6826, 0.3172 },
+ { 0.6850, 0.3149 },
+ { 0.6873, 0.3126 },
+ { 0.6894, 0.3104 },
+ { 0.6915, 0.3083 },
+ { 0.6935, 0.3064 },
+ { 0.6954, 0.3045 },
+ { 0.6972, 0.3027 },
+ { 0.6989, 0.3010 },
+ { 0.7006, 0.2993 },
+ { 0.7022, 0.2977 },
+ { 0.7037, 0.2962 },
+ { 0.7052, 0.2948 },
+ { 0.7066, 0.2934 },
+ { 0.7079, 0.2920 },
+ { 0.7092, 0.2907 },
+ { 0.7105, 0.2895 },
+ { 0.7117, 0.2882 },
+ { 0.7129, 0.2871 },
+ { 0.7140, 0.2859 },
+ { 0.7151, 0.2848 },
+ { 0.7162, 0.2838 },
+ { 0.7172, 0.2828 },
+ { 0.7181, 0.2819 },
+ { 0.7190, 0.2809 },
+ { 0.7199, 0.2801 },
+ { 0.7208, 0.2792 },
+ { 0.7216, 0.2784 },
+ { 0.7223, 0.2777 },
+ { 0.7230, 0.2769 },
+ { 0.7237, 0.2763 },
+ { 0.7243, 0.2757 },
+ { 0.7249, 0.2751 },
+ { 0.7255, 0.2745 },
+ { 0.7260, 0.2740 },
+ { 0.7265, 0.2735 },
+ { 0.7270, 0.2730 },
+ { 0.7274, 0.2726 },
+ { 0.7279, 0.2721 },
+ { 0.7283, 0.2717 },
+ { 0.7287, 0.2713 },
+ { 0.7290, 0.2710 },
+ { 0.7294, 0.2706 },
+ { 0.7297, 0.2703 },
+ { 0.7300, 0.2700 },
+ { 0.7302, 0.2698 },
+ { 0.7305, 0.2695 },
+ { 0.7307, 0.2693 },
+ { 0.7309, 0.2691 },
+ { 0.7311, 0.2689 },
+ { 0.7313, 0.2687 },
+ { 0.7315, 0.2685 },
+ { 0.7316, 0.2684 },
+ { 0.7318, 0.2682 },
+ { 0.7320, 0.2680 },
+ { 0.7322, 0.2678 },
+ { 0.7323, 0.2677 },
+ { 0.7324, 0.2676 },
+ { 0.7326, 0.2674 },
+ { 0.7327, 0.2673 },
+ { 0.7329, 0.2671 },
+ { 0.7330, 0.2670 },
+ { 0.7331, 0.2669 },
+ { 0.7333, 0.2667 },
+ { 0.7334, 0.2666 },
+ { 0.7336, 0.2664 },
+ { 0.7337, 0.2663 },
+ { 0.7338, 0.2662 },
+ { 0.7339, 0.2661 },
+ { 0.7340, 0.2660 },
+ { 0.7341, 0.2659 },
+ { 0.7342, 0.2658 },
+ { 0.7343, 0.2657 },
+ { 0.7343, 0.2657 },
+ { 0.7344, 0.2656 },
+ { 0.7344, 0.2656 },
+ { 0.7345, 0.2655 },
+ { 0.7345, 0.2655 },
+ { 0.7346, 0.2654 },
+ { 0.7346, 0.2654 },
+ { 0.7346, 0.2654 },
+ { 0.7346, 0.2654 },
+ { 0.7347, 0.2653 },
+ { 0.7347, 0.2653 },
+ { 0.7347, 0.2653 } /* 780 nm */
+};
+
+typedef struct {
+ guint min;
+ guint max;
+ gboolean valid;
+} GcmCieWidgetBufferItem;
+
+static gboolean gcm_cie_widget_expose (GtkWidget *cie, GdkEventExpose *event);
+static void gcm_cie_widget_finalize (GObject *object);
+
+enum
+{
+ PROP_0,
+ PROP_USE_GRID,
+ PROP_RED_X,
+ PROP_RED_Y,
+ PROP_GREEN_X,
+ PROP_GREEN_Y,
+ PROP_BLUE_X,
+ PROP_BLUE_Y,
+ PROP_WHITE_X,
+ PROP_WHITE_Y,
+};
+
+/**
+ * dkp_cie_get_property:
+ **/
+static void
+dkp_cie_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GcmCieWidget *cie = GCM_CIE_WIDGET (object);
+ switch (prop_id) {
+ case PROP_USE_GRID:
+ g_value_set_boolean (value, cie->priv->use_grid);
+ break;
+ case PROP_RED_X:
+ g_value_set_double (value, cie->priv->red_x);
+ break;
+ case PROP_RED_Y:
+ g_value_set_double (value, cie->priv->red_y);
+ break;
+ case PROP_GREEN_X:
+ g_value_set_double (value, cie->priv->green_x);
+ break;
+ case PROP_GREEN_Y:
+ g_value_set_double (value, cie->priv->green_y);
+ break;
+ case PROP_BLUE_X:
+ g_value_set_double (value, cie->priv->blue_x);
+ break;
+ case PROP_BLUE_Y:
+ g_value_set_double (value, cie->priv->blue_y);
+ break;
+ case PROP_WHITE_X:
+ g_value_set_double (value, cie->priv->white_x);
+ break;
+ case PROP_WHITE_Y:
+ g_value_set_double (value, cie->priv->white_y);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * dkp_cie_set_property:
+ **/
+static void
+dkp_cie_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GcmCieWidget *cie = GCM_CIE_WIDGET (object);
+
+ switch (prop_id) {
+ case PROP_USE_GRID:
+ cie->priv->use_grid = g_value_get_boolean (value);
+ break;
+ case PROP_RED_X:
+ cie->priv->red_x = g_value_get_double (value);
+ break;
+ case PROP_RED_Y:
+ cie->priv->red_y = g_value_get_double (value);
+ break;
+ case PROP_GREEN_X:
+ cie->priv->green_x = g_value_get_double (value);
+ break;
+ case PROP_GREEN_Y:
+ cie->priv->green_y = g_value_get_double (value);
+ break;
+ case PROP_BLUE_X:
+ cie->priv->blue_x = g_value_get_double (value);
+ break;
+ case PROP_BLUE_Y:
+ cie->priv->blue_y = g_value_get_double (value);
+ break;
+ case PROP_WHITE_X:
+ cie->priv->white_x = g_value_get_double (value);
+ break;
+ case PROP_WHITE_Y:
+ cie->priv->white_y = g_value_get_double (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+
+ /* refresh widget */
+ gtk_widget_hide (GTK_WIDGET (cie));
+ gtk_widget_show (GTK_WIDGET (cie));
+}
+
+/**
+ * gcm_cie_widget_class_init:
+ **/
+static void
+gcm_cie_widget_class_init (GcmCieWidgetClass *class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ widget_class->expose_event = gcm_cie_widget_expose;
+ object_class->get_property = dkp_cie_get_property;
+ object_class->set_property = dkp_cie_set_property;
+ object_class->finalize = gcm_cie_widget_finalize;
+
+ g_type_class_add_private (class, sizeof (GcmCieWidgetPrivate));
+
+ /* properties */
+ g_object_class_install_property (object_class,
+ PROP_USE_GRID,
+ g_param_spec_boolean ("use-grid", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_RED_X,
+ g_param_spec_double ("red-x", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_RED_Y,
+ g_param_spec_double ("red-y", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_GREEN_X,
+ g_param_spec_double ("green-x", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_GREEN_Y,
+ g_param_spec_double ("green-y", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_BLUE_X,
+ g_param_spec_double ("blue-x", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_BLUE_Y,
+ g_param_spec_double ("blue-y", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_WHITE_X,
+ g_param_spec_double ("white-x", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_WHITE_Y,
+ g_param_spec_double ("white-y", NULL, NULL,
+ -G_MAXDOUBLE, G_MAXDOUBLE, 0.0f,
+ G_PARAM_READWRITE));
+}
+
+/**
+ * gcm_cie_widget_init:
+ **/
+static void
+gcm_cie_widget_init (GcmCieWidget *cie)
+{
+ PangoFontMap *fontmap;
+ PangoContext *context;
+ PangoFontDescription *desc;
+
+ cie->priv = GCM_CIE_WIDGET_GET_PRIVATE (cie);
+ cie->priv->red_x = 0;
+ cie->priv->red_y = 0;
+ cie->priv->blue_x = 0;
+ cie->priv->blue_y = 0;
+ cie->priv->use_grid = TRUE;
+ cie->priv->x_offset = 20.0f;
+ cie->priv->y_offset = 10.0f;
+ cie->priv->tongue_buffer = g_ptr_array_new_with_free_func (g_free);
+
+ /* default is CIE REC 709 */
+ cie->priv->red_x = 0.64;
+ cie->priv->red_y = 0.33;
+ cie->priv->green_x = 0.30;
+ cie->priv->green_y = 0.60;
+ cie->priv->blue_x = 0.15;
+ cie->priv->blue_y = 0.06;
+ cie->priv->white_x = 0.3127;
+ cie->priv->white_y = 0.3291;
+ cie->priv->gamma = 0.0;
+
+ /* do pango stuff */
+ fontmap = pango_cairo_font_map_get_default ();
+ context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+ pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
+
+ cie->priv->layout = pango_layout_new (context);
+ desc = pango_font_description_from_string (GCM_CIE_WIDGET_FONT);
+ pango_layout_set_font_description (cie->priv->layout, desc);
+ pango_font_description_free (desc);
+}
+
+/**
+ * gcm_cie_widget_finalize:
+ **/
+static void
+gcm_cie_widget_finalize (GObject *object)
+{
+ PangoContext *context;
+ GcmCieWidget *cie = (GcmCieWidget*) object;
+
+ context = pango_layout_get_context (cie->priv->layout);
+ g_object_unref (cie->priv->layout);
+ g_object_unref (context);
+ g_ptr_array_unref (cie->priv->tongue_buffer);
+ G_OBJECT_CLASS (gcm_cie_widget_parent_class)->finalize (object);
+}
+
+/**
+ * gcm_cie_widget_draw_grid:
+ *
+ * Draw the 10x10 dotted grid onto the cie.
+ **/
+static void
+gcm_cie_widget_draw_grid (GcmCieWidget *cie, cairo_t *cr)
+{
+ guint i;
+ gfloat b;
+ gdouble dotted[] = {1., 2.};
+ gfloat divwidth = (gfloat)cie->priv->chart_width / 10.0f;
+ gfloat divheight = (gfloat)cie->priv->chart_height / 10.0f;
+
+ cairo_save (cr);
+ cairo_set_line_width (cr, 1);
+ cairo_set_dash (cr, dotted, 2, 0.0);
+
+ /* do vertical lines */
+ cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+ for (i=1; i<10; i++) {
+ b = ((gfloat) i * divwidth);
+ cairo_move_to (cr, (gint)b + 0.5f, 0);
+ cairo_line_to (cr, (gint)b + 0.5f, cie->priv->chart_height);
+ cairo_stroke (cr);
+ }
+
+ /* do horizontal lines */
+ for (i=1; i<10; i++) {
+ b = ((gfloat) i * divheight);
+ cairo_move_to (cr, 0, (gint)b + 0.5f);
+ cairo_line_to (cr, cie->priv->chart_width, (int)b + 0.5f);
+ cairo_stroke (cr);
+ }
+
+ cairo_restore (cr);
+}
+
+/**
+ * gcm_cie_widget_map_from_display:
+ **/
+static void
+gcm_cie_widget_map_from_display (GcmCieWidget *cie, guint x, guint y, guint *x_retval, guint *y_retval)
+{
+ GcmCieWidgetPrivate *priv = cie->priv;
+ *x_retval = x + priv->x_offset;
+ *y_retval = y - priv->y_offset;
+}
+
+/**
+ * gcm_cie_widget_map_to_display:
+ **/
+static void
+gcm_cie_widget_map_to_display (GcmCieWidget *cie, guint x, guint y, guint *x_retval, guint *y_retval)
+{
+ GcmCieWidgetPrivate *priv = cie->priv;
+ *x_retval = x - priv->x_offset;
+ *y_retval = y + priv->y_offset;
+}
+
+/**
+ * gcm_cie_widget_compute_monochrome_color_location:
+ **/
+static void
+gcm_cie_widget_compute_monochrome_color_location (GcmCieWidget *cie, gdouble wave_length,
+ guint *x_retval, guint *y_retval)
+{
+ guint ix = wave_length - 380;
+ const gdouble px = spectral_chromaticity[ix][0];
+ const gdouble py = spectral_chromaticity[ix][1];
+ GcmCieWidgetPrivate *priv = cie->priv;
+
+ *x_retval = px * (priv->chart_width - 1);
+ *y_retval = (priv->chart_height - 1) - py * (priv->chart_height - 1);
+
+ gcm_cie_widget_map_from_display (cie, *x_retval, *y_retval, x_retval, y_retval);
+}
+
+/**
+ * gcm_cie_widget_save_point:
+ **/
+static void
+gcm_cie_widget_save_point (GcmCieWidget *cie, const guint y, const guint value)
+{
+ GcmCieWidgetBufferItem *item;
+ GcmCieWidgetPrivate *priv = cie->priv;
+
+ if (y >= priv->tongue_buffer->len)
+ return;
+ item = g_ptr_array_index (priv->tongue_buffer, y);
+ if (item->valid) {
+ if (value < item->min)
+ item->min = value;
+ if (value > item->max)
+ item->max = value;
+ } else {
+ item->min = value;
+ item->valid = TRUE;
+ }
+}
+
+/**
+ * gcm_cie_widget_add_point:
+ **/
+static void
+gcm_cie_widget_add_point (GcmCieWidget *cie, guint icx, guint icy, guint icx_last, guint icy_last)
+{
+ gfloat grad;
+ guint i;
+ gint dy, dx;
+ gfloat c;
+ gint x;
+
+ /* nothing to plot */
+ if (icx > cie->priv->chart_width)
+ return;
+ if (icy > cie->priv->chart_height)
+ return;
+
+ /* nothing to plot */
+ if (icx == icx_last && icy == icy_last)
+ return;
+
+ /* no change in y axis */
+ if (icy == icy_last)
+ return;
+
+ /* trivial */
+ if (icx == icx_last) {
+ for (i=icy; i<=icy_last; i++)
+ gcm_cie_widget_save_point (cie, i, icx);
+ for (i=icy_last; i<=icy; i++)
+ gcm_cie_widget_save_point (cie, i, icx);
+ return;
+ }
+
+ /* plot on the buffer */
+ dy = icy - icy_last;
+ dx = icx - icx_last;
+ grad = ((gfloat) dy) / ((gfloat) dx);
+ c = icy - (grad * (gfloat) icx);
+ for (i=icy; i<=icy_last; i++) {
+ x = (gint) (((gfloat) (i - c)) / grad);
+ gcm_cie_widget_save_point (cie, i, x);
+ }
+ for (i=icy_last; i<=icy; i++) {
+ x = (gint) (((gfloat) (i - c)) / grad);
+ gcm_cie_widget_save_point (cie, i, x);
+ }
+}
+
+/**
+ * gcm_cie_widget_get_min_max_tongue:
+ **/
+static void
+gcm_cie_widget_get_min_max_tongue (GcmCieWidget *cie)
+{
+ guint wavelength;
+ guint icx, icy;
+ guint icx_last, icy_last;
+ GcmCieWidgetBufferItem *item;
+ guint i;
+ GcmCieWidgetPrivate *priv = cie->priv;
+
+ /* add enough elements to the array */
+ g_ptr_array_set_size (priv->tongue_buffer, 0);
+ for (i=0; i<priv->chart_height; i++) {
+ item = g_new0 (GcmCieWidgetBufferItem, 1);
+ g_ptr_array_add (priv->tongue_buffer, item);
+ }
+
+ /* get first co-ordinate */
+ gcm_cie_widget_compute_monochrome_color_location (cie, 380, &icx_last, &icy_last);
+
+ /* this is fast path */
+ for (wavelength = 380+1; wavelength <= 700; wavelength++) {
+ gcm_cie_widget_compute_monochrome_color_location (cie, wavelength, &icx, &icy);
+ gcm_cie_widget_add_point (cie, icx, icy, icx_last, icy_last);
+ icx_last = icx;
+ icy_last = icy;
+ }
+
+ /* add data */
+ gcm_cie_widget_compute_monochrome_color_location (cie, 380, &icx, &icy);
+ gcm_cie_widget_add_point (cie, icx, icy, icx_last, icy_last);
+}
+
+/**
+ * gcm_cie_widget_draw_tongue_outline:
+ **/
+static void
+gcm_cie_widget_draw_tongue_outline (GcmCieWidget *cie, cairo_t *cr)
+{
+ guint wavelength;
+ guint icx, icy;
+ guint icx_last, icy_last;
+
+ cairo_save (cr);
+ cairo_set_line_width (cr, 2.0f);
+ cairo_set_source_rgb (cr, 0.5f, 0.5f, 0.5f);
+
+ /* get first co-ordinate */
+ gcm_cie_widget_compute_monochrome_color_location (cie, 380, &icx_last, &icy_last);
+ cairo_move_to (cr, icx_last, icy_last);
+
+ /* this is fast path */
+ for (wavelength = 380+1; wavelength <= 700; wavelength++) {
+
+ /* get point */
+ gcm_cie_widget_compute_monochrome_color_location (cie, wavelength, &icx, &icy);
+
+ /* nothing to plot */
+ if (icx == icx_last && icy == icy_last)
+ continue;
+
+ /* draw line */
+ cairo_line_to (cr, icx, icy);
+
+ icx_last = icx;
+ icy_last = icy;
+ }
+
+ /* join bottom */
+ cairo_close_path (cr);
+ cairo_stroke_preserve (cr);
+ cairo_set_line_width (cr, 1.0f);
+ cairo_set_source_rgb (cr, 0.0f, 0.0f, 0.0f);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+}
+
+/**
+ * gcm_cie_widget_xyz_to_rgb:
+ *
+ * Given an additive tricolor system CS, defined by the CIE x and y
+ * chromaticities of its three primaries (z is derived trivially as
+ * 1- (x+y)), and a desired chromaticity (XC, YC, ZC) in CIE space,
+ * determine the contribution of each primary in a linear combination
+ * which sums to the desired chromaticity. If the requested
+ * chromaticity falls outside the Maxwell triangle (color gamut)
+ * formed by the three primaries, one of the r, g, or b weights will
+ * be negative.
+ *
+ * Caller can use gcm_cie_widget_constrain_rgb () to desaturate an outside-gamut
+ * color to the closest representation within the available
+ * gamut.
+ **/
+static void
+gcm_cie_widget_xyz_to_rgb (GcmCieWidget *cie,
+ gdouble xc, gdouble yc, gdouble zc,
+ gdouble *r, gdouble *g, gdouble *b)
+{
+ gdouble xr, yr, zr, xg, yg, zg, xb, yb, zb;
+ gdouble xw, yw, zw;
+ gdouble rx, ry, rz, gx, gy, gz, bx, by, bz;
+ gdouble rw, gw, bw;
+ GcmCieWidgetPrivate *priv = cie->priv;
+
+ xr = priv->red_x; yr = priv->red_y; zr = 1 - (xr + yr);
+ xg = priv->green_x; yg = priv->green_y; zg = 1 - (xg + yg);
+ xb = priv->blue_x; yb = priv->blue_y; zb = 1 - (xb + yb);
+
+ xw = priv->white_x; yw = priv->white_y; zw = 1 - (xw + yw);
+
+ /* xyz -> rgb matrix, before scaling to white. */
+ rx = yg*zb - yb*zg; ry = xb*zg - xg*zb; rz = xg*yb - xb*yg;
+ gx = yb*zr - yr*zb; gy = xr*zb - xb*zr; gz = xb*yr - xr*yb;
+ bx = yr*zg - yg*zr; by = xg*zr - xr*zg; bz = xr*yg - xg*yr;
+
+ /* white scaling factors - dividing by yw scales the white luminance to unity */
+ rw = (rx*xw + ry*yw + rz*zw) / yw;
+ gw = (gx*xw + gy*yw + gz*zw) / yw;
+ bw = (bx*xw + by*yw + bz*zw) / yw;
+
+ /* xyz -> rgb matrix, correctly scaled to white. */
+ rx = rx / rw; ry = ry / rw; rz = rz / rw;
+ gx = gx / gw; gy = gy / gw; gz = gz / gw;
+ bx = bx / bw; by = by / bw; bz = bz / bw;
+
+ /* rgb of the desired point */
+ *r = rx*xc + ry*yc + rz*zc;
+ *g = gx*xc + gy*yc + gz*zc;
+ *b = bx*xc + by*yc + bz*zc;
+}
+
+/**
+ * gcm_cie_widget_constrain_rgb:
+ *
+ * If the requested RGB shade contains a negative weight for one of
+ * the primaries, it lies outside the color gamut accessible from
+ * the given triple of primaries. Desaturate it by adding white,
+ * equal quantities of R, G, and B, enough to make RGB all positive.
+ **/
+static gboolean
+gcm_cie_widget_constrain_rgb (gdouble *r, gdouble *g, gdouble *b)
+{
+ gdouble w;
+
+ /* amount of white needed is w = - min (0, *r, *g, *b) */
+ w = (0 < *r) ? 0 : *r;
+ w = (w < *g) ? w : *g;
+ w = (w < *b) ? w : *b;
+ w = - w;
+
+ /* add just enough white to make r, g, b all positive. */
+ if (w > 0) {
+ *r += w; *g += w; *b += w;
+ return TRUE; /* color modified to fit RGB gamut */
+ }
+
+ return FALSE; /* color within RGB gamut */
+}
+
+/**
+ * gcm_cie_widget_gamma_correct:
+ *
+ * Transform linear RGB values to nonlinear RGB values.
+ *
+ * Rec. 709 is ITU-R Recommendation BT. 709 (1990)
+ * ``Basic Parameter Values for the HDTV Standard for the Studio and for
+ * International Programme Exchange'', formerly CCIR Rec. 709.
+ *
+ * For details see
+ * http://www.inforamp.net/~poynton/ColorFAQ.html
+ * http://www.inforamp.net/~poynton/GammaFAQ.html
+ **/
+static void
+gcm_cie_widget_gamma_correct (GcmCieWidget *cie, gdouble *c)
+{
+ GcmCieWidgetPrivate *priv = cie->priv;
+
+ if (priv->gamma == 0.0) {
+ /* rec. 709 gamma correction. */
+ gdouble cc = 0.018;
+ if (*c < cc) {
+ *c *= (1.099 * powf (cc, 0.45) - 0.099) / cc;
+ } else {
+ *c = 1.099 * powf (*c, 0.45) - 0.099;
+ }
+ } else {
+ /* Nonlinear color = (Linear color)^ (1/gamma) */
+ *c = powf (*c, 1.0/priv->gamma);
+ }
+}
+
+/**
+ * gcm_cie_widget_gamma_correct_rgb:
+ **/
+static void
+gcm_cie_widget_gamma_correct_rgb (GcmCieWidget *cie,
+ gdouble *r, gdouble *g, gdouble *b)
+{
+ gcm_cie_widget_gamma_correct (cie, r);
+ gcm_cie_widget_gamma_correct (cie, g);
+ gcm_cie_widget_gamma_correct (cie, b);
+}
+
+/**
+ * gcm_cie_widget_draw_line:
+ *
+ * Draw the data line onto the cie with a big green line. We should already
+ * limit the data to < ~100 values, so this shouldn't take too long.
+ **/
+static void
+gcm_cie_widget_draw_line (GcmCieWidget *cie, cairo_t *cr)
+{
+ guint x, y;
+ guint x_scaled, y_scaled;
+ GcmCieWidgetPrivate *priv = cie->priv;
+ GcmCieWidgetBufferItem *item;
+
+ /* save for speed */
+ gcm_cie_widget_get_min_max_tongue (cie);
+
+ cairo_save (cr);
+ for (y = 0; y < priv->chart_height; ++y) {
+
+ /* get buffer data to se if there's any point rendering this line */
+ item = g_ptr_array_index (priv->tongue_buffer, y);
+ if (!item->valid)
+ continue;
+
+ for (x=item->min; x < item->max; x++) {
+
+ gdouble cx, cy, cz;
+ gdouble jr, jg, jb;
+ gdouble r, g, b, mx;
+ gdouble jmax;
+
+ /* scale for display */
+ gcm_cie_widget_map_to_display (cie, x, y, &x_scaled, &y_scaled);
+
+ cx = ((gdouble) x_scaled) / (priv->chart_width - 1);
+ cy = 1.0 - ((gdouble) y_scaled) / (priv->chart_height - 1);
+ cz = 1.0 - (cx + cy);
+
+ gcm_cie_widget_xyz_to_rgb (cie, cx, cy, cz, &jr, &jg, &jb);
+ mx = 1.0f;
+
+ /* Check whether the requested color is within the
+ * gamut achievable with the given color system. If
+ * not, draw it in a reduced intensity, interpolated
+ * by desaturation to the closest within-gamut color.
+ */
+ if (gcm_cie_widget_constrain_rgb (&jr, &jg, &jb))
+ mx = (1.0 * 3) / 4;
+
+ /* Scale to max (rgb) = 1. */
+ jmax = MAX (jr, MAX (jg, jb));
+ if (jmax > 0) {
+ jr = jr / jmax;
+ jg = jg / jmax;
+ jb = jb / jmax;
+ }
+
+ /* gamma correct from linear rgb to nonlinear rgb. */
+ gcm_cie_widget_gamma_correct_rgb (cie, &jr, &jg, &jb);
+ r = mx * jr;
+ g = mx * jg;
+ b = mx * jb;
+
+ cairo_set_source_rgb (cr, r, g, b);
+ cairo_rectangle (cr, x, y, 1, 1);
+ cairo_fill (cr);
+ }
+ }
+
+ cairo_restore (cr);
+
+ /* overdraw line with nice antialiasing */
+ gcm_cie_widget_draw_tongue_outline (cie, cr);
+}
+
+/**
+ * gcm_cie_widget_draw_bounding_box:
+ **/
+static void
+gcm_cie_widget_draw_bounding_box (cairo_t *cr, gint x, gint y, gint width, gint height)
+{
+ /* background */
+ cairo_rectangle (cr, x, y, width, height);
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_fill (cr);
+
+ /* solid outline box */
+ cairo_rectangle (cr, x + 0.5f, y + 0.5f, width - 1, height - 1);
+ cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
+ cairo_set_line_width (cr, 1);
+ cairo_stroke (cr);
+}
+
+/**
+ * gcm_cie_widget_draw_cie:
+ *
+ * Draw the complete cie, with the box, the grid, the horseshoe and the shading.
+ **/
+static void
+gcm_cie_widget_draw_cie (GtkWidget *cie_widget, cairo_t *cr)
+{
+ GtkAllocation allocation;
+
+ GcmCieWidget *cie = (GcmCieWidget*) cie_widget;
+ g_return_if_fail (cie != NULL);
+ g_return_if_fail (GCM_IS_CIE_WIDGET (cie));
+
+ cairo_save (cr);
+
+ /* make size adjustment */
+ gtk_widget_get_allocation (cie_widget, &allocation);
+ cie->priv->chart_height = allocation.height;
+ cie->priv->chart_width = allocation.width;
+
+ /* cie background */
+ gcm_cie_widget_draw_bounding_box (cr, 0, 0, cie->priv->chart_width, cie->priv->chart_height);
+ if (cie->priv->use_grid)
+ gcm_cie_widget_draw_grid (cie, cr);
+
+ gcm_cie_widget_draw_line (cie, cr);
+
+ cairo_restore (cr);
+}
+
+/**
+ * gcm_cie_widget_expose:
+ *
+ * Just repaint the entire cie widget on expose.
+ **/
+static gboolean
+gcm_cie_widget_expose (GtkWidget *cie, GdkEventExpose *event)
+{
+ cairo_t *cr;
+
+ /* get a cairo_t */
+ cr = gdk_cairo_create (gtk_widget_get_window (cie));
+ cairo_rectangle (cr,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cairo_clip (cr);
+ ((GcmCieWidget *)cie)->priv->cr = cr;
+
+ gcm_cie_widget_draw_cie (cie, cr);
+
+ cairo_destroy (cr);
+ return FALSE;
+}
+
+/**
+ * gcm_cie_widget_new:
+ * Return value: A new GcmCieWidget object.
+ **/
+GtkWidget *
+gcm_cie_widget_new (void)
+{
+ return g_object_new (GCM_TYPE_CIE_WIDGET, NULL);
+}
+
+/***************************************************************************
+ *** MAKE CHECK TESTS ***
+ ***************************************************************************/
+#ifdef EGG_TEST
+#include "egg-test.h"
+
+void
+gcm_cie_widget_test (EggTest *test)
+{
+ GtkWidget *widget;
+ GtkWidget *dialog;
+ GtkWidget *vbox;
+ gboolean ret;
+ GError *error = NULL;
+
+ if (!egg_test_start (test, "GcmCieWidget"))
+ return;
+
+ /************************************************************/
+ egg_test_title (test, "get a CIE widget object");
+ widget = gcm_cie_widget_new ();
+ egg_test_assert (test, widget != NULL);
+
+ /* show in a dialog as an example */
+ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "CIE widget");
+ vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_pack_end (GTK_BOX(vbox), widget, TRUE, TRUE, 12);
+ gtk_widget_set_size_request (widget, 200, 200);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+ gtk_widget_show (widget);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ egg_test_end (test);
+}
+#endif
+
diff --git a/src/gcm-cie-widget.h b/src/gcm-cie-widget.h
new file mode 100644
index 0000000..efcc012
--- /dev/null
+++ b/src/gcm-cie-widget.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2009 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GCM_CIE_WIDGET_H__
+#define __GCM_CIE_WIDGET_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GCM_TYPE_CIE_WIDGET (gcm_cie_widget_get_type ())
+#define GCM_CIE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCM_TYPE_CIE_WIDGET, GcmCieWidget))
+#define GCM_CIE_WIDGET_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GCM_CIE_WIDGET, GcmCieWidgetClass))
+#define GCM_IS_CIE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCM_TYPE_CIE_WIDGET))
+#define GCM_IS_CIE_WIDGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), EFF_TYPE_CIE_WIDGET))
+#define GCM_CIE_WIDGET_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), GCM_TYPE_CIE_WIDGET, GcmCieWidgetClass))
+
+typedef struct GcmCieWidget GcmCieWidget;
+typedef struct GcmCieWidgetClass GcmCieWidgetClass;
+typedef struct GcmCieWidgetPrivate GcmCieWidgetPrivate;
+
+struct GcmCieWidget
+{
+ GtkDrawingArea parent;
+ GcmCieWidgetPrivate *priv;
+};
+
+struct GcmCieWidgetClass
+{
+ GtkDrawingAreaClass parent_class;
+};
+
+GType gcm_cie_widget_get_type (void);
+GtkWidget *gcm_cie_widget_new (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/gcm-self-test.c b/src/gcm-self-test.c
index 5624175..015c781 100644
--- a/src/gcm-self-test.c
+++ b/src/gcm-self-test.c
@@ -32,6 +32,7 @@ void gcm_profile_test (EggTest *test);
void gcm_brightness_test (EggTest *test);
void gcm_clut_test (EggTest *test);
void gcm_dmi_test (EggTest *test);
+void gcm_cie_widget_test (EggTest *test);
int
main (int argc, char **argv)
@@ -40,7 +41,7 @@ main (int argc, char **argv)
if (! g_thread_supported ())
g_thread_init (NULL);
- g_type_init ();
+ gtk_init (&argc, &argv);
test = egg_test_init ();
egg_debug_init (&argc, &argv);
@@ -53,6 +54,7 @@ main (int argc, char **argv)
gcm_brightness_test (test);
gcm_clut_test (test);
gcm_dmi_test (test);
+ gcm_cie_widget_test (test);
return (egg_test_finish (test));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]