Index: pixmaps/upload.svg
===================================================================
--- pixmaps/upload.svg	(revision 0)
+++ pixmaps/upload.svg	(revision 0)
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="upload.svg"
+   sodipodi:docbase="/home/klattimer/workspace/sexyhacks/GSMColorPicker"
+   inkscape:version="0.45.1"
+   sodipodi:version="0.32"
+   id="svg11300"
+   height="32"
+   width="32"
+   inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+   inkscape:export-xdpi="90.000000"
+   inkscape:export-ydpi="90.000000"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs3">
+    <linearGradient
+       id="linearGradient2304">
+      <stop
+         id="stop2306"
+         offset="0"
+         style="stop-color:#73d216" />
+      <stop
+         id="stop2308"
+         offset="1.0000000"
+         style="stop-color:#4e9a06" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient1442">
+      <stop
+         id="stop1444"
+         offset="0"
+         style="stop-color:#73d216" />
+      <stop
+         id="stop1446"
+         offset="1.0000000"
+         style="stop-color:#4e9a06" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient8662"
+       inkscape:collect="always">
+      <stop
+         id="stop8664"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop8666"
+         offset="1"
+         style="stop-color:#000000;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient8650"
+       inkscape:collect="always">
+      <stop
+         id="stop8652"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop8654"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8662"
+       id="radialGradient1444"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9574038,0,0,0.2519481,-7.8008277,17.882096)"
+       cx="24.837126"
+       cy="36.421127"
+       fx="24.837126"
+       fy="36.421127"
+       r="15.644737" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8650"
+       id="radialGradient2916"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,-1.639511,1.2477073,0,-0.7887167,50.520377)"
+       cx="24.53788"
+       cy="0.40010813"
+       fx="24.53788"
+       fy="0.40010813"
+       r="17.171415" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-y="26"
+     inkscape:window-x="37"
+     inkscape:window-height="1039"
+     inkscape:window-width="1475"
+     inkscape:showpageshadow="true"
+     inkscape:document-units="px"
+     inkscape:grid-bbox="true"
+     showgrid="true"
+     inkscape:current-layer="layer1"
+     inkscape:cy="14.82149"
+     inkscape:cx="13.476992"
+     inkscape:zoom="44.177004"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.4"
+     borderopacity="1"
+     bordercolor="#666666"
+     pagecolor="#ffffb3"
+     id="base"
+     fill="#4e9a06"
+     stroke="#4e9a06"
+     width="32px"
+     height="32px"
+     borderlayer="true"
+     showguides="true"
+     inkscape:guide-bbox="true">
+    <sodipodi:guide
+       orientation="vertical"
+       position="16.003801"
+       id="guide2646" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Jakub Steiner</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:source>http://jimmac.musichall.cz</dc:source>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+        <dc:title>Go Down</dc:title>
+        <dc:subject>
+          <rdf:Bag>
+            <rdf:li>go</rdf:li>
+            <rdf:li>lower</rdf:li>
+            <rdf:li>down</rdf:li>
+            <rdf:li>arrow</rdf:li>
+            <rdf:li>pointer</rdf:li>
+            <rdf:li>&gt;</rdf:li>
+          </rdf:Bag>
+        </dc:subject>
+        <dc:contributor>
+          <cc:Agent>
+            <dc:title>Andreas Nilsson</dc:title>
+          </cc:Agent>
+        </dc:contributor>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Reproduction" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Distribution" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Notice" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Attribution" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     inkscape:label="Layer 1"
+     id="layer1">
+    <path
+       style="opacity:0.20454544;color:#000000;fill:url(#radialGradient1444);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 8 23.71875 C 3.8007462 24.417285 1 25.659396 1 27.0625 C 1 29.238298 7.7007116 31 15.96875 31 C 24.236789 31 30.968751 29.238298 30.96875 27.0625 C 30.96875 25.669209 28.181501 24.45105 24.03125 23.75 L 24.0625 27.5625 C 24.062472 27.838631 23.838631 28.062472 23.5625 28.0625 L 8.5 28.03125 C 8.2238691 28.031222 8.0000277 27.807381 8 27.53125 L 8 23.71875 z "
+       id="path8660" />
+    <path
+       style="opacity:0.48128339;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000036;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 22.569585,26.572772 L 9.5024221,26.553215 L 9.4797859,16.536803 L 4.6265001,16.524485 L 16.008001,2.8113028 L 27.397918,16.550556 L 22.52643,16.554693 L 22.569585,26.572772 z "
+       id="path8658"
+       sodipodi:nodetypes="cccccccc" />
+    <path
+       sodipodi:nodetypes="cccscc"
+       id="path2878"
+       d="M 3.5238289,17.001913 L 9.007046,16.956641 L 9.0603961,22.21291 C 13.590765,13.401105 21.871498,15.128187 22.353124,9.6945344 C 22.353124,9.6945344 15.984277,2.1846647 15.984277,2.1846647 L 3.5238289,17.001913 z "
+       style="opacity:0.5080214;color:#000000;fill:url(#radialGradient2916);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+  </g>
+</svg>
Index: pixmaps/download.svg
===================================================================
--- pixmaps/download.svg	(revision 0)
+++ pixmaps/download.svg	(revision 0)
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="download.svg"
+   sodipodi:docbase="/home/klattimer/workspace/sexyhacks/GSMColorPicker"
+   inkscape:version="0.45.1"
+   sodipodi:version="0.32"
+   id="svg11300"
+   height="32"
+   width="32"
+   inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+   inkscape:export-xdpi="90.000000"
+   inkscape:export-ydpi="90.000000"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   version="1.0">
+  <defs
+     id="defs3">
+    <linearGradient
+       id="linearGradient1442">
+      <stop
+         id="stop1444"
+         offset="0"
+         style="stop-color:#73d216" />
+      <stop
+         id="stop1446"
+         offset="1.0000000"
+         style="stop-color:#4e9a06" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient8662"
+       inkscape:collect="always">
+      <stop
+         id="stop8664"
+         offset="0"
+         style="stop-color:#000000;stop-opacity:1;" />
+      <stop
+         id="stop8666"
+         offset="1"
+         style="stop-color:#000000;stop-opacity:0;" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient8650"
+       inkscape:collect="always">
+      <stop
+         id="stop8652"
+         offset="0"
+         style="stop-color:#ffffff;stop-opacity:1;" />
+      <stop
+         id="stop8654"
+         offset="1"
+         style="stop-color:#ffffff;stop-opacity:0;" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8662"
+       id="radialGradient1444"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9574038,0,0,0.2519481,-7.8008277,17.882096)"
+       cx="24.837126"
+       cy="36.421127"
+       fx="24.837126"
+       fy="36.421127"
+       r="15.644737" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient1442"
+       id="radialGradient1469"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,-0.843022,1.020168,0,0.606436,42.58614)"
+       cx="35.292667"
+       cy="20.494493"
+       fx="35.292667"
+       fy="20.494493"
+       r="16.9562" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8650"
+       id="radialGradient1471"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,-2.046729,-1.55761,0,44.11559,66.93275)"
+       cx="15.987216"
+       cy="1.5350308"
+       fx="15.987216"
+       fy="1.5350308"
+       r="17.171415" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8650"
+       id="radialGradient2650"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,1.6135044,1.2279157,0,-0.3348922,-20.930097)"
+       cx="15.987216"
+       cy="1.5350308"
+       fx="15.987216"
+       fy="1.5350308"
+       r="17.171415" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient1442"
+       id="radialGradient2653"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,0.6645822,-0.8042323,0,33.964818,-1.736856)"
+       cx="35.292667"
+       cy="20.494493"
+       fx="35.292667"
+       fy="20.494493"
+       r="16.9562" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:window-y="26"
+     inkscape:window-x="0"
+     inkscape:window-height="1039"
+     inkscape:window-width="1475"
+     inkscape:showpageshadow="true"
+     inkscape:document-units="px"
+     inkscape:grid-bbox="true"
+     showgrid="true"
+     inkscape:current-layer="layer1"
+     inkscape:cy="21.82691"
+     inkscape:cx="17.692268"
+     inkscape:zoom="31.237859"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.4"
+     borderopacity="1"
+     bordercolor="#666666"
+     pagecolor="#ffffb3"
+     id="base"
+     fill="#4e9a06"
+     stroke="#4e9a06"
+     width="32px"
+     height="32px"
+     borderlayer="true"
+     showguides="true"
+     inkscape:guide-bbox="true">
+    <sodipodi:guide
+       orientation="vertical"
+       position="16.003801"
+       id="guide2646" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Jakub Steiner</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:source>http://jimmac.musichall.cz</dc:source>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+        <dc:title>Go Down</dc:title>
+        <dc:subject>
+          <rdf:Bag>
+            <rdf:li>go</rdf:li>
+            <rdf:li>lower</rdf:li>
+            <rdf:li>down</rdf:li>
+            <rdf:li>arrow</rdf:li>
+            <rdf:li>pointer</rdf:li>
+            <rdf:li>&gt;</rdf:li>
+          </rdf:Bag>
+        </dc:subject>
+        <dc:contributor>
+          <cc:Agent>
+            <dc:title>Andreas Nilsson</dc:title>
+          </cc:Agent>
+        </dc:contributor>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Reproduction" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Distribution" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Notice" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Attribution" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:groupmode="layer"
+     inkscape:label="Layer 1"
+     id="layer1">
+    <path
+       style="opacity:0.20454544;color:#000000;fill:url(#radialGradient1444);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 11.59375 23.3125 C 5.4817822 23.80926 1 25.291665 1 27.0625 C 1 29.238298 7.7007116 31 15.96875 31 C 24.236789 31 30.968751 29.238298 30.96875 27.0625 C 30.96875 25.291666 26.486968 23.80926 20.375 23.3125 L 16.375 28.125 C 16.280109 28.243732 16.120742 28.312501 15.96875 28.3125 C 15.816758 28.3125 15.688641 28.243732 15.59375 28.125 L 11.59375 23.3125 z "
+       id="path8660" />
+    <path
+       sodipodi:nodetypes="cccccc"
+       id="path8645"
+       d="M 3.6079996,12.041487 L 8.9939796,12.032249 L 8.991866,2.0611985 L 21.319018,1.8873245 C 20.712063,16.346136 12.979179,10.508257 9.3063266,18.907006 L 3.6079996,12.041487 z "
+       style="opacity:0.5080214;color:#000000;fill:url(#radialGradient2650);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    <path
+       style="opacity:0.48128339;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000036;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 22.569585,2.479522 L 9.5024221,2.499079 L 9.4797859,12.515491 L 4.6265001,12.527809 L 16.008001,26.240989 L 27.397918,12.501738 L 22.52643,12.497601 L 22.569585,2.479522 z "
+       id="path8658"
+       sodipodi:nodetypes="cccccccc" />
+  </g>
+</svg>
Index: src/gsm_color_button.c
===================================================================
--- src/gsm_color_button.c	(revision 0)
+++ src/gsm_color_button.c	(revision 0)
@@ -0,0 +1,889 @@
+/*
+ * Gnome system monitor colour pickers
+ * Copyright (C) 2007 Karl Lattimer <karl@qdh.org.uk>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This software 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 the software; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <gdk/gdkkeysyms.h>
+#include <math.h>
+#include <cairo.h>
+
+#include "gsm_color_button.h"
+
+#define GSM_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSM_TYPE_COLOR_BUTTON, GSMColorButtonPrivate))
+
+struct _GSMColorButtonPrivate
+{
+  GtkWidget *cs_dialog;		/* Color selection dialog */
+
+  gchar *title;			/* Title for the color selection window */
+
+  GdkColor color;
+
+  gdouble fraction;		/* Only used by GSMCP_TYPE_PIE */
+  guint type;
+  cairo_surface_t *image_buffer;
+  gdouble highlight;
+};
+
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_PERCENTAGE,
+  PROP_TITLE,
+  PROP_COLOR,
+  PROP_TYPE
+};
+
+/* Signals */
+enum
+{
+  COLOR_SET,
+  LAST_SIGNAL
+};
+
+#define GSMCP_MIN_WIDTH 15
+#define GSMCP_MIN_HEIGHT 15
+
+static void gsm_color_button_class_intern_init (gpointer);
+static void gsm_color_button_class_init (GSMColorButtonClass * klass);
+static void gsm_color_button_init (GSMColorButton * color_button);
+static void gsm_color_button_finalize (GObject * object);
+static void gsm_color_button_set_property (GObject * object, guint param_id,
+					   const GValue * value,
+					   GParamSpec * pspec);
+static void gsm_color_button_get_property (GObject * object, guint param_id,
+					   GValue * value,
+					   GParamSpec * pspec);
+static void gsm_color_button_realize (GtkWidget * widget);
+static void gsm_color_button_size_request (GtkWidget * widget,
+					   GtkRequisition * requisition);
+static void gsm_color_button_size_allocate (GtkWidget * widget,
+					    GtkAllocation * allocation);
+static void gsm_color_button_unrealize (GtkWidget * widget);
+static void gsm_color_button_state_changed (GtkWidget * widget,
+					    GtkStateType previous_state);
+static void gsm_color_button_style_set (GtkWidget * widget,
+					GtkStyle * previous_style);
+static gint gsm_color_button_clicked (GtkWidget * widget,
+				      GdkEventButton * event);
+static gboolean gsm_color_button_motion_notify (GtkWidget * widget,
+						GdkEventMotion * event);
+static gboolean gsm_color_button_enter_notify (GtkWidget * widget,
+					       GdkEventCrossing * event);
+static gboolean gsm_color_button_leave_notify (GtkWidget * widget,
+					       GdkEventCrossing * event);
+/* source side drag signals */
+static void gsm_color_button_drag_begin (GtkWidget * widget,
+					 GdkDragContext * context,
+					 gpointer data);
+static void gsm_color_button_drag_data_get (GtkWidget * widget,
+					    GdkDragContext * context,
+					    GtkSelectionData * selection_data,
+					    guint info, guint time,
+					    GSMColorButton * color_button);
+
+/* target side drag signals */
+static void gsm_color_button_drag_data_received (GtkWidget * widget,
+						 GdkDragContext * context,
+						 gint x,
+						 gint y,
+						 GtkSelectionData *
+						 selection_data, guint info,
+						 guint32 time,
+						 GSMColorButton *
+						 color_button);
+
+
+static guint color_button_signals[LAST_SIGNAL] = { 0 };
+
+static gpointer gsm_color_button_parent_class = NULL;
+
+static const GtkTargetEntry drop_types[] = { {"application/x-color", 0, 0} };
+
+GType
+gsm_color_button_get_type ()
+{
+  static GType gsm_color_button_type = 0;
+
+  if (!gsm_color_button_type)
+    {
+      static const GTypeInfo gsm_color_button_info = {
+	sizeof (GSMColorButtonClass),
+	NULL,
+	NULL,
+	(GClassInitFunc) gsm_color_button_class_intern_init,
+	NULL,
+	NULL,
+	sizeof (GSMColorButton),
+	0,
+	(GInstanceInitFunc) gsm_color_button_init,
+      };
+
+      gsm_color_button_type =
+	g_type_register_static (GTK_TYPE_DRAWING_AREA, "GSMColorButton",
+				&gsm_color_button_info, 0);
+    }
+
+  return gsm_color_button_type;
+}
+
+static void
+gsm_color_button_class_intern_init (gpointer klass)
+{
+  gsm_color_button_parent_class = g_type_class_peek_parent (klass);
+  gsm_color_button_class_init ((GSMColorButtonClass *) klass);
+}
+
+static void
+gsm_color_button_class_init (GSMColorButtonClass * klass)
+{
+  GObjectClass *gobject_class;
+  GtkWidgetClass *widget_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  widget_class = GTK_WIDGET_CLASS (klass);
+
+  gobject_class->get_property = gsm_color_button_get_property;
+  gobject_class->set_property = gsm_color_button_set_property;
+  gobject_class->finalize = gsm_color_button_finalize;
+  widget_class->state_changed = gsm_color_button_state_changed;
+  widget_class->size_request = gsm_color_button_size_request;
+  widget_class->size_allocate = gsm_color_button_size_allocate;
+  widget_class->realize = gsm_color_button_realize;
+  widget_class->unrealize = gsm_color_button_unrealize;
+  widget_class->style_set = gsm_color_button_style_set;
+  widget_class->button_release_event = gsm_color_button_clicked;
+  widget_class->motion_notify_event = gsm_color_button_motion_notify;
+  widget_class->enter_notify_event = gsm_color_button_enter_notify;
+  widget_class->leave_notify_event = gsm_color_button_leave_notify;
+
+  klass->color_set = NULL;
+
+  g_object_class_install_property (gobject_class,
+				   PROP_PERCENTAGE,
+				   g_param_spec_double ("fraction",
+							_("Fraction"),
+							_("Percentage full for pie colour pickers"),
+							0, 1, 0.5,
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_TITLE,
+				   g_param_spec_string ("title",
+							_("Title"),
+							_("The title of the color selection dialog"),
+							_("Pick a Color"),
+							G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_COLOR,
+				   g_param_spec_boxed ("color",
+						       _("Current Color"),
+						       _("The selected color"),
+						       GDK_TYPE_COLOR,
+						       G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_TYPE,
+				   g_param_spec_uint ("type", _("Type"),
+						      _("Type of color picker"),
+						      0, 4, 0,
+						      G_PARAM_READWRITE));
+
+  color_button_signals[COLOR_SET] = g_signal_new (_("color_set"),
+						  G_TYPE_FROM_CLASS
+						  (gobject_class),
+						  G_SIGNAL_RUN_FIRST,
+						  G_STRUCT_OFFSET
+						  (GSMColorButtonClass,
+						   color_set), NULL, NULL,
+						  gtk_marshal_VOID__VOID,
+						  G_TYPE_NONE, 0);
+
+  g_type_class_add_private (gobject_class, sizeof (GSMColorButtonPrivate));
+}
+
+static void
+render (GtkWidget * widget)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (widget);
+  GdkColor *color = &color_button->priv->color;
+  cairo_t *cr = gdk_cairo_create (widget->window);
+  cairo_path_t *path = NULL;
+  gint width, height;
+  gdouble radius, arc_start, arc_end;
+  RsvgHandle *handle;
+  GError *error = NULL;
+
+  gdk_cairo_set_source_color (cr, color);
+  gdk_drawable_get_size (widget->window, &width, &height);
+
+  switch (color_button->priv->type)
+    {
+    case GSMCP_TYPE_CPU:
+      gtk_widget_set_size_request (widget, GSMCP_MIN_WIDTH, GSMCP_MIN_HEIGHT);
+      cairo_paint (cr);
+      cairo_set_line_width (cr, 1);
+      cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+      cairo_rectangle (cr, 0.5, 0.5, width - 1, height - 1);
+      cairo_stroke (cr);
+      cairo_set_line_width (cr, 1);
+      cairo_set_source_rgba (cr, 1, 1, 1, 0.4);
+      cairo_rectangle (cr, 1.5, 1.5, width - 3, height - 3);
+      cairo_stroke (cr);
+      break;
+    case GSMCP_TYPE_PIE:
+      if (width < 32)		// 32px minimum size
+	gtk_widget_set_size_request (widget, 32, 32);
+      if (width < height)
+	radius = width / 2;
+      else
+	radius = height / 2;
+      arc_start =
+	((2 * G_PI) * (-1 * color_button->priv->fraction)) - (0.5 * G_PI);
+      arc_end = -1 * (G_PI / 2);
+      cairo_set_line_width (cr, 1);
+
+      // Draw external stroke and fill
+      cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25,
+		 arc_start, arc_end);
+      cairo_line_to (cr, (width / 2) + .5, (height / 2) + .5);
+
+      cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 2.25,
+		 arc_start, arc_start);
+      cairo_line_to (cr, (width / 2) + .5, (height / 2) + .5);
+
+      cairo_fill_preserve (cr);
+      cairo_set_source_rgba (cr, 0, 0, 0, 0.7);
+      cairo_stroke (cr);
+
+      cairo_set_source_rgba (cr, 1, 1, 1, 0.45);
+      cairo_set_line_width (cr, 1);
+
+      // Draw internal highlight
+      cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.75,
+		 arc_start + (1 / (radius - 3.75)),
+		 arc_end - (1 / (radius - 3.75)));
+      //if (arc_end - 1)
+      cairo_arc_negative (cr, (width / 2) + .5, (height / 2) + .5, 1,
+		 arc_end - 1, arc_start + 1);
+      
+      cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 3.75,
+		 arc_start + (1 / (radius - 3.75)),
+		 arc_start + (1 / (radius - 3.75)));
+
+      cairo_stroke (cr);
+      // Draw external shape
+      cairo_set_line_width (cr, 1);
+      cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
+      cairo_arc (cr, (width / 2) + .5, (height / 2) + .5, radius - 1.25, 0,
+		 G_PI * 2);
+      cairo_stroke (cr);
+
+      break;
+    case GSMCP_TYPE_NETWORK_IN:
+      /* Fill the image buffer */
+      if (color_button->priv->image_buffer == NULL)
+	{
+	  handle = rsvg_handle_new_from_file (DATADIR "/pixmaps/gnome-system-monitor/download.svg", &error);
+	  cairo_surface_t *tmp_surface;
+	  cairo_t *tmp_cr;
+	  tmp_surface = cairo_surface_create_similar (cairo_get_target (cr),
+						      CAIRO_CONTENT_COLOR_ALPHA,
+						      32, 32);
+	  tmp_cr = cairo_create (tmp_surface);
+	  rsvg_handle_render_cairo (handle, tmp_cr);
+	  cairo_destroy (tmp_cr);
+	  rsvg_handle_free (handle);
+	  color_button->priv->image_buffer = tmp_surface;
+	}
+      gtk_widget_set_size_request (widget, 32, 32);
+      cairo_move_to (cr, 8.5, 1.5);
+      cairo_line_to (cr, 23.5, 1.5);
+      cairo_line_to (cr, 23.5, 11.5);
+      cairo_line_to (cr, 29.5, 11.5);
+      cairo_line_to (cr, 16.5, 27.5);
+      cairo_line_to (cr, 15.5, 27.5);
+      cairo_line_to (cr, 2.5, 11.5);
+      cairo_line_to (cr, 8.5, 11.5);
+      cairo_line_to (cr, 8.5, 1.5);
+      cairo_close_path (cr);
+      path = cairo_copy_path (cr);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+      cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+      cairo_set_line_width (cr, 1);
+      cairo_fill_preserve (cr);
+      cairo_set_miter_limit (cr, 5.0);
+      cairo_stroke (cr);
+      cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+      cairo_append_path (cr, path);
+      cairo_path_destroy(path);
+      cairo_stroke (cr);
+      cairo_set_source_surface (cr, color_button->priv->image_buffer, 0.0,
+				0.0);
+      cairo_paint (cr);
+
+      break;
+    case GSMCP_TYPE_NETWORK_OUT:
+      /* Fill the image buffer */
+      if (color_button->priv->image_buffer == NULL)
+	{
+	  handle = rsvg_handle_new_from_file (DATADIR "/pixmaps/gnome-system-monitor/upload.svg", &error);
+	  cairo_surface_t *tmp_surface;
+	  cairo_t *tmp_cr;
+	  tmp_surface = cairo_surface_create_similar (cairo_get_target (cr),
+						      CAIRO_CONTENT_COLOR_ALPHA,
+						      32, 32);
+	  tmp_cr = cairo_create (tmp_surface);
+	  rsvg_handle_render_cairo (handle, tmp_cr);
+	  cairo_destroy (tmp_cr);
+	  rsvg_handle_free (handle);
+	  color_button->priv->image_buffer = tmp_surface;
+	}
+      gtk_widget_set_size_request (widget, 32, 32);
+      cairo_move_to (cr, 16.5, 1.5);
+      cairo_line_to (cr, 29.5, 17.5);
+      cairo_line_to (cr, 23.5, 17.5);
+      cairo_line_to (cr, 23.5, 27.5);
+      cairo_line_to (cr, 8.5, 27.5);
+      cairo_line_to (cr, 8.5, 17.5);
+      cairo_line_to (cr, 2.5, 17.5);
+      cairo_line_to (cr, 15.5, 1.5);
+      cairo_line_to (cr, 16.5, 1.5);
+      cairo_close_path (cr);
+      path = cairo_copy_path (cr);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+      cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+      cairo_set_line_width (cr, 1);
+      cairo_fill_preserve (cr);
+      cairo_set_miter_limit (cr, 5.0);
+      cairo_stroke (cr);
+      cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
+      cairo_append_path (cr, path);
+      cairo_path_destroy(path);
+      cairo_stroke (cr);
+      cairo_set_source_surface (cr, color_button->priv->image_buffer, 0.0,
+				0.0);
+      cairo_paint (cr);
+
+      break;
+    }
+  cairo_destroy (cr);
+  //g_print("Highlight: %f\n", color_button->priv->highlight);
+}
+
+/* Handle exposure events for the color picker's drawing area */
+static gint
+expose_event (GtkWidget * widget, GdkEventExpose * event, gpointer data)
+{
+  render (GTK_WIDGET (data));
+
+  return FALSE;
+}
+
+static void
+gsm_color_button_realize (GtkWidget * widget)
+{
+  GTK_WIDGET_CLASS (gsm_color_button_parent_class)->realize (widget);
+  render (widget);
+}
+
+static void
+gsm_color_button_size_request (GtkWidget * widget,
+			       GtkRequisition * requisition)
+{
+  g_return_if_fail (widget != NULL || requisition != NULL);
+  g_return_if_fail (GSM_IS_COLOR_BUTTON (widget));
+
+  requisition->width = GSMCP_MIN_WIDTH;
+  requisition->height = GSMCP_MIN_HEIGHT;
+}
+
+static void
+gsm_color_button_size_allocate (GtkWidget * widget,
+				GtkAllocation * allocation)
+{
+  GSMColorButton *color_button;
+
+  g_return_if_fail (widget != NULL || allocation != NULL);
+  g_return_if_fail (GSM_IS_COLOR_BUTTON (widget));
+
+  widget->allocation = *allocation;
+  color_button = GSM_COLOR_BUTTON (widget);
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window, allocation->x, allocation->y,
+			      allocation->width, allocation->height);
+    }
+}
+
+static void
+gsm_color_button_unrealize (GtkWidget * widget)
+{
+
+  GTK_WIDGET_CLASS (gsm_color_button_parent_class)->unrealize (widget);
+}
+
+static void
+gsm_color_button_style_set (GtkWidget * widget, GtkStyle * previous_style)
+{
+
+  GTK_WIDGET_CLASS (gsm_color_button_parent_class)->style_set (widget,
+							       previous_style);
+
+}
+
+static void
+gsm_color_button_state_changed (GtkWidget * widget,
+				GtkStateType previous_state)
+{
+}
+
+static void
+gsm_color_button_drag_data_received (GtkWidget * widget,
+				     GdkDragContext * context,
+				     gint x,
+				     gint y,
+				     GtkSelectionData * selection_data,
+				     guint info,
+				     guint32 time,
+				     GSMColorButton * color_button)
+{
+  guint16 *dropped;
+
+  if (selection_data->length < 0)
+    return;
+
+  /* We accept drops with the wrong format, since the KDE color
+   * chooser incorrectly drops application/x-color with format 8.
+   */
+  if (selection_data->length != 8)
+    {
+      g_warning (_("Received invalid color data\n"));
+      return;
+    }
+
+
+  dropped = (guint16 *) selection_data->data;
+
+  color_button->priv->color.red = dropped[0];
+  color_button->priv->color.green = dropped[1];
+  color_button->priv->color.blue = dropped[2];
+
+  gtk_widget_queue_draw (GTK_WIDGET (&color_button->widget));
+
+  g_signal_emit (color_button, color_button_signals[COLOR_SET], 0);
+
+  g_object_freeze_notify (G_OBJECT (color_button));
+  g_object_notify (G_OBJECT (color_button), "color");
+  g_object_thaw_notify (G_OBJECT (color_button));
+}
+
+
+static void
+set_color_icon (GdkDragContext * context, GdkColor * color)
+{
+  GdkPixbuf *pixbuf;
+  guint32 pixel;
+
+  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 48, 32);
+
+  pixel = ((color->red & 0xff00) << 16) |
+    ((color->green & 0xff00) << 8) | (color->blue & 0xff00);
+
+  gdk_pixbuf_fill (pixbuf, pixel);
+
+  gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
+  g_object_unref (pixbuf);
+}
+
+static void
+gsm_color_button_drag_begin (GtkWidget * widget,
+			     GdkDragContext * context, gpointer data)
+{
+  GSMColorButton *color_button = data;
+
+  set_color_icon (context, &color_button->priv->color);
+}
+
+static void
+gsm_color_button_drag_data_get (GtkWidget * widget,
+				GdkDragContext * context,
+				GtkSelectionData * selection_data,
+				guint info,
+				guint time, GSMColorButton * color_button)
+{
+  guint16 dropped[4];
+
+  dropped[0] = color_button->priv->color.red;
+  dropped[1] = color_button->priv->color.green;
+  dropped[2] = color_button->priv->color.blue;
+  dropped[3] = 65535;		// This widget doesn't care about alpha
+
+  gtk_selection_data_set (selection_data, selection_data->target,
+			  16, (guchar *) dropped, 8);
+}
+
+
+static void
+gsm_color_button_init (GSMColorButton * color_button)
+{
+  color_button->priv = GSM_COLOR_BUTTON_GET_PRIVATE (color_button);
+
+  rsvg_init ();
+
+  color_button->priv->color.red = 0;
+  color_button->priv->color.green = 0;
+  color_button->priv->color.blue = 0;
+  color_button->priv->fraction = 0.5;
+  color_button->priv->type = GSMCP_TYPE_CPU;
+  color_button->priv->image_buffer = NULL;
+  color_button->priv->title = g_strdup (_("Pick a Color")); 	/* default title */
+
+  gtk_drag_dest_set (GTK_WIDGET (color_button),
+		     GTK_DEST_DEFAULT_MOTION |
+		     GTK_DEST_DEFAULT_HIGHLIGHT |
+		     GTK_DEST_DEFAULT_DROP, drop_types, 1, GDK_ACTION_COPY);
+  gtk_drag_source_set (GTK_WIDGET (color_button),
+		       GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
+		       drop_types, 1, GDK_ACTION_COPY);
+  g_signal_connect (color_button, "drag_begin",
+		    G_CALLBACK (gsm_color_button_drag_begin), color_button);
+  g_signal_connect (color_button, "drag_data_received",
+		    G_CALLBACK (gsm_color_button_drag_data_received),
+		    color_button);
+  g_signal_connect (color_button, "drag_data_get",
+		    G_CALLBACK (gsm_color_button_drag_data_get),
+		    color_button);
+
+  g_signal_connect (color_button, "expose-event",
+		    G_CALLBACK (expose_event), color_button);
+}
+
+static void
+gsm_color_button_finalize (GObject * object)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (object);
+
+  if (color_button->priv->cs_dialog != NULL)
+    gtk_widget_destroy (color_button->priv->cs_dialog);
+  color_button->priv->cs_dialog = NULL;
+
+  g_free (color_button->priv->title);
+  color_button->priv->title = NULL;
+
+  cairo_surface_destroy (color_button->priv->image_buffer);
+  color_button->priv->image_buffer = NULL;
+
+  rsvg_term ();
+  G_OBJECT_CLASS (gsm_color_button_parent_class)->finalize (object);
+}
+
+GtkWidget *
+gsm_color_button_new (const GdkColor * color, guint type)
+{
+  return g_object_new (GSM_TYPE_COLOR_BUTTON, "color", color, "type", type,
+		       NULL);
+}
+
+static void
+dialog_ok_clicked (GtkWidget * widget, gpointer data)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (data);
+  GtkColorSelection *color_selection;
+
+  color_selection =
+    GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG
+			 (color_button->priv->cs_dialog)->colorsel);
+
+  gtk_color_selection_get_current_color (color_selection,
+					 &color_button->priv->color);
+
+  gtk_widget_hide (color_button->priv->cs_dialog);
+
+  gtk_widget_queue_draw (GTK_WIDGET (&color_button->widget));
+
+  g_signal_emit (color_button, color_button_signals[COLOR_SET], 0);
+
+  g_object_freeze_notify (G_OBJECT (color_button));
+  g_object_notify (G_OBJECT (color_button), "color");
+  g_object_thaw_notify (G_OBJECT (color_button));
+}
+
+static gboolean
+dialog_destroy (GtkWidget * widget, gpointer data)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (data);
+
+  color_button->priv->cs_dialog = NULL;
+
+  return FALSE;
+}
+
+static void
+dialog_cancel_clicked (GtkWidget * widget, gpointer data)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (data);
+
+  gtk_widget_hide (color_button->priv->cs_dialog);
+}
+
+static gint
+gsm_color_button_clicked (GtkWidget * widget, GdkEventButton * event)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (widget);
+  GtkColorSelectionDialog *color_dialog;
+
+  /* if dialog already exists, make sure it's shown and raised */
+  if (!color_button->priv->cs_dialog)
+    {
+      /* Create the dialog and connects its buttons */
+      GtkWidget *parent;
+
+      parent = gtk_widget_get_toplevel (GTK_WIDGET (color_button));
+
+      color_button->priv->cs_dialog =
+	gtk_color_selection_dialog_new (color_button->priv->title);
+
+      color_dialog =
+	GTK_COLOR_SELECTION_DIALOG (color_button->priv->cs_dialog);
+
+      if (GTK_WIDGET_TOPLEVEL (parent) && GTK_IS_WINDOW (parent))
+	{
+	  if (GTK_WINDOW (parent) !=
+	      gtk_window_get_transient_for (GTK_WINDOW (color_dialog)))
+	    gtk_window_set_transient_for (GTK_WINDOW (color_dialog),
+					  GTK_WINDOW (parent));
+
+	  gtk_window_set_modal (GTK_WINDOW (color_dialog),
+				gtk_window_get_modal (GTK_WINDOW (parent)));
+	}
+
+      g_signal_connect (color_dialog->ok_button, "clicked",
+			G_CALLBACK (dialog_ok_clicked), color_button);
+      g_signal_connect (color_dialog->cancel_button, "clicked",
+			G_CALLBACK (dialog_cancel_clicked), color_button);
+      g_signal_connect (color_dialog, "destroy",
+			G_CALLBACK (dialog_destroy), color_button);
+    }
+
+  color_dialog = GTK_COLOR_SELECTION_DIALOG (color_button->priv->cs_dialog);
+
+  gtk_color_selection_set_previous_color (GTK_COLOR_SELECTION
+					  (color_dialog->colorsel),
+					  &color_button->priv->color);
+
+  gtk_color_selection_set_current_color (GTK_COLOR_SELECTION
+					 (color_dialog->colorsel),
+					 &color_button->priv->color);
+
+  gtk_window_present (GTK_WINDOW (color_button->priv->cs_dialog));
+  return 0;
+}
+
+static gboolean
+gsm_color_button_motion_notify (GtkWidget * widget, GdkEventMotion * event)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (widget);
+  color_button->priv->highlight = 1.0;
+  g_print ("MOVE\n");
+  return FALSE;
+}
+
+static gboolean
+gsm_color_button_enter_notify (GtkWidget * widget, GdkEventCrossing * event)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (widget);
+  color_button->priv->highlight = 1.0;
+  g_print ("ENTER\n");
+  return FALSE;
+}
+
+static gboolean
+gsm_color_button_leave_notify (GtkWidget * widget, GdkEventCrossing * event)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (widget);
+  color_button->priv->highlight = 0;
+  g_print ("EXIT\n");
+  return FALSE;
+}
+
+guint
+gsm_color_button_get_cbtype (GSMColorButton * color_button)
+{
+  g_return_val_if_fail (GSM_IS_COLOR_BUTTON (color_button), 0);
+
+  return color_button->priv->type;
+}
+
+void
+gsm_color_button_set_cbtype (GSMColorButton * color_button, guint type)
+{
+  g_return_if_fail (GSM_IS_COLOR_BUTTON (color_button));
+
+  color_button->priv->type = type;
+
+  gtk_widget_queue_draw (GTK_WIDGET (&color_button->widget));
+
+  g_object_notify (G_OBJECT (color_button), "type");
+}
+
+gdouble
+gsm_color_button_get_fraction (GSMColorButton * color_button)
+{
+  g_return_val_if_fail (GSM_IS_COLOR_BUTTON (color_button), 0);
+
+  return color_button->priv->fraction;
+}
+
+void
+gsm_color_button_set_fraction (GSMColorButton * color_button,
+			       gdouble fraction)
+{
+  g_return_if_fail (GSM_IS_COLOR_BUTTON (color_button));
+
+  color_button->priv->fraction = fraction;
+
+  gtk_widget_queue_draw (GTK_WIDGET (&color_button->widget));
+
+  g_object_notify (G_OBJECT (color_button), "fraction");
+}
+
+void
+gsm_color_button_get_color (GSMColorButton * color_button, GdkColor * color)
+{
+  g_return_if_fail (GSM_IS_COLOR_BUTTON (color_button));
+
+  color->red = color_button->priv->color.red;
+  color->green = color_button->priv->color.green;
+  color->blue = color_button->priv->color.blue;
+}
+
+void
+gsm_color_button_set_color (GSMColorButton * color_button,
+			    const GdkColor * color)
+{
+  g_return_if_fail (GSM_IS_COLOR_BUTTON (color_button));
+  g_return_if_fail (color != NULL);
+
+  color_button->priv->color.red = color->red;
+  color_button->priv->color.green = color->green;
+  color_button->priv->color.blue = color->blue;
+
+  gtk_widget_queue_draw (GTK_WIDGET (&color_button->widget));	//->priv->draw_area);
+
+  g_object_notify (G_OBJECT (color_button), "color");
+}
+
+void
+gsm_color_button_set_title (GSMColorButton * color_button,
+			    const gchar * title)
+{
+  gchar *old_title;
+
+  g_return_if_fail (GSM_IS_COLOR_BUTTON (color_button));
+
+  old_title = color_button->priv->title;
+  color_button->priv->title = g_strdup (title);
+  g_free (old_title);
+
+  if (color_button->priv->cs_dialog)
+    gtk_window_set_title (GTK_WINDOW (color_button->priv->cs_dialog),
+			  color_button->priv->title);
+
+  g_object_notify (G_OBJECT (color_button), "title");
+}
+
+G_CONST_RETURN gchar *
+gsm_color_button_get_title (GSMColorButton * color_button)
+{
+  g_return_val_if_fail (GSM_IS_COLOR_BUTTON (color_button), NULL);
+
+  return color_button->priv->title;
+}
+
+static void
+gsm_color_button_set_property (GObject * object,
+			       guint param_id,
+			       const GValue * value, GParamSpec * pspec)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (object);
+
+  switch (param_id)
+    {
+    case PROP_PERCENTAGE:
+      gsm_color_button_set_fraction (color_button,
+				     g_value_get_double (value));
+      break;
+    case PROP_TITLE:
+      gsm_color_button_set_title (color_button, g_value_get_string (value));
+      break;
+    case PROP_COLOR:
+      gsm_color_button_set_color (color_button, g_value_get_boxed (value));
+      break;
+    case PROP_TYPE:
+      gsm_color_button_set_cbtype (color_button, g_value_get_uint (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+    }
+}
+
+static void
+gsm_color_button_get_property (GObject * object,
+			       guint param_id,
+			       GValue * value, GParamSpec * pspec)
+{
+  GSMColorButton *color_button = GSM_COLOR_BUTTON (object);
+  GdkColor color;
+
+  switch (param_id)
+    {
+    case PROP_PERCENTAGE:
+      g_value_set_double (value,
+			  gsm_color_button_get_fraction (color_button));
+      break;
+    case PROP_TITLE:
+      g_value_set_string (value, gsm_color_button_get_title (color_button));
+      break;
+    case PROP_COLOR:
+      gsm_color_button_get_color (color_button, &color);
+      g_value_set_boxed (value, &color);
+      break;
+    case PROP_TYPE:
+      g_value_set_uint (value, gsm_color_button_get_cbtype (color_button));
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+    }
+}
+
+#define __GSM_COLOR_BUTTON_C__
Index: src/gsm_color_button.h
===================================================================
--- src/gsm_color_button.h	(revision 0)
+++ src/gsm_color_button.h	(revision 0)
@@ -0,0 +1,92 @@
+/*
+ * Gnome system monitor colour pickers
+ * Copyright (C) 2007 Karl Lattimer <karl@qdh.org.uk>
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This software 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 the software; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GSM_COLOR_BUTTON_H__
+#define __GSM_COLOR_BUTTON_H__
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gtk/gtkdrawingarea.h>
+#include <cairo.h>
+#include <librsvg/rsvg.h>
+#include <librsvg/rsvg-cairo.h>
+
+G_BEGIN_DECLS
+/* The GtkColorSelectionButton widget is a simple color picker in a button.	
+ * The button displays a sample of the currently selected color.	When 
+ * the user clicks on the button, a color selection dialog pops up.	
+ * The color picker emits the "color_set" signal when the color is set.
+ */
+#define GSM_TYPE_COLOR_BUTTON            (gsm_color_button_get_type ())
+#define GSM_COLOR_BUTTON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_COLOR_BUTTON, GSMColorButton))
+#define GSM_COLOR_BUTTON_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_COLOR_BUTTON, GSMColorButtonClass))
+#define GSM_IS_COLOR_BUTTON(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_COLOR_BUTTON))
+#define GSM_IS_COLOR_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_COLOR_BUTTON))
+#define GSM_COLOR_BUTTON_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_COLOR_BUTTON, GSMColorButtonClass))
+typedef struct _GSMColorButton           GSMColorButton;
+typedef struct _GSMColorButtonClass      GSMColorButtonClass;
+typedef struct _GSMColorButtonPrivate    GSMColorButtonPrivate;
+
+struct _GSMColorButton
+{
+  GtkDrawingArea widget;
+
+  /*< private > */
+
+  GSMColorButtonPrivate *priv;
+};
+
+/* Widget types */
+enum
+{
+  GSMCP_TYPE_CPU,
+  GSMCP_TYPE_PIE,
+  GSMCP_TYPE_NETWORK_IN,
+  GSMCP_TYPE_NETWORK_OUT,
+  GSMCP_TYPES
+};
+
+struct _GSMColorButtonClass
+{
+  GtkWidgetClass parent_class;
+
+  void (*color_set) (GSMColorButton * cp);
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+};
+
+GType gsm_color_button_get_type (void) G_GNUC_CONST;
+GtkWidget *gsm_color_button_new (const GdkColor * color, guint type);
+void gsm_color_button_set_color (GSMColorButton * color_button, const GdkColor * color);
+void gsm_color_button_set_fraction (GSMColorButton * color_button, const gdouble fraction);
+void gsm_color_button_set_cbtype (GSMColorButton * color_button, guint type);
+void gsm_color_button_get_color (GSMColorButton * color_button, GdkColor * color);
+gdouble gsm_color_button_get_fraction (GSMColorButton * color_button);
+guint gsm_color_button_get_cbtype (GSMColorButton * color_button);
+void gsm_color_button_set_title (GSMColorButton * color_button, const gchar * title);
+G_CONST_RETURN gchar *gsm_color_button_get_title (GSMColorButton * color_button);
+
+G_END_DECLS
+#endif /* __GSM_COLOR_BUTTON_H__ */
