Replace g_idle_add/g_timeout_add with their gdk_threads counterparts
[hildon] / hildon / hildon-color-chooser.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
5  *
6  * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
7  * Contact: Rodrigo Novo <rodrigo.novo@nokia.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; version 2.1 of
12  * the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  *
24  */
25
26 /**
27  * SECTION:hildon-color-chooser
28  * @short_description: A widget used to select a color from an HSV colorspace.
29  * @see_also: #HildonColorChooserDialog
30  *
31  * HildonColorChooser is a widget that displays an HSV colorspace. 
32  * The user can manipulate the colorspace and easily select and shade of any color
33  * he wants. 
34  *
35  * Normally you should not need to use this widget directly. Using #HildonColorButton or
36  * #HildonColorChooserDialog is much more handy. 
37  * 
38  */
39
40 #undef                                          HILDON_DISABLE_DEPRECATED
41
42 #include                                        "hildon-color-chooser.h"
43 #include                                        "hildon-color-chooser-private.h"
44
45 static GtkWidgetClass*                          parent_class = NULL;
46
47 /* "crosshair" is hardcoded for now */
48 static gchar crosshair[64]                      = { 0, 0, 0, 2, 2, 0, 0, 0,
49                                                     0, 2, 2, 3, 3, 2, 2, 0,
50                                                     0, 2, 3, 0, 0, 3, 2, 0,
51                                                     2, 3, 0, 0, 0, 0, 3, 2,
52                                                     2, 3, 0, 0, 0, 0, 3, 2,
53                                                     0, 2, 3, 0, 0, 3, 2, 0,
54                                                     0, 2, 2, 3, 3, 2, 2, 0,
55                                                     0, 0, 0, 2, 2, 0, 0, 0};
56
57 static void 
58 hildon_color_chooser_init                       (HildonColorChooser *self);
59
60 static void 
61 hildon_color_chooser_class_init                 (HildonColorChooserClass *klass);
62
63 static void 
64 hildon_color_chooser_dispose                    (HildonColorChooser *self);
65
66 static void 
67 hildon_color_chooser_size_request               (GtkWidget *widget, 
68                                                  GtkRequisition *req);
69
70 static void 
71 hildon_color_chooser_size_allocate              (GtkWidget *widget, 
72                                                  GtkAllocation *alloc);
73
74 static void
75 hildon_color_chooser_realize                    (GtkWidget *widget);
76
77 static void
78 hildon_color_chooser_unrealize                  (GtkWidget *widget);
79
80 static void 
81 hildon_color_chooser_map                        (GtkWidget *widget);
82
83 static void 
84 hildon_color_chooser_unmap                      (GtkWidget *widget);
85
86 static gboolean 
87 hildon_color_chooser_expose                     (GtkWidget *widget, 
88                                                  GdkEventExpose *event);
89
90 static gboolean
91 hildon_color_chooser_button_press               (GtkWidget *widget, 
92                                                  GdkEventButton *event);
93
94 static gboolean
95 hildon_color_chooser_button_release             (GtkWidget *widget, 
96                                                  GdkEventButton *event);
97
98 static gboolean 
99 hildon_color_chooser_pointer_motion             (GtkWidget *widget, 
100                                                  GdkEventMotion *event);
101
102 static void 
103 get_border                                      (GtkWidget *w, 
104                                                  char *name, 
105                                                  GtkBorder *b);
106
107 static void 
108 init_borders                                    (GtkWidget *w, 
109                                                  GtkBorder *inner, 
110                                                  GtkBorder *outer);
111
112 inline void 
113 inline_clip_to_alloc                            (void *s, 
114                                                  GtkAllocation *a);
115
116 inline void 
117 inline_sub_times                                (GTimeVal *result, 
118                                                  GTimeVal *greater, 
119                                                  GTimeVal *lesser);
120
121 inline void 
122 inline_limited_expose                           (HildonColorChooser *self);
123
124 inline void 
125 inline_draw_hue_bar                             (GtkWidget *widget, 
126                                                  int x, 
127                                                  int y, 
128                                                  int w, 
129                                                  int h, 
130                                                  int sy, 
131                                                  int sh);
132
133 inline void
134 inline_draw_hue_bar_dimmed                      (GtkWidget *widget, 
135                                                  int x, 
136                                                  int y, 
137                                                  int w, 
138                                                  int h, 
139                                                  int sy, 
140                                                  int sh);
141
142 inline void 
143 inline_draw_sv_plane                            (HildonColorChooser *self, 
144                                                  int x, 
145                                                  int y, 
146                                                  int w, 
147                                                  int h);
148
149 inline void 
150 inline_draw_sv_plane_dimmed                     (HildonColorChooser *self, 
151                                                  int x, 
152                                                  int y, 
153                                                  int w, 
154                                                  int h);
155
156 inline void 
157 inline_draw_crosshair                           (unsigned char *buf, 
158                                                  int x, 
159                                                  int y, 
160                                                  int w, 
161                                                  int h);
162
163 inline void 
164 inline_h2rgb                                    (unsigned short hue, 
165                                                  unsigned long *rgb);
166
167 static gboolean
168 hildon_color_chooser_expose_timer               (gpointer data);
169
170 static void
171 hildon_color_chooser_set_property               (GObject *object, 
172                                                  guint param_id,
173                                                  const GValue *value, 
174                                                  GParamSpec *pspec);
175
176 static void
177 hildon_color_chooser_get_property               (GObject *object, 
178                                                  guint param_id,
179                                                  GValue *value, 
180                                                  GParamSpec *pspec);
181
182 #define                                         EXPOSE_INTERVAL 50000
183
184 #define                                         FULL_COLOR8 0xff
185
186 #define                                         FULL_COLOR 0x00ffffff
187
188 enum 
189 {
190     COLOR_CHANGED,
191     LAST_SIGNAL
192 };
193
194 enum
195 {
196     PROP_0,
197     PROP_COLOR
198 };
199
200 static guint                                    color_chooser_signals [LAST_SIGNAL] = { 0 };
201
202 GType G_GNUC_CONST
203 hildon_color_chooser_get_type                   (void)
204 {
205     static GType chooser_type = 0;
206
207     if (!chooser_type) {
208         static const GTypeInfo chooser_info =
209         {
210             sizeof (HildonColorChooserClass),
211             NULL,
212             NULL,
213             (GClassInitFunc) hildon_color_chooser_class_init,
214             NULL,
215             NULL,
216             sizeof (HildonColorChooser),
217             0,
218             (GInstanceInitFunc) hildon_color_chooser_init,
219             NULL
220         };
221
222         chooser_type = g_type_register_static (GTK_TYPE_WIDGET,
223                 "HildonColorChooser",
224                 &chooser_info, 0);
225     }
226
227     return chooser_type;
228 }
229
230 static void
231 hildon_color_chooser_init                       (HildonColorChooser *sel)
232 {
233
234     GTK_WIDGET_SET_FLAGS (sel, GTK_NO_WINDOW);
235     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (sel);
236     g_assert (priv);
237
238     priv->currhue = 0;
239     priv->currsat = 0;
240     priv->currval = 0;
241
242     priv->mousestate = 0;
243     priv->mousein = FALSE;
244
245     g_get_current_time (&priv->expose_info.last_expose_time);
246
247     priv->expose_info.last_expose_hue = priv->currhue;
248     priv->expose_info.expose_queued = 0;
249
250     priv->dimmed_plane = NULL;
251     priv->dimmed_bar = NULL;
252 }
253
254 static void
255 hildon_color_chooser_class_init                 (HildonColorChooserClass *klass)
256 {
257     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
258     GObjectClass *object_class = G_OBJECT_CLASS (klass);
259
260     parent_class = g_type_class_peek_parent (klass);
261     
262     object_class->dispose               = (gpointer) hildon_color_chooser_dispose;
263     object_class->get_property          = hildon_color_chooser_get_property;
264     object_class->set_property          = hildon_color_chooser_set_property;
265
266     widget_class->size_request          = hildon_color_chooser_size_request;
267     widget_class->size_allocate         = hildon_color_chooser_size_allocate;
268     widget_class->realize               = hildon_color_chooser_realize;
269     widget_class->unrealize             = hildon_color_chooser_unrealize;
270     widget_class->map                   = hildon_color_chooser_map;
271     widget_class->unmap                 = hildon_color_chooser_unmap;
272     widget_class->expose_event          = hildon_color_chooser_expose;
273     widget_class->button_press_event    = hildon_color_chooser_button_press;
274     widget_class->button_release_event  = hildon_color_chooser_button_release;
275     widget_class->motion_notify_event   = hildon_color_chooser_pointer_motion;
276
277     gtk_widget_class_install_style_property (widget_class,
278                                              g_param_spec_boxed ("inner_size",
279                                                                  "Inner sizes",
280                                                                  "Sizes of SV plane, H bar and spacing",
281                                                                  GTK_TYPE_BORDER,
282                                                                  G_PARAM_READABLE));
283
284     gtk_widget_class_install_style_property (widget_class,
285                                              g_param_spec_boxed ("outer_border",
286                                                                  "Outer border",
287                                                                  "The outer border for the chooser",
288                                                                  GTK_TYPE_BORDER,
289                                                                  G_PARAM_READABLE));
290
291     gtk_widget_class_install_style_property (widget_class,
292                                              g_param_spec_boxed ("graphic_border",
293                                                                  "Graphical borders",
294                                                                  "Size of graphical border",
295                                                                  GTK_TYPE_BORDER,
296                                                                  G_PARAM_READABLE));
297
298     /**
299      * HildonColorChooser:color:
300      *
301      * The currently selected color.
302      */
303     g_object_class_install_property (object_class, PROP_COLOR,
304             g_param_spec_boxed ("color",
305                 "Current Color",
306                 "The selected color",
307                 GDK_TYPE_COLOR,
308                 G_PARAM_READWRITE));
309
310     color_chooser_signals[COLOR_CHANGED] = g_signal_new("color-changed", 
311             G_OBJECT_CLASS_TYPE (object_class),
312             G_SIGNAL_RUN_FIRST, 
313             G_STRUCT_OFFSET (HildonColorChooserClass, color_changed),
314             NULL, 
315             NULL, 
316             g_cclosure_marshal_VOID__VOID, 
317             G_TYPE_NONE, 
318             0);
319
320     g_type_class_add_private (klass, sizeof (HildonColorChooserPrivate));
321 }
322
323 static void
324 hildon_color_chooser_dispose                    (HildonColorChooser *sel)
325 {
326     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (sel);
327     g_assert (priv);
328
329     if (priv->dimmed_bar != NULL) {
330         g_object_unref (priv->dimmed_bar);
331         priv->dimmed_bar = NULL;
332     }
333
334     if (priv->dimmed_plane != NULL) {
335         g_object_unref (priv->dimmed_plane);
336         priv->dimmed_plane = NULL;
337     }
338
339     G_OBJECT_CLASS (parent_class)->dispose (G_OBJECT (sel));
340 }
341
342 static void
343 hildon_color_chooser_size_request               (GtkWidget *widget, 
344                                                  GtkRequisition *req)
345 {
346     GtkBorder inner, outer;
347
348     init_borders (widget, &inner, &outer);
349
350     req->width = inner.left + inner.top + inner.bottom + outer.left + outer.right;
351     req->height = inner.right + outer.top + outer.bottom;
352 }
353
354 static void 
355 hildon_color_chooser_size_allocate              (GtkWidget *widget, 
356                                                  GtkAllocation *alloc)
357 {
358     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
359     GtkBorder outer, inner;
360
361     g_assert (priv);
362
363     widget->allocation = *alloc;
364     
365     init_borders(widget, &inner, &outer);
366
367     priv->hba.height = alloc->height - outer.top - outer.bottom;
368     priv->hba.y = alloc->y + outer.top;
369     priv->hba.width = inner.top;
370     priv->hba.x = alloc->x + alloc->width - outer.right - inner.top;
371
372     priv->spa.x = alloc->x + outer.left;
373     priv->spa.y = alloc->y + outer.top;
374     priv->spa.height = alloc->height - outer.top - outer.bottom;
375     priv->spa.width = alloc->width - outer.left - outer.right - inner.top - inner.bottom;
376
377     if (GTK_WIDGET_REALIZED (widget)) {
378         gdk_window_move_resize (priv->event_window, 
379                 widget->allocation.x, 
380                 widget->allocation.y, 
381                 widget->allocation.width, 
382                 widget->allocation.height);
383     }
384 }
385
386 static void
387 hildon_color_chooser_realize                    (GtkWidget *widget)
388 {
389     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
390
391     g_assert (priv);
392     GdkWindowAttr attributes;
393     gint attributes_mask;
394
395     attributes.x = widget->allocation.x;
396     attributes.y = widget->allocation.y;
397     attributes.width = widget->allocation.width;
398     attributes.height = widget->allocation.height;
399     attributes.wclass = GDK_INPUT_ONLY;
400     attributes.window_type = GDK_WINDOW_CHILD;
401
402     attributes.event_mask = gtk_widget_get_events (widget) | 
403         GDK_BUTTON_PRESS_MASK           | 
404         GDK_BUTTON_RELEASE_MASK         | 
405         GDK_POINTER_MOTION_MASK         |
406         GDK_POINTER_MOTION_HINT_MASK    | 
407         GDK_BUTTON_MOTION_MASK          |
408         GDK_BUTTON1_MOTION_MASK;
409
410     attributes.visual = gtk_widget_get_visual (widget);
411     attributes.colormap = gtk_widget_get_colormap (widget);
412
413     attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_WMCLASS;
414     priv->event_window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
415
416
417     gdk_window_set_user_data (priv->event_window, widget);
418
419     GTK_WIDGET_CLASS (parent_class)->realize (widget);
420 }
421
422 static void
423 hildon_color_chooser_unrealize                  (GtkWidget *widget)
424 {
425     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
426
427     g_assert (priv);
428
429     if (priv->event_window) {
430         gdk_window_set_user_data (priv->event_window, NULL);
431         gdk_window_destroy (priv->event_window);
432         priv->event_window = NULL;
433     }
434
435     GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
436 }
437
438 static void 
439 hildon_color_chooser_map                        (GtkWidget *widget)
440 {
441     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
442
443     g_assert (priv);
444     GTK_WIDGET_CLASS(parent_class)->map(widget);
445
446     if (priv->event_window) {
447         gdk_window_show (priv->event_window);
448     }
449 }
450
451 static void 
452 hildon_color_chooser_unmap                      (GtkWidget *widget)
453 {
454     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
455
456     g_assert (priv);
457
458     if (priv->event_window) {
459         gdk_window_hide (priv->event_window);
460     }
461
462     GTK_WIDGET_CLASS (parent_class)->unmap (widget);
463 }
464
465 inline void 
466 inline_clip_to_alloc                            (void *s, 
467                                                  GtkAllocation *a)
468 {
469     struct {
470         int x, y, w, h;
471     } *area = s;
472
473
474     if (area->x < a->x) {
475         area->w -= a->x - area->x;
476         area->x = a->x;
477     } if (area->y < a->y) {
478         area->h -= a->y - area->y;
479         area->y = a->y;
480     }
481     if (area->x + area->w > a->x + a->width) 
482         area->w = a->width - (area->x - a->x);
483
484     if (area->y + area->h > a->y + a->height) 
485         area->h = a->height - (area->y - a->y);
486 }
487
488 static gboolean 
489 hildon_color_chooser_expose                     (GtkWidget *widget, 
490                                                  GdkEventExpose *event)
491 {
492     HildonColorChooser *sel = HILDON_COLOR_CHOOSER (widget);
493     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
494
495     g_assert (priv);
496
497     GtkBorder graphical_border;
498
499     struct {
500         int x, y, w, h;
501     } area;
502
503
504     if(! GTK_WIDGET_REALIZED (widget)) {
505         return FALSE;
506     }
507
508     get_border (widget, "graphic_border", &graphical_border);
509     
510     if (event->area.width || event->area.height) {
511
512         gdk_draw_rectangle (widget->window,
513                 widget->style->black_gc,
514                 FALSE,
515                 priv->hba.x - 2, 
516                 priv->hba.y - 2, 
517                 priv->hba.width + 3,
518                 priv->hba.height + 3);
519
520         gdk_draw_rectangle (widget->window,
521                 widget->style->black_gc,
522                 FALSE,
523                 priv->spa.x - 2, 
524                 priv->spa.y - 2, 
525                 priv->spa.width + 3,
526                 priv->spa.height + 3);
527     }
528
529     if (priv->expose_info.expose_queued) {
530         if (GTK_WIDGET_SENSITIVE (widget)) {
531             inline_draw_hue_bar (widget, priv->hba.x, priv->hba.y, priv->hba.width, priv->hba.height, priv->hba.y, priv->hba.height);
532
533             inline_draw_sv_plane (sel, priv->spa.x, priv->spa.y, priv->spa.width, priv->spa.height);
534         } else {
535             inline_draw_hue_bar_dimmed (widget, priv->hba.x, priv->hba.y, priv->hba.width, priv->hba.height, priv->hba.y, priv->hba.height);
536
537             inline_draw_sv_plane_dimmed (sel, priv->spa.x, priv->spa.y, priv->spa.width, priv->spa.height);
538         }
539
540         priv->expose_info.expose_queued = 0;
541
542         g_get_current_time (&priv->expose_info.last_expose_time);
543
544     } else {
545         /* clip hue bar region */
546         area.x = event->area.x;
547         area.y = event->area.y;
548         area.w = event->area.width;
549         area.h = event->area.height;
550
551         inline_clip_to_alloc (&area, &priv->hba);
552
553         if(GTK_WIDGET_SENSITIVE (widget)) {
554             inline_draw_hue_bar (widget, area.x, area.y, area.w, area.h, priv->hba.y, priv->hba.height);
555         } else {
556             inline_draw_hue_bar_dimmed (widget, area.x, area.y, area.w, area.h, priv->hba.y, priv->hba.height);
557         }
558         
559         area.x = event->area.x;
560         area.y = event->area.y;
561         area.w = event->area.width;
562         area.h = event->area.height;
563
564         inline_clip_to_alloc (&area, &priv->spa);
565
566         if (GTK_WIDGET_SENSITIVE (widget)) {
567             inline_draw_sv_plane (sel, area.x, area.y, area.w, area.h);
568         } else {
569             inline_draw_sv_plane_dimmed (sel, area.x, area.y, area.w, area.h);
570         }
571     }
572
573     return FALSE;
574 }
575
576
577 inline void 
578 inline_sub_times                                (GTimeVal *result, 
579                                                  GTimeVal *greater, 
580                                                  GTimeVal *lesser)
581 {
582     result->tv_sec = greater->tv_sec - lesser->tv_sec;
583     result->tv_usec = greater->tv_usec - lesser->tv_usec;
584
585     if (result->tv_usec < 0) {
586         result->tv_sec--;
587         result->tv_usec += 1000000;
588     }
589 }
590
591 inline void 
592 inline_limited_expose                           (HildonColorChooser *sel)
593 {
594     GTimeVal curr_time, result;
595     GdkEventExpose event;
596     HildonColorChooserPrivate *priv; 
597    
598     if (! GTK_WIDGET_REALIZED (GTK_WIDGET (sel))) {
599         return;
600     }
601
602     priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (sel);
603     g_assert (priv);
604
605     if(priv->currhue == priv->expose_info.last_expose_hue) {
606         return; /* no need to redraw */
607     }
608
609     priv->expose_info.last_expose_hue = priv->currhue;
610
611     g_get_current_time (&curr_time);
612
613     inline_sub_times (&result, &curr_time, &priv->expose_info.last_expose_time);
614
615     if(result.tv_sec != 0 || result.tv_usec >= EXPOSE_INTERVAL) {
616
617         priv->expose_info.expose_queued = 1;
618
619         event.type = GDK_EXPOSE;
620         event.area.width = 0;
621         event.area.height = 0;
622         event.window = GTK_WIDGET(sel)->window;
623
624         gtk_widget_send_expose(GTK_WIDGET(sel), (GdkEvent *)&event);
625
626     } else if(! priv->expose_info.expose_queued) {
627         priv->expose_info.expose_queued = 1;
628         gdk_threads_add_timeout ((EXPOSE_INTERVAL - result.tv_usec) / 1000, hildon_color_chooser_expose_timer, sel);
629     }
630 }
631
632 static gboolean 
633 hildon_color_chooser_button_press               (GtkWidget *widget, 
634                                                  GdkEventButton *event)
635 {
636     HildonColorChooser *sel = HILDON_COLOR_CHOOSER (widget);
637     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
638
639     g_assert (priv);
640     int x, y, tmp;
641
642     x = (int) event->x + widget->allocation.x;
643     y = (int) event->y + widget->allocation.y;
644
645     if (x >= priv->spa.x && x <= priv->spa.x + priv->spa.width &&
646         y >= priv->spa.y && y <= priv->spa.y + priv->spa.height) {
647
648         tmp = y - priv->spa.y;
649         priv->currsat = tmp * 0xffff / priv->spa.height;
650         tmp = x - priv->spa.x;
651         priv->currval = tmp * 0xffff / priv->spa.width;
652
653         g_signal_emit (sel, color_chooser_signals[COLOR_CHANGED], 0);
654         gtk_widget_queue_draw (widget);
655
656         priv->mousestate = 1;
657         priv->mousein = TRUE;
658
659         gtk_grab_add(widget);
660
661     } else if (x >= priv->hba.x && x <= priv->hba.x + priv->hba.width &&
662                y >= priv->hba.y && y <= priv->hba.y + priv->hba.height) {
663
664         tmp = y - priv->hba.y;
665         priv->currhue = tmp * 0xffff / priv->hba.height;
666
667         g_signal_emit (sel, color_chooser_signals[COLOR_CHANGED], 0);
668         inline_limited_expose (sel);
669
670         priv->mousestate = 2;
671         priv->mousein = TRUE;
672
673         gtk_grab_add (widget);
674     }
675
676     return FALSE;
677 }
678
679 static gboolean
680 hildon_color_chooser_button_release             (GtkWidget *widget, 
681                                                  GdkEventButton *event)
682 {
683     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
684
685     g_assert (priv);
686
687     if (priv->mousestate) {
688         gtk_grab_remove (widget);
689     }
690
691     priv->mousestate = 0;
692     priv->mousein = FALSE;
693
694     return FALSE;
695 }
696
697 static gboolean 
698 hildon_color_chooser_pointer_motion             (GtkWidget *widget, 
699                                                  GdkEventMotion *event)
700 {
701     HildonColorChooser *sel = HILDON_COLOR_CHOOSER (widget);
702     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
703
704     gint x, y, tmp;
705
706     g_assert (priv);
707
708     x = (int) event->x + widget->allocation.x;
709     y = (int) event->y + widget->allocation.y;
710
711     if (priv->mousestate == 1) {
712         if (x >= priv->spa.x && x <= priv->spa.x + priv->spa.width &&
713             y >= priv->spa.y && y <= priv->spa.y + priv->spa.height) {
714
715             priv->currsat = (((long)(y - priv->spa.y)) * 0xffff) / priv->spa.height;
716             priv->currval = (((long)(x - priv->spa.x)) * 0xffff) / priv->spa.width;
717
718             g_signal_emit (sel, color_chooser_signals[COLOR_CHANGED], 0);
719             gtk_widget_queue_draw(widget);
720
721         } else if (priv->mousein == TRUE) {
722         }
723
724     } else if (priv->mousestate == 2) {
725         if (x >= priv->hba.x && x <= priv->hba.x + priv->hba.width &&
726             y >= priv->hba.y && y <= priv->hba.y + priv->hba.height) {
727             tmp = y - priv->hba.y;
728             tmp *= 0xffff;
729             tmp /= priv->hba.height;
730
731             if(tmp != priv->currhue) {
732                 priv->currhue = tmp;
733
734                 g_signal_emit (sel, color_chooser_signals[COLOR_CHANGED], 0);
735                 inline_limited_expose (sel);
736             }
737
738         } else if (priv->mousein == TRUE) {
739         }
740     }
741
742     gdk_event_request_motions (event);
743
744     return FALSE;
745 }
746
747 static void 
748 get_border                                      (GtkWidget *w, 
749                                                  char *name, 
750                                                  GtkBorder *b)
751 {
752     GtkBorder *tb = NULL;
753
754     gtk_widget_style_get (w, name, &tb, NULL);
755
756     if (tb) {
757         *b = *tb;
758         gtk_border_free (tb);
759     } else {
760         b->left = 0;
761         b->right = 0;
762         b->top = 0;
763         b->bottom = 0;
764     }
765 }
766
767 static void 
768 init_borders                                    (GtkWidget *w, 
769                                                  GtkBorder *inner, 
770                                                  GtkBorder *outer)
771 {
772     GtkBorder *tb;
773
774     get_border (w, "outer_border", outer);
775
776     gtk_widget_style_get (w, "inner_size", &tb, NULL);
777
778     if (tb) {
779         *inner = *tb;
780         gtk_border_free (tb);
781     } else {
782         inner->left = 64;
783         inner->right = 64;
784         inner->top = 12;
785         inner->bottom = 2;
786     }
787
788     if (inner->left < 2) inner->left = 2;
789     if (inner->right < 2) inner->right = 2;
790     if (inner->top < 2) inner->top = 2;
791 }
792
793 /**
794  * hildon_color_chooser_set_color:
795  * @chooser: a #HildonColorChooser
796  * @color: a color to be set
797  *
798  * Sets the color selected in the widget.
799  * Will move the crosshair pointer to indicate the passed color.
800  */
801 void 
802 hildon_color_chooser_set_color                  (HildonColorChooser *chooser, 
803                                                  GdkColor *color)
804 {
805     unsigned short hue, sat, val;
806     unsigned long min, max;
807     signed long tmp, diff;
808     HildonColorChooserPrivate *priv;
809
810     g_return_if_fail (HILDON_IS_COLOR_CHOOSER (chooser));
811     g_return_if_fail (color != NULL);
812
813     priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (chooser);
814     g_assert (priv);
815
816     /* ugly nesting */
817     min = MIN (MIN (color->red, color->green), color->blue);
818     max = MAX (MAX (color->red, color->green), color->blue);
819     diff = max - min;
820     
821     val = max;
822
823     if (val > 0 && diff != 0) {
824         sat = (diff * 0x0000ffff) / max;
825
826         if (color->red == max) {
827             tmp = (signed) color->green - (signed) color->blue;
828             tmp *= 10922;
829             tmp /= diff;
830             if(tmp < 0) {
831                 tmp += 65532;
832             }
833             hue = tmp;
834         } else if (color->green == max) {
835             hue = (((signed long) color->blue - (signed long)color->red) * 10922 / diff) + 21844;
836         } else {
837             hue = (((signed long) color->red -(signed long) color->green) * 10922 / diff) + 43688;
838         }
839     } else {
840         hue = 0;
841         sat = 0;
842     }
843
844     priv->currhue = hue;
845     priv->currsat = sat;
846     priv->currval = val;
847
848     inline_limited_expose (chooser);
849     g_signal_emit (chooser, color_chooser_signals[COLOR_CHANGED], 0);
850 }
851
852 inline void
853 inline_h2rgb                                    (unsigned short hue, 
854                                                  unsigned long *rgb)
855 {
856     unsigned short hue_rotation, hue_value;
857
858     hue_rotation  = hue / 10922;
859     hue_value     = hue % 10922;
860
861     switch (hue_rotation) {
862
863         case 0:
864         case 6:
865             rgb[0] = FULL_COLOR;
866             rgb[1] = hue_value * 6*256;
867             rgb[2] = 0;
868             break;
869
870         case 1:
871             rgb[0] = FULL_COLOR - (hue_value * 6*256);
872             rgb[1] = FULL_COLOR;
873             rgb[2] = 0;
874             break;
875
876         case 2:
877             rgb[0] = 0;
878             rgb[1] = FULL_COLOR;
879             rgb[2] = hue_value * 6*256;
880             break;
881
882         case 3:
883             rgb[0] = 0;
884             rgb[1] = FULL_COLOR - (hue_value * 6*256);
885             rgb[2] = FULL_COLOR;
886             break;
887
888         case 4:
889             rgb[0] = hue_value * 6*256;
890             rgb[1] = 0;
891             rgb[2] = FULL_COLOR;
892             break;
893
894         case 5:
895             rgb[0] = FULL_COLOR;
896             rgb[1] = 0;
897             rgb[2] = FULL_COLOR - (hue_value * 6*256);
898             break;
899
900         default:
901             rgb[0] = 0;
902             rgb[1] = 0;
903             rgb[2] = 0;
904             break;
905     }
906 }
907
908 static void 
909 intern_h2rgb8                                   (unsigned short hue, 
910                                                  unsigned char *rgb)
911 {
912     unsigned short hue_rotation, hue_value;
913
914     hue >>= 8;
915     hue_rotation  = hue / 42;
916     hue_value     = hue % 42;
917
918     switch (hue_rotation) {
919         case 0:
920         case 6:
921             rgb[0] = FULL_COLOR8;
922             rgb[1] = hue_value * 6;
923             rgb[2] = 0;
924             break;
925
926         case 1:
927             rgb[0] = FULL_COLOR8 - (hue_value * 6);
928             rgb[1] = FULL_COLOR8;
929             rgb[2] = 0;
930             break;
931
932         case 2:
933             rgb[0] = 0;
934             rgb[1] = FULL_COLOR8;
935             rgb[2] = hue_value * 6;
936             break;
937
938         case 3:
939             rgb[0] = 0;
940             rgb[1] = FULL_COLOR8 - (hue_value * 6);
941             rgb[2] = FULL_COLOR8;
942             break;
943
944         case 4:
945             rgb[0] = hue_value * 6;
946             rgb[1] = 0;
947             rgb[2] = FULL_COLOR8;
948             break;
949
950         case 5:
951             rgb[0] = FULL_COLOR8;
952             rgb[1] = 0;
953             rgb[2] = FULL_COLOR8 - (hue_value * 6);
954             break;
955
956         default:
957             rgb[0] = 0;
958             rgb[1] = 0;
959             rgb[2] = 0;
960             break;
961     }
962 }
963
964 /* optimization: do not ask hue for each round but have bilinear vectors */
965 /* rethink: benefits from handling data 8 bit? (no shift round) */
966 inline void 
967 inline_draw_hue_bar                             (GtkWidget *widget, 
968                                                  int x, 
969                                                  int y, 
970                                                  int w, 
971                                                  int h, 
972                                                  int sy, 
973                                                  int sh)
974 {
975     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (widget);
976
977     unsigned short hvec, hcurr;
978     unsigned char *buf, *ptr, tmp[3];
979     int i, j, tmpy;
980     g_assert (priv);
981
982     if (w <= 0 || h <= 0) {
983         return;
984     }
985
986     buf = (unsigned char *) g_malloc (w * h * 3);
987
988     hvec = 65535 / sh;
989     hcurr = hvec * (y - sy);
990     
991     ptr = buf;
992
993     for (i = 0; i < h; i++) {
994         intern_h2rgb8 (hcurr, tmp);
995
996         for (j = 0; j < w; j++) {
997             ptr[0] = tmp[0];
998             ptr[1] = tmp[1];
999             ptr[2] = tmp[2];
1000             ptr += 3;
1001         }
1002
1003         hcurr += hvec;
1004     }
1005
1006
1007     gdk_draw_rgb_image (widget->parent->window, 
1008             widget->style->fg_gc[0], 
1009             x, y, 
1010             w, h, 
1011             GDK_RGB_DITHER_NONE, buf, w * 3);
1012
1013     tmpy = priv->hba.y + (priv->currhue * priv->hba.height / 0xffff);
1014     gdk_draw_line (widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], priv->hba.x, tmpy, priv->hba.x + priv->hba.width - 1, tmpy);
1015
1016     if ((((priv->currhue * priv->hba.height) & 0xffff) > 0x8000) && (tmpy < (priv->hba.y + priv->hba.height))) {
1017         gdk_draw_line (widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], 
1018                 priv->hba.x, tmpy+1, priv->hba.x + priv->hba.width - 1, tmpy+1);
1019     } else if (tmpy > priv->hba.y) {
1020         gdk_draw_line(widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], priv->hba.x, 
1021                 tmpy-1, priv->hba.x + priv->hba.width - 1, tmpy-1);
1022     }
1023
1024     g_free(buf);
1025 }
1026
1027 inline void 
1028 inline_draw_hue_bar_dimmed                      (GtkWidget *widget, 
1029                                                  int x, 
1030                                                  int y, 
1031                                                  int w, 
1032                                                  int h, 
1033                                                  int sy, 
1034                                                  int sh)
1035 {
1036     HildonColorChooser *sel = HILDON_COLOR_CHOOSER (widget);
1037     HildonColorChooserPrivate *priv;
1038
1039     if (w <= 0 || h <= 0) {
1040         return;
1041     }
1042
1043     priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (sel);
1044     g_assert (priv);
1045
1046     /* We need to create (and cache) the pixbuf if we don't 
1047      * have it yet */
1048     if (priv->dimmed_bar == NULL) {
1049         int i, j;
1050         unsigned short hvec, hcurr, avg;
1051         unsigned char *buf, *ptr, tmp[3];
1052         buf = (unsigned char *) g_malloc (w * h * 3);
1053
1054         hvec = 65535 / sh;
1055         hcurr = hvec * (y - sy);
1056         ptr = buf;
1057
1058         for (i = 0; i < h; i++) {
1059             intern_h2rgb8 (hcurr, tmp);
1060
1061             for(j = 0; j < w; j++) {
1062                 avg = ((unsigned short) tmp[0]*3 + (unsigned short) tmp[1]*2 + (unsigned short) tmp[2])/6;
1063                 ptr[0] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
1064                 ptr[1] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
1065                 ptr[2] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
1066                 ptr += 3;
1067             }
1068
1069             hcurr += hvec;
1070         }
1071
1072         priv->dimmed_bar = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w * 3, (gpointer) g_free, buf);
1073     }
1074
1075     gdk_draw_pixbuf (widget->parent->window, widget->style->fg_gc [0], priv->dimmed_bar, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
1076 }
1077
1078 inline void 
1079 inline_draw_crosshair                           (unsigned char *buf, 
1080                                                  int x, 
1081                                                  int y, 
1082                                                  int w, 
1083                                                  int h)
1084 {
1085     int i, j, sx, sy;
1086
1087     /* bad "clipping", clip the loop to save cpu */
1088     for(i = 0; i < 8; i++) {
1089         for(j = 0; j < 8; j++) {
1090             sx = j + x; sy = i + y;
1091
1092             if (sx >= 0 && sx < w && sy >= 0 && sy < h) {
1093                 if (crosshair[j + 8*i]) {
1094                     if (crosshair[j + 8*i] & 0x1) {
1095                         buf[(sx)*3+(sy)*w*3+0] = 255;
1096                         buf[(sx)*3+(sy)*w*3+1] = 255;
1097                         buf[(sx)*3+(sy)*w*3+2] = 255;
1098                     } else {
1099                         buf[(sx)*3+(sy)*w*3+0] = 0;
1100                         buf[(sx)*3+(sy)*w*3+1] = 0;
1101                         buf[(sx)*3+(sy)*w*3+2] = 0;
1102                     }
1103                 }
1104             }
1105         }
1106     }
1107 }
1108
1109 inline void 
1110 inline_draw_sv_plane                            (HildonColorChooser *sel, 
1111                                                  int x, 
1112                                                  int y, 
1113                                                  int w, 
1114                                                  int h)
1115 {
1116     GtkWidget *widget = GTK_WIDGET (sel);
1117     unsigned char *buf, *ptr;
1118     unsigned long rgbx[3] = { 0x00ffffff, 0x00ffffff, 0x00ffffff }, rgbtmp[3];
1119     signed long rgby[3];
1120     HildonColorChooserPrivate *priv;
1121     int i, j;
1122     int tmp;
1123
1124     if (w <= 0 || h <= 0) {
1125         return;
1126     }
1127
1128     priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (sel);
1129     g_assert (priv);
1130     tmp = priv->spa.width * priv->spa.height;
1131
1132     buf = (unsigned char *) g_malloc (w * h * 3);
1133     ptr = buf;
1134
1135     inline_h2rgb (priv->currhue, rgbtmp);
1136
1137     rgby[0] = rgbtmp[0] - rgbx[0];
1138     rgby[1] = rgbtmp[1] - rgbx[1];
1139     rgby[2] = rgbtmp[2] - rgbx[2];
1140
1141     rgbx[0] /= priv->spa.width;
1142     rgbx[1] /= priv->spa.width;
1143     rgbx[2] /= priv->spa.width;
1144
1145     rgby[0] /= tmp;
1146     rgby[1] /= tmp;
1147     rgby[2] /= tmp;
1148
1149     rgbx[0] += (y - priv->spa.y) * rgby[0];
1150     rgbx[1] += (y - priv->spa.y) * rgby[1];
1151     rgbx[2] += (y - priv->spa.y) * rgby[2];
1152
1153     for(i = 0; i < h; i++) {
1154         rgbtmp[0] = rgbx[0] * (x - priv->spa.x);
1155         rgbtmp[1] = rgbx[1] * (x - priv->spa.x);
1156         rgbtmp[2] = rgbx[2] * (x - priv->spa.x);
1157
1158         for(j = 0; j < w; j++) {
1159             ptr[0] = rgbtmp[0] >> 16;
1160             ptr[1] = rgbtmp[1] >> 16;
1161             ptr[2] = rgbtmp[2] >> 16;
1162             rgbtmp[0] += rgbx[0];
1163             rgbtmp[1] += rgbx[1];
1164             rgbtmp[2] += rgbx[2];
1165             ptr += 3;
1166         }
1167
1168         rgbx[0] += rgby[0];
1169         rgbx[1] += rgby[1];
1170         rgbx[2] += rgby[2];
1171     }
1172
1173     inline_draw_crosshair (buf, 
1174             (priv->spa.width * priv->currval / 0xffff) - x + priv->spa.x - 4, 
1175             (priv->spa.height * priv->currsat / 0xffff) - y + priv->spa.y - 4, 
1176             w, h);
1177
1178     gdk_draw_rgb_image (widget->parent->window, widget->style->fg_gc[0], x, y, w, h, GDK_RGB_DITHER_NONE, buf, w * 3);
1179     g_free(buf);
1180 }
1181
1182 inline void 
1183 inline_draw_sv_plane_dimmed                     (HildonColorChooser *sel, 
1184                                                  int x, 
1185                                                  int y, 
1186                                                  int w, 
1187                                                  int h)
1188 {
1189     GtkWidget *widget = GTK_WIDGET (sel);
1190     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (sel);
1191
1192     g_assert (priv);
1193
1194     if (w <= 0 || h <= 0) {
1195         return;
1196     }
1197
1198     /* We need to create (and cache) the pixbuf if we don't 
1199      * have it yet */
1200     if (priv->dimmed_plane == NULL) {
1201         unsigned char *buf, *ptr;
1202         unsigned long rgbx[3] = { 0x00ffffff, 0x00ffffff, 0x00ffffff }, rgbtmp[3];
1203         unsigned long avg;
1204         signed long rgby[3];
1205         int tmp = priv->spa.width * priv->spa.height, i, j;
1206
1207         buf = (unsigned char *) g_malloc (w * h * 3);
1208
1209         ptr = buf;
1210
1211         /* possibe optimization: as we are drawing grayscale plane, there might
1212            be some simpler algorithm to do this*/
1213         rgbtmp[0] = 0x00ffffff;
1214         rgbtmp[1] = 0x00000000;
1215         rgbtmp[2] = 0x00000000;
1216
1217         rgby[0] = rgbtmp[0] - rgbx[0];
1218         rgby[1] = rgbtmp[1] - rgbx[1];
1219         rgby[2] = rgbtmp[2] - rgbx[2];
1220
1221         rgbx[0] /= priv->spa.width;
1222         rgbx[1] /= priv->spa.width;
1223         rgbx[2] /= priv->spa.width;
1224
1225         rgby[0] /= tmp;
1226         rgby[1] /= tmp;
1227         rgby[2] /= tmp;
1228
1229         rgbx[0] += (y - priv->spa.y) * rgby[0];
1230         rgbx[1] += (y - priv->spa.y) * rgby[1];
1231         rgbx[2] += (y - priv->spa.y) * rgby[2];
1232
1233         for(i = 0; i < h; i++) {
1234             rgbtmp[0] = rgbx[0] * (x - priv->spa.x);
1235             rgbtmp[1] = rgbx[1] * (x - priv->spa.x);
1236             rgbtmp[2] = rgbx[2] * (x - priv->spa.x);
1237
1238             for(j = 0; j < w; j++) {
1239                 avg = (rgbtmp[0] + rgbtmp[1] + rgbtmp[2])/3;
1240                 avg >>= 16;
1241                 ptr[0] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
1242                 ptr[1] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
1243                 ptr[2] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
1244                 rgbtmp[0] += rgbx[0];
1245                 rgbtmp[1] += rgbx[1];
1246                 rgbtmp[2] += rgbx[2];
1247                 ptr += 3;
1248             }
1249
1250             rgbx[0] += rgby[0];
1251             rgbx[1] += rgby[1];
1252             rgbx[2] += rgby[2];
1253         }
1254
1255         priv->dimmed_plane = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w * 3, (gpointer) g_free, buf);
1256     }
1257
1258     gdk_draw_pixbuf (widget->parent->window, widget->style->fg_gc [0], priv->dimmed_plane, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
1259 }
1260
1261
1262 static gboolean 
1263 hildon_color_chooser_expose_timer               (gpointer data)
1264 {
1265     HildonColorChooser *sel = HILDON_COLOR_CHOOSER (data);
1266     HildonColorChooserPrivate *priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (sel);
1267
1268     g_assert (priv);
1269
1270     if (priv->expose_info.expose_queued) {
1271         gtk_widget_queue_draw (GTK_WIDGET (data));
1272     }
1273
1274     return FALSE;
1275 }
1276
1277 /**
1278  * hildon_color_chooser_get_color:
1279  * @chooser: a #HildonColorChooser
1280  * @color: a color structure to fill with the currently selected color
1281  *
1282  * Retrives the currently selected color in the chooser.
1283  *
1284  */
1285 void
1286 hildon_color_chooser_get_color                  (HildonColorChooser *chooser, 
1287                                                  GdkColor *color)
1288 {
1289     HildonColorChooserPrivate *priv;
1290     GdkVisual *system_visual = gdk_visual_get_system ();
1291     unsigned long rgb[3], rgb2[3];
1292
1293     g_return_if_fail (HILDON_IS_COLOR_CHOOSER (chooser));
1294     g_return_if_fail (color != NULL);
1295
1296     priv = HILDON_COLOR_CHOOSER_GET_PRIVATE (chooser);
1297     g_assert (priv);
1298
1299     inline_h2rgb (priv->currhue, rgb);
1300
1301     rgb2[0] = 0xffffff - rgb[0];
1302     rgb2[1] = 0xffffff - rgb[1];
1303     rgb2[2] = 0xffffff - rgb[2];
1304
1305     color->red   = ((rgb[0] >> 8) + ((rgb2[0] >> 8) * (0xffff - priv->currsat) / 0xffff)) * priv->currval / 0xffff;
1306     color->green = ((rgb[1] >> 8) + ((rgb2[1] >> 8) * (0xffff - priv->currsat) / 0xffff)) * priv->currval / 0xffff;
1307     color->blue  = ((rgb[2] >> 8) + ((rgb2[2] >> 8) * (0xffff - priv->currsat) / 0xffff)) * priv->currval / 0xffff;
1308
1309     color->pixel = ((color->red >> (16 - system_visual->red_prec)) << system_visual->red_shift) |
1310         ((color->green >> (16 - system_visual->green_prec)) << system_visual->green_shift) |
1311         ((color->blue >> (16 - system_visual->blue_prec)) << system_visual->blue_shift);
1312 }
1313
1314 /**
1315  * hildon_color_chooser_new:
1316  *
1317  * Creates a new #HildonColorChooser.
1318  *
1319  * Returns: the new #HildonColorChooser
1320  **/
1321 GtkWidget*
1322 hildon_color_chooser_new                        (void)
1323 {
1324     return (GtkWidget *) g_object_new (HILDON_TYPE_COLOR_CHOOSER, NULL);
1325 }
1326
1327 static void
1328 hildon_color_chooser_set_property               (GObject *object, 
1329                                                  guint param_id,
1330                                                  const GValue *value, 
1331                                                  GParamSpec *pspec)
1332 {
1333     g_return_if_fail (HILDON_IS_COLOR_CHOOSER (object));
1334
1335     switch (param_id) 
1336     {
1337
1338         case PROP_COLOR: {
1339             GdkColor *color = g_value_get_boxed (value);
1340             hildon_color_chooser_set_color ((HildonColorChooser *) object, color);
1341             } break;
1342
1343         default:
1344             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
1345             break;
1346     }
1347 }
1348
1349 static void
1350 hildon_color_chooser_get_property               (GObject *object, 
1351                                                  guint param_id,
1352                                                  GValue *value, 
1353                                                  GParamSpec *pspec)
1354 {
1355     g_return_if_fail (HILDON_IS_COLOR_CHOOSER (object));
1356
1357     switch (param_id) 
1358     {
1359
1360         case PROP_COLOR: {
1361             GdkColor color;
1362             hildon_color_chooser_get_color ((HildonColorChooser *) object, &color);
1363             g_value_set_boxed (value, &color);
1364             } break;
1365
1366         default:
1367             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
1368             break;
1369     }
1370 }
1371
1372