~ubuntu-branches/ubuntu/saucy/yelp/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/06_setup_error_on_missing_dbus.patch/libyelp/yelp-settings.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2011-12-06 20:43:45 UTC
  • mfrom: (1.1.53) (2.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20111206204345-npwjyiz6kvrip28n
Tags: 3.2.1-0ubuntu1
* New upstream version, resynchronize on Debian, remaining diffs,
  we should probably promote libjs-jquery-ui in a next upload and revert the
  diff on that and rebase on the dfsg tarball from Debian
* debian/control.in:
  - don't Depends on libjs-jquery-ui, it's in universe
  - Build-Depends on lpi, dh-autoreconf, gnome-common
  - Suggest ttf-dejavu, instead of Recommend  
* debian/patches/00_no_am_gnu_gettext.patch:
  - Can't use both AM_GNU_GETTEXT and IT_PROG_INTLTOOL
* debian/patches/01_lpi.patch:
  - launchpad integration
* debian/patches/05_menu_tooltip.patch:
  - Change tooltip from "Get help with GNOME" to "Get help with Ubuntu"
* debian/patches/06_make_ubuntu_docs_default.patch
  - Use ubuntu-help as default instead of gnome-help
* debian/patches/07_disable_package_search.patch:
  - Remove "Search for packages containing this document" feature
    because it doesn't work in the default Ubuntu install
* debian/rules:
  - use autoreconf rule
* debian/yelp.install:
  - install the apport hook
* debian/yelp.links:
  - revert, we don't use libjs-jquery-ui

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 
2
/*
 
3
 * Copyright (C) 2004-2009 Shaun McCance <shaunm@gnome.org>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License as
 
7
 * published by the Free Software Foundation; either version 2 of the
 
8
 * License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public
 
16
 * License along with this program; if not, write to the
 
17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
 * Boston, MA 02111-1307, USA.
 
19
 *
 
20
 * Author: Shaun McCance <shaunm@gnome.org>
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include <config.h>
 
25
#endif
 
26
 
 
27
#include <stdarg.h>
 
28
 
 
29
#include <gtk/gtk.h>
 
30
#include <glib/gi18n.h>
 
31
 
 
32
#include "yelp-settings.h"
 
33
 
 
34
struct _YelpSettingsPriv {
 
35
    GMutex       *mutex;
 
36
 
 
37
    gchar         colors[YELP_SETTINGS_NUM_COLORS][8];
 
38
    gchar        *setfonts[YELP_SETTINGS_NUM_FONTS];
 
39
    gchar        *fonts[YELP_SETTINGS_NUM_FONTS];
 
40
    gchar        *icons[YELP_SETTINGS_NUM_ICONS];
 
41
    gint          icon_size;
 
42
 
 
43
    GtkSettings  *gtk_settings;
 
44
    GtkIconTheme *gtk_icon_theme;
 
45
 
 
46
    gint          font_adjustment;
 
47
 
 
48
    gulong        gtk_theme_changed;
 
49
    gulong        gtk_font_changed;
 
50
    gulong        icon_theme_changed;
 
51
 
 
52
    gboolean      show_text_cursor;
 
53
 
 
54
    gboolean      editor_mode;
 
55
 
 
56
    GHashTable   *env;
 
57
};
 
58
 
 
59
enum {
 
60
    COLORS_CHANGED,
 
61
    FONTS_CHANGED,
 
62
    ICONS_CHANGED,
 
63
    LAST_SIGNAL
 
64
};
 
65
static guint settings_signals[LAST_SIGNAL] = {0,};
 
66
 
 
67
enum {  
 
68
  PROP_0,
 
69
  PROP_GTK_SETTINGS,
 
70
  PROP_GTK_ICON_THEME,
 
71
  PROP_FONT_ADJUSTMENT,
 
72
  PROP_SHOW_TEXT_CURSOR,
 
73
  PROP_EDITOR_MODE
 
74
};
 
75
 
 
76
gchar *icon_names[YELP_SETTINGS_NUM_ICONS];
 
77
 
 
78
G_DEFINE_TYPE (YelpSettings, yelp_settings, G_TYPE_OBJECT);
 
79
#define GET_PRIV(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_SETTINGS, YelpSettingsPriv))
 
80
 
 
81
static void           yelp_settings_class_init   (YelpSettingsClass    *klass);
 
82
static void           yelp_settings_init         (YelpSettings         *settings);
 
83
static void           yelp_settings_constructed  (GObject              *object);
 
84
static void           yelp_settings_dispose      (GObject              *object);
 
85
static void           yelp_settings_finalize     (GObject              *object);
 
86
static void           yelp_settings_get_property (GObject              *object,
 
87
                                                  guint                 prop_id,
 
88
                                                  GValue               *value,
 
89
                                                  GParamSpec           *pspec);
 
90
static void           yelp_settings_set_property (GObject              *object,
 
91
                                                  guint                 prop_id,
 
92
                                                  const GValue         *value,
 
93
                                                  GParamSpec           *pspec);
 
94
 
 
95
static void           gtk_theme_changed          (GtkSettings          *gtk_settings,
 
96
                                                  GParamSpec           *pspec,
 
97
                                                  YelpSettings         *settings);
 
98
static void           gtk_font_changed           (GtkSettings          *gtk_settings,
 
99
                                                  GParamSpec           *pspec,
 
100
                                                  YelpSettings         *settings);
 
101
static void           icon_theme_changed         (GtkIconTheme         *theme,
 
102
                                                  YelpSettings         *settings);
 
103
 
 
104
static void           rgb_to_hsv                 (gdouble  r,
 
105
                                                  gdouble  g,
 
106
                                                  gdouble  b,
 
107
                                                  gdouble *h,
 
108
                                                  gdouble *s,
 
109
                                                  gdouble *v);
 
110
static void           hsv_to_hex                 (gdouble  h,
 
111
                                                  gdouble  s,
 
112
                                                  gdouble  v,
 
113
                                                  gchar    *str);
 
114
 
 
115
/******************************************************************************/
 
116
 
 
117
static void
 
118
yelp_settings_class_init (YelpSettingsClass *klass)
 
119
{
 
120
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
121
    gint i;
 
122
 
 
123
    object_class->constructed  = yelp_settings_constructed;
 
124
    object_class->dispose  = yelp_settings_dispose;
 
125
    object_class->finalize = yelp_settings_finalize;
 
126
    object_class->get_property = yelp_settings_get_property;
 
127
    object_class->set_property = yelp_settings_set_property;
 
128
 
 
129
    for (i = 0; i < YELP_SETTINGS_NUM_ICONS; i++) {
 
130
        switch (i) {
 
131
        case YELP_SETTINGS_ICON_BUG:
 
132
            icon_names[i] = "yelp-note-bug";
 
133
            break;
 
134
        case YELP_SETTINGS_ICON_IMPORTANT:
 
135
            icon_names[i] = "yelp-note-important";
 
136
            break;
 
137
        case YELP_SETTINGS_ICON_NOTE:
 
138
            icon_names[i] = "yelp-note";
 
139
            break;
 
140
        case YELP_SETTINGS_ICON_TIP:
 
141
            icon_names[i] = "yelp-note-tip";
 
142
            break;
 
143
        case YELP_SETTINGS_ICON_WARNING:
 
144
            icon_names[i] = "yelp-note-warning";
 
145
            break;
 
146
        default:
 
147
            g_assert_not_reached ();
 
148
        }
 
149
    }
 
150
 
 
151
    g_object_class_install_property (object_class,
 
152
                                     PROP_GTK_SETTINGS,
 
153
                                     g_param_spec_object ("gtk-settings",
 
154
                                                          _("GtkSettings"),
 
155
                                                          _("A GtkSettings object to get settings from"),
 
156
                                                          GTK_TYPE_SETTINGS,
 
157
                                                          G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
 
158
                                                          G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
 
159
 
 
160
    g_object_class_install_property (object_class,
 
161
                                     PROP_GTK_ICON_THEME,
 
162
                                     g_param_spec_object ("gtk-icon-theme",
 
163
                                                          _("GtkIconTheme"),
 
164
                                                          _("A GtkIconTheme object to get icons from"),
 
165
                                                          GTK_TYPE_ICON_THEME,
 
166
                                                          G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
 
167
                                                          G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
 
168
 
 
169
    g_object_class_install_property (object_class,
 
170
                                     PROP_FONT_ADJUSTMENT,
 
171
                                     g_param_spec_int ("font-adjustment",
 
172
                                                       _("Font Adjustment"),
 
173
                                                       _("A size adjustment to add to font sizes"),
 
174
                                                       -3, 10, 0,
 
175
                                                       G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
 
176
                                                       G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
 
177
 
 
178
    g_object_class_install_property (object_class,
 
179
                                     PROP_SHOW_TEXT_CURSOR,
 
180
                                     g_param_spec_boolean ("show-text-cursor",
 
181
                                                           _("Show Text Cursor"),
 
182
                                                           _("Show the text cursor or caret for accessible navigation"),
 
183
                                                           FALSE,
 
184
                                                           G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
 
185
                                                           G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
 
186
 
 
187
    g_object_class_install_property (object_class,
 
188
                                     PROP_EDITOR_MODE,
 
189
                                     g_param_spec_boolean ("editor-mode",
 
190
                                                           _("Editor Mode"),
 
191
                                                           _("Enable features useful to editors"),
 
192
                                                           FALSE,
 
193
                                                           G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
 
194
                                                           G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
 
195
 
 
196
    settings_signals[COLORS_CHANGED] =
 
197
        g_signal_new ("colors-changed",
 
198
                      G_OBJECT_CLASS_TYPE (klass),
 
199
                      G_SIGNAL_RUN_LAST,
 
200
                      0, NULL, NULL,
 
201
                      g_cclosure_marshal_VOID__VOID,
 
202
                      G_TYPE_NONE, 0);
 
203
 
 
204
    settings_signals[FONTS_CHANGED] =
 
205
        g_signal_new ("fonts-changed",
 
206
                      G_OBJECT_CLASS_TYPE (klass),
 
207
                      G_SIGNAL_RUN_LAST,
 
208
                      0, NULL, NULL,
 
209
                      g_cclosure_marshal_VOID__VOID,
 
210
                      G_TYPE_NONE, 0);
 
211
 
 
212
    settings_signals[ICONS_CHANGED] =
 
213
        g_signal_new ("icons-changed",
 
214
                      G_OBJECT_CLASS_TYPE (klass),
 
215
                      G_SIGNAL_RUN_LAST,
 
216
                      0, NULL, NULL,
 
217
                      g_cclosure_marshal_VOID__VOID,
 
218
                      G_TYPE_NONE, 0);
 
219
 
 
220
    g_type_class_add_private (klass, sizeof (YelpSettingsPriv));
 
221
}
 
222
 
 
223
static void
 
224
yelp_settings_init (YelpSettings *settings)
 
225
{
 
226
    gint i;
 
227
 
 
228
    settings->priv = GET_PRIV (settings);
 
229
    settings->priv->mutex = g_mutex_new ();
 
230
    settings->priv->icon_size = 24;
 
231
 
 
232
    for (i = 0; i < YELP_SETTINGS_NUM_ICONS; i++)
 
233
        settings->priv->icons[i] = NULL;
 
234
    for (i = 0; i < YELP_SETTINGS_NUM_FONTS; i++) {
 
235
        settings->priv->setfonts[i] = NULL;
 
236
        settings->priv->fonts[i] = NULL;
 
237
    }
 
238
 
 
239
    settings->priv->env = g_hash_table_new_full (g_str_hash, g_str_equal,
 
240
                                                 g_free, NULL);
 
241
}
 
242
 
 
243
static void
 
244
yelp_settings_constructed (GObject *object)
 
245
{
 
246
    YelpSettings *settings = YELP_SETTINGS (object);
 
247
    GDBusConnection *connection;
 
248
    GVariant *ret, *names;
 
249
    GVariantIter iter;
 
250
    gchar *name;
 
251
    GError *error = NULL;
 
252
 
 
253
    connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
 
254
    if (connection == NULL) {
 
255
        g_warning ("Unable to connect to dbus: %s", error->message);
 
256
        g_error_free (error);
 
257
        return;
 
258
    }
 
259
 
 
260
    ret = g_dbus_connection_call_sync (connection,
 
261
                                       "org.freedesktop.DBus",
 
262
                                       "/org/freedesktop/DBus",
 
263
                                       "org.freedesktop.DBus",
 
264
                                       "ListNames",
 
265
                                       NULL,
 
266
                                       G_VARIANT_TYPE ("(as)"),
 
267
                                       G_DBUS_CALL_FLAGS_NONE,
 
268
                                       -1, NULL, &error);
 
269
    if (ret == NULL) {
 
270
        g_warning ("Unable to query dbus: %s", error->message);
 
271
        g_error_free (error);
 
272
        return;
 
273
    }
 
274
    names = g_variant_get_child_value (ret, 0);
 
275
    g_variant_iter_init (&iter, names);
 
276
    while (g_variant_iter_loop (&iter, "&s", &name)) {
 
277
        if (g_str_equal (name, "org.gnome.Panel"))
 
278
            yelp_settings_set_env (settings, "gnome-panel");
 
279
        else if (g_str_equal (name, "org.gnome.Shell"))
 
280
            yelp_settings_set_env (settings, "gnome-shell");
 
281
        else if (g_str_equal (name, "com.canonical.Unity"))
 
282
            yelp_settings_set_env (settings, "unity");
 
283
        else if (g_str_equal (name, "org.xfce.Panel"))
 
284
            yelp_settings_set_env (settings, "xfce");
 
285
    }
 
286
    g_variant_unref (names);
 
287
    g_variant_unref (ret);
 
288
}
 
289
 
 
290
static void
 
291
yelp_settings_dispose (GObject *object)
 
292
{
 
293
    YelpSettings *settings = YELP_SETTINGS (object);
 
294
 
 
295
    G_OBJECT_CLASS (yelp_settings_parent_class)->dispose (object);
 
296
}
 
297
 
 
298
static void
 
299
yelp_settings_finalize (GObject *object)
 
300
{
 
301
    YelpSettings *settings = YELP_SETTINGS (object);
 
302
 
 
303
    g_mutex_free (settings->priv->mutex);
 
304
 
 
305
    g_hash_table_destroy (settings->priv->env);
 
306
 
 
307
    G_OBJECT_CLASS (yelp_settings_parent_class)->finalize (object);
 
308
}
 
309
 
 
310
static void
 
311
yelp_settings_get_property (GObject    *object,
 
312
                            guint       prop_id,
 
313
                            GValue     *value,
 
314
                            GParamSpec *pspec)
 
315
{
 
316
    YelpSettings *settings = YELP_SETTINGS (object);
 
317
 
 
318
    switch (prop_id) {
 
319
    case PROP_GTK_SETTINGS:
 
320
        g_value_set_object (value, settings->priv->gtk_settings);
 
321
        break;
 
322
    case PROP_GTK_ICON_THEME:
 
323
        g_value_set_object (value, settings->priv->gtk_icon_theme);
 
324
        break;
 
325
    case PROP_FONT_ADJUSTMENT:
 
326
        g_value_set_int (value, settings->priv->font_adjustment);
 
327
        break;
 
328
    case PROP_SHOW_TEXT_CURSOR:
 
329
        g_value_set_boolean (value, settings->priv->show_text_cursor);
 
330
        break;
 
331
    case PROP_EDITOR_MODE:
 
332
        g_value_set_boolean (value, settings->priv->editor_mode);
 
333
        break;
 
334
    default:
 
335
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
336
        break;
 
337
    }
 
338
}
 
339
 
 
340
static void
 
341
yelp_settings_set_property (GObject      *object,
 
342
                            guint         prop_id,
 
343
                            const GValue *value,
 
344
                            GParamSpec   *pspec)
 
345
{
 
346
    YelpSettings *settings = YELP_SETTINGS (object);
 
347
 
 
348
    switch (prop_id) {
 
349
    case PROP_GTK_SETTINGS:
 
350
        if (settings->priv->gtk_settings) {
 
351
            g_signal_handler_disconnect (settings->priv->gtk_settings,
 
352
                                         settings->priv->gtk_theme_changed);
 
353
            g_signal_handler_disconnect (settings->priv->gtk_settings,
 
354
                                         settings->priv->gtk_font_changed);
 
355
            g_object_unref (settings->priv->gtk_settings);
 
356
        }
 
357
        settings->priv->gtk_settings = g_value_get_object (value);
 
358
        if (settings->priv->gtk_settings != NULL) {
 
359
            g_object_ref (settings->priv->gtk_settings);
 
360
            settings->priv->gtk_theme_changed =
 
361
                g_signal_connect (settings->priv->gtk_settings,
 
362
                                  "notify::gtk-theme-name",
 
363
                                  (GCallback) gtk_theme_changed,
 
364
                                  settings);
 
365
            settings->priv->gtk_font_changed =
 
366
                g_signal_connect (settings->priv->gtk_settings,
 
367
                                  "notify::gtk-font-name",
 
368
                                  (GCallback) gtk_font_changed,
 
369
                                  settings);
 
370
            gtk_theme_changed (settings->priv->gtk_settings, NULL, settings);
 
371
            gtk_font_changed (settings->priv->gtk_settings, NULL, settings);
 
372
        }
 
373
        else {
 
374
            settings->priv->gtk_theme_changed = 0;
 
375
            settings->priv->gtk_font_changed = 0;
 
376
        }
 
377
        break;
 
378
    case PROP_GTK_ICON_THEME:
 
379
        if (settings->priv->gtk_icon_theme) {
 
380
            g_signal_handler_disconnect (settings->priv->gtk_icon_theme,
 
381
                                         settings->priv->icon_theme_changed);
 
382
            g_object_unref (settings->priv->gtk_icon_theme);
 
383
        }
 
384
        settings->priv->gtk_icon_theme = g_value_get_object (value);
 
385
        if (settings->priv->gtk_icon_theme != NULL) {
 
386
            gchar **search_path;
 
387
            gint search_path_len, i;
 
388
            gboolean append_search_path = TRUE;
 
389
            gtk_icon_theme_get_search_path (settings->priv->gtk_icon_theme,
 
390
                                            &search_path, &search_path_len);
 
391
            for (i = search_path_len - 1; i >= 0; i--)
 
392
                if (g_str_equal (search_path[i], YELP_ICON_PATH)) {
 
393
                    append_search_path = FALSE;
 
394
                    break;
 
395
                }
 
396
            if (append_search_path)
 
397
                gtk_icon_theme_append_search_path (settings->priv->gtk_icon_theme,
 
398
                                                   YELP_ICON_PATH);
 
399
            append_search_path = TRUE;
 
400
            for (i = search_path_len - 1; i >= 0; i--)
 
401
                if (g_str_equal (search_path[i], DATADIR"/yelp/icons")) {
 
402
                    append_search_path = FALSE;
 
403
                    break;
 
404
                }
 
405
            if (append_search_path)
 
406
                gtk_icon_theme_append_search_path (settings->priv->gtk_icon_theme,
 
407
                                                   DATADIR"/yelp/icons");
 
408
            g_strfreev (search_path);
 
409
            g_object_ref (settings->priv->gtk_icon_theme);
 
410
            settings->priv->icon_theme_changed =
 
411
                g_signal_connect (settings->priv->gtk_icon_theme,
 
412
                                  "changed",
 
413
                                  (GCallback) icon_theme_changed,
 
414
                                  settings);
 
415
            icon_theme_changed (settings->priv->gtk_icon_theme, settings);
 
416
        }
 
417
        else {
 
418
            settings->priv->icon_theme_changed = 0;
 
419
        }
 
420
        break;
 
421
    case PROP_FONT_ADJUSTMENT:
 
422
        settings->priv->font_adjustment = g_value_get_int (value);
 
423
        gtk_font_changed (settings->priv->gtk_settings, NULL, settings);
 
424
        break;
 
425
    case PROP_SHOW_TEXT_CURSOR:
 
426
        settings->priv->show_text_cursor = g_value_get_boolean (value);
 
427
        break;
 
428
    case PROP_EDITOR_MODE:
 
429
        settings->priv->editor_mode = g_value_get_boolean (value);
 
430
        break;
 
431
    default:
 
432
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
433
        break;
 
434
    }
 
435
}
 
436
 
 
437
/******************************************************************************/
 
438
 
 
439
YelpSettings *
 
440
yelp_settings_get_default (void)
 
441
{
 
442
    static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
 
443
    static YelpSettings *settings = NULL;
 
444
    g_static_mutex_lock (&mutex);
 
445
    if (settings == NULL)
 
446
        settings = g_object_new (YELP_TYPE_SETTINGS,
 
447
                                 "gtk-settings", gtk_settings_get_default (),
 
448
                                 "gtk-icon-theme", gtk_icon_theme_get_default (),
 
449
                                 NULL);
 
450
    g_static_mutex_unlock (&mutex);
 
451
    return settings;
 
452
}
 
453
 
 
454
/******************************************************************************/
 
455
 
 
456
gchar *
 
457
yelp_settings_get_color (YelpSettings       *settings,
 
458
                         YelpSettingsColor   color)
 
459
{
 
460
    gchar *colorstr;
 
461
    g_return_val_if_fail (color < YELP_SETTINGS_NUM_COLORS, NULL);
 
462
 
 
463
    g_mutex_lock (settings->priv->mutex);
 
464
    colorstr = g_strdup (settings->priv->colors[color]);
 
465
    g_mutex_unlock (settings->priv->mutex);
 
466
 
 
467
    return colorstr;
 
468
}
 
469
 
 
470
gchar **
 
471
yelp_settings_get_colors (YelpSettings *settings)
 
472
{
 
473
    gchar **colors = g_new0 (gchar *, YELP_SETTINGS_NUM_COLORS + 1);
 
474
    gint i;
 
475
    for (i = 0; i < YELP_SETTINGS_NUM_COLORS; i++)
 
476
        colors[i] = yelp_settings_get_color (settings, i);
 
477
    return colors;
 
478
}
 
479
 
 
480
void
 
481
yelp_settings_set_colors (YelpSettings      *settings,
 
482
                          YelpSettingsColor  first_color,
 
483
                          ...)
 
484
{
 
485
    YelpSettingsColor color;
 
486
    va_list args;
 
487
 
 
488
    g_mutex_lock (settings->priv->mutex);
 
489
    va_start (args, first_color);
 
490
 
 
491
    color = first_color;
 
492
    while ((gint) color >= 0) {
 
493
        gchar *colorstr = va_arg (args, gchar *);
 
494
        gint i;
 
495
        for (i = 0; i < 7; i++) {
 
496
            settings->priv->colors[color][i] = colorstr[i];
 
497
            if (colorstr[i] == '\0')
 
498
                break;
 
499
        }
 
500
        settings->priv->colors[color][7] = '\0';
 
501
        color = va_arg (args, YelpSettingsColor);
 
502
    }
 
503
 
 
504
    va_end (args);
 
505
    g_mutex_unlock (settings->priv->mutex);
 
506
 
 
507
    g_signal_emit (settings, settings_signals[COLORS_CHANGED], 0);
 
508
}
 
509
 
 
510
const gchar*
 
511
yelp_settings_get_color_param (YelpSettingsColor color)
 
512
{
 
513
    static const gchar *params[YELP_SETTINGS_NUM_COLORS] = {
 
514
        "color.background",
 
515
        "color.text",
 
516
        "color.text_light",
 
517
        "color.link",
 
518
        "color.link_visted",
 
519
        "color.gray_background",
 
520
        "color.dark_background",
 
521
        "color.gray_border",
 
522
        "color.blue_background",
 
523
        "color.blue_border",
 
524
        "color.red_background",
 
525
        "color.red_border",
 
526
        "color.yellow_background",
 
527
        "color.yellow_border"
 
528
    };
 
529
    g_return_val_if_fail (color < YELP_SETTINGS_NUM_COLORS, NULL);
 
530
    return params[color];
 
531
}
 
532
 
 
533
/******************************************************************************/
 
534
 
 
535
gchar *
 
536
yelp_settings_get_font (YelpSettings     *settings,
 
537
                        YelpSettingsFont  font)
 
538
{
 
539
    gchar *ret;
 
540
    g_return_val_if_fail (font < YELP_SETTINGS_NUM_FONTS, NULL);
 
541
 
 
542
    g_mutex_lock (settings->priv->mutex);
 
543
    if (settings->priv->setfonts[font])
 
544
        ret = g_strdup (settings->priv->setfonts[font]);
 
545
    else
 
546
        ret = g_strdup (settings->priv->fonts[font]);
 
547
    g_mutex_unlock (settings->priv->mutex);
 
548
 
 
549
    return ret;
 
550
}
 
551
 
 
552
gchar *
 
553
yelp_settings_get_font_family (YelpSettings     *settings,
 
554
                               YelpSettingsFont  font)
 
555
{
 
556
    const gchar *def = (font == YELP_SETTINGS_FONT_VARIABLE) ? "Sans" : "Monospace";
 
557
    gchar *desc, *ret, *c; /* do not free */
 
558
    g_return_val_if_fail (font < YELP_SETTINGS_NUM_FONTS, NULL);
 
559
 
 
560
    g_mutex_lock (settings->priv->mutex);
 
561
 
 
562
    if (settings->priv->setfonts[font])
 
563
        desc = g_strdup (settings->priv->setfonts[font]);
 
564
    else
 
565
        desc = g_strdup (settings->priv->fonts[font]);
 
566
 
 
567
    if (desc == NULL) {
 
568
        ret = g_strdup (def);
 
569
        goto done;
 
570
    }
 
571
 
 
572
    c = strrchr (desc, ' ');
 
573
    if (c == NULL) {
 
574
        g_warning ("Cannot parse font: %s", desc);
 
575
        ret = g_strdup (def);
 
576
        goto done;
 
577
    }
 
578
 
 
579
    ret = g_strndup (desc, c - desc);
 
580
 
 
581
 done:
 
582
    g_mutex_unlock (settings->priv->mutex);
 
583
    return ret;
 
584
}
 
585
 
 
586
gint
 
587
yelp_settings_get_font_size (YelpSettings     *settings,
 
588
                             YelpSettingsFont  font)
 
589
{
 
590
    gchar *desc, *c; /* do not free */
 
591
    gint ret;
 
592
    g_return_val_if_fail (font < YELP_SETTINGS_NUM_FONTS, 0);
 
593
 
 
594
    g_mutex_lock (settings->priv->mutex);
 
595
 
 
596
    if (settings->priv->setfonts[font])
 
597
        desc = g_strdup (settings->priv->setfonts[font]);
 
598
    else
 
599
        desc = g_strdup (settings->priv->fonts[font]);
 
600
 
 
601
    if (desc == NULL) {
 
602
        ret = 10;
 
603
        goto done;
 
604
    }
 
605
 
 
606
    c = strrchr (desc, ' ');
 
607
    if (c == NULL) {
 
608
        g_warning ("Cannot parse font %s", desc);
 
609
        ret = 10;
 
610
        goto done;
 
611
    }
 
612
 
 
613
    ret = g_ascii_strtod (c, NULL);
 
614
 
 
615
 done:
 
616
    g_mutex_unlock (settings->priv->mutex);
 
617
    ret += settings->priv->font_adjustment;
 
618
    ret = (ret < 5) ? 5 : ret;
 
619
    return ret;
 
620
}
 
621
 
 
622
void
 
623
yelp_settings_set_fonts (YelpSettings     *settings,
 
624
                         YelpSettingsFont  first_font,
 
625
                         ...)
 
626
{
 
627
    YelpSettingsFont font;
 
628
    va_list args;
 
629
 
 
630
    g_mutex_lock (settings->priv->mutex);
 
631
    va_start (args, first_font);
 
632
 
 
633
    font = first_font;
 
634
    while ((gint) font >= 0) {
 
635
        gchar *fontname = va_arg (args, gchar *);
 
636
        if (settings->priv->setfonts[font] != NULL)
 
637
            g_free (settings->priv->setfonts[font]);
 
638
        settings->priv->setfonts[font] = g_strdup (fontname);
 
639
        font = va_arg (args, YelpSettingsFont);
 
640
    }
 
641
 
 
642
    va_end (args);
 
643
    g_mutex_unlock (settings->priv->mutex);
 
644
 
 
645
    g_signal_emit (settings, settings_signals[FONTS_CHANGED], 0);
 
646
}
 
647
 
 
648
gint
 
649
yelp_settings_get_font_adjustment (YelpSettings *settings)
 
650
{
 
651
    return settings->priv->font_adjustment;
 
652
}
 
653
 
 
654
void
 
655
yelp_settings_set_font_adjustment (YelpSettings *settings,
 
656
                                   gint          adjustment)
 
657
{
 
658
    g_object_set (settings, "font-adjustment", adjustment, NULL);
 
659
}
 
660
 
 
661
/******************************************************************************/
 
662
 
 
663
gint
 
664
yelp_settings_get_icon_size (YelpSettings *settings)
 
665
{
 
666
    return settings->priv->icon_size;
 
667
}
 
668
 
 
669
void
 
670
yelp_settings_set_icon_size (YelpSettings *settings,
 
671
                             gint          size)
 
672
{
 
673
    settings->priv->icon_size = size;
 
674
    if (settings->priv->gtk_icon_theme != NULL)
 
675
        icon_theme_changed (settings->priv->gtk_icon_theme, settings);
 
676
}
 
677
 
 
678
gchar *
 
679
yelp_settings_get_icon (YelpSettings     *settings,
 
680
                        YelpSettingsIcon  icon)
 
681
{
 
682
    gchar *ret;
 
683
    g_return_val_if_fail (icon < YELP_SETTINGS_NUM_ICONS, NULL);
 
684
 
 
685
    g_mutex_lock (settings->priv->mutex);
 
686
    ret = g_strdup (settings->priv->icons[icon]);
 
687
    g_mutex_unlock (settings->priv->mutex);
 
688
 
 
689
    return ret;
 
690
}
 
691
 
 
692
void
 
693
yelp_settings_set_icons (YelpSettings     *settings,
 
694
                         YelpSettingsIcon  first_icon,
 
695
                         ...)
 
696
{
 
697
    YelpSettingsIcon icon;
 
698
    va_list args;
 
699
 
 
700
    g_mutex_lock (settings->priv->mutex);
 
701
    va_start (args, first_icon);
 
702
 
 
703
    icon = first_icon;
 
704
    while ((gint) icon >= 0) {
 
705
        gchar *filename = va_arg (args, gchar *);
 
706
        if (settings->priv->icons[icon] != NULL)
 
707
            g_free (settings->priv->icons[icon]);
 
708
        settings->priv->icons[icon] = g_filename_to_uri (filename, NULL, NULL);
 
709
        icon = va_arg (args, YelpSettingsIcon);
 
710
    }
 
711
 
 
712
    va_end (args);
 
713
    g_mutex_unlock (settings->priv->mutex);
 
714
 
 
715
    g_signal_emit (settings, settings_signals[ICONS_CHANGED], 0);
 
716
}
 
717
 
 
718
const gchar *
 
719
yelp_settings_get_icon_param (YelpSettingsIcon icon)
 
720
{
 
721
    static const gchar *params[YELP_SETTINGS_NUM_ICONS] = {
 
722
        "icons.note.bug",
 
723
        "icons.note.important",
 
724
        "icons.note",
 
725
        "icons.note.tip",
 
726
        "icons.note.warning"
 
727
    };
 
728
    g_return_val_if_fail (icon < YELP_SETTINGS_NUM_ICONS, NULL);
 
729
    return params[icon];
 
730
}
 
731
 
 
732
/******************************************************************************/
 
733
 
 
734
gboolean
 
735
yelp_settings_get_show_text_cursor (YelpSettings *settings)
 
736
{
 
737
    return settings->priv->show_text_cursor;
 
738
}
 
739
 
 
740
void
 
741
yelp_settings_set_show_text_cursor (YelpSettings *settings,
 
742
                                    gboolean      show)
 
743
{
 
744
    g_object_set (settings, "show-text-cursor", show, NULL);
 
745
}
 
746
 
 
747
gboolean
 
748
yelp_settings_get_editor_mode (YelpSettings *settings)
 
749
{
 
750
    return settings->priv->editor_mode;
 
751
}
 
752
 
 
753
void
 
754
yelp_settings_set_editor_mode (YelpSettings *settings,
 
755
                               gboolean      editor_mode)
 
756
{
 
757
    g_object_set (settings, "editor-mode", editor_mode, NULL);
 
758
}
 
759
 
 
760
/******************************************************************************/
 
761
 
 
762
void
 
763
yelp_settings_set_env (YelpSettings *settings,
 
764
                       const gchar  *env)
 
765
{
 
766
    if (g_hash_table_lookup (settings->priv->env, env) == NULL) {
 
767
        gchar *ins = g_strdup (env);
 
768
        g_hash_table_insert (settings->priv->env, ins, ins);
 
769
    }
 
770
}
 
771
 
 
772
void
 
773
yelp_settings_unset_env (YelpSettings *settings,
 
774
                         const gchar  *env)
 
775
{
 
776
    g_hash_table_remove (settings->priv->env, env);
 
777
}
 
778
 
 
779
gboolean
 
780
yelp_settings_check_env (YelpSettings *settings,
 
781
                         const gchar  *env)
 
782
{
 
783
    return (g_hash_table_lookup (settings->priv->env, env) != NULL);
 
784
}
 
785
 
 
786
/******************************************************************************/
 
787
 
 
788
gchar **
 
789
yelp_settings_get_all_params (YelpSettings *settings,
 
790
                              gint          extra,
 
791
                              gint         *end)
 
792
{
 
793
    gchar **params;
 
794
    gint i, ix;
 
795
    GString *envstr;
 
796
    GList *envs, *envi;
 
797
 
 
798
    params = g_new0 (gchar *,
 
799
                     (2*YELP_SETTINGS_NUM_COLORS) + (2*YELP_SETTINGS_NUM_ICONS) + extra + 7);
 
800
 
 
801
    for (i = 0; i < YELP_SETTINGS_NUM_COLORS; i++) {
 
802
        gchar *val;
 
803
        ix = 2 * i;
 
804
        params[ix] = g_strdup (yelp_settings_get_color_param (i));
 
805
        val = yelp_settings_get_color (settings, i);
 
806
        params[ix + 1] = g_strdup_printf ("\"%s\"", val);
 
807
        g_free (val);
 
808
    }
 
809
    for (i = 0; i < YELP_SETTINGS_NUM_ICONS; i++) {
 
810
        gchar *val;
 
811
        ix = 2 * (YELP_SETTINGS_NUM_COLORS + i);
 
812
        params[ix] = g_strdup (yelp_settings_get_icon_param (i));
 
813
        val = yelp_settings_get_icon (settings, i);
 
814
        params[ix + 1] = g_strdup_printf ("\"%s\"", val);
 
815
        g_free (val);
 
816
    }
 
817
    ix = 2 * (YELP_SETTINGS_NUM_COLORS + YELP_SETTINGS_NUM_ICONS);
 
818
    params[ix++] = g_strdup ("icons.size.note");
 
819
    params[ix++] = g_strdup_printf ("%i", yelp_settings_get_icon_size (settings));
 
820
    params[ix++] = g_strdup ("yelp.editor_mode");
 
821
    if (settings->priv->editor_mode)
 
822
        params[ix++] = g_strdup ("true()");
 
823
    else
 
824
        params[ix++] = g_strdup ("false()");
 
825
 
 
826
    envstr = g_string_new ("'html");
 
827
    envs = g_hash_table_get_keys (settings->priv->env);
 
828
    for (envi = envs; envi != NULL; envi = envi->next) {
 
829
        g_string_append_c (envstr, ' ');
 
830
        g_string_append (envstr, (gchar *) envi->data);
 
831
    }
 
832
    g_string_append_c (envstr, '\'');
 
833
    g_list_free (envs);
 
834
    params[ix++] = g_strdup ("mal.if.env");
 
835
    params[ix++] = g_string_free (envstr, FALSE);
 
836
 
 
837
    params[ix] = NULL;
 
838
 
 
839
    if (end != NULL)
 
840
        *end = ix;
 
841
    return params;
 
842
}
 
843
 
 
844
/******************************************************************************/
 
845
 
 
846
static void
 
847
gtk_theme_changed (GtkSettings  *gtk_settings,
 
848
                   GParamSpec   *pspec,
 
849
                   YelpSettings *settings)
 
850
{
 
851
    GtkWidget *widget;
 
852
    GtkStyle  *style;
 
853
    GdkColor  *color;
 
854
    GdkColor   blue = { 0, 0x1E1E, 0x3E3E, 0xE7E7 };
 
855
    gdouble    base_h, base_s, base_v;
 
856
    gdouble    text_h, text_s, text_v;
 
857
    gint i;
 
858
 
 
859
    g_mutex_lock (settings->priv->mutex);
 
860
 
 
861
    style = gtk_rc_get_style_by_paths (gtk_settings,
 
862
                                       "GtkTextView", "GtkTextView",
 
863
                                       GTK_TYPE_TEXT_VIEW);
 
864
    if (style)
 
865
        g_object_ref (G_OBJECT (style));
 
866
    else
 
867
        style = gtk_style_new ();
 
868
 
 
869
 
 
870
    rgb_to_hsv (style->text[GTK_STATE_NORMAL].red / 65535.0,
 
871
                style->text[GTK_STATE_NORMAL].green / 65535.0,
 
872
                style->text[GTK_STATE_NORMAL].blue / 65535.0,
 
873
                &text_h, &text_s, &text_v);
 
874
    rgb_to_hsv (style->base[GTK_STATE_NORMAL].red / 65535.0,
 
875
                style->base[GTK_STATE_NORMAL].green / 65535.0,
 
876
                style->base[GTK_STATE_NORMAL].blue / 65535.0,
 
877
                &base_h, &base_s, &base_v);
 
878
 
 
879
    /* YELP_SETTINGS_COLOR_BASE */
 
880
    g_snprintf (settings->priv->colors[YELP_SETTINGS_COLOR_BASE], 8,
 
881
                "#%02X%02X%02X",
 
882
                style->base[GTK_STATE_NORMAL].red >> 8,
 
883
                style->base[GTK_STATE_NORMAL].green >> 8,
 
884
                style->base[GTK_STATE_NORMAL].blue >> 8);
 
885
 
 
886
    /* YELP_SETTINGS_COLOR_TEXT */
 
887
    g_snprintf (settings->priv->colors[YELP_SETTINGS_COLOR_TEXT], 8,
 
888
                "#%02X%02X%02X",
 
889
                style->text[GTK_STATE_NORMAL].red >> 8,
 
890
                style->text[GTK_STATE_NORMAL].green >> 8,
 
891
                style->text[GTK_STATE_NORMAL].blue >> 8);
 
892
 
 
893
    /* YELP_SETTINGS_COLOR_LINK */
 
894
    widget = gtk_link_button_new ("http://www.gnome.org");
 
895
    gtk_widget_style_get (widget, "link-color", &color, NULL);
 
896
    if (!color)
 
897
        color = &blue;
 
898
    g_snprintf (settings->priv->colors[YELP_SETTINGS_COLOR_LINK], 8,
 
899
                "#%02X%02X%02X",
 
900
                color->red >> 8,
 
901
                color->green >> 8,
 
902
                color->blue >> 8);
 
903
    if (color != &blue)
 
904
        gdk_color_free (color);
 
905
 
 
906
    /* YELP_SETTINGS_COLOR_LINK_VISITED */
 
907
    color = NULL;
 
908
    gtk_widget_style_get (widget, "visited-link-color", &color, NULL);
 
909
    if (color) {
 
910
        g_snprintf (settings->priv->colors[YELP_SETTINGS_COLOR_LINK_VISITED], 8,
 
911
                    "#%02X%02X%02X",
 
912
                    color->red >> 8,
 
913
                    color->green >> 8,
 
914
                    color->blue >> 8);
 
915
        gdk_color_free (color);
 
916
    }
 
917
 
 
918
    g_object_ref_sink (widget);
 
919
    g_object_unref (widget);
 
920
 
 
921
    /* YELP_SETTINGS_COLOR_TEXT_LIGHT */
 
922
    hsv_to_hex (text_h, 
 
923
                text_s,
 
924
                text_v - ((text_v - base_v) * 0.25),
 
925
                settings->priv->colors[YELP_SETTINGS_COLOR_TEXT_LIGHT]);
 
926
 
 
927
    /* YELP_SETTINGS_COLOR_GRAY */
 
928
    hsv_to_hex (base_h, 
 
929
                base_s,
 
930
                base_v - ((base_v - text_v) * 0.05),
 
931
                settings->priv->colors[YELP_SETTINGS_COLOR_GRAY_BASE]);
 
932
    hsv_to_hex (base_h, 
 
933
                base_s,
 
934
                base_v - ((base_v - text_v) * 0.1),
 
935
                settings->priv->colors[YELP_SETTINGS_COLOR_DARK_BASE]);
 
936
    hsv_to_hex (base_h, 
 
937
                base_s,
 
938
                base_v - ((base_v - text_v) * 0.26),
 
939
                settings->priv->colors[YELP_SETTINGS_COLOR_GRAY_BORDER]);
 
940
 
 
941
    /* YELP_SETTINGS_COLOR_BLUE */
 
942
    hsv_to_hex (211,
 
943
                0.1,
 
944
                base_v - ((base_v - text_v) * 0.01),
 
945
                settings->priv->colors[YELP_SETTINGS_COLOR_BLUE_BASE]);
 
946
    hsv_to_hex (211,
 
947
                0.45,
 
948
                base_v - ((base_v - text_v) * 0.19),
 
949
                settings->priv->colors[YELP_SETTINGS_COLOR_BLUE_BORDER]);
 
950
 
 
951
    /* YELP_SETTINGS_COLOR_RED */
 
952
    hsv_to_hex (0,
 
953
                0.13,
 
954
                base_v - ((base_v - text_v) * 0.01),
 
955
                settings->priv->colors[YELP_SETTINGS_COLOR_RED_BASE]);
 
956
    hsv_to_hex (0,
 
957
                0.83,
 
958
                base_v - ((base_v - text_v) * 0.06),
 
959
                settings->priv->colors[YELP_SETTINGS_COLOR_RED_BORDER]);
 
960
 
 
961
    /* YELP_SETTINGS_COLOR_YELLOW */
 
962
    hsv_to_hex (60,
 
963
                0.25,
 
964
                base_v - ((base_v - text_v) * 0.01),
 
965
                settings->priv->colors[YELP_SETTINGS_COLOR_YELLOW_BASE]);
 
966
    hsv_to_hex (60,
 
967
                1.0,
 
968
                base_v - ((base_v - text_v) * 0.07),
 
969
                settings->priv->colors[YELP_SETTINGS_COLOR_YELLOW_BORDER]);
 
970
 
 
971
    g_object_unref (G_OBJECT (style));
 
972
 
 
973
    g_mutex_unlock (settings->priv->mutex);
 
974
 
 
975
    g_signal_emit (settings, settings_signals[COLORS_CHANGED], 0);
 
976
}
 
977
 
 
978
static void
 
979
gtk_font_changed (GtkSettings  *gtk_settings,
 
980
                  GParamSpec   *pspec,
 
981
                  YelpSettings *settings)
 
982
{
 
983
    gchar *font, *c;
 
984
 
 
985
    /* This happens when font_adjustment is set during init */
 
986
    if (gtk_settings == NULL)
 
987
        return;
 
988
 
 
989
    g_free (settings->priv->fonts[YELP_SETTINGS_FONT_VARIABLE]);
 
990
    g_object_get (gtk_settings, "gtk-font-name", &font, NULL);
 
991
    settings->priv->fonts[YELP_SETTINGS_FONT_VARIABLE] = font;
 
992
 
 
993
    c = strrchr (font, ' ');
 
994
    if (c == NULL) {
 
995
        g_warning ("Cannot parse font: %s", font);
 
996
        font = g_strdup ("Monospace 10");
 
997
    }
 
998
    else {
 
999
        font = g_strconcat ("Monospace", c, NULL);
 
1000
    }
 
1001
 
 
1002
    g_free (settings->priv->fonts[YELP_SETTINGS_FONT_FIXED]);
 
1003
    settings->priv->fonts[YELP_SETTINGS_FONT_FIXED] = font;
 
1004
 
 
1005
    g_signal_emit (settings, settings_signals[FONTS_CHANGED], 0);
 
1006
}
 
1007
 
 
1008
static void
 
1009
icon_theme_changed (GtkIconTheme *theme,
 
1010
                    YelpSettings *settings)
 
1011
{
 
1012
    GtkIconInfo *info;
 
1013
    gint i;
 
1014
 
 
1015
    g_mutex_lock (settings->priv->mutex);
 
1016
 
 
1017
    for (i = 0; i < YELP_SETTINGS_NUM_ICONS; i++) {
 
1018
        if (settings->priv->icons[i] != NULL)
 
1019
            g_free (settings->priv->icons[i]);
 
1020
        info = gtk_icon_theme_lookup_icon (theme,
 
1021
                                           icon_names[i],
 
1022
                                           settings->priv->icon_size,
 
1023
                                           GTK_ICON_LOOKUP_NO_SVG);
 
1024
        if (info != NULL) {
 
1025
            settings->priv->icons[i] = g_filename_to_uri (gtk_icon_info_get_filename (info),
 
1026
                                                          NULL, NULL);
 
1027
            gtk_icon_info_free (info);
 
1028
        }
 
1029
        else {
 
1030
            settings->priv->icons[i] = NULL;
 
1031
        }
 
1032
    }
 
1033
 
 
1034
    g_mutex_unlock (settings->priv->mutex);
 
1035
 
 
1036
    g_signal_emit (settings, settings_signals[ICONS_CHANGED], 0);
 
1037
}
 
1038
 
 
1039
gint
 
1040
yelp_settings_cmp_icons (const gchar *icon1,
 
1041
                         const gchar *icon2)
 
1042
{
 
1043
    static const gchar *icons[] = {
 
1044
        "yelp-page-search-symbolic",
 
1045
        "yelp-page-video-symbolic",
 
1046
        "yelp-page-task-symbolic",
 
1047
        "yelp-page-tip-symbolic",
 
1048
        "yelp-page-problem-symbolic",
 
1049
        "yelp-page-ui-symbolic",
 
1050
        "yelp-page-symbolic",
 
1051
        NULL
 
1052
    };
 
1053
    gint i;
 
1054
    for (i = 0; icons[i] != NULL; i++) {
 
1055
        gboolean eq1 = icon1 ? g_str_has_prefix (icon1, icons[i]) : FALSE;
 
1056
        gboolean eq2 = icon2 ? g_str_has_prefix (icon2, icons[i]) : FALSE;
 
1057
        if (eq1 && eq2)
 
1058
            return 0;
 
1059
        else if (eq1)
 
1060
            return -1;
 
1061
        else if (eq2)
 
1062
            return 1;
 
1063
    }
 
1064
    if (icon1 == NULL && icon2 == NULL)
 
1065
        return 0;
 
1066
    else if (icon2 == NULL)
 
1067
        return -1;
 
1068
    else if (icon1 == NULL)
 
1069
        return 1;
 
1070
    else
 
1071
        return strcmp (icon1, icon2);
 
1072
}
 
1073
 
 
1074
/******************************************************************************/
 
1075
 
 
1076
static void
 
1077
rgb_to_hsv (gdouble r, gdouble g, gdouble b, gdouble *h, gdouble *s, gdouble *v)
 
1078
{
 
1079
    gdouble min, max, delta;
 
1080
 
 
1081
    max = (r > g) ? r : g;
 
1082
    max = (max > b) ? max : b;
 
1083
    min = (r < g) ? r : g;
 
1084
    min = (min < b) ? min : b;
 
1085
 
 
1086
    delta = max - min;
 
1087
 
 
1088
    *v = max;
 
1089
    *s = 0;
 
1090
    *h = 0;
 
1091
 
 
1092
    if (max != min) {
 
1093
        *s = delta / *v;
 
1094
 
 
1095
        if (r == max)
 
1096
            *h = (g - b) / delta;
 
1097
        else if (g == max)
 
1098
            *h = 2 + (b - r) / delta;
 
1099
        else if (b == max)
 
1100
            *h = 4 + (r - g) / delta;
 
1101
 
 
1102
        *h *= 60;
 
1103
        if (*h < 0.0)
 
1104
            *h += 360;
 
1105
    }
 
1106
}
 
1107
 
 
1108
static void
 
1109
hsv_to_hex (gdouble h, gdouble s, gdouble v, gchar *str)
 
1110
{
 
1111
    gint hue;
 
1112
    gdouble c;
 
1113
    gdouble m1, m2, m3;
 
1114
    gdouble r, g, b;
 
1115
    guint8 red, green, blue;
 
1116
 
 
1117
    c = v * s;
 
1118
    h /= 60;
 
1119
    hue = (int) h;
 
1120
    m1 = v * (1 - s);
 
1121
    m2 = v * (1 - s * (h - hue));
 
1122
    m3 = v * (1 - s * (-h + hue + 1));
 
1123
 
 
1124
    r = g = b = v;
 
1125
    switch (hue) {
 
1126
    case 0:
 
1127
        b = m1; g = m3; break;
 
1128
    case 1:
 
1129
        b = m1; r = m2; break;
 
1130
    case 2:
 
1131
        r = m1; b = m3; break;
 
1132
    case 3:
 
1133
        r = m1; g = m2; break;
 
1134
    case 4:
 
1135
        g = m1; r = m3; break;
 
1136
    case 5:
 
1137
        g = m1; b = m2; break;
 
1138
    }
 
1139
 
 
1140
    red = r * 255;
 
1141
    green = g * 255;
 
1142
    blue = b * 255;
 
1143
    g_snprintf (str, 8, "#%02X%02X%02X", red, green, blue);
 
1144
}